docs(12-04): update SUMMARY + STATE + ROADMAP for CR-01 VAPID gap closure

This commit is contained in:
Lucas Berger
2026-06-15 15:16:41 -04:00
parent 0d53249b02
commit 49b82d2ef4
3 changed files with 32 additions and 13 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ Make FamilySync configurable, administrable, and maintainable for real multi-mem
- [x] **Phase 9: Faster Write-Back** - Event-driven outbox drain so edits land in ~1-2s instead of ~15s, preserving every outbox durability guarantee (completed 2026-06-12)
- [x] **Phase 10: Admin Role & Settings** - DB foundation (is_admin / reminder_lead / app_config) + role-gated admin UI to rotate app passwords and designate the shared calendar (completed 2026-06-13)
- [x] **Phase 11: Per-Event Reminders** - Reminder selector on the event form (incl. "None") serialized as VALARM, with a variable-lead scheduler that honors each event's choice (completed 2026-06-14)
- [ ] **Phase 12: Initial Setup Wizard** - First-run validated bootstrap of env/VAPID/DB/OIDC + first app password, reusing the admin route surface
- [x] **Phase 12: Initial Setup Wizard** - First-run validated bootstrap of env/VAPID/DB/OIDC + first app password, reusing the admin route surface (completed 2026-06-15)
- [x] **Phase 13: Real Lint Gate (ESLint)** - Wire ESLint flat config (typescript-eslint + React) across both apps so the Phase 8 CI lint slot actually fails on violations instead of no-op'ing (completed 2026-06-12)
- [x] **Phase 14: Desktop E2E Coverage** - Add a Desktop Chrome Playwright profile + make the mobile-authored specs desktop-safe so the Phase 8 regression gate validates desktop, not just mobile (completed 2026-06-12)
- [x] **Phase 15: Doc-Only CI Skip + Markdown Lint** - Aggregate-gate the slow api/harness CI jobs so doc-only PRs to main merge without running them (no branch-protection deadlock), and add markdownlint to `fast-checks` so docs get a fast format+lint gate (promoted from backlog 999.17) (completed 2026-06-12)
+2 -2
View File
@@ -4,7 +4,7 @@ milestone: v1.1
milestone_name: Operability & Polish
status: verifying
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_updated: "2026-06-15T19:16:35.449Z"
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:51:35.993Z
Last session: 2026-06-15T19:16:35.431Z
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
@@ -58,15 +58,15 @@ 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; 245 tests pass; playwright-cli full no-credential smoke pass (/config 200 confirmed)**
**Setup wizard PWA side: 7 API client functions, standalone 4-step SetupPage, App.tsx gate + /setup route; TDD; 249 tests pass; playwright-cli no-credential smoke pass (/config 200 confirmed); VAPID validation wired (CR-01 closed, SETUP-02 satisfied)**
## Performance
- **Duration:** 50 min
- **Duration:** 50 min (original) + gap closure (CR-01 fix, 2026-06-15T19:14Z)
- **Started:** 2026-06-15T18:20:37Z
- **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
- **Completed:** 2026-06-15T19:15:00Z (gap closed)
- **Tasks completed:** 4 of 4 + gap closure (CR-01 VAPID wiring)
- **Files modified:** 7 (includes gap closure)
## Accomplishments
@@ -96,7 +96,7 @@ The UI-SPEC was revised in a prior planning session (commit 0f3c378). Verified a
- `role="main"` on content column; `aria-live="polite"` on validation rows
- 4 sub-components: StepIndicator, ValidationRow, ActionRow, step cards
- Step 1 (Welcome): orientation text, "Before you start" note block, Continue button
- Step 2 (Instance Configuration): 4 fields (App URL, OIDC issuer, client_id, VAPID public key); Save & Validate triggers sequential DB+OIDC validation; Continue appears only when both pass
- Step 2 (Instance Configuration): 4 fields (App URL, OIDC issuer, client_id, VAPID public key); Save & Validate triggers sequential DBOIDC→VAPID validation; Continue appears only when ALL THREE pass (CR-01 gap closure)
- Step 3 (Calendar Credential): email+password fields; CalDAV validation; Complete Setup button
- Surface 7 (Terminal): ShieldCheck icon, "Setup complete" heading, Sign in link
- Surface 8 (Already Locked): via `alreadyLocked` prop or any 423 response mid-wizard
@@ -166,12 +166,14 @@ Screenshot: `.planning/phases/12-initial-setup-wizard/screenshot-setup-config-20
4. **Task 3: App.tsx gate + tests**`1587bca` (feat)
5. **Task 4 RED: contract regression tests**`9f20c8b` (test)
6. **Task 4 GREEN: BUG 1+2 fixes**`120ce85` (fix)
7. **CR-01 RED: VAPID validation gate tests**`7d0205d` (test)
8. **CR-01 GREEN: wire validateSetupVapid**`0d53249` (fix)
## Files Created/Modified
- `apps/pwa/src/api/client.ts` — 7 setup functions + SetupAlreadyLockedError; camelCase payload fix; ZodError extraction fix
- `apps/pwa/src/routes/SetupPage.tsx` — new (standalone wizard, 5 surfaces, 530 lines); camelCase mutation payload fix
- `apps/pwa/src/routes/SetupPage.test.tsx` — new (17 tests, RED gate + implementation tests)
- `apps/pwa/src/routes/SetupPage.tsx` — new (standalone wizard, 5 surfaces); camelCase mutation payload fix; CR-01: validateSetupVapid wired, vapid ValidationRow added, gate updated
- `apps/pwa/src/routes/SetupPage.test.tsx` — new (17 tests, RED gate + implementation tests); CR-01: 4 VAPID validation tests added
- `apps/pwa/src/api/setupClient.contract.test.ts` — new (9 contract regression tests for BUG 1+2)
- `apps/pwa/src/App.tsx` — setupQuery + /setup route + redirect gate added
- `apps/pwa/src/App.test.tsx` — new (6 tests covering both gate branches)
@@ -209,6 +211,19 @@ Screenshot: `.planning/phases/12-initial-setup-wizard/screenshot-setup-config-20
- **Files modified:** `apps/pwa/src/api/client.ts`
- **Commit:** `120ce85` (Task 4 GREEN)
**5. [CR-01 Gap Closure] SETUP-02 — validateSetupVapid never called in wizard (BLOCKER)**
- **Found during:** Phase 12 verification (12-VERIFICATION.md status: gaps_found)
- **Issue:** `validateSetupVapid` was exported from `client.ts` and the backend route `POST /api/setup/validate/vapid` was fully implemented, but `SetupPage.tsx` Step2Config never imported or called it. An operator with missing/swapped/corrupted VAPID env vars completed the wizard with HTTP 200 on every step and push notifications silently broken in production. REQUIREMENTS.md SETUP-02 requires "VAPID private key decodes to 32 bytes and pairs with the public key."
- **Fix:**
- Import `validateSetupVapid` in `SetupPage.tsx`
- Add `vapid: ValidationRowState` to `validationRows` state and `ValidationRowStatus` type
- Extend `configMutation.onSuccess` chain: DB → OIDC → VAPID (sequential)
- Add `ValidationRow` for VAPID with pending/success/failure text ("VAPID keys verified.")
- Gate `setBothPassed(true)` on all three rows passing (db AND oidc AND vapid)
- Update `anyPending` and `handleSaveAndValidate` reset to include vapid state
- **Files modified:** `apps/pwa/src/routes/SetupPage.tsx`, `apps/pwa/src/routes/SetupPage.test.tsx`
- **Commits:** `7d0205d` (RED), `0d53249` (GREEN)
## Known Stubs
None — all wizard steps render from live state (no hardcoded empty values). The validation steps (DB, OIDC, CalDAV) require a live API to produce success states; the component correctly shows pending/success/failure per actual API responses.
@@ -227,6 +242,8 @@ No new threat surface beyond what is explicitly modeled in the plan's threat_mod
- GREEN gate: `62d80f6` feat commit (all tests pass — Task 2) — PRESENT
- RED gate: `9f20c8b` test commit (2 failing contract tests — Task 4 BUG 2) — PRESENT
- GREEN gate: `120ce85` fix commit (all 245 tests pass — Task 4) — PRESENT
- RED gate: `7d0205d` test commit (3 failing VAPID tests — CR-01 gap) — PRESENT
- GREEN gate: `0d53249` fix commit (all 249 tests pass — CR-01 gap closure) — PRESENT
- REFACTOR: no refactoring commit needed
## Self-Check: PASSED
@@ -245,7 +262,9 @@ Commits verified:
- `1587bca` — Task 3
- `9f20c8b` — Task 4 RED
- `120ce85` — Task 4 GREEN
- `7d0205d` — CR-01 RED (VAPID tests)
- `0d53249` — CR-01 GREEN (VAPID wired)
Test suite: 245 passed | 0 failed
Test suite: 249 passed | 0 failed
TypeCheck: clean (0 errors)
playwright-cli: /config 200 confirmed; redirect gate confirmed; DB validation 200; OIDC 400 (expected — Authelia unreachable)
playwright-cli: /config 200 confirmed; redirect gate confirmed; DB validation 200; OIDC 400 (expected — Authelia unreachable from container); VAPID endpoint live (curl POST /api/setup/validate/vapid returns 200); VAPID row wired in Step 2 chain