Files

9.4 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, plan_head_before, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals plan_head_before tech-stack key-files key-decisions patterns-established requirements-completed coverage duration completed status
quick-260917-gyd 01 auth
next.js
middleware
jwt
i18n
vitest
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)
web-auth
web-settings
tokens tasks commits
6602 3 3
4778824c73
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
created modified
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
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
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
Sitzungswaechter-Muster: dreiwertige Klassifikation (authenticated/unauthenticated/unavailable) statt AuthUser | null, damit ein API-Ausfall nicht als tote Sitzung fehlinterpretiert wird
QUICK-260917-GYD
id description requirement verification human_judgment
D1 Middleware haengt next-Parameter (Pfad + Query ohne _rsc) an beide Login-Umleitungen an; nicht fuer / und /login… QUICK-260917-GYD
kind ref status
unit apps/web/src/lib/safe-next.test.ts (9 Faelle) pass
false
id description requirement verification human_judgment
D2 Anmeldeseite springt nach Erfolg auf den bereinigten next-Wert; unsichere Werte fallen auf / zurueck QUICK-260917-GYD
kind ref status
unit apps/web/src/lib/safe-next.test.ts (sanitizeNextPath-Faelle) pass
false
id description requirement verification human_judgment
D3 fetchSessionState() loescht das Cookie nur bei 401/403/leerer 200-Antwort, meldet 5xx/Netzwerkfehler als unavailable ohne Cookie-Loeschung QUICK-260917-GYD
kind ref status
unit apps/web/src/lib/auth-actions.test.ts (8 Faelle) pass
false
id description requirement verification human_judgment
D4 Header leitet bei toter Sitzung per Vollnavigation auf /login?next=… um und bleibt bei API-Ausfall still (Avatar zeigt weiterhin ?) QUICK-260917-GYD
kind ref status
unit apps/web/src/components/layout/header.test.tsx (4 Faelle) pass
false
id description requirement verification human_judgment
D5 Einstellungen → Widgets zeigt Lade- und Leerhinweis ueber i18n (de/en) statt hartkodiertem Englisch QUICK-260917-GYD
kind ref status
other grep-Gates auf settings/dashboard/page.tsx + de.json/en.json settings.widgets.empty (Task-3-verify) pass
false
id description verification human_judgment rationale
D6 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
true Erfordert einen echten Browser-Lauf gegen die laufende API/DB (Orchestrator-Aufgabe, nicht Teil dieses Ausfuehrungsplans laut <verification>-Sektion des Plans)
7min 2026-09-17 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