From 7557c9aafe6346c05016fbd04125a50d1cd8f180 Mon Sep 17 00:00:00 2001 From: Schalli Date: Mon, 21 Sep 2026 14:35:29 +0200 Subject: [PATCH] docs(quick-260921-jt4): Plan fuer 30 a11y-Befunde und vier Restposten 29 der 30 Fundstellen werden behoben, eine bleibt begruendet stehen. Loesungswege vorab empirisch an Biome 2.5.0 geprueft: der in D-01 als Rueckfall genannte Weg (role+tabIndex) taeuscht -- er tauscht drei Befunde gegen einen neuen useSemanticElements-Befund und wird deshalb nirgends benutzt. Zwei Annahmen der Auftragsbeschreibung beim Nachlesen korrigiert: vier der elf Klick-Befunde sind onError-Handler an img-Elementen, und alle fuenf ARIA-Befunde sind aria-label auf rollenlosen Elementen. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J --- .../260921-jt4-PLAN.md | 720 ++++++++++++++++++ 1 file changed, 720 insertions(+) create mode 100644 .planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md diff --git a/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md b/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md new file mode 100644 index 0000000..bdd77a9 --- /dev/null +++ b/.planning/quick/260921-jt4-barrierefreiheit-mit-bedienentscheidunge/260921-jt4-PLAN.md @@ -0,0 +1,720 @@ +--- +phase: quick-260921-jt4 +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - apps/web/src/app/(portal)/marketplace/components/MarketplaceCard.tsx + - apps/web/src/app/(portal)/marketplace/components/MarketplaceCard.test.tsx + - apps/web/src/components/dashboard/widget-catalog-modal.tsx + - apps/web/src/components/dashboard/widget-catalog-modal.test.tsx + - apps/web/src/components/settings/calendar-settings-panel.tsx + - apps/web/src/components/settings/calendar-settings-panel.test.tsx + - apps/web/src/components/dashboard/widgets/note-widget.tsx + - apps/web/src/components/dashboard/widgets/note-widget.test.tsx + - apps/web/src/components/dashboard/widgets/note-task-list.tsx + - apps/web/src/components/dashboard/widgets/note-task-list.test.tsx + - apps/web/src/components/dashboard/widgets/calendar-widget.tsx + - apps/web/src/components/dashboard/widgets/calendar-widget.test.tsx + - apps/web/src/components/dashboard/widgets/calculator-widget.tsx + - apps/web/src/components/dashboard/widgets/favorites-widget.tsx + - apps/web/src/components/layout/header.tsx + - apps/web/src/components/settings/account-settings-form.tsx + - apps/web/src/app/(auth)/login/page.tsx + - apps/web/src/app/(auth)/reset-password/page.tsx + - apps/web/src/app/(auth)/reset-password/[token]/page.tsx + - apps/web/src/app/(portal)/change-password/page.tsx + - apps/web/src/app/(portal)/modules/cert-manager/components/SplitTab.tsx + - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.ts + - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.test.ts + - apps/web/src/lib/translations-identity.test.tsx + - apps/web/src/messages/de.json + - apps/web/src/messages/en.json + - apps/api/src/tenders/tender-normalizer.service.ts +autonomous: true +requirements: [D-01, D-02, D-03, D-04, D-05, D-06, D-07] + +estimate: + tokens: 150000 + raw_tokens: 150000 + tasks: 3 + confidence: low + +must_haves: + truths: + - "Jede Stelle, die heute nur mit der Maus bedienbar ist, ist danach auch mit der + Tastatur bedienbar und wird von einer Vorlesehilfe als Schaltflaeche angesagt — + belegt durch Komponententests, die ein Tastaturereignis ausloesen, nicht durch + Auszeichnungs-Behauptungen (D-01)." + - "Das Erscheinungsbild ist an keiner der 13 Dateien ein anderes als vorher: kein + neuer Rahmen, kein neuer Abstand, keine verschobene Kachel (D-04)." + - "Biome meldet nach Abschluss genau 399 Befunde, 0 davon der Stufe error, und genau + EINEN a11y-Befund — den bewusst stehengelassenen Tastatur-Handler des + Taschenrechner-Rahmens. Keine einzige Unterdrueckung per biome-ignore (D-07)." + - "Drei Druecke auf Weiter im Kalender-Widget holen die Quellenliste genau einmal + statt dreimal, und zwei aufeinanderfolgende Termin-Abrufe tragen nie denselben + from/to-Bereich — gemessen im Netzwerkprotokoll des Browsers, nicht per fetch aus + der Seite." + - "Der ZIP-Name des Zertifikat-Aufteilers kommt aus dem Uebersetzungskatalog und ist + auf einer Windows-Freigabe garantiert gueltig, weil eine gepruefte Schutzfunktion + jeden unzulaessigen Namen abfaengt — nicht, weil das deutsche Wort zufaellig + harmlos ist." + - "Jede neue Beschriftung steht in de.json UND en.json, deutsche Oberflaechentexte in + der Sie-Form; beide Kataloge haben danach dieselbe Schluesselmenge (D-05)." + - "Fuer jede der 30 Fundstellen steht in der SUMMARY, welcher der vier Wege gewaehlt + wurde und — bei der Rueckfallvariante oder beim Stehenlassen — warum der gerade + Weg dort nicht ging." + artifacts: + - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.ts + - apps/web/src/app/(portal)/modules/cert-manager/zip-filename.test.ts + - apps/web/src/components/dashboard/widget-catalog-modal.test.tsx + - apps/web/src/components/settings/calendar-settings-panel.test.tsx + - apps/web/src/lib/translations-identity.test.tsx + key_links: + - "Hintergrundflaeche eines Dialogs -> echte Schaltflaeche -> onClose: beim + Loeschen-Dialog MUSS dieser Weg abbrechen, niemals bestaetigen." + - "note-widget -> previewOptions -> rehypeSanitize: die XSS-Schranke T-IEX-01 muss + den Umbau des Kaestchen-Handlers unveraendert ueberleben." + - "calendar-widget -> computeFetchWindow -> fetchEvents: der Sperrgriff darf den + 5-Minuten-Auffrischer nicht mitsperren, sonst friert die Anzeige ein." +--- + + +Die 30 zurueckgestellten Barrierefreiheits-Befunde abarbeiten — mit den vom Orchestrator +getroffenen Bedienentscheidungen D-01 bis D-04 — und die vier namentlich vermerkten +Restposten aus den heutigen Vorgaengen bi2 und gof schliessen. + +Purpose: Heute sind mehrere Bedienelemente ausschliesslich mit der Maus erreichbar. Wer +mit der Tastatur oder einer Vorlesehilfe arbeitet, kann sie nicht ausloesen — das ist der +eigentliche Schaden hinter diesen Befunden, kein Schoenheitsfehler der Zaehlung. + +Output: 13 Oberflaechendateien mit echten Schaltflaechen statt klickbarer Bereiche, zwei +Uebersetzungskataloge im Gleichstand, fuenf neue bzw. erweiterte Testdateien, ein +gemessener Rueckgang von 429 auf 399 Befunde und zwei Kalender-Abrufe weniger pro +Monatswechsel. + + + +@~/.claude/gsd-core/workflows/execute-plan.md +@~/.claude/gsd-core/templates/summary.md + + + +@.planning/STATE.md +@CLAUDE.md +@.planning/quick/260921-bi2-lint-rueckstand-abbauen-mechanische-fixe/260921-bi2-SUMMARY.md +@.planning/quick/260921-gof-effekt-abhaengigkeiten-in-react-21-befun/260921-gof-VERIFICATION.md + + + +Vom Planer am 2026-09-21 unmittelbar vor dem Schreiben dieses Plans gemessen, nicht +uebernommen: + +``` +npx biome lint . --reporter=json + -> total 429 real 350 test 79 errors 0 a11y 30 +``` + +Die Zahl 429 ist die **Gesamtzahl inklusive Testdateien** (350 echter Quelltext + 79 +Testdateien), nicht der reine Quelltextanteil — die Auftragsbeschreibung bezeichnet sie +als "real source only", das ist eine Fehlbeschriftung der sonst korrekten Zahl. Alle 30 +a11y-Befunde liegen in echtem Quelltext. + +Die 30 Fundstellen, mit Zeilennummer zum Zeitpunkt der Planung (Zeilen verschieben sich +beim Umbau — arbeite nach Element, nicht nach Zeilennummer): + +| Datei | Zeile | Regel | +|---|---|---| +| `app/(auth)/login/page.tsx` | 105 | noAutofocus | +| `app/(auth)/reset-password/[token]/page.tsx` | 139 | noAutofocus | +| `app/(auth)/reset-password/page.tsx` | 99 | noAutofocus | +| `app/(portal)/change-password/page.tsx` | 86 | noAutofocus | +| `marketplace/components/MarketplaceCard.tsx` | 116 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents | +| `components/dashboard/widget-catalog-modal.tsx` | 56 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents | +| `components/dashboard/widget-catalog-modal.tsx` | 64 | noNoninteractiveElementInteractions, useKeyWithClickEvents | +| `dashboard/widgets/calculator-widget.tsx` | 323 | noNoninteractiveElementInteractions | +| `dashboard/widgets/calculator-widget.tsx` | 345 | useAriaPropsSupportedByRole | +| `dashboard/widgets/calendar-widget.tsx` | 253 | noNoninteractiveElementInteractions, noStaticElementInteractions | +| `dashboard/widgets/favorites-widget.tsx` | 266 | useAriaPropsSupportedByRole | +| `dashboard/widgets/favorites-widget.tsx` | 462 | noNoninteractiveElementInteractions | +| `dashboard/widgets/favorites-widget.tsx` | 474 | noNoninteractiveElementInteractions | +| `dashboard/widgets/note-widget.tsx` | 184 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents | +| `components/layout/header.tsx` | 156 | noNoninteractiveElementInteractions | +| `components/settings/account-settings-form.tsx` | 161 | noNoninteractiveElementInteractions | +| `components/settings/calendar-settings-panel.tsx` | 159, 182, 199 | useAriaPropsSupportedByRole | +| `components/settings/calendar-settings-panel.tsx` | 373 | noNoninteractiveElementInteractions, noStaticElementInteractions, useKeyWithClickEvents | + +**Zwei Befunde der Auftragsbeschreibung sind beim Nachlesen anders als angenommen** — der +Plan folgt dem gelesenen Quelltext, nicht der Annahme: + +1. **Vier der elf `noNoninteractiveElementInteractions` sind ueberhaupt keine Klicks**, + sondern `onError`-Handler an ``-Elementen (Ersatzweg fuer nicht ladende + Profilbilder und Favoriten-Symbole): `header.tsx:156`, `account-settings-form.tsx:161`, + `favorites-widget.tsx:462` und `:474`. Ein Ladefehler ist keine Bedienung; hier gibt es + nichts in eine Schaltflaeche zu verwandeln. +2. **Alle fuenf `useAriaPropsSupportedByRole` haben dieselbe Gestalt**: ein `aria-label` + sitzt auf einem schlichten `
` bzw. `` ohne Rolle. Solche Elemente haben die + Rolle `generic`, die gar keine ARIA-Merkmale traegt — die Beschriftung wird von jeder + Vorlesehilfe **stillschweigend verworfen**. Das ist ein echter Mangel, kein Formfehler. + + + +Die folgenden Loesungswege wurden vom Planer **empirisch an Biome 2.5.0 mit der +Projektkonfiguration geprueft** (Probedatei unter `apps/web/src/__probe__/`, danach +geloescht). Das ist keine Vermutung — jede Zeile ist gemessen: + +| Probe | Ergebnis | +|---|---| +| `