docs(quick): Aktenstand 260917-gyd (Web-Robustheit) + Plan 260917-h2s (Desktop-Erkennung, Beta-Label, deutscher Installer)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
---
|
||||
phase: quick-260917-gyd
|
||||
plan: 01
|
||||
subsystem: auth
|
||||
tags: [next.js, middleware, jwt, i18n, vitest]
|
||||
|
||||
requires: []
|
||||
provides:
|
||||
- "safe-next.ts: buildNextParam()/sanitizeNextPath() als reine, getestete Funktionen fuer den Ruecksprung-Parameter (Open-Redirect-Schutz)"
|
||||
- "fetchSessionState() in auth-actions.ts: klassifiziert die Sitzung (authenticated/unauthenticated/unavailable) und loescht das Cookie nur bei nachweislich toter Sitzung"
|
||||
- "Header-Waechter erkennt tote Sitzung und leitet auf /login?next=… um, bleibt bei API-Ausfall still"
|
||||
- "Einstellungen → Widgets vollstaendig uebersetzt (i18n statt hartkodiertem Englisch)"
|
||||
affects: [web-auth, web-settings]
|
||||
|
||||
actuals:
|
||||
tokens: 6602
|
||||
tasks: 3
|
||||
commits: 3
|
||||
plan_head_before: 4778824c73caafbf859c71c5c5a1c40401732296
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "safe-next.ts: reine Funktionen ohne Node-/DOM-APIs, damit ein Modul sowohl von der Edge-Middleware als auch vom Client importiert werden kann"
|
||||
- "fetchSessionState() klassifiziert API-Antworten in drei Zustaende (authenticated/unauthenticated/unavailable) statt eines binaeren Erfolg/Misserfolg, um Abmelde-Schleifen bei API-Ausfaellen zu vermeiden"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- apps/web/src/lib/safe-next.ts
|
||||
- apps/web/src/lib/safe-next.test.ts
|
||||
- apps/web/src/lib/auth-actions.test.ts
|
||||
- apps/web/src/components/layout/header.test.tsx
|
||||
modified:
|
||||
- apps/web/src/middleware.ts
|
||||
- apps/web/src/app/(auth)/login/page.tsx
|
||||
- apps/web/src/lib/auth-actions.ts
|
||||
- apps/web/src/components/layout/header.tsx
|
||||
- apps/web/src/app/(portal)/settings/dashboard/page.tsx
|
||||
- apps/web/src/messages/de.json
|
||||
- apps/web/src/messages/en.json
|
||||
- CHANGELOG.md
|
||||
|
||||
key-decisions:
|
||||
- "fetchCurrentUser() bleibt unveraendert (Signatur und Verhalten) — change-password/page.tsx, account-settings-form.tsx und deren Test-Mock haengen davon ab; fetchSessionState() ist additiv daneben entstanden, mit akzeptierter kleiner Code-Duplikation der fetch-Zeilen"
|
||||
- "Cookie-Loeschung bei toter Sitzung passiert ausschliesslich in der Server Action fetchSessionState() (cookieStore.delete() ist nur dort erlaubt), der Header liest nur den klassifizierten Zustand und navigiert"
|
||||
- "login/page.tsx liest next erst beim Absenden aus window.location.search statt per useSearchParams(), weil der Hook in Next 15 eine Suspense-Grenze braucht und sonst next build fuer die statisch vorgerenderte Login-Seite abbricht"
|
||||
|
||||
patterns-established:
|
||||
- "Sitzungswaechter-Muster: dreiwertige Klassifikation (authenticated/unauthenticated/unavailable) statt AuthUser | null, damit ein API-Ausfall nicht als tote Sitzung fehlinterpretiert wird"
|
||||
|
||||
requirements-completed: [QUICK-260917-GYD]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "Middleware haengt next-Parameter (Pfad + Query ohne _rsc) an beide Login-Umleitungen an; nicht fuer / und /login…"
|
||||
requirement: QUICK-260917-GYD
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/web/src/lib/safe-next.test.ts (9 Faelle)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D2
|
||||
description: "Anmeldeseite springt nach Erfolg auf den bereinigten next-Wert; unsichere Werte fallen auf / zurueck"
|
||||
requirement: QUICK-260917-GYD
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/web/src/lib/safe-next.test.ts (sanitizeNextPath-Faelle)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "fetchSessionState() loescht das Cookie nur bei 401/403/leerer 200-Antwort, meldet 5xx/Netzwerkfehler als unavailable ohne Cookie-Loeschung"
|
||||
requirement: QUICK-260917-GYD
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/web/src/lib/auth-actions.test.ts (8 Faelle)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D4
|
||||
description: "Header leitet bei toter Sitzung per Vollnavigation auf /login?next=… um und bleibt bei API-Ausfall still (Avatar zeigt weiterhin ?)"
|
||||
requirement: QUICK-260917-GYD
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "apps/web/src/components/layout/header.test.tsx (4 Faelle)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D5
|
||||
description: "Einstellungen → Widgets zeigt Lade- und Leerhinweis ueber i18n (de/en) statt hartkodiertem Englisch"
|
||||
requirement: QUICK-260917-GYD
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "grep-Gates auf settings/dashboard/page.tsx + de.json/en.json settings.widgets.empty (Task-3-verify)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D6
|
||||
description: "Browser-Nachweis: ohne Sitzung /settings/general/desktop aufrufen → Login-URL traegt next, nach Anmeldung landet man auf der Desktop-Seite; Sitzungscookie mit nicht mehr existierender Benutzer-ID → Umleitung zur Anmeldeseite statt ?-Avatar"
|
||||
verification: []
|
||||
human_judgment: true
|
||||
rationale: "Erfordert einen echten Browser-Lauf gegen die laufende API/DB (Orchestrator-Aufgabe, nicht Teil dieses Ausfuehrungsplans laut <verification>-Sektion des Plans)"
|
||||
|
||||
duration: 7min
|
||||
completed: 2026-09-17
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Quick Task 260917-gyd: Ruecksprung nach Anmeldung, Sitzungswaechter bei toter API-Sitzung, Widgets-Seite uebersetzt Summary
|
||||
|
||||
**`next`-Parameter fuer den Ruecksprung nach Anmeldung (safe-next.ts, Open-Redirect-getestet), `fetchSessionState()` unterscheidet tote Sitzung von API-Ausfall und leitet den Header ab, Einstellungen → Widgets durchgaengig deutsch.**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 7 min
|
||||
- **Started:** 2026-09-17T10:24:00Z
|
||||
- **Completed:** 2026-09-17T10:30:49Z
|
||||
- **Tasks:** 3
|
||||
- **Files modified:** 12
|
||||
|
||||
## Accomplishments
|
||||
- Middleware und Anmeldeseite tragen jetzt einen getesteten `next`-Ruecksprung durch — der Desktop-App-Link „Update herunterladen" landet nach der Anmeldung wieder auf der urspruenglich angeforderten Seite
|
||||
- `fetchSessionState()` erkennt eine tote Sitzung (401/403/leere 200-Antwort) zuverlaessig und trennt sie von einem stillen API-Ausfall (5xx/Netzwerkfehler) — der Header meldet sich bei toter Sitzung ab statt ein halb angemeldetes „?"-Avatar-Portal zu zeigen
|
||||
- Einstellungen → Widgets zeigt Lade- und Leerhinweis vollstaendig ueber i18n
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Ruecksprung — `next`-Parameter in Middleware und Anmeldeseite** - `4b279ea` (feat)
|
||||
2. **Task 2: Sitzungswaechter — `fetchSessionState()` unterscheidet tote Sitzung von API-Ausfall** - `474d170` (feat)
|
||||
3. **Task 3: Widgets-Seite uebersetzen, CHANGELOG ergaenzen, Gesamtlauf** - `2868ffe` (feat)
|
||||
|
||||
_Alle drei Tasks folgten TDD (RED zuerst bei Task 1 und 2, Task 3 ohne `tdd="true"`)._
|
||||
|
||||
## Files Created/Modified
|
||||
- `apps/web/src/lib/safe-next.ts` - `buildNextParam()`/`sanitizeNextPath()`, reine Funktionen, Open-Redirect-Schutz
|
||||
- `apps/web/src/lib/safe-next.test.ts` - 9 Testfaelle beider Funktionen
|
||||
- `apps/web/src/middleware.ts` - beide Login-Umleitungen ueber gemeinsamen `redirectToLogin()`-Helfer mit `next`
|
||||
- `apps/web/src/app/(auth)/login/page.tsx` - springt nach Erfolg auf `sanitizeNextPath(next)`
|
||||
- `apps/web/src/lib/auth-actions.ts` - `fetchSessionState()` (neu, additiv), `fetchCurrentUser()` unveraendert
|
||||
- `apps/web/src/lib/auth-actions.test.ts` - 8 Klassifikations-Testfaelle
|
||||
- `apps/web/src/components/layout/header.tsx` - Waechter im useEffect ersetzt `fetchCurrentUser` durch `fetchSessionState`
|
||||
- `apps/web/src/components/layout/header.test.tsx` - 4 Testfaelle (authenticated/unauthenticated auf Unterseite/auf `/`/unavailable)
|
||||
- `apps/web/src/app/(portal)/settings/dashboard/page.tsx` - `tCommon('loading')` und `t('widgets.empty')` statt Festtext
|
||||
- `apps/web/src/messages/de.json`, `en.json` - `settings.widgets.empty` (additiv)
|
||||
- `CHANGELOG.md` - drei Stichpunkte unter „Behoben"
|
||||
|
||||
## Decisions Made
|
||||
- `fetchCurrentUser()` unangetastet gelassen (Signatur- und Verhaltensgarantie fuer change-password/page.tsx und account-settings-form.tsx), `fetchSessionState()` daneben additiv mit kleiner Code-Duplikation der fetch-Aufrufzeilen
|
||||
- Cookie-Loeschung ausschliesslich in der Server Action, nicht im Client-Header
|
||||
- `next`-Wert wird in login/page.tsx erst beim Absenden aus `window.location.search` gelesen (kein `useSearchParams()`, wegen fehlender Suspense-Grenze bei der statisch vorgerenderten Anmeldeseite)
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - plan executed exactly as written.
|
||||
|
||||
## Issues Encountered
|
||||
- `bug-report-button.test.tsx` (nicht Teil dieses Plans) schlug einmal im Gesamtlauf flakey fehl (Checkbox-Timing) und lief beim naechsten Lauf sowie isoliert gruen — ausserhalb des Scopes dieses Plans, nicht auto-gefixt, kein Deviation-Eintrag noetig.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- Browser-Nachweis (ohne Sitzung `/settings/general/desktop` aufrufen, tote Sitzung simulieren, Widgets-Seite pruefen) steht laut Plan beim Orchestrator aus, nicht Teil dieser Ausfuehrung.
|
||||
- Keine Blocker fuer Folgearbeiten; `fetchCurrentUser()` bleibt fuer bestehende Aufrufer nutzbar.
|
||||
|
||||
---
|
||||
*Phase: quick-260917-gyd*
|
||||
*Completed: 2026-09-17*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- FOUND: apps/web/src/lib/safe-next.ts
|
||||
- FOUND: apps/web/src/lib/safe-next.test.ts
|
||||
- FOUND: apps/web/src/middleware.ts
|
||||
- FOUND: apps/web/src/app/(auth)/login/page.tsx
|
||||
- FOUND: apps/web/src/lib/auth-actions.ts
|
||||
- FOUND: apps/web/src/lib/auth-actions.test.ts
|
||||
- FOUND: apps/web/src/components/layout/header.tsx
|
||||
- FOUND: apps/web/src/components/layout/header.test.tsx
|
||||
- FOUND: apps/web/src/app/(portal)/settings/dashboard/page.tsx
|
||||
- FOUND: apps/web/src/messages/de.json
|
||||
- FOUND: apps/web/src/messages/en.json
|
||||
- FOUND: CHANGELOG.md
|
||||
- FOUND commit: 4b279ea
|
||||
- FOUND commit: 474d170
|
||||
- FOUND commit: 2868ffe
|
||||
Reference in New Issue
Block a user