Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.4 KiB
Phase 18 — Plan Index & Coverage Audit
Created: 2026-06-15 Plans: 4 (3 waves) Mode: standard · TDD mode ON · MVP off
Wave Structure
| Wave | Plans | Autonomous | Files (disjoint per wave) |
|---|---|---|---|
| 1 | 18-01 (accessor + IANA validator, TDD) | yes | lib/householdTimezone.ts (+test) |
| 2 | 18-02 (admin endpoints, TDD), 18-03 (broker wiring, TDD) | yes, yes | 02: routes/admin.ts (+test); 03: broker/reminderScheduler.ts + broker/outboxWorker.ts (+tests) — no overlap with 02 |
| 3 | 18-04 (PWA picker UI) | no (human-verify checkpoint) | pwa/api/client.ts, pwa/routes/AdminPage.tsx |
Dependency rationale: 02 and 03 both depend only on the Wave-1 accessor and touch disjoint files → parallel in Wave 2. 04 depends on the 02 endpoint contract → Wave 3.
Artifacts This Phase Produces (MANDATORY)
| Symbol / Artifact | Kind | File | Plan |
|---|---|---|---|
getHouseholdTimezone(db) |
function (async, → Promise) | apps/api/src/lib/householdTimezone.ts |
01 |
isValidIanaTimezone(tz) |
function (→ boolean) | apps/api/src/lib/householdTimezone.ts |
01 |
'household_timezone' |
app_config key string (new additive row, no migration) | apps/api/src/db/schema.ts appConfig (existing table) |
01/02 |
GET /api/admin/config/timezone |
route | apps/api/src/routes/admin.ts |
02 |
PUT /api/admin/config/timezone |
route | apps/api/src/routes/admin.ts |
02 |
POST /api/admin/config/timezone/seed |
route (no-overwrite seed, D-02/D-03) | apps/api/src/routes/admin.ts |
02 |
timezoneSchema |
Zod schema | apps/api/src/routes/admin.ts |
02 |
fetchAdminTimezone() |
client fn | apps/pwa/src/api/client.ts |
04 |
setAdminTimezone(timezone) |
client fn | apps/pwa/src/api/client.ts |
04 |
AdminTimezoneResponse |
interface | apps/pwa/src/api/client.ts |
04 |
Timezone section (aria-label="Timezone") |
UI component/section | apps/pwa/src/routes/AdminPage.tsx |
04 |
apps/api/tests/lib/householdTimezone.test.ts |
new test file | — | 01 |
Test files extended (not new): apps/api/tests/routes/admin.test.ts (02),
apps/api/tests/broker/reminderScheduler.test.ts + apps/api/tests/broker/outboxWorker.test.ts (03).
Multi-Source Coverage Audit
GOAL (ROADMAP Phase 18 goal)
"Auto-detect the household timezone and allow changing it" → COVERED: detection seed (D-02, Plans 02 seed endpoint + 04 detected-zone affordance); change (D-04, Plans 02 PUT + 04 picker); behavioral wiring (D-05, Plan 03).
REQ (phase_req_ids from REQUIREMENTS.md)
No REQ-IDs are mapped to Phase 18 in ROADMAP.md (confirmed: "Requirements: TBD"). Per the planning context, the D-01..D-07 decision set is the coverage contract — see CONTEXT below. Not a gap.
RESEARCH (18-RESEARCH.md features/constraints)
- Single accessor
getHouseholdTimezone+ IANA validator → Plan 01. - GET/PUT endpoints on adminRouter, no new router → Plan 02.
- Seed endpoint, additive/non-blocking (Phase 12 not yet executed) → Plan 02.
- Rewire reminderScheduler:247 + outboxWorker:501,607 → Plan 03.
- PWA picker, no new package, Intl-based → Plan 04.
- No new npm installs (Package Legitimacy Audit: zero) → honored across all plans; T-18-SC = no-op.
CONTEXT (D-01..D-07 — the trackable decision contract)
| Decision | Covered by | Where |
|---|---|---|
D-01 single household app_config key household_timezone |
Plan 01 (key literal), Plan 02 (upsert) | accessor + endpoints |
| D-02 browser-detect + seed at first run | Plan 02 (seed endpoint), Plan 04 (detected-zone affordance) | endpoints + UI |
| D-03 no auto-overwrite after seed | Plan 02 (seed writes only if unset) | seed endpoint |
| D-04 change via role-gated /admin Settings | Plan 02 (requireAdmin endpoints), Plan 04 (Timezone section) | endpoints + UI |
| D-05 stored TZ = source of truth, single accessor at both scheduler sites | Plan 01 (accessor), Plan 03 (both sites route through it) | accessor + broker |
| D-06 fallback chain when unset | Plan 01 (verbatim fallback), Plan 03 (existing tests stay green) | accessor + broker |
| D-07 do not touch display/timed-write path | Plan 03 + Plan 04 (boundary as acceptance criterion) | broker + UI |
No unplanned items. Deferred Ideas (per-member timezones; driving display/timed off stored TZ) are correctly absent from all plans.