ad5e758721069654d084e8df4819e2bedc71fbb7
25
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
603319a145 |
Arbeitsschloss: zwei Sitzungen sehen sich jetzt
HEUTE ZWEIMAL NUR GUTGEGANGEN. Zwei Claude-Sitzungen arbeiteten
gleichzeitig in diesem Verzeichnis, ohne voneinander zu wissen.
Keine hat etwas falsch gemacht — sie konnten es nicht wissen.
* Beide haben `git add -A` benutzt. Haette die eine
unfestgeschriebene Arbeit der anderen im Baum gehabt, waere sie
mitcommittet worden — unter fremdem Namen, in einer fremden
Begruendung, und niemandem waere es aufgefallen. Nachgesehen:
diesmal war nichts dabei.
* Beide haben den Stempellauf gestartet. Der schreibt 45 Dateien
um. Wer dort eine offen hatte, bekam sie unter den Haenden weg
geaendert.
Dasselbe hat in RunOne am 03.09.2026 sieben Minuten Ausfall
gekostet. Dort gibt es seitdem `arbeitsschloss.sh`; diese Fassung
uebernimmt seine Lehren.
WAS ES IST UND WAS NICHT. Es ist kein Riegel — wer wirklich muss,
kommt vorbei. Es beantwortet die eine Frage, die heute niemand
beantworten konnte: „arbeitet hier gerade sonst jemand?"
Die teuren Fehler liegen bei einem Schloss alle in derselben
Richtung: Es blockiert zu viel und wird deshalb abgeschafft. Also:
* Es blockiert NICHT, wenn das Schloss DEINES ist. RunOnes erste
Fassung fragte „ist abgeschlossen" statt „haelt es jemand
anders" — damit haette, wer ordentlich abschliesst, nie mehr
ausliefern koennen. Dafuer gibt es `fremd`.
* Es VERFAELLT nach zwei Stunden, und dass da jemand war, steht
beim Uebernehmen dabei.
* Es blockiert NICHT, wenn es selbst unlesbar ist — dritter
Ausgang, kein Stillstand.
* Notausgang: SCHLOSS_ZWANG=ja git commit …
DAS PROBLEM, AN DEM RUNONE HAENGT, IST HIER GELOEST. Dort faellt die
Kennung im Zweifel auf den Systembenutzer zurueck, und zwei
Claudian-Sitzungen laufen BEIDE als `claudian` — die Sicherung griff
ausgerechnet zwischen den zwei Faellen nicht, fuer die sie gebaut
wurde. Deshalb ist dort `export ARBEITER=…` Pflicht, und Pflicht
heisst: man vergisst es.
Hier steht `CLAUDE_CODE_SESSION_ID` in jeder Sitzung und ist je
Sitzung verschieden (nachgesehen, 36 Zeichen UUID). Zwei Sitzungen
auf demselben Windows-Benutzer unterscheiden sich damit von selbst,
ohne dass jemand etwas tun muss. Reihenfolge: ARBEITER, dann
Sitzungskennung, dann Benutzername MIT Warnung.
NIEMAND MUSS DARAN DENKEN:
* die beiden Stempelwerkzeuge nehmen es selbst und geben es selbst
frei — auch nach einem Absturz und bei Strg+C (wie `bauen.sh` im
Shop; eines, an das man denken muss, wird vergessen und ab da
umgangen)
* `tools/git-haken/pre-commit` bricht jeden Commit ab, solange
jemand ANDERS das Schloss haelt. Das ist die Stelle, die heute
gefehlt hat: `git add -A` ist der Griff, den man ohne Nachdenken
macht, und gegen einen Reflex hilft keine Regel auf Papier.
* `core.hooksPath` statt `.git/hooks` — letzteres ist nicht
versioniert und waere nach einem Klon genau dann leer, wenn es
gebraucht wird.
GEPRUEFT, server/pruef-arbeitsschloss.mjs: 33 Pruefungen, 0 Fehler —
in einem WEGWERF-Verzeichnis mit eigenem git, damit kein echtes
Schloss angefasst wird. Darunter am echten git:
ohne Schloss committen -> geht (0)
mit dem EIGENEN Schloss -> geht (0)
mit einem FREMDEN Schloss -> bricht ab (1), nennt wer und warum
und es stehen genau ZWEI Commits da, nicht drei
SCHLOSS_ZWANG=ja -> kommt vorbei
ohne das Schloss-Werkzeug -> laesst durch
Dazu: verfallenes Schloss laesst durch, mit laengerer Frist blockt
dasselbe Schloss wieder (Gegenprobe), unlesbarer Inhalt und
unlesbarer Zeitstempel blockieren nicht.
Portnummern nach der neuen Pruefdatei nachgemessen: Pruefbereich bis
5415, 462 Nummern, 0 Kollisionen. pruef-struktur 75/0,
pruef-fingermass 5/0, pruef-ports 10/0.
In DEPLOY.md steht es jetzt an erster Stelle — eine Sicherung, von
der nur der weiss, der sie gebaut hat, ist die erste, die umgangen
wird.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
1afb38258c |
Anfuehrungszeichen: drei Loecher in meiner eigenen Wache
Die zweite Sitzung hat in den Praesentationen des Vaults 83 Stellen
gefunden — und damit auf Loecher in MEINER Wache gezeigt. Ich habe
sie nachgemessen, alle drei waren echt.
LOCH 1 — SIE SAH NUR `server/workspace-*.js`
Also ausgerechnet nicht `workspace.js`, die groesste Datei des
Hauses. Der weitere Filter fand dort sofort drei Stellen:
workspace.js:3404 Kanal „Chat-Moderation" (Protokoll)
workspace.js:3422 „${titel}" -> ${haus} (Protokoll)
workspace.js:3304 „${… || "ohne Titel"}" (siehe Loch 3)
Das ist heute der DRITTE Fall von „die Wache kennt nur die halbe
Menge" — nach pruef-struktur (sah nur die Pruefdateien, nicht die
Anwendung) und pruef-fingermass (sah keine variable Breite).
LOCH 2 — IHR AUSDRUCK GILT JE ZEILE
Ein `„`, das erst in der naechsten Zeile mit einem geraden `"`
schliesst, fiel durch. Gemessen: drei echte Faelle, zwei davon
sichtbarer Seitentext.
workspace/leistung.html „nicht / zugeordnet"
workspace/leistung.html „Backstage-Tabelle / einfuegen"
workspace/assets/js/ampel.js „noch ' + 'verbessern"
Beim letzten laeuft das Zitat ueber eine Zeichenketten-Verkettung.
Neue Regel ohne Fehlalarme: erst alle RICHTIG geschlossenen Paare
entfernen (auch mehrzeilig), dann die einzeilig falschen (die meldet
die alte Regel). Was danach noch ein `„` hat und binnen drei Zeilen
ein gerades `"`, ist ein Fund. Ausgenommen bleibt das Zeichen ALS
WERT — in `content: "„";` und in den Sprachtabellen ist das `„` der
Inhalt und das `"` die Begrenzung.
LOCH 3 — EINE AUSNAHME, DIE EINEN FUND VERSCHLUCKT HAT
Gefunden durch die ZAHL, nicht durch den Blick: Der weitere Filter
liess die Ausnahmen von 12 auf 13 steigen. Die dreizehnte war
`… „${zeile[titelSpalte] || "ohne Titel"}"`
Der Ausdruck blieb am `"` von `"ohne Titel"` haengen; als Inhalt kam
`${zeile[titelSpalte] || ` heraus, das endet auf ein Leerzeichen,
und damit galt „der Satz geht in der naechsten Zeile weiter". Das
echte Schlusszeichen stand hinter dem `}` und war gerade.
Dass die Ausnahmen gezaehlt UND genannt werden, hat ihn gefunden.
Genau dafuer steht die Zeile dort.
Behoben an der Wurzel: Anfuehrungszeichen innerhalb einer Einsetzung
`${…}` werden vorher durch X ersetzt, bei gleicher Laenge und
gleichen Zeilenumbruechen. Das nimmt einer ganzen Sorte
Fehlklassifizierung die Grundlage — die Ausnahmen fielen danach von
13 auf 11.
UND EIN VIERTES, BEIM MESSEN AUFGEFALLEN
`„Van-Van”` in assets/js/data-modis.js schliesst mit U+201D, dem
ENGLISCHEN Zeichen. Zweimal, beide Male in einer DEUTSCHEN Zeile
(`de:` und `"de-CH":`) — nicht einmal eine Uebersetzung, in der es
richtig waere. Eigene Regel dafuer, die keine Ausnahme braucht: Wer
mit `„` oeffnet, schliesst deutsch; in fremdsprachigen Zeilen steht
gar kein `„` am Anfang.
DIE AUSNAHMEZAHL IST JETZT STRENG. Sie stand auf „hoechstens 12" —
damit waere der Anstieg auf 13 nicht aufgefallen. Jetzt genau 11,
wie bei den Grundlinien in pruef-fingermass.
GEPRUEFT: pruef-struktur 68 -> 75 Pruefungen, 0 Fehler. Dazu
leistung-optik 59/0, ampel 47/0, treff 85/0, modi-verborgen 87/0 —
die Seiten, deren Text ich angefasst habe. Steuerzeichen: 830
Dateien, keines. Beide Stempel gesetzt.
Sechs echte Stellen berichtigt, vier neue Gegenproben.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
95c4599baa |
Anfuehrungszeichen: 199 falsche Schlusszeichen im sichtbaren Text
Deutsch oeffnet mit „ und schliesst mit “. An 199 Stellen, die ein
Mensch liest, stand als Schlusszeichen ein GERADES " -- „Nächstes"
statt „Nächstes“. Auf sechzehn oeffentlichen Seiten, in vierzig
Dateien des Workspace und in zwoelf Servermodulen, die Texte
verschicken.
Auf dem Bildschirm sieht man den Unterschied sofort. Beim Schreiben
nicht: Das gerade " liegt auf der Tastatur, die anderen nicht.
WARUM EIN ERSTER ANLAUF ZURUECKGENOMMEN WURDE
Ein gerades " ist an vielen Stellen SYNTAX und kein Schriftzeichen --
Grenze einer Zeichenkette, Grenze eines HTML-Attributs, Zeichen in
einem regulaeren Ausdruck. Wer stumpf ersetzt, macht aus
„<a href="https://… ein kaputtes Attribut
/^["'„»\s]+|["'“«.\s]+$/ einen kaputten Ausdruck
"… nichts „mal " + "eben …" eine kaputte Zeichenkette
DIE UNTERSCHEIDUNG LAEUFT AN MERKMALEN, NICHT AN EINER LISTE
< > = dazwischen -> HTML-Marke oder Attribut
endet auf Leerzeichen -> die Zeichenkette hoert hier auf, der
Satz geht in der naechsten Zeile weiter.
Ein deutsches Schlusszeichen steht NIE
hinter einem Leerzeichen.
Rueckstrich mittendrin -> regulaerer Ausdruck
${ ohne } -> mitten in einem Ausdruck
Eine Liste erlaubter Ausnahmen waere die naechste, die niemand
pflegt. Zwoelf Stellen bleiben dadurch stehen, alle zwoelf einzeln
angesehen und alle zwoelf zu Recht -- dort steht das richtige
Schlusszeichen ohnehin weiter unten im Satz.
Fuenf davon waren allerdings ECHTE Fehler HINTER dem Link
(`…>HasiDog</a>".`) -- die erste Regel hatte nur das Attribut
gesehen, nicht den Satz danach. Gezielt nachgezogen.
Ein maskiertes `\"` in workspace-vorlagen.js (28 Hooks) wird zu “ --
ohne Rueckstrich, denn “ begrenzt nichts.
KOMMENTARE BLEIBEN, WIE SIE SIND. Dort liest es niemand ausser mir;
eine Wache, die auch Kosmetik anmahnt, wird weggeklickt. Beim ersten
Messen fielen ausserdem acht Stellen aus buehne.html faelschlich an,
weil `/* */` in HTML (in <style> und <script>) nicht ausgeblendet
war -- jetzt schon.
DIE WACHE DAZU
pruef-struktur prueft es ab sofort mit derselben Regel: 322 Dateien
mit sichtbarem Text, 0 Funde, und die zwoelf bewussten Ausnahmen
werden GEZAEHLT und genannt (erlaubt: 12). Eine Ausnahme, die niemand
sieht, waechst -- und irgendwann steht der echte Fall darin.
GEPRUEFT
pruef-struktur 59 -> 68 Pruefungen, 0 Fehler
node --check auf allen geaenderten JS-Dateien
nachgemessen: 199 geaendert, 12 mit Grund stehen geblieben
gruen geblieben: bewerbung-aufgaben 163, nachwuchs 262,
reaktion 421, support 63, content 45, terminregel 35, treff 85
Und nachgesehen, ob eine Pruefung noch die alte Schreibweise
ERWARTET: 13 Fundstellen, alle dreizehn nur Text in ihrer eigenen
Ausgabe, keine einzige ein Vergleich mit dem Seitentext.
GEGENPROBE: In reaktion.html ein Schlusszeichen zurueckgedreht ->
„workspace/reaktion.html:546 „Nächstes"", mit Datei und Zeile. Und
die Erkennung einzeln gegen HTML-Attribut, fortgesetzte
Zeichenkette, regulaeren Ausdruck und eingesetzten Wert geprueft.
Stempel gesetzt: workspace 670 Verweise in 45 Dateien, oeffentlich
554 in 48 Seiten.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
2c12b8706e |
Highlights des Teams sind sofort zu sehen -- ohne zweiten Klick
Filipe, 30.09.2026: „wenn wir bei highlights videos rein setzen will
ich nicht mehr dass wir sie freigeben muessen, sobald die reingesetzt
wurden sollen die sofort zu sehen sein."
=====================================================================
WAS ICH NICHT GETAN HABE, UND WARUM NICHT
=====================================================================
Die naheliegende Loesung waere gewesen, `highlight` aus
`TREFF_FREIGABE_BRETTER` zu streichen. Das waere falsch: Auf diesem
Brett laedt auch die COMMUNITY hoch -- Clips, Bilder, Fanart. Im
Quelltext steht woertlich daneben:
„Zwei Schloesser, weil hier fremde Inhalte hochgeladen werden --
Urheberrecht und Anstand sind nichts, was man nachtraeglich
klaert."
Filipe meint nicht das. Er meint: „wenn WIR videos rein setzen".
=====================================================================
DIE UNTERSCHEIDUNG STAND SCHON IM HAUS -- nur nicht im Code
=====================================================================
Derselbe Quelltext sagt ueber die zwei Freigabe-Bretter
Verschiedenes:
ansteht -> der SCHALTER „Im Treff zeigen". Das Team entscheidet
JE TERMIN, ob die Community ihn sieht.
highlight -> der Urheberrechts- und Anstandsfilter.
Ein Filter fragt „hat das jemand angesehen?". Wenn der, der ihn
bedienen darf, den Eintrag SELBST anlegt, ist die Antwort ja. Genau
diese Begruendung steht seit dem Uebernehmen aus dem Katalog im
Haus: „Eine zweite daneben waere keine Sicherheit, sondern ein
Klick."
Ein Schalter dagegen ist eine Entscheidung je Fall. Termine bleiben
deshalb unberuehrt -- sonst stuende jeder interne Termin sofort im
Treff, und danach hat niemand gefragt.
Neu: `FREIGABE_IST_FILTER` und `sofortFreigeben()` in
workspace-treff.js. DIE BEDINGUNG FRAGT DIE ROLLE, NICHT DEN WEG --
waere der Weg gefragt, waere aus dem Filter ein Loch geworden, sobald
jemand einen zweiten Weg baut. Ein Community-Mitglied ab „Stamm"
darf weiterhin einstellen; sein Eintrag wartet auf das Team.
Gerufen an ZWEI Stellen: beim Videoweg und beim Anlegen von Hand.
Beide hatten es bisher nicht.
=====================================================================
DIE VORHANDENE FREIGABEPRUEFUNG BEWEIST DAS NICHT
=====================================================================
Sie blieb nach der Aenderung gruen -- und das zu Recht: Sie legt ihre
Eintraege unmittelbar in der Datenbank an und prueft damit den
Mechanismus, nicht den Weg. Haette ich mich darauf verlassen, waere
eine Aenderung ausgeliefert worden, fuer die keine Zeile spricht.
pruef-treff (+5): DogFather legt ueber den echten Weg an -> die
Community sieht es SOFORT. Ein TERMIN bleibt verborgen. Die Regel
gibt fuer eine Rolle von aussen NICHT frei und fuer Termine
ueberhaupt nicht.
pruef-video (+3): Der Videoweg hat seinen eigenen Aufruf -- genau
dort wird einer vergessen. Geprueft wird die Freigabezeile selbst,
samt Gegenprobe „freigegeben ist nur, was auch angelegt wurde".
Meinen Abschnitt hatte ich erst HINTER das Abschalten des
nachgebauten TikTok-Dienstes gehaengt -- der Kopf der Datei warnt
woertlich davor („das Abschalten steht ganz hinten"). Gelesen habe
ich ihn, als es rot wurde.
UND `pruef-struktur` HAT MEINE EIGENE NEUE ZEILE GEFANGEN: Sie bildete
das Datum aus UTC statt Ortszeit -- zwischen Mitternacht und zwei Uhr
waere es der falsche Tag gewesen. Behoben mit `tagLokal()`, Minuten
nach dem Schreiben.
Gemessen: pruef-treff 85/0 (war 80), pruef-video 74/0 (war 71),
pruef-highlights 31/0, pruef-bereiche-lesend 37/0,
pruef-treff-werkzeuge 73/0, pruef-alle-sehen-es 43/0,
pruef-community-sicht 10/0, pruef-wege-nach-draussen 67/0,
pruef-struktur 44/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
f53791cefd |
Dritte Schicht: auch die Webdesign-Seiten trugen Stempel vom August
Nach den 35 oeffentlichen Seiten und den zwei Zahlen des Service
Workers lag dieselbe Faeulnis noch eine Ebene tiefer:
webdesign/*.html 49x ?v=20260823wd20 (23. August)
1x ?v=20260825wd51 (25. August)
Zwei VERSCHIEDENE Stempel in 13 Seiten, und beide aus dem August. Sie
verweisen auf dieselben Dateien wie die Startseite -- darunter
`main.css` --, und der Server schickt dazu ein Jahr `immutable`. Wer
den Bereich seit August besucht hatte, hatte sie eingefroren, ganz
unabhaengig vom Service Worker.
Dritte Schicht desselben Fehlers an einem Vormittag. Alle drei hatten
dieselbe Ursache: eine Zahl, die ein Mensch pflegen sollte.
Der Stempler nimmt die 13 Seiten jetzt mit -- 554 Verweise in 48
Seiten, EIN Stempel. `workspace/` bleibt ausgenommen: Dort arbeitet
`workspace-stempel.mjs`, und zwei Werkzeuge auf demselben Ordner
waeren zwei Antworten auf dieselbe Frage.
Und die Wache liest sie mit. Haette sie nur die Wurzel gelesen, waere
sie gruen gewesen und haette die Haelfte geprueft -- genau die Sorte
gruener Haken, die nichts bedeutet.
Viermal heute ist mir beim Schreiben ein Backslash durch die Shell
verlorengegangen (`\1` wurde zum Steuerzeichen, `\\` zu nichts).
Die Hausnotiz sagt das seit Langem; ich habe es viermal trotzdem
gemacht. Ab jetzt: alles mit Backslash geht durch das Werkzeug, nicht
durch die Befehlszeile.
Gemessen: pruef-zwischenspeicher 34/0, pruef-bewegung 9/0,
pruef-css-klassen 37/0, pruef-struktur 44/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
12fa0e45ba |
Der Webdesign-Bereich lieferte seit dem 27.08. ein veraltetes main.css aus
Der Stempel-Fund von eben hatte eine Fortsetzung: DEPLOY.md verlangte
seit dem 26.08. „ZWEI Zahlen hochzaehlen", mit Begruendung und
Messwerten daneben.
webdesign/sw.js const CACHE_NAME = "dogfather-webdesign-v64"
assets/js/wd-core.js .register("/webdesign/sw.js?v=64", …)
Gemessen am 30.09.2026 standen beide seit dem 27.08. auf v64 --
waehrend SIEBEN Commits die Dateien geaendert hatten, die der Service
Worker vorhaelt. Er haelt sechs vor, und `/assets/css/main.css` ist
eine davon.
Wer den Webdesign-Bereich einmal geoeffnet hatte, bekam sie seither
aus seinem Zwischenspeicher. Auch die Behebung von heute Vormittag
waere dort nicht angekommen.
EIN KOMMENTAR, DER VOR EINEM FEHLER WARNT, VERHINDERT IHN NICHT. Die
Anleitung war richtig, ausfuehrlich und begruendet. Getan hat es
trotzdem niemand -- fuenf Wochen lang. Das ist dieselbe Lehre wie am
11.09., als ein Warnhinweis neben einer abgeschriebenen Spaltenliste
stand und drei Spalten mit Inhalt trotzdem verlorengingen.
DESHALB MACHT ES JETZT DAS WERKZEUG. `tools/seiten-stempel.mjs`
setzt beide Zahlen auf denselben Stempel wie die Seiten. Passt eines
der zwei Muster nicht mehr, bricht es ab, statt stillschweigend
weiterzulaufen -- sonst waere die Zahl ab da wieder von Hand
gepflegt, und das merkt niemand.
Dass der Vorrat bei jedem Stempeln neu aufgebaut wird, ist Absicht:
sechs kleine Dateien kosten nichts, ein unbemerkt alter Stand fuenf
Wochen.
UND EINE WACHE DAZU. `pruef-zwischenspeicher` prueft jetzt:
· beide Zahlen stehen da
· sie sind GLEICH -- sonst wird der Vorrat geleert, aber der
Service Worker gar nicht erst neu geladen (Cloudflare ersetzt
sein `no-cache` durch vier Stunden)
· die Zahl ist nicht aelter als die vorgehaltenen Dateien
Die Liste der vorgehaltenen Dateien wird AUS DEM SERVICE WORKER
gelesen, nicht abgeschrieben -- eine zweite hier waere die, die beim
naechsten Eintrag auseinanderlaeuft.
Gegenprobe gemacht: die zwei Zahlen um eine Minute auseinander ->
rot, zurueck -> gruen.
DEPLOY.md sagt jetzt, dass es automatisch geht, und nennt den Befund
im Wortlaut daneben.
Gemessen: pruef-zwischenspeicher 34/0 (war 30/0), pruef-bewegung 9/0,
pruef-css-klassen 37/0, pruef-struktur 44/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
68b421b79a |
Zahlungen-Bühne: besserer Bildausschnitt statt flacher Mitte
Das cryo-kristall-Motiv (Zahlungen) ist als einziges der sechs HOCHKANT (702x941) statt quer (1672x941). Auf der breiten 16:9-Bühne zeigt "cover" davon nur einen horizontalen Streifen -- der mittige (Standard center center) traf die unruhigen Kristallsplitter und wirkte flach und beschnitten. Jetzt zeigt Zahlungen den oberen Streifen (background-position center 15%): die eleganten geschwungenen Kristallbänder rechts als Blickfang, links ruhiger dunkler Raum für die Karten -- eine klare Komposition wie bei den anderen Motiven. Nur für Zahlungen überschrieben, die übrigen fünf bleiben mittig. Nebenbei: Der Wert kommt aus --vw-blick, das für alle Bereiche längst definiert, bisher aber nirgends ausgelesen wurde (toter Code). Die neue .vw-buehne-Ausnahme wendet ihn für Zahlungen erstmals an. Service-Worker-Cache v63 -> v64 (beide Stellen), damit Geräte mit der App den neuen Ausschnitt bekommen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
40714b382e |
"Es fehlt: —." war ein Satz ohne Aussage
Beim optischen Durchsehen der Handy-Aufnahmen gefunden: Im Bereich
Zahlungen stand woertlich
NOCH NICHT EINGERICHTET
Es fehlt: —. Solange sagt das Kundenportal freundlich Bescheid …
Kommt die Liste der fehlenden Angaben leer zurueck -- etwa weil der
Server sie nicht mitschickt --, fiel der Text auf einen Gedankenstrich
zurueck. Man liest eine Fehlermeldung, die nicht sagt, was fehlt, und
sucht dann bei den Zugangsdaten statt bei der Antwort des Servers.
Jetzt zwei getrennte Saetze: einer, wenn bekannt ist WAS fehlt, und
einer fuer den Fall, dass nur bekannt ist DASS etwas fehlt.
Ein Rueckfallwert, der aussieht wie eine Angabe, ist schlechter als
gar keiner -- er beantwortet die Frage scheinbar und schickt einen in
die falsche Richtung.
Nebenbei geprueft und in Ordnung: Der Installationshinweis am unteren
Rand verdeckt nichts dauerhaft; er schafft sich seinen Platz ueber ein
gemessenes padding-bottom (steht seit dem 23.08.2026 so drin, damals
blockierte er den Annehmen-Knopf).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
504965e875 |
Push-Zustand macht der Uebersicht keinen Platz mehr streitig
Ein Gesamtdurchlauf aller Suiten nach dem heutigen Tag hat vier Fehlschlaege in pruef-handy.mjs gezeigt -- eine Regression aus meiner eigenen Arbeit. DIE URSACHE Die Karte zum Zustand der Benachrichtigung stand als ausgewachsener Block ganz oben in der Uebersicht. Auf dem Handy schob sie die erste Kennzahl auf 513 Punkte nach unten: Man oeffnete die Verwaltung und sah zuerst einen Hinweis, die Arbeit erst nach dem Scrollen. ZWEI ANLAEUFE, WEIL DER ERSTE ZU KURZ SPRANG Zuerst wurde nur der GUTE Fall zu einer Zeile. Das half nichts -- im Pruefbrowser sind Benachrichtigungen blockiert, also griff weiterhin der Zweig mit der grossen Karte. Eine Aenderung, die nur den Fall behebt, den man gerade vor Augen hat, ist keine. Jetzt sind alle drei Zustaende eine Zeile mit Punkt und Kurztext, die Erklaerung erst beim Aufklappen. Und der gute Zustand steht am ENDE der Uebersicht statt oben: Eine Bestaetigung, dass nichts zu tun ist, gehoert nicht an den Anfang. Oben bleibt nur, was Handlung verlangt. Ergebnis: 513 -> 204 Punkte bis zum Ende des Kopfbereichs, Laenge 2635 -> 2028. DREI RUNDUNGSFAELLE .wd-btn--klein und zwei summary-Elemente kamen mit Rahmen und Zeilenhoehe auf 43,x Punkte. Der Test vergleicht mit "< 44", gibt aber gerundet "44" aus -- man sucht dann einen Fehler in einer Zahl, die richtig aussieht. Jetzt 44.5 bzw. 46; optisch aendert das nichts. ZWEI PRUEFUNGEN PRAEZISIERT, NICHT AUFGEWEICHT 1. "Erste Zahl im oberen Drittel" mass ab dem Seitenanfang und schlug damit auch bei einer BERECHTIGTEN Warnung an. Ein Test, der Warnungen als Mangel zaehlt, erzieht dazu, sie zu verstecken. Er misst jetzt den festen Kopfbereich (Titel, Suche, Reiter) -- also das, was man nicht wegbekommt. 2. Die Folgepruefung mass zunaechst Punkte-Abstaende. Das war fragil: Der Reiterstreifen klebt beim Scrollen oben fest, eine Messung lieferte -204. Sie zaehlt jetzt HINWEISBLOECKE statt Punkte -- unabhaengig von Scrollposition und Schriftgroesse. Gemeint war ohnehin "hoechstens eine Meldung", nicht "hoechstens 140px". 56/56 in pruef-handy, alle uebrigen Suiten unveraendert gruen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
c03793b25f |
Oberflaeche fuer Auskunft und Loeschung
Sitzt im Kunden-Bereich, zugeklappt. Ein eigener Reiter waere zu prominent fuer etwas, das man vielleicht zweimal im Jahr braucht -- ganz weglassen hiesse, im Ernstfall von Hand durch ein Dutzend Tabellen zu suchen, bei laufender Monatsfrist. DREI SCHRITTE, IN DIESER REIHENFOLGE Auskunft erstellen unschaedlich, jederzeit Loeschvorschau zeigt, was betroffen waere Loeschen nur nach Vorschau, mit doppelter Eingabe Die Auskunft laesst sich als Datei herunterladen, nicht nur ansehen. Man muss sie der Person schicken koennen, und zwar vollstaendig -- abtippen waere der sicherste Weg, etwas zu vergessen. JSON, weil Art. 20 DSGVO ein "gaengiges, maschinenlesbares Format" verlangt. Die Vorschau zeigt beides getrennt: was geloescht wuerde, und was bleiben muss -- mit Grund und mit dem Datum, ab dem es weg darf. Ohne diese Angabe muesste man bei jeder Anfrage neu nachschlagen, welche Frist gilt. Vor dem Loeschen wird die Adresse ein zweites Mal verlangt. Der Unterschied zwischen .de und .com ist ein Buchstabe, die Folge unwiederbringlich. GEPRUEFT Im Handy-Format mit nachgebildeten Antworten: Auskunft zeigt die Bereiche samt Kennzeichnung "aufbewahrungspflichtig", der Herunterladen-Knopf erscheint, die Vorschau trennt richtig, eine abweichende Bestaetigung wird abgelehnt. Kein Ueberlauf, keine Skriptfehler. Die Handy-Suite bleibt bei 25/25, keine Namenskollision. Ein Fehler lag dabei im Test selbst: Playwright prueft die ZULETZT registrierte Route zuerst, und meine allgemeine Auffangregel ueberdeckte die spezifischen. Die Auskunft meldete "nichts gespeichert", obwohl die Oberflaeche richtig arbeitete. Die Endpunkte dazu liegen in server-internal und brauchen noch einen Deploy durch Filipe (/home/dogiintern, Rechte 700). Bis dahin meldet die Oberflaeche einen 404 -- mit dem Hinweis, dass der Server einen Neustart mit dem neuen Stand braucht, statt nur "Fehler" zu sagen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
ea11cefe17 |
Verwaltung auf dem Handy: vier Fehler behoben
Geprueft mit nachgebildeten Daten -- lange Firmennamen, lange
E-Mail-Adressen, mehrstellige Betraege. Eine leere Seite laeuft nie
ueber; die Fehler, um die es geht, entstehen erst mit Inhalt.
1. DAS RASTER DER KOPFZEILE WAR BREITER ALS SEIN BEHAELTER
Auf 390px summierten sich die beiden Spalten auf 372,7px, waehrend die
Leiste nur 358px breit ist. Rasterspalten schrumpfen von sich aus nicht
unter ihren Inhalt ("min-width: auto"). Alles darin schob sich nach
rechts hinaus: die Kopfzeile 8px, der Reiterstreifen 12px.
Sichtbar war das kaum -- der Streifen ist ohnehin wischbar, rechts
fehlte nur ein Stueck Rand. Genau deshalb blieb es liegen: ein Fehler,
der sich als Eigenart tarnt. Jetzt minmax(0, …) plus min-width: 0 an
den Kindern; lange Titel kuerzen mit Auslassungspunkten, statt zu
schieben.
2. DER INSTALLATIONSHINWEIS ZEIGTE DAS FALSCHE SYMBOL
Seit die Verwaltung eine eigene App ist, stand dort weiter der schwarze
Husky. Man las "Als App installieren" neben dem einen Bild und bekam
das andere auf den Startbildschirm. Das Symbol wird jetzt aus dem
Manifest abgeleitet, das die Seite tatsaechlich einbindet -- damit
stimmt es auch fuer jede kuenftige App, ohne dass jemand daran denken
muss.
3. DIE UEBERSICHT BRACH BEI UNVOLLSTAENDIGER ANTWORT AB
d.projekte und d.verlauf wurden ungeprueft mit .length angefasst,
waehrend drei andere Felder ausdruecklich geprueft wurden. Fehlte eine
der Listen, brach die Uebersicht mit "Cannot read properties of
undefined" ab -- und zwar NACH dem Aufbau der oberen Kacheln: Die halbe
Seite stand da, der Rest fehlte kommentarlos. Genau der Fall, den der
Kommentar daneben als "realistisch" beschreibt. Jetzt wird aufgefuellt
statt abgebrochen.
4. ZWEI FEHLALARME IM TEST SELBST
Der Test meldete den Reiterstreifen als Ueberlauf (er ist ein
Wischstreifen -- dass dort etwas ausserhalb liegt, ist sein Sinn) und
eine 1x1-Checkbox als zu kleines Tippziel (bedient wird sie ueber ihr
Label, 315x162 Punkte). Beides wuerde dazu verleiten, Funktionierendes
"zu reparieren". Der Test unterscheidet das jetzt.
Ebenso meldete er "Strg" und "Enter" mit 10,4px -- beide sind auf
schmalen Schirmen laengst ausgeblendet. getComputedStyle liefert auch
fuer verborgene Elemente eine Schriftgroesse; jetzt zaehlt nur
Sichtbares.
25 Pruefungen ueber sechs Bereiche gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
1608521854 |
Verwaltung ist jetzt eine eigene App
Wunsch: "ich will die verwaltungsseite auch getrennt runter laden koennen und installieren koenne." Bisher gab es ein Manifest fuer den ganzen Webdesign-Bereich; die Verwaltung war darin nur eine Verknuepfung. Jetzt hat sie ein eigenes mit eigener "id" -- der Wert, an dem alles haengt: Ohne ihn halten Browser beide fuer dieselbe App, und die zweite Installation ueberschreibt die erste, statt danebenzustehen. EIGENES SYMBOL Zwei gleich aussehende Kacheln auf dem Startbildschirm waeren keine Trennung. Das neue Symbol ist ein Ausschnitt des Eiskristall-Wappens -- dasselbe Motiv, das die Verwaltung ohnehin traegt, und klar unterscheidbar vom schwarzen Husky der oeffentlichen App. Erzeugt aus cryo-wappen.webp in drei Groessen, die beschneidbare Fassung weiter herausgezoomt, damit Android die Spitzen des Wappens nicht abschneidet. Als JPEG statt PNG: 76 statt 385 KB bei 512 Punkten. Bei einem fotografischen Motiv hat PNG nichts zu gewinnen, und 385 KB fuer ein Symbol waeren unverhaeltnismaessig. ⚠️ DER GELTUNGSBEREICH IST ABSICHTLICH WEIT Naheliegend waere "/webdesign/verwaltung" gewesen. Das haette die App unbrauchbar gemacht: Ohne gueltigen Ausweis leitet der Server auf /webdesign/zugang.html um -- ausserhalb des Bereichs, und was ausserhalb liegt, oeffnet der Browser in einem eigenen Fenster. Weil der Zugang beim Schliessen endet, waere das bei fast jedem Start passiert: Man tippt auf die App und landet im Browser. Nachgemessen: verwaltung.html antwortet ohne Ausweis mit 302. EIN STILLES VERSPRECHEN EINGELOEST Die Verknuepfungen zeigen auf "?bereich=anfragen" und dergleichen -- und derselbe Parameter steht in den Push-Meldungen. Ausgewertet hat ihn bisher NIEMAND. Man landete immer auf der Uebersicht, ohne dass etwas kaputt aussah. Jetzt oeffnet die Seite den gewuenschten Reiter, ueber einen ausgeloesten Klick auf den vorhandenen Reiter statt ueber nachgebaute Logik: Daran haengen Signatur, Leuchtbalken, Nachladen und der Wischstreifen auf dem Handy. Auch hier hat erst der Test den Fehler gezeigt -- und danach einen in der Pruefung selbst: Sie erreichte die Funktion gar nicht, weil diese im gekapselten Bereich liegt. Jetzt nach aussen gegeben, wie schon window.vwBalkenSetzen. 23 Pruefungen gruen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
92d2b568de |
Pruefung auf doppelte Funktionsnamen — und ein zweiter Fund
Die Kollision von heute war weder fuer den Browser noch fuer einen Syntaxpruefer sichtbar: Zwei Funktionen desselben Namens sind erlaubtes JavaScript, die spaetere gewinnt lautlos. Auch die Oberflaechen-Tests schwiegen -- sie pruefen, ob Kacheln DA sind, nicht ob sinnvoller Text darin steht. pruef-namenskollision.mjs durchsucht jetzt alle 110 Dateien mit eigenem JavaScript. Mit Gegenprobe, damit die Pruefung nicht selbst kaputtgehen und dabei "sauber" melden kann. ZWEITER FUND, AELTER ALS MEIN FEHLER Sie meldete sofort eine weitere Kollision: tageSeit stand zweimal in verwaltung.html. Beide rechneten dasselbe, mit einem Unterschied -- bei fehlendem Datum gab die eine null zurueck, die andere 0. Die spaetere (mit 0) gewann. Damit war die frueher definierte wirkungslos, und mit ihr die Pruefungen "if (t === null) return ''" in altersText und dringlichkeit: Ohne Datum stand dort "seit heute" statt gar nichts. Entfernt wurde die spaetere. Die beiden verbliebenen Aufrufer vertragen null genauso wie 0 -- nachgeprueft, nicht angenommen: Math.max(x, null) ergibt x, und null >= 7 ist falsch, gleich wie bei 0. 110 Dateien jetzt sauber. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
0e8c1447f2 |
DRINGEND: Namenskollision zerstoerte die Uebersicht
Alle Kacheln der Uebersicht zeigten "[object Object]" und "undefined". Ursache war mein Push-Code von heute. Er brachte eine Hilfsfunktion namens kachel(titel, inhalt, art) mit -- und weiter oben in derselben Datei gibt es seit langem kachel(o), die die Uebersichtskacheln baut. JavaScript kennt keine Ueberladung. Steht spaeter eine zweite Funktion desselben Namens im selben Gueltigkeitsbereich, gewinnt sie. Ohne Warnung, ohne Fehlermeldung, ohne dass irgendein Werkzeug anschlaegt. Danach bekam jede Uebersichtskachel mein Objekt als ersten Parameter und gab es als Zahl aus. Besonders tueckisch: Die Push-Karte selbst funktionierte einwandfrei -- sie steht ja unmittelbar ueber den kaputten Kacheln. Der sichtbare Schaden lag weit weg von seiner Ursache, und nichts deutete auf den neuen Code hin. Die Funktion heisst jetzt pushKachel und sagt damit, wozu sie gehoert. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
0f253df134 |
Service Worker: Versionsnummer in der Adresse gegen fremden Cache
Bei der Fehlersuche zur lahmgelegten App kam ein zweiter, aelterer
Mangel zum Vorschein.
GEMESSEN
Dienst selbst Cache-Control: no-cache
nach Cloudflare Cache-Control: max-age=14400 (auch bei MISS)
Cloudflare ersetzt die Vorgabe des Servers durch vier Stunden. Ursache
ist eine feste "Browser Cache TTL" in den Einstellungen. Der Kommentar
in server/index.js behauptet das Gegenteil ("Cloudflare respektiert
laut Doku ein vom Origin gesetztes Cache-Control") -- fuer diese Domain
stimmt das nicht. Nachgemessen, nicht vermutet.
WARUM DAS MEHR ALS EIN SCHOENHEITSFEHLER IST
Jede Aenderung am Service Worker erreicht die Geraete bis zu vier
Stunden zu spaet. Solange alles laeuft, faellt das nicht auf. Ist der
ausgelieferte Stand aber fehlerhaft -- wie heute, als eine zu strenge
Inhaltsrichtlinie ihn lahmlegte und die App "Keine Verbindung" zeigte
--, sind es vier Stunden, in denen sich nichts reparieren laesst.
Genau dann, wenn Tempo zaehlt, ist man am langsamsten.
LOESUNG OHNE FREMDE EINSTELLUNGEN
Die Registrierung laedt jetzt "/webdesign/sw.js?v=56". Aendert sich die
Nummer, ist es eine andere Adresse -- dafuer kann kein Zwischenspeicher
einen alten Stand haben. Die Nummer wird zusammen mit CACHE_NAME
hochgezaehlt; beide gehoeren zusammen und stehen jetzt auf 56.
Das wirkt unabhaengig davon, wie Cloudflare eingestellt ist. Die
Einstellung selbst sollte trotzdem geprueft werden -- sie betrifft auch
CSS und JavaScript.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
81c7d40274 |
Grosse Kacheln kippen jetzt weniger als kleine
Auf der Portfolio-Seite war die Bewegung zu stark. Der Grund liegt nicht am Winkel, sondern an der Groesse: Bei gleichem Winkel legt eine grosse Kachel an ihren Ecken viel mehr Weg zurueck als eine kleine. Eine Preiskachel auf der Startseite ist 282 Punkte lang, eine Portfolio-Kachel 1503. Fuenf Grad sehen bei der einen beilaeufig aus und bei der anderen wie das Kippen des halben Bildschirms -- obwohl in beiden Faellen exakt derselbe Wert im Stilblatt steht. Der Winkel haengt jetzt an der Kachelgroesse. Bezugswert sind 420 Punkte: Kacheln bis dahin kippen voll, groessere anteilig weniger. Nach unten bei 1,4 Grad begrenzt, damit auch die groesste Kachel noch erkennbar reagiert und der Effekt nicht einfach ausfaellt. Gemessen ueber alle Seiten: index 282px Faktor 5,00 2,45 Grad ueber 588px Faktor 3,57 1,76 Grad portal 562px Faktor 3,74 1,83 Grad ablauf 1130px Faktor 1,86 1,19 Grad leistungen 1206px Faktor 1,74 1,14 Grad portfolio 1503px Faktor 1,40 0,92 Grad Der Durchlauf sammelt diese Werte jetzt und prueft das Verhaeltnis: Die grosse Kachel MUSS weniger kippen als die kleine, und der Faktor darf nie unter 1,4 fallen. Ein blosser Test auf "hoechstens neun Grad" haette den Unterschied nicht bemerkt -- beide Faelle lagen ja deutlich darunter, und trotzdem war einer davon zu viel. Geprueft: 298 Pruefungen gruen (Bewegung 34, Portfolio 19, Verwaltung 62, CRYONOVA 53, Blickfang 13, System 5, Abmelden 16, Abbruch 42, Angebot 54). Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
e4216a2c7a |
Kachel-Effekte gelten jetzt auf der ganzen Seite, nicht nur intern
Neigung, Glanzstreifen und Lichtkante lagen bisher nur im Verwaltungsbereich. Sie stehen jetzt im Grundsystem und gelten damit ueberall: Startseite, Leistungen, Ablauf, Portfolio, "Ueber mich", Kundenportal. Die Farbe kommt aus --wd-lumen. Jede Kachel bringt die ohnehin mit (Token-Regel 02), der Verwaltungsbereich ueberschreibt sie mit der Farbe des jeweiligen Bereichs. Dadurch braucht es keine einzige Sonderregel. DREI FEHLER, DIE DIE REGRESSION GEFUNDEN HAT 1. Die Einblendung hat die Neigung geloescht. ".wd-bereit .wd-auf.wd-sichtbar" setzt "transform: none" und hat mit drei Klassen die hoehere Gewichtung. Sichtbar war das nur auf Seiten, deren Kacheln eine Einblendung tragen: Auf "ablauf" kippte die Kachel, auf "leistungen" nicht -- und der Wert kam in beiden Faellen korrekt an. Die Einblendung nutzt jetzt "translate". Das ist zum dritten Mal dieselbe Falle nach Buehne und Kacheln im Verwaltungsbereich. Merksatz: Wer "transform" animiert oder zuruecksetzt, blockiert es fuer alles andere. 2. Die Perspektive hat die Buehne zerlegt. "perspective" auf dem Abschnitt macht diesen zum Bezugsrahmen fuer position:fixed in seinem Inneren -- genau wie "transform" oder "filter". Die bildschirmfuellende Buehne im Verwaltungsbereich lag danach nicht mehr am Fenster, sondern am Abschnitt: gemessen 472 statt 900 Punkte Hoehe. Die Perspektive steckt jetzt als Funktion im transform der Kachel selbst. Der gemeinsame Fluchtpunkt benachbarter Kacheln entfaellt damit, was bei hoechstens fuenf Grad niemand sieht. 3. Kachel-Neigung und Bild-Parallaxe haben sich aufgeschaukelt. Die kippende Kachel schiebt das Bild unter dem Zeiger weg, der landet dadurch auf einem Nachbarelement, das Bild springt zurueck auf null -- und beim naechsten Zucken von vorne. Messbar war das als "an einer Ecke sauber, an der anderen dauerhaft 0". Klare Arbeitsteilung: Ein Bild INNERHALB einer Kachel bekommt nur den Zoom, die Kachel kippt darum herum. Freistehende Bilder behalten ihre eigene Gegenbewegung. NEUER DURCHLAUF ueber alle Seiten (pruef-bewegung.mjs) Weil die Effekte im Grundsystem liegen, reicht eine Pruefung auf einer Seite nicht: Genau so ist Fehler 1 entstanden und waere unbemerkt geblieben. Der Durchlauf geht sechs Seiten ab und prueft je Seite Neigung, Winkel unter neun Grad, Zuruecksetzen beim Verlassen und Skriptfehler. Zwei Stolpersteine stecken darin dokumentiert: Die Startseite legt beim Laden einen Vorhang ueber alles (wer zu frueh misst, trifft den Vorhang statt der Kachel), und eine Portfolio-Kachel ist ueber 1400 Punkte hoch -- ein fester Anteil ihrer Hoehe landet ausserhalb des Bildschirms. Geprueft: 291 Pruefungen gruen (Bewegung 27, Portfolio 19, Verwaltung 62, CRYONOVA 53, Blickfang 13, System 5, Abmelden 16, Abbruch 42, Angebot 54). Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
76aea6ac3f |
Bilder bewegen sich unter dem Zeiger
Faehrt der Zeiger ueber ein Bild, tritt es leicht naeher und wandert ein Stueck GEGEN die Zeigerrichtung -- als schaue man durch ein Fenster und lehne sich zur Seite. Warum gegen die Richtung: Bewegt sich das Bild MIT dem Zeiger, wirkt es wie ein Aufkleber, der verrutscht. Nur die Gegenbewegung liest das Auge als Tiefe hinter dem Rahmen. Derselbe Grund wie bei der Buehne im Verwaltungsbereich, eine Ebene kleiner. Der Effekt liegt im GRUNDSYSTEM, nicht in einer einzelnen Seite. Er gilt damit ueberall: Portfolio, Startseite, "Ueber mich", Zugangswand und die Vorschaubilder im Verwaltungsbereich. Eine Sonderloesung je Seite waere beim naechsten neuen Bild wieder vergessen worden. Zwei Zahlen, die bewusst klein sind: - Der Ausschlag liegt bei hoechstens 14 Punkten (gemessen 13,9). - Der Zoom bei 1,055. Zusammen ergibt das Bewegung, ohne dass ein Bild beim blossen Vorbeifahren seinen Ausschnitt merklich aendert. Ein groesserer Wert waere kein Effekt mehr, sondern ein Bildsprung. Umgerechnet wird auf die Groesse des jeweiligen Bildes (-1 bis +1), nicht in festen Bildpunkten. Sonst wanderten ein Vorschaubild von 1200 Punkten Breite und ein Logo von 80 gleich weit -- beim kleinen saehe das aus wie ein Ruck. Zwei Faelle, die im Code ausdruecklich abgefangen sind: - Der Zeiger liegt ueber einem Element, das das Bild UEBERDECKT (etwa einem Textblock in derselben Kachel). Ohne Behandlung bliebe das Bild stehen, sobald man den Rahmen verlaesst, aber die Kachel noch nicht. - Der Zeiger steht neben dem Bild, aber noch in der Kachel. Die Werte liefen dann weit ueber 1 hinaus und das Bild schoesse aus dem Rahmen. Deshalb wird auf -1 bis +1 begrenzt. Beim Verlassen stellt sich alles zurueck -- sonst bliebe das Bild verschoben stehen, nachdem der Zeiger laengst weg ist. Bei prefers-reduced-motion ist der Effekt aus. Geprueft: 265 Pruefungen gruen (Portfolio 20, Verwaltung 62, CRYONOVA 53, Blickfang 13, System 5, Abmelden 16, Abbruch 42, Angebot 54). Der Test prueft ausdruecklich die RICHTUNG der Bewegung, nicht nur, dass sich ueberhaupt etwas tut. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
131bc8a755 |
Anfragen annehmen und ablehnen — mit laufender Zeit bis zur Übergabe
Annehmen war bisher nur ein Etikett: Man stellte den Status um, und es passierte nichts. Kunde, Projekt, Aufgabenliste, Termin und Zugang musste man danach von Hand in fünf Schritten nachbauen. Der alte Code gab das im Kommentar selbst zu -- schlug der zweite von zwei Aufrufen fehl, stand der Kunde schon in der Datenbank und man durfte es nicht noch einmal versuchen. Jetzt macht das EIN Aufruf, ganz oder gar nicht: Kunde finden oder anlegen, Projekt anlegen, die komplette Aufgabenliste des Pakets einsetzen, Liefertermin berechnen, Einladungslink erzeugen. Der Kunde verfolgt ab diesem Moment alles in seinem Portal. Die Zeit läuft wirklich: - Eigenes Datumsfeld (termin_am) neben dem freien Text. Aus 'Mitte Oktober' kann man keine verbleibenden Tage rechnen. - Werktage statt Kalendertage, inklusive luxemburgischer Feiertage. Die beweglichen werden über die Osterformel berechnet statt gepflegt -- eine Liste ist im übernächsten Jahr lautlos falsch. - Vorschlag je Paket (Onepager 10, Website 20, Shop 30 Werktage), überschreibbar vor dem Bestätigen. - Verbleibende Zeit wird SERVERSEITIG gerechnet. Der Browser kennt die Feiertage nicht; zwei verschiedene Zahlen für denselben Termin wären schlimmer als gar keine. Ablehnen mit Grund und vorbereiteter Absage in fünf Sprachen, Text serverseitig erzeugt und vor dem Abschicken lesbar. Ein laufendes Projekt lässt sich nicht nachträglich als Anfrage ablehnen. Sechs Fehler dabei gefunden: - Ein unbekanntes Paket hätte GAR KEINEN Termin bekommen statt des Ersatzwerts. Zwei Funktionen lasen dieselbe Tabelle, nur eine hatte einen Rückfallwert. Eine fehlende Zahl fällt nirgends auf. - wd_anfragen hat keine Spalte 'firma' -- better-sqlite3 weist undefined ab, die ganze Annahme wäre gescheitert. - Migrationen stehen in einer ausdrücklichen Liste; 0015 fehlte darin. - datumKurz() wurde aufgerufen, gab es aber nicht. Der Fehler wäre erst NACH dem Anlegen aufgetreten. - Der Installations-Hinweis lag fest über dem Annehmen-Knopf und machte ihn auf dem Handy untreffbar. Die Seite reserviert jetzt Platz dafür. - 'richttermin' ist freier Text, lief aber durch einen Datumsformatierer: Der Kunde las 'Invalid Date' an der wichtigsten Stelle seines Projekts. Geprüft: 49 Prüfungen der Terminrechnung gegen nachschlagbare Osterdaten und Wochentage, 70 gegen eine echte Datenbank (darunter: zweiter Klick legt nichts doppelt an, Abbruch mittendrin lässt NICHTS zurück, gesperrter Kunde wird nicht still entsperrt), 42 im Browser auf Computer und Handy, 40 im Portal. Alle bestehenden Prüfungen weiter grün. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
4fe66e1e0e |
"Preise & Zeit" entfernt -- Inhalte in die Leistungen uebernommen
"leistungen und preis&zeit ist ja das gleiche, nimm die kategorie
preise&zeit komplett weg"
Stimmt bei den Paketen und Preisen: Beide Seiten zeigten dieselben
Zahlen. Zwei Orte fuer dieselbe Zahl sind eine Einladung, dass sie
irgendwann auseinanderlaufen -- und dann steht ein falscher Preis auf
der Seite, ohne dass es jemand merkt.
NICHT ALLES WAR DOPPELT
Vor dem Loeschen nachgesehen statt einfach geloescht. Zwei Abschnitte
gab es NUR dort:
"Was den Preis bewegt" -- beantwortet die Frage, die nach jeder
Preisliste kommt: Warum kostet es bei mir mehr oder weniger?
Ohne sie ist eine Preisspanne eine Behauptung.
"Wie bezahlt wird" -- Angebot, 30 % Anzahlung, Restbetrag, Betreuung.
Rechtlich relevant und aus den AGB verlinkt.
Beide sind in die Leistungen umgezogen, samt ihrer 24 Textbausteine in
allen fuenf Sprachen. Waeren sie mitgeloescht worden, haette es niemand
sofort bemerkt -- und die Seite haette ab dann Preise genannt, ohne sie
zu erklaeren.
WEITERLEITUNG STATT 404
Die Adresse /webdesign/preise.html bleibt bedient und fuehrt auf die
Leistungen. Lesezeichen, alte Links aus Nachrichten und die installierte
App zeigen sonst ins Leere, und ein 404 auf einer Preisseite ist der
denkbar schlechteste erste Eindruck.
302 statt 301: Eine dauerhafte Weiterleitung merken sich Browser
hartnaeckig; sollte die Seite je zurueckkehren, muesste jeder Besucher
seinen Zwischenspeicher leeren.
EIN FEHLER BEIM EINBAU
Die Weiterleitung stand zuerst weiter unten in der Schranke, bei den
ohne Code erreichbaren Seiten. Dort haette sie nur fuer NICHT angemeldete
Besucher gegriffen -- wer angemeldet ist, passiert die Schranke vorher
mit next() und haette einen 404 auf die geloeschte Datei bekommen.
Genau die Person also, die die Seite am ehesten im Lesezeichen hat.
Jetzt steht sie ganz vorne, vor jeder Zugangspruefung.
GEPRUEFT: 10 Pruefungen -- beide uebernommenen Abschnitte erscheinen in
allen fuenf Sprachen, kein unuebersetzter Schluessel sichtbar. Kein
Verweis auf die alte Seite blieb irgendwo stehen (ablauf.html hatte
einen, der ist umgebogen). Gestaltung 0 Befunde, Textkodierung sauber,
Designsystem 5.
Versionsstempel und Cache auf v20.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d6e75ce56a |
Kacheln: Licht folgt dem Zeiger, Rand glueht mit
"ich will das die kacheln richtig speziell sind und modern ... dass viel mehr auffaellt und doch modern und profissionell" Die Kacheln hatten Verlaufsrand, Verlaufsflaeche, Schatten und Lichtkante -- alles richtig, alles STATISCH. Was fehlte, war das Gefuehl von Material: eine Flaeche, die auf Licht reagiert. ZWEI EBENEN Ein weicher Lichtfleck folgt dem Zeiger ueber die Flaeche. Und -- der Teil, der wirklich auffaellt -- der RAND glueht an derselben Stelle auf und verlaeuft nach beiden Seiten aus. Das geht ohne zusaetzliches Element: Die Kachel hat bereits zwei Hintergrundebenen (Flaeche padding-box, Verlaufsrand border-box). Beim Ueberfahren bekommt die Randebene einen Lichtpunkt an der Zeigerstelle. Der Rand ist nur einen Pixel breit -- genau dort laesst sich Licht am staerksten zeigen, ohne kitschig zu werden. Ein Lichtfleck OHNE mitleuchtende Kante wirkt wie ein Fleck AUF der Kachel; mit ihr wirkt die ganze Kachel beleuchtet. Die Flaeche selbst bleibt beim Ueberfahren unveraendert -- sonst wuerde der Text flackern. VIER ENTSCHEIDUNGEN GEGEN BILLIGE OPTIK Die Farbe folgt der Kachel: blaue leuchten blau, lila lila. Sonst braeche der Effekt die Farbordnung, die ueberall sonst Bedeutung traegt. Nur bei echtem Zeiger (hover: hover, pointer: fine). Auf dem Handy gibt es keinen; dort bliebe der Lichtfleck an einer zufaelligen Stelle kleben. Aus bei prefers-reduced-motion. Auch wenn sich nichts bewegt: Etwas, das dem Zeiger folgt, ist Bewegung. Erste Fassung war mit 13 % zu zurueckhaltend -- am Screenshot geprueft und auf 22 % angehoben. "Man soll es spueren" ist richtig, aber es muss auch ankommen. SPARSAM GEBAUT EIN Zuhoerer am Dokument statt einem je Kachel -- sonst muesste jede nachgeladene Kachel einzeln nachgeruestet werden. Geschrieben wird erst im naechsten Bildaufbau: Der Zeiger meldet sich bis zu tausendmal je Sekunde, der Bildschirm zeichnet sechzigmal; ohne Drosselung rechnet der Browser neunhundertmal umsonst. Der Inhalt bekommt z-index 1. Ohne das legt sich der absolut gesetzte Lichtfleck ueber den Text -- absolut positionierte Elemente malen ueber Fluss-Inhalt, auch wenn sie im Quelltext davor stehen. Das Ergebnis waere ein Schleier auf der Schrift, den man erst beim Vergleich zweier Kacheln bemerkt. Eigens geprueft. GEPRUEFT: 7 Pruefungen fuer den Effekt selbst -- unsichtbar im Ruhezustand, erscheint beim Ueberfahren, folgt dem Zeiger auf 6 Pixel genau, Inhalt liegt darueber, lila Kacheln leuchten lila, bei Bewegungsempfindlichkeit vollstaendig abgeschaltet. Gestaltung 0 Befunde, Designsystem 5, Verwaltung 69, Portal 32. Versionsstempel und Cache auf v19. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
3ca9f0b0cd |
Gestaltung: WCAG-Messung ueber alle Seiten, alle Befunde behoben
"Sieht gut aus" ist Geschmack und laesst sich nicht pruefen. Handwerkliche
Qualitaet laesst sich pruefen -- und bei einer WEBDESIGN-Seite ist sie
zugleich das Verkaufsargument: Wer selbst schludert, kann schlecht
Sorgfalt verkaufen.
Neues Werkzeug pruef-design.mjs misst 13 Seiten x 5 Sprachen auf
Handy-Breite gegen WCAG 2.2 AA -- denselben Standard, auf den auch das
Barrierefreiheitsstaerkungsgesetz verweist. Der Browser rechnet, es wird
nichts geschaetzt.
ERGEBNIS: 0 Befunde. Kontrast, Klickflaechen, Tastaturfokus,
Ueberschriftenstruktur, Bildalternativen, Feldbeschriftungen,
lang-Attribut, Schriftgroessen.
ECHTE BEFUNDE, DIE BEHOBEN WURDEN
1. 23 Schriftgroessen unter 12px (bis hinunter zu 10,9px), verteilt ueber
CSS und sieben Seiten. Betroffen waren durchweg gesperrte
Grossbuchstaben-Beschriftungen -- also genau die Textsorte, die klein
ohnehin am schlechtesten lesbar ist. Alle auf mindestens 12px, die
gesperrten auf 12,8px. Das ist zugleich die Dauervorgabe
"augenschonend" ernst genommen.
2. Ueberschriftensprung h2 -> h4 in der Fusszeile, auf ALLEN 13 Seiten in
allen 5 Sprachen (42 Stellen). Wer sich mit einem Screenreader durch
die Ueberschriften bewegt, hoert dadurch eine Gliederung, die es nicht
gibt, und vermutet uebersprungene Abschnitte. Jetzt h2 mit
Gestaltungsklasse: Die Ebene sagt etwas ueber die STRUKTUR, die
Groesse ueber die GEWICHTUNG -- zwei verschiedene Dinge.
3. code-Auszeichnung auf der Rechtsseite rutschte durch relative
Groessenangabe auf 11,2px. Jetzt mit Untergrenze abgesichert.
SECHS FEHLALARME IM WERKZEUG -- ALLE GEFUNDEN UND BESEITIGT
Der erste Lauf meldete 302 Fundstellen. Fast alle waren falsch. Haette
ich sie "repariert", haette ich funktionierende Gestaltung zerstoert.
Jeder Fehlalarm hatte eine eigene, nicht offensichtliche Ursache:
* Farbverlaeufe: getComputedStyle().backgroundColor liefert bei einer
reinen Verlaufsflaeche "rgba(0,0,0,0)". Die Suche lief an der hellen
Knopfflaeche VORBEI bis zum dunklen Seitengrund und verglich dunkle
Schrift mit dunklem Grund -- Ergebnis 1:1 fuer 60 einwandfreie
Knoepfe. Jetzt werden die Farbstopps ausgelesen und der
unguenstigste Fall gerechnet.
* MEHRERE Hintergrundebenen: Die Karten nutzen den bekannten Kniff
"Flaeche padding-box, Rahmenverlauf border-box". Der helle
Rahmenverlauf ist im Textbereich gar nicht sichtbar. Alle Ebenen
zusammenzurechnen ergab 820 Meldungen mit Werten wie "3,45:1" fuer
Text, der in Wahrheit ueber 7:1 liegt. CSS malt die ERSTE Ebene oben
-- nur die zaehlt. Das Trennen an Kommas muss dabei die Kommas
INNERHALB der Verlaufsklammern respektieren.
* Verlaufsschrift (background-clip:text): Dort ist die Schriftfarbe
durchsichtig und der Verlauf IST der Text. Farbe gegen Hintergrund zu
vergleichen ergibt zwangslaeufig 1:1.
* Verlaufsstopps mit wenig Deckkraft (9 % und 4 % Gold in den
Hinweiskaesten) wurden verworfen statt auf den Untergrund gerechnet.
Uebrig blieb "nicht messbar" fuer 72 Textstellen. Ein Pruefwerkzeug,
das bei allem passt, prueft nichts.
* Laufende Ueberblendungen: getComputedStyle liefert waehrend einer
Ueberblendung den ZWISCHENWERT. Nach blur() verblasst der Fokusring
ueber 0,16 s -- misst man sofort, sieht man ihn noch, und "vorher"
ist identisch mit "nachher". Das Codefeld der Verwaltung wurde
dadurch als "ohne sichtbaren Fokus" gemeldet. Nachgewiesen mit
el.matches(":focus") === false bei gleichzeitig sichtbarem Schatten.
Loesung: Ueberblendungen fuer die Messung abschalten.
* Ausgeblendete Abschnitte: Eine Ueberschrift in einem versteckten
Bereich hat selbst weiterhin display:block. Im Portal wurden dadurch
drei h1 gezaehlt, obwohl immer nur eine sichtbar ist. Jetzt
getClientRects().
Dazu zwei bekannte Muster, die das Werkzeug jetzt kennt: der Sprunglink
(absichtlich aus dem Bild geschoben) und die winzigen Auswahlfelder
hinter den Kacheln (die Kachel IST die Klickflaeche).
ALLE UEBRIGEN PRUEFUNGEN WEITERHIN GRUEN nach den Aenderungen:
Anfragedetail 20, Verwaltung 69, Portal 32, Widerruf 58, Textkodierung
55 Seiten-Sprach-Kombinationen.
Versionsstempel und Cache-Name auf v8.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
14ad108c87 |
Rechtliches: elektronische Widerrufsfunktion (§ 356a BGB), Impressum, AGB,
Widerrufsbelehrung und Datenschutz
RECHERCHIERT, NICHT AUS DEM GEDAECHTNIS
Der Webdesign-Bereich hatte KEINE eigene Rechtsseite -- obwohl dort
Vertraege geschlossen und Zahlungen ausgeloest werden. Die Fusszeile
verwies auf die Kontaktseite des Universe, die ein Content-Projekt
beschreibt, kein Dienstleistungsgeschaeft.
Die Web-Recherche hat eine Pflicht zutage gefoerdert, die seit zwei
Monaten gilt und die die Seite nicht erfuellt hat:
§ 356a BGB -- elektronische Widerrufsfunktion, in Kraft seit
19.06.2026. Sie gilt fuer ALLE Fernabsatzvertraege, die ueber eine
Online-Benutzeroberflaeche geschlossen werden, nicht nur fuer
Finanzdienstleistungen.
WARUM DAS HIER GILT: Im Kundenportal nimmt der Kunde Zusatzangebote per
Klick VERBINDLICH an ("Damit nimmst du das Zusatzangebot verbindlich
an"). Das ist ein Vertragsschluss ueber eine Online-Benutzeroberflaeche.
Fuer die geplanten PayPal-Zahlungen gilt dasselbe.
Der Anbieter sitzt in Luxemburg. Fuer Verbraucher mit gewoehnlichem
Aufenthalt in Deutschland gilt nach Art. 6 Rom-I-VO trotzdem das
deutsche zwingende Verbraucherrecht, weil die Seite sich erkennbar an den
deutschsprachigen Markt richtet. Deshalb wurde der STRENGERE Standard
umgesetzt, nicht der bequemere.
WAS GEBAUT WURDE
webdesign/widerruf.html -- die Widerrufsfunktion, genau nach dem
Wortlaut der Vorschrift:
* Beschriftung "Vertrag widerrufen" (gesetzlich vorgegeben)
* ZWEITE Schaltflaeche "Widerruf bestaetigen" (ebenfalls vorgegeben --
ein einstufiges Formular wuerde die Vorschrift nicht erfuellen)
* unverzuegliche Eingangsbestaetigung mit Nummer, ZEITPUNKT (nicht nur
Datum), Empfaenger und dem Wortlaut der Erklaerung
* Link in der Fusszeile JEDER Seite -- "staendig verfuegbar,
hervorgehoben platziert, leicht zugaenglich" heisst nicht "in den AGB
versteckt"
Drei Entscheidungen, die unmittelbar aus dem Sinn der Vorschrift folgen:
KEINE ANMELDUNG. Die Seite ist von der Zugangswand ausgenommen. Wer
seinen Code verlegt hat, wuerde sonst seine Frist verlieren --
Fristverlust durch eine selbstgebaute Huerde ist der schlimmste
denkbare Fall.
KEINE MENGENBEGRENZUNG. Ueberall sonst richtig, hier ein
Rechtsverlust: Wer in der letzten Stunde seiner Frist wegen eines
hakenden Netzes dreimal klickt, darf nicht abgewiesen werden.
KEIN ZWISCHENSPEICHER. Beim Anfrageformular ein Segen, hier eine
Falle: Auf einem geteilten Rechner laege der halb ausgefuellte Widerruf
des einen im Browser des naechsten.
webdesign/rechtliches.html -- Impressum, AGB, Widerrufsbelehrung samt
Muster-Widerrufsformular, Datenschutzerklaerung. Alle Betreiberangaben
sind aus den bestehenden Seiten UEBERNOMMEN, nichts erfunden: Anschrift
in Mondercange, Kleinunternehmerregelung nach Art. 57 TVA-Gesetz LU und
Richtlinie (EU) 2020/285, netcup/Cloudflare, PayPal Luxemburg.
Migration 0014: wd_widerrufe (der dauerhafte Datentraeger und der
Nachweis, wird nie geleert) und wd_zustimmungen. Letztere speichert nicht
nur den Haken, sondern den WORTLAUT, den der Kunde gesehen hat -- die
Beweislast fuer die Zustimmung zum vorzeitigen Leistungsbeginn liegt beim
Unternehmer (§ 356 Abs. 4 BGB), und im Streit zaehlt, WAS bestaetigt
wurde. Bewusst OHNE Fremdschluessel: CASCADE wuerde den Nachweis mit dem
Kunden mitloeschen, RESTRICT wuerde eine DSGVO-Loeschung blockieren.
Druckansicht: Die Eingangsbestaetigung ist ein Rechtsnachweis. Auf Papier
schwarz auf weiss, ohne Navigation und Knoepfe -- ein Nachweis, den
niemand ausdruckt, weil er eine halbe Patrone kostet, erfuellt seinen
Zweck nicht.
ZWEI ECHTE FEHLER GEFUNDEN
1. Die Pflicht-Sternchen verschwanden nach der Uebersetzung. Ursache:
data-i18n stand auf dem <label> selbst und ersetzte dessen ganzen
Inhalt -- samt <span class="wd-pflicht">. Das Anfrageformular macht es
laengst richtig (data-i18n auf einem INNEREN span); die neue Seite
hatte das Muster nicht uebernommen. Aufgefallen ist es nur, weil der
Test die Pflichtfelder GEZAEHLT hat statt sie vorauszusetzen.
2. window.WD.sprache() gibt es nicht, die Funktion heisst getSprache().
Dadurch brach der Uebergang zur zweiten Stufe stumm ab.
GEPRUEFT: 58 Pruefungen, alle bestanden. Darunter die gesetzlich
vorgegebenen Beschriftungen in allen FUENF Sprachen, "kein Grund noetig",
genau drei Pflichtfelder, Datum UND Uhrzeit in der Bestaetigung, und die
Druckansicht.
WAS FILIPE NOCH PRUEFEN LASSEN MUSS: Diese Texte sind sorgfaeltig
recherchiert, aber ich bin keine Rechtsanwaeltin. Vor dem oeffentlichen
Start gehoert das Ganze einmal zu einer im luxemburgischen Recht
qualifizierten Fachperson -- besonders die grenzueberschreitende Lage
(Sitz LU, Kunden in DE/CH/FR/PT) und die Frage, ob die Seite in
Franzoesisch und Portugiesisch aktiv verkaufen soll. Dann muessen die
Rechtstexte auch dorthin uebersetzt werden, und zwar fachlich.
Versionsstempel und Cache-Name auf v7.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
356bb974b8 |
Knopf war unlesbar, und der Code wird jetzt bei jedem Schliessen neu verlangt
Zwei Rueckmeldungen vom 22.08.2026, beide behoben und mit Tests abgesichert.
1) "das sieht nicht gut aus" (Bildschirmfoto des Hauptknopfs)
Ursache: ".wd a" ist Klasse+Element und damit spezifischer als die reine
Knopfklasse ".wd-btn--haupt". Die Textfarbe des Knopfs wurde dadurch
ueberstimmt -- hellblaue Schrift auf hellblauem Grund, praktisch
unlesbar. Derselbe Spezifitaetsfehler wie zuvor bei den Namen auf der
Zugangswand. Fix: ".wd a:not(.wd-btn)" plus zweistufig geschriebene
Knopfregeln, damit das nicht wieder passieren kann.
2) "das sieht lang gezogen aus"
Die Pillenform (border-radius 999px) laesst breite Knoepfe
auseinandergezogen wirken, weil der Radius optisch mit der Breite
mitwaechst. Jetzt fester Radius von 14px -- gleiche Form bei jeder
Breite, ruhiger und hochwertiger.
3) "ich will das ich jedes mal den code gefragt werde wenn man die seite
zu macht"
Das Sitzungs-Cookie allein reicht dafuer nicht: Browser stellen genau
solche Cookies beim Wiederherstellen von Tabs zurueck ("Dort
fortfahren, wo du aufgehoert hast"), man landet dann ohne Codeabfrage
wieder mitten in der Seite. Zusaetzlich jetzt eine Sitzungsmarke im
sessionStorage, die beim echten Schliessen verschwindet. Fehlt sie bei
vorhandenem Cookie, wird die Sitzung serverseitig beendet und zur
Zugangswand geleitet. Token-Notbremse von 24 auf 8 Stunden gesenkt.
13/13 Tests im echten Browser, inklusive Schutz vor Endlosschleife.
DEPLOY.md: zwei Checkouts auf dem Server dokumentiert (/home/dogiweb und
/home/dogiintern) und der Vorfall, dass /webdesign nach dem Pull kurz ohne
Zugangsschutz erreichbar war, weil der Dienstneustart fehlte.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4b3ec450d5 |
Webdesign-Bereich: Fundament, oeffentliche Seiten, Zugangsschutz, PayPal
Umsetzung des "Website Masterplan" (16 Seiten) unter /webdesign. Zugangsschutz mit EIGENER Schranke (server/webdesign-gate.js) statt gate.js: gate.js laesst seit dem oeffentlichen Start am 21.08.2026 jeden durch, weil die Pruefung auf SITE_PUBLIC_LAUNCH_AT als allererste Zeile steht. Haette man /webdesign dahintergehaengt, waere der ausdruecklich nicht-oeffentliche Bereich inklusive Preisen und spaeteren Kundendaten ab der ersten Sekunde fuer jeden lesbar gewesen. Eigenes Sitzungs-Cookie, bereich="webdesign" im Token, damit ein gueltiges Universe-Cookie hier NICHT gilt. 37/37 Tests. Sieben oeffentliche Seiten in fuenf Sprachen (de, de-CH mit echtem Dialekt, en, fr, pt). Preise, Zeitrahmen, Paketnamen und die 30-%-Regel stehen an genau EINER Stelle in wd-core.js -- der Masterplan verlangt "ueberall widerspruchsfrei", und vier Kopien laufen bei der ersten Preisaenderung auseinander. Als App installierbar auf Handy und PC. Der Service Worker speichert bewusst KEINE HTML-Seite zwischen: nach dem Abmelden wuerden sonst geschuetzte Seiten weiter ausgeliefert, ohne dass der Server je gefragt wird. 18/18 Tests. Handy-Abnahme ueber alle Seiten in fuenf Breiten (320-1440) und fuenf Sprachen: 40/40. Der Test fand 35 echte Fehler (Touch-Ziele unter 44px), behoben im Designsystem statt einzeln pro Seite. PayPal (Wunsch 22.08.2026 "sofort auf meinem paypal"): Orders API mit intent=CAPTURE, also sofortiger Einzug statt blosser Reservierung. Gebuehr und Nettobetrag getrennt gespeichert. Betraege durchgehend als Ganzzahl in Cent. Gefaelschte Webhooks werden abgewiesen. Fail closed solange Zugangsdaten fehlen. 28/28 Tests gegen einen nachgebauten PayPal-Server. Datenbank: 15 Tabellen mit Praefix wd_, fachlich vollstaendig vom Universe getrennt. Co-Authored-By: Claude Opus 5 <[email protected]> |