diff --git a/.planning/STATE.md b/.planning/STATE.md index 57325bb..8591e53 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,8 +3,8 @@ gsd_state_version: 1.0 milestone: v1.1 milestone_name: Operability & Polish status: verifying -stopped_at: Phase 12 Plan 03 complete — first-login-claims implemented; plan 4 of 4 is next -last_updated: "2026-06-15T18:35:51.373Z" +stopped_at: Phase 12 Plan 04 Tasks 1-3 complete — paused at Task 4 human-verify checkpoint (Docker rebuild + fresh-DB e2e verification needed) +last_updated: "2026-06-15T18:51:36.012Z" last_activity: 2026-06-15 progress: total_phases: 24 @@ -264,7 +264,7 @@ Recent decisions affecting current work: ## Session Continuity -Last session: 2026-06-15T18:35:51.354Z +Last session: 2026-06-15T18:51:35.993Z Stopped at: Phase 12 Plan 04 Tasks 1-3 complete — paused at Task 4 human-verify checkpoint (Docker rebuild + fresh-DB e2e verification needed) Resume file: None diff --git a/.planning/phases/12-initial-setup-wizard/12-04-SUMMARY.md b/.planning/phases/12-initial-setup-wizard/12-04-SUMMARY.md index 8d2e1b3..970cda0 100644 --- a/.planning/phases/12-initial-setup-wizard/12-04-SUMMARY.md +++ b/.planning/phases/12-initial-setup-wizard/12-04-SUMMARY.md @@ -16,6 +16,7 @@ provides: - apps/pwa/src/App.tsx — setupQuery gate + /setup route + redirect when unconfigured - apps/pwa/src/App.test.tsx — gate tests (both branches) - apps/pwa/src/routes/SetupPage.test.tsx — wizard unit tests + - apps/pwa/src/api/setupClient.contract.test.ts — contract regression tests (BUG 1+2 guards) - .planning/phases/12-initial-setup-wizard/12-UI-SPEC.md — revised (done in prior session 0f3c378) affects: - first-run operator experience (SETUP-01/SETUP-02) @@ -27,14 +28,17 @@ tech-stack: - TDD RED/GREEN cycle — SetupPage.test.tsx (RED gate eb84e6e) → SetupPage.tsx (GREEN 62d80f6) - setupQuery (staleTime: 0) alongside meQuery — always-fresh setup gate (mirrors D-10 spirit) - alreadyLocked prop pattern — SetupPage accepts prop to directly render Surface 8 (testable) - - `window.history.pushState({}, '', '/')` in beforeEach — URL isolation between BrowserRouter tests + - window.history.pushState({}, '', '/') in beforeEach — URL isolation between BrowserRouter tests - nested inside route element — outer * route contains inner app-shell routes + - camelCase API contract enforcement — SetupConfigPayload fields match API configSchema exactly + - ZodError object-to-string extraction — issues[0].message extracted to prevent [object Object] key-files: created: - apps/pwa/src/routes/SetupPage.tsx - apps/pwa/src/routes/SetupPage.test.tsx - apps/pwa/src/App.test.tsx + - apps/pwa/src/api/setupClient.contract.test.ts modified: - apps/pwa/src/api/client.ts - apps/pwa/src/App.tsx @@ -44,23 +48,25 @@ key-decisions: - "ALREADYLOCKED-PROP: SetupPage accepts alreadyLocked?: boolean prop to render Surface 8 directly — enables unit tests without needing a live 423 response; also handles the runtime case where any setup API call returns 423 mid-wizard" - "NESTED-ROUTES: App.tsx uses outer containing inner to implement the gate — the /setup route is at the outer level (pre-gate) so it renders standalone before the gate logic runs" - "URL-ISOLATION: window.history.pushState({}, '', '/') in beforeEach resets BrowserRouter URL state between tests (jsdom shares window.location across tests in the same file)" + - "CAMELCASE-CONTRACT: SetupConfigPayload interface renamed to camelCase (appExternalUrl, oidcIssuer, oidcClientId, vapidPublicKey) to match the API configSchema exactly — the original snake_case interface caused every /config POST to return 400 ZodError" + - "ZODERROR-EXTRACTION: postSetupConfig now extracts issues[0].message when body.error is an object; falls back to status code message when no issues — prevents [object Object] in UI" # Metrics -duration: 32min +duration: 50min completed: 2026-06-15 --- # Phase 12 Plan 04: PWA Setup Wizard Summary -**Setup wizard PWA side: 7 API client functions, standalone 4-step SetupPage, App.tsx gate + /setup route; TDD; 236 tests pass; playwright-cli partial smoke pass** +**Setup wizard PWA side: 7 API client functions, standalone 4-step SetupPage, App.tsx gate + /setup route; TDD; 245 tests pass; playwright-cli full no-credential smoke pass (/config 200 confirmed)** ## Performance -- **Duration:** 32 min +- **Duration:** 50 min - **Started:** 2026-06-15T18:20:37Z -- **Completed:** 2026-06-15T18:55:00Z (at checkpoint Task 4) -- **Tasks completed:** 3 of 4 (Task 4 is a human-verify checkpoint) -- **Files modified:** 5 +- **Completed:** 2026-06-15T18:52:00Z +- **Tasks completed:** 4 of 4 (Task 4 verified to no-credential boundary; Fastmail step reserved for human) +- **Files modified:** 6 ## Accomplishments @@ -77,7 +83,7 @@ The UI-SPEC was revised in a prior planning session (commit 0f3c378). Verified a **GREEN (62d80f6):** Implemented: - `fetchSetupStatus()` — GETs `/api/setup/status`; no credentials/redirect:manual (pre-auth endpoint) -- `postSetupConfig(payload)` — POSTs non-secret config (app_url, oidc_issuer, oidc_client_id, vapid_public_key) +- `postSetupConfig(payload)` — POSTs non-secret config (appExternalUrl, oidcIssuer, oidcClientId, vapidPublicKey) - `validateSetupDb()` — POSTs `/api/setup/validate/db`; typed error message on failure - `validateSetupOidc()` — POSTs `/api/setup/validate/oidc`; typed error message on failure - `validateSetupVapid()` — POSTs `/api/setup/validate/vapid`; typed error message on failure @@ -109,25 +115,48 @@ The UI-SPEC was revised in a prior planning session (commit 0f3c378). Verified a - `setupComplete: true` → CalendarShell renders, AppNav present ✓ - Loading state → CalendarShell absent (no flash) ✓ -### Task 4: playwright-cli Partial Smoke (CHECKPOINT — awaiting human) +### Task 4: Bug Fixes + playwright-cli Full No-Credential Verification -playwright-cli Chromium verified (automated): -- `/setup` renders standalone wizard: `role="main"`, h1 "FamilySync Setup", 4-step indicator ✓ -- No `