docs(quick-260921-jt4): Barrierefreiheit 30 -> 1, vier Restposten erledigt
Tessera CI/CD / Lint & Type Check (push) Successful in 53s
Tessera CI/CD / Tests (push) Successful in 1m14s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 19s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m38s

Zusammenfassung und STATE.md zum Quick-Vorgang 260921-jt4.

Der Planer hat zwei Vorgaben des Orchestrators widerlegt: der
vorgesehene Rueckfallweg mit role und Tastaturhandler tauscht gemessen
drei Befunde gegen einen neuen, und vier der elf vermeintlichen
Klick-Befunde sind onError-Handler an Bildern, also gar keine
Bedienung. Alle fuenf ARIA-Befunde waren Beschriftungen auf rollenlosen
Elementen, die Vorleseprogramme still verwerfen.

Laufzeitnachweis vom Orchestrator: drei Monatswechsel holen die
Quellenliste nur noch einmal statt viermal, der Termin-Abruf mit
identischem Zeitraum ist weg. Der 5-Minuten-Auffrischer ist per
gestellter Uhr als intakt belegt, nicht per Warten im Browser - zwei
solche Messversuche waren ungueltig, weil das Werkzeug die Seite
zwischendurch neu laedt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
2026-09-21 15:23:10 +02:00
parent f471b785db
commit 8d604b855a
2 changed files with 280 additions and 4 deletions
+5 -4
View File
@@ -4,8 +4,8 @@ milestone: v1.2
current_phase: 18
current_phase_name: desktop-client-fertigstellen
status: verified
stopped_at: "Sieben Quick-Vorgaenge am 2026-09-21 abgeschlossen und verifiziert (9ie, a1d, bi2, fi3, gof, i8x, iwr). Der fehlerverdaechtige Lint-Rueckstand ist damit vollstaendig geprueft: zwei echte Fehler gefunden und behoben (tote Passwortwechsel-Sperre an der API, stille 403-Antworten in der Benutzerverwaltung), der Rest war harmlos oder Absicht, je Stelle in den Akten begruendet. Offen und NICHT fehlerverdaechtig: 288 any im Quellcode, 30 a11y-Befunde mit Gestaltungsbedarf. Naechster Auftrag des Nutzers: zwei neue Dashboard-Widgets."
last_updated: "2026-09-21T12:45:00.000Z"
stopped_at: "Acht Quick-Vorgaenge am 2026-09-21 (9ie, a1d, bi2, fi3, gof, i8x, iwr, jt4). OFFEN UND WICHTIG: CI-Lauf 395 war rot wegen eines WACKELTESTS, nicht wegen der Arbeit — apps/web/src/components/bug-report/bug-report-button.test.tsx Test 1 faellt rund einmal in 17 vollen Laeufen durch (Vorschaubild da, Haekchen 'Bildschirmfoto anhaengen' aus). Stammt aus quick-260914-m97. Noch NICHT geklaert, ob das nur im Test so aussieht oder ob ein Nutzer sein Bild in der Vorschau sieht und es trotzdem nicht mitgeschickt wird — das ist der naechste Auftrag. Danach: 288 any in apps/api, dann zwei neue Dashboard-Widgets (eins davon ein Bilderrahmen, das zweite noch unbenannt). jt4 ist noch nicht gepusht."
last_updated: "2026-09-21T13:30:00.000Z"
last_activity: 2026-09-21
last_activity_desc: Quick 260921-9ie, a1d, bi2, fi3 und gof — Lint-Tor scharf, Benutzerverwaltung meldet abgewiesene Aktionen, Lint-Rueckstand 2923 → 446, erzwungener Passwortwechsel an der API durchgesetzt (war eine tote Sperre), 21 Effekt-Abhaengigkeiten einzeln beurteilt; alle fuenf verifiziert, die letzten drei am laufenden System
state_head: 4d485432c003a6caf68f6d85aff7de0bd27794e2
@@ -31,7 +31,7 @@ See: .planning/PROJECT.md (updated 2026-07-17)
Phase: 18 (desktop-client-fertigstellen) — COMPLETE (2026-09-17, Verifikation passed, Windows-Bedienprobe bestanden)
Plan: 6 of 6
Status: Alle 18 Phasen abgeschlossen; Version 1.2.0 freigegeben. Kein laufender Meilenstein. Nach 1.2.0 auf main (Beta): Bildmarke in Akzentfarbe, CI-Desktop-Skip, Favoriten-Symbol/-Sortierung, Desktop-Server-Adresse, Update in der App (signiert), Versionszeile auf der Setup-Seite — alles verifiziert und auf VM/CI nachgewiesen
Last activity: 2026-09-21 - Quick 260921-iwr: 30 Listenschluessel- und Zusicherungs-Stellen geprueft, kein echter Fehler; beide Verdachtsmomente (LDAP-Seite, Cert-Manager) durch Messung widerlegt. Der fehlerverdaechtige Rueckstand ist damit abgearbeitet
Last activity: 2026-09-21 - Quick 260921-jt4: Barrierefreiheit 30 → 1 Befund und die vier Restposten erledigt; zwei Vorgaben des Orchestrators vom Planer widerlegt (Rueckfallweg erzeugt neue Befunde, vier vermeintliche Klicks sind onError-Handler). Kalender-Verschwendung im Browser nachgemessen, 5-Minuten-Auffrischer per gestellter Uhr als intakt belegt
Progress: [██████████] 99%
@@ -451,6 +451,7 @@ Gerettet aus `.continue-here.md`. Relevant fuer die noch offenen Live-Tests.
| 260921-gof | **21 React-Effekt-Abhaengigkeiten einzeln beurteilt — 15 davon waren Fallen, nicht Fehler.** Die Klasse war aus 260921-bi2 zurueckgestellt worden, weil jeder Befund einzeln zu beurteilen ist. Ergebnis: nur **2 echte Defekte** (A), **15 Fallen** (B, das naive Eintragen haette eine Abruf-Schleife erzeugt), **3 Absicht** (C, mit begruendetem `biome-ignore` — erste Verwendung im Projekt), **1 Ballast** (D). **Die gefaehrlichste Stelle:** `calendar-widget.tsx:82` — `showToday` setzt bei jedem Klick ein frisches `Date`; `monthDate` naiv in die Liste einzutragen haette **jeden** Druck auf den Monatstitel einen Termin-Abruf ausloesen lassen, ueber die API bis zum Exchange-Server. Reihenfolge war Pflicht: erst Identitaet stabilisieren, dann die Liste umstellen. **Die haeufigste Falle:** `t` aus `useTranslations` ist in diesem Projekt bei jedem Durchlauf eine frische Funktion (die Test-Attrappen sind nachweislich so gebaut) — 8 Befunde. Griff ohne Ausnahme-Kommentar: den uebersetzten Text vor dem Hook in eine Konstante ziehen und diese eintragen; React vergleicht Zeichenketten per Wert. **Nebenbefund:** 11 `eslint-disable`-Zeilen fuer genau diese Regel waren wirkungslos, seit Biome ESLint abgeloest hat — alle entfernt. **Laufzeitnachweis vom Orchestrator im Browser** (Netzwerkprotokoll, nie `fetch` aus der Seite; gegen neu gebaute Abbilder): Dashboard 62 s Ruhe → Protokoll byte-identisch, genau 1 `calendar/events`; Monatstitel 3x gedrueckt → nur der erste Druck (Bereich aendert sich wirklich) loest einen Abruf aus, Druck 2 und 3 **null**; "Weiter" 3x → 3 Abrufe, korrekt; Stoppuhr 6 s real → Anzeige 00:06, 4 Runden ueber 4,8 s → 16/17/19/20 monoton, kein Ruecksprung. Dazu acht weitere Ansichten je 20-25 s ruhen gelassen (Marktplatz, Modulverwaltung, Gruppenverwaltung, DKV dreimal, Ausschreibungsradar zweimal) — jeder Endpunkt genau einmal. `InvoiceHistoryTable` hatte als einzige Datei keinen Test und ist damit gemessen statt nur gelesen; `ResultsList` ist die Stelle, an der die `t`-Falle in bi2 tatsaechlich zuschnappte. **Zahlen:** Warnungen 467 → 446 (exakt 21, nichts anderswo gewachsen), `useExhaustiveDependencies` 0, web-Tests 66/462 → 67/477, api 71/1136 unveraendert, type-check 4/4, `pnpm lint` 5/5 ohne Fehlerrang. Verifikation passed. **Benannt, nicht behoben:** zwei Verschwendungen im Kalender-Abruffenster (gleicher Zeitbereich zweimal geholt; `calendar/sources` bei jedem Monatswechsel) — vorbestehend; und `t` in vier vorbestehenden Abhaengigkeitslisten ausserhalb des Auftrags, die Biome nie gemeldet hat. | 2026-09-21 | b3f0e3c,e2c508c,e780b2c | [260921-gof-effekt-abhaengigkeiten-in-react-21-befun](./quick/260921-gof-effekt-abhaengigkeiten-in-react-21-befun/) |
| 260921-i8x | **Fuenf fehlerverdaechtige Lint-Klassen geprueft — kein einziger echter Fehler darunter.** Zwoelf Stellen einzeln beurteilt, Ergebnis: 7x gleichwertig oder Absicht, 2x Haertung, 3x idiomatisch korrekt. Das ist das Ergebnis, keine Ausrede — die Klassen klangen gefaehrlicher als sie waren. **Die eine Stelle mit echtem Wert:** `apps/web/src/lib/safe-next.ts`, der Schutz gegen Weiterleitung auf fremde Seiten nach der Anmeldung. Der Kommentar dort behauptete, die Steuerzeichen stuenden als Unicode-Escapes im Muster; die rohen Bytes zeigten das Gegenteil (NUL, 0x1F, 0x7F direkt eingebettet). Funktionierte, war aber zerbrechlich: verschluckt ein Werkzeug das NUL-Byte, wird aus dem Bereich stillschweigend ein anderer und der Schutz loechrig — der Rueckgabewert landet in `login/page.tsx` direkt in `window.location.href`. Jetzt echte Escapes, Datei ohne ein einziges Steuerbyte. **Beweis der Gleichwertigkeit, nicht Behauptung:** ueber alle 65536 Codepunkte dieselbe Menge abgelehnter Zeichen — 54 Stueck (32 Steuerzeichen 0x00-0x1F, dazu 0x7F, Backslash und die 20 Leerraum-Zeichen von `\s`), null Abweichung; vom Orchestrator unabhaengig gegen ein selbst gebautes Referenzmuster nachgerechnet. **Bewusst nicht angefasst:** die NUL-Maskierung in `ldap.service.ts` (RFC 4515) — genau dieses Zeichen zu treffen ist ihr Zweck, wer sie "repariert", oeffnet LDAP-Filter-Injection. Ebenso die drei `while ((m = re.exec(s)))`-Schleifen (idiomatisch, kein verrutschtes Gleichheitszeichen) und `noUselessSwitchCase` aus bi2. **Zwei Korrekturen an frueheren Annahmen:** `sanitizeNextPath` laeuft NICHT in der Edge-Middleware (die importiert nur `buildNextParam`), und das blosse Umschreiben auf Escapes senkt die Warnzahl nicht — Biome beanstandet die Escape-Schreibweise genauso, es braucht zusaetzlich einen einzeiligen Unterdrueckungskommentar. **Werkzeugfalle, dreimal zugeschnappt:** das Schreibwerkzeug wandelt `\uXXXX` still in das echte Zeichen um — der Planer erzeugte so zehn rohe Steuerbytes in seiner ersten Planfassung, der Executor zweimal in Commit-Text und Akte (git verweigerte den Commit wegen eines NUL-Bytes), und der Orchestrator beim Nachrechnen. Umgehung ueber `python3`/`chr(92)` ist im Plan hinterlegt. **Zahlen:** 446 → 434, `noControlCharactersInRegex`/`useIterableCallbackReturn`/`noGlobalIsNan` je 0, `suppressions/unused` 0, web-Tests 67/477 → 68/481, api 71/1136 → 72/1137, type-check 4/4, lint 5/5. | 2026-09-21 | f85c91b,076ca4b,b92dd5d | [260921-i8x-fehlerverdaechtige-lint-klassen-steuerze](./quick/260921-i8x-fehlerverdaechtige-lint-klassen-steuerze/) |
| 260921-iwr | **Listenschluessel und Ausrufezeichen-Zusicherungen: 30 Stellen geprueft, wieder kein echter Fehler.** Damit ist der fehlerverdaechtige Rueckstand abgearbeitet. **Zwei Vorannahmen des Orchestrators widerlegt, beide durch Messung statt Argument:** (1) Die LDAP-Seite galt als heisser Kandidat, weil dort Zuordnungsregeln hinzugefuegt und geloescht werden — die Liste, die tatsaechlich waechst und schrumpft (`config.fieldMappings`), benutzt jedoch laengst `key={mapping.id}`; die sechs Meldungen betreffen zustandslose Textlisten. (2) Im Cert-Manager galt eine Zusicherung auf hochgeladenen Dateiinhalt als moeglicher Absturz — der Planer hat eine 83-Byte-Schrottdatei gebaut, die node-forge `bag.cert = null` setzen laesst, und gegen den echten Dienst laufen lassen: **alle vier Pfade enden mit 400, nie 500**, und `certificateToPem(null)` wirft nachweislich, statt still ein falsches Zertifikat zu bauen. Also weder Verfuegbarkeits- noch Integritaetsluecke, sondern eine irrefuehrende Fehlermeldung. **Ein Fund dreht die Richtung um:** bei `admin/modules/grants/page.tsx:246` waere die Korrektur schaedlich — die Gruppierung fasst nur aufeinanderfolgende Kategorien zusammen, die Positionsnummer ist dort fuer die Eindeutigkeit noetig, ohne sie entstuenden doppelte Schluessel. **Geaendert: 5 Stellen** (drei Waechter im Cert-Manager, die den Meldungstext praezisieren — Status bleibt 400, rot-dann-gruen belegt; zwei ueberfluessige Zusicherungen in `imap.provider.ts`, die imapflow ohnehin als Pflichtfeld typisiert). **25 Stellen bleiben bewusst stehen und bleiben in der Zaehlung sichtbar** — mit Begruendung je Stelle in der Akte, damit der naechste Durchgang sie nicht erneut aufrollt; kein Unterdrueckungskommentar, um die Zahl zu schoenen. **Das Tor hat sich selbst bewaehrt:** der erste Entwurf eines Waechters erzeugte einen neuen Lint-Fund (430 statt 429) und wurde von der Verifikation des Plans gefangen; die Reparatur brach `tsc`, weil `@types/node-forge` `Bag.cert` als `Certificate | undefined` deklariert, waehrend die Bibliothek zur Laufzeit `null` zuweist — Endfassung prueft beides. **Zahlen:** 434 → 429, `noArrayIndexKey` unveraendert 19 (alle geprueft, alle harmlos), `noNonNullAssertion` 11 → 6, web-Tests 68/481 → 69/484, api 72/1137 → 72/1143, type-check 4/4, lint 5/5. | 2026-09-21 | 8716fa5,b4aaed4,27909e4,de69863 | [260921-iwr-listenschluessel-per-positionsnummer-und](./quick/260921-iwr-listenschluessel-per-positionsnummer-und/) |
| 260921-jt4 | **Barrierefreiheit von 30 auf 1 Befund, plus die vier zurueckgestellten Restposten.** Die 30 a11y-Befunde galten seit bi2 als "braucht Bedienentscheidungen"; die hat der Orchestrator getroffen, und der Planer hat **zwei davon widerlegt**: (1) Der vorgesehene Rueckfallweg (`role` + `tabIndex` + Tastaturhandler, wo kein echter Knopf geht) tauscht gemessen drei Befunde gegen einen neuen `useSemanticElements` — eine Regel, die bi2 gerade erst auf 0 gebracht hatte; wird nirgends benutzt, fuer den Verschachtelungsfall (Marktplatz-Karte) tritt eine deckende Geschwister-Schaltflaeche an seine Stelle. (2) **Vier der elf "Klick"-Befunde sind gar keine Klicks**, sondern `onError`-Handler an `<img>` — da gibt es keinen Tastaturweg zu schaffen, sie bekommen `aria-hidden`. **Ein Fund darueber hinaus:** alle fuenf ARIA-Befunde sind `aria-label` auf rollenlosen Elementen — die werden von Vorleseprogrammen still verworfen, die Beschriftungen kamen also bei niemandem an; jetzt mit korrekter Rolle. Sechs Stellen wurden zu echten `<button>` (Aussehen unveraendert), vier `autoFocus` auf Seiten entfernt (auf Seiten reisst er beim Laden den Fokus an sich — im Dialog waere er richtig gewesen, alle vier waren Seiten). **Ein Befund bleibt bewusst stehen und bleibt gezaehlt** (`calculator-widget.tsx:323`), samt ausdruecklich verworfener Umgehung. **Restposten:** ZIP-Name uebersetzt mit getesteter Schutzfunktion `zip-filename.ts` (der frueher genannte Umlaut-Einwand trifft fuer "Zertifikate.zip" nicht zu, die Schutzfunktion sichert kuenftige Uebersetzungen ab); die ueberfluessige `case`-Marke im Normalisierer aufgeloest, Absicht in den Kommentar gewandert; Kalender-Verschwendung abgestellt. **Zur `t`-Frage eine Korrektur an gof:** `use-intl` 4.13 erzeugt `t` in einem `useMemo`, es ist also in der Bibliothek stabil — instabil ist es nur in den Test-Attrappen, und daher kam der Beleg von damals. Die acht Korrekturen aus gof bleiben richtig und schaedlich sind sie nicht, aber die Begruendung war zu breit; ein Test an der Wurzel misst es jetzt. **Laufzeitnachweis vom Orchestrator** (Browser, 90 Tage Vorschau — bei der Voreinstellung 30 tritt der Doppelabruf gar nicht auf, die Messung haette also nichts gezeigt): drei Monatswechsel holen `calendar/sources` nur noch **1x statt 4x**, und der Termin-Abruf mit identischem Zeitraum ist weg (3 Klicks → 2 Abrufe statt 3). Der 5-Minuten-Auffrischer bleibt unangetastet — belegt nicht durch Warten im Browser (zwei Messversuche waren ungueltig, weil das Werkzeug die Seite zwischendurch neu laedt: nach 330 s Wartezeit war das Dokument 37 s alt), sondern durch Test 19 mit gestellter Uhr: nach `advanceTimersByTime(300_000)` werden **beide** Abrufe erneut ausgefuehrt. **Zahlen:** 429 → 399, a11y 30 → 1, web-Tests 69/484 → 73/529, api 72/1143 unveraendert, type-check 4/4, lint 5/5, keine neuen Unterdrueckungen. | 2026-09-21 | a8531d4,3d0bc0b,0c89c13,b601141,e651c24,+7 | [260921-jt4-barrierefreiheit-mit-bedienentscheidunge](./quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/) |
## Deferred Items
@@ -496,4 +497,4 @@ Last session: 2026-09-21T04:50:00Z
Resumed: 2026-09-21 — Sitzung ueber /gsd-resume-work fortgesetzt. Stand geprueft: Arbeitsbaum sauber, main == origin/main auf 55aa287, CI-Lauf 387 fuer 55aa287 erfolgreich (Beta-Images gebaut). Push und CI aus dem letzten Stopp-Punkt sind damit erledigt.
Stopped at: Warte auf Nutzerentscheidung, womit weitergearbeitet wird. Offen fuer den User: alpha pullen (web+api) und danach am Windows-VM-Client die echte Fehlermeldung schicken (Betreff `[Desktop/Windows]` + `Herkunft:`-Zeile pruefen); eigenen Arbeitsplatz-Client einmal per Browser-Installer erneuern; Freigabe 1.3.0 auf Zuruf. Technisch offen im Ledger: WINDOWS #35 (Biome laeuft nicht — biome.json:3 `organizeImports` ist in Biome 2.5.0 unbekannt, `biome check` bricht mit Konfigurationsfehler ab, reproduziert 2026-09-21) und WINDOWS #36 (403-Antworten bleiben in handleSubmit/handleDelete ohne sichtbare Reaktion).
Resume file: None
Last activity: 2026-09-21 - Quick 260921-iwr: 30 Listenschluessel- und Zusicherungs-Stellen geprueft, kein echter Fehler; beide Verdachtsmomente (LDAP-Seite, Cert-Manager) durch Messung widerlegt. Der fehlerverdaechtige Rueckstand ist damit abgearbeitet
Last activity: 2026-09-21 - Quick 260921-jt4: Barrierefreiheit 30 → 1 Befund und die vier Restposten erledigt; zwei Vorgaben des Orchestrators vom Planer widerlegt (Rueckfallweg erzeugt neue Befunde, vier vermeintliche Klicks sind onError-Handler). Kalender-Verschwendung im Browser nachgemessen, 5-Minuten-Auffrischer per gestellter Uhr als intakt belegt