docs(10): fold backlog 999.5 self-service onboarding into CONTEXT (D-07), reconcile with ROADMAP

This commit is contained in:
Lucas Berger
2026-06-13 13:17:22 -04:00
parent efa42801b5
commit cb3ae9081f
@@ -1,6 +1,7 @@
# Phase 10: Admin Role & Settings - Context # Phase 10: Admin Role & Settings - Context
**Gathered:** 2026-06-12 **Gathered:** 2026-06-12
**Updated:** 2026-06-13 — folded backlog 999.5 self-service onboarding INTO scope (D-07), reconciling with the ROADMAP fold (commit bcc9682, 2026-06-11). The original discuss-phase had listed it as deferred without accounting for that ROADMAP edit.
**Status:** Ready for planning **Status:** Ready for planning
<domain> <domain>
@@ -14,8 +15,9 @@ Phase 10 introduces an admin role and the role-gated Admin Settings surface, and
- **Admin role (ADMIN-03):** a role check gating admin routes/UI; non-admins cannot reach or invoke them. First-login-wins bootstrap (see D-01). - **Admin role (ADMIN-03):** a role check gating admin routes/UI; non-admins cannot reach or invoke them. First-login-wins bootstrap (see D-01).
- **App-password / credential management (ADMIN-01):** an admin can view household members and rotate / re-enter a member's provider credential from the UI; validated against the provider (CalDAV PROPFIND for Fastmail) before saving, stored encrypted via the existing `crypto.ts` / `APP_PASSWORD_ENCRYPTION_KEY` path; never displayed, logged, or echoed. - **App-password / credential management (ADMIN-01):** an admin can view household members and rotate / re-enter a member's provider credential from the UI; validated against the provider (CalDAV PROPFIND for Fastmail) before saving, stored encrypted via the existing `crypto.ts` / `APP_PASSWORD_ENCRYPTION_KEY` path; never displayed, logged, or echoed.
- **Shared-calendar designation (ADMIN-02):** an admin picks which synced calendar is the shared family calendar (`calendars.is_shared`) from the UI, replacing the manual DB write. - **Shared-calendar designation (ADMIN-02):** an admin picks which synced calendar is the shared family calendar (`calendars.is_shared`) from the UI, replacing the manual DB write.
- **Self-service credential onboarding (folded from backlog 999.5):** a member with no `member_credentials` row gets a `needsProviderSetup` signal and can enter / validate (CalDAV PROPFIND) / encrypt their **own** Fastmail app password on first login — the member-scoped counterpart of the admin-managed flow (see D-07), reusing the same validate→encrypt→initial-sync path. Member-scoped: a member can only set their own credential.
**NOT in this phase:** the Phase 12 setup wizard itself; per-event reminder UI/scheduling (Phase 11); full multi-provider support (backlog 999.1 — only the generic *shape* lands here, Fastmail/CalDAV is the only implemented provider); self-service credential onboarding (backlog 999.5). **NOT in this phase:** the Phase 12 setup wizard itself; per-event reminder UI/scheduling (Phase 11); full multi-provider support (backlog 999.1 — only the generic *shape* lands here, Fastmail/CalDAV is the only implemented provider). *(Self-service onboarding from backlog 999.5 is folded IN — see the Delivers bullet above and D-07.)*
</domain> </domain>
<decisions> <decisions>
@@ -37,6 +39,9 @@ Phase 10 introduces an admin role and the role-gated Admin Settings surface, and
### Shared-calendar designation (ADMIN-02) ### Shared-calendar designation (ADMIN-02)
- **D-06: Exclusive single-select.** The admin picks exactly one synced calendar as the shared family calendar. Setting a new one clears `is_shared` on any prior shared calendar (single shared calendar, matching the core value). Picker lists the synced calendars; selection is a radio/toggle, not independent multi-toggles. - **D-06: Exclusive single-select.** The admin picks exactly one synced calendar as the shared family calendar. Setting a new one clears `is_shared` on any prior shared calendar (single shared calendar, matching the core value). Picker lists the synced calendars; selection is a radio/toggle, not independent multi-toggles.
### Self-service credential onboarding (ADMIN-01 / folded from backlog 999.5)
- **D-07: Member self-service credential, member-scoped.** A member with no provider credential gets a `needsProviderSetup` signal (no `member_credentials` row) and can enter / validate (CalDAV PROPFIND) / encrypt their **own** Fastmail app password — the self-service counterpart to the admin-managed rotation (D-05), sharing the identical validate→encrypt→initial-sync path. A member can set ONLY their own credential; the cross-member rotation stays admin-only (D-05). Non-technical-friendly instructions are a **hard UX constraint**: link to Fastmail's app-password page and name the required Calendars/CalDAV scope. Never log/echo the password. Folded in per the ROADMAP edit (commit bcc9682). Reuses the same generic provider shape as D-04 (Fastmail/CalDAV only; no second provider here).
### Claude's Discretion ### Claude's Discretion
- **Migration packaging:** ship the full v1.1 column/table bundle (`is_admin`, `app_config`, `reminder_lead_minutes`) in one Phase-10 migration per the ROADMAP note, so Phases 11/12 don't each carry their own migration. Use `drizzle-kit generate` + `migrate` — never `push` (see [[drizzle-mariadb-push-unsafe]]). - **Migration packaging:** ship the full v1.1 column/table bundle (`is_admin`, `app_config`, `reminder_lead_minutes`) in one Phase-10 migration per the ROADMAP note, so Phases 11/12 don't each carry their own migration. Use `drizzle-kit generate` + `migrate` — never `push` (see [[drizzle-mariadb-push-unsafe]]).
- **`app_config` shape:** create the table now with at least a `setup_complete` flag (Phase 12). Add other global keys only as Phase 10 actually needs them; keep it a simple key/value or single-row config — planner's call. - **`app_config` shape:** create the table now with at least a `setup_complete` flag (Phase 12). Add other global keys only as Phase 10 actually needs them; keep it a simple key/value or single-row config — planner's call.
@@ -92,6 +97,7 @@ Phase 10 introduces an admin role and the role-gated Admin Settings surface, and
- `upsertUser` (`auth/user.ts`) → first-login-wins flag write. - `upsertUser` (`auth/user.ts`) → first-login-wins flag write.
- `calendars.is_shared` write moves from manual DB edit to the ADMIN-02 endpoint; the calendar legend / shared-calendar consumers already read `is_shared`. - `calendars.is_shared` write moves from manual DB edit to the ADMIN-02 endpoint; the calendar legend / shared-calendar consumers already read `is_shared`.
- `app_config.setup_complete` → consumed by Phase 12; `calendar_events.reminder_lead_minutes` → consumed by Phase 11. - `app_config.setup_complete` → consumed by Phase 12; `calendar_events.reminder_lead_minutes` → consumed by Phase 11.
- `needsProviderSetup` signal (member has no `member_credentials` row) → surfaced to the PWA (e.g. on `/api/me` or a dedicated endpoint — planner's call) to drive the member self-service onboarding entry (D-07); reuses the admin flow's validate→encrypt→initial-sync path, member-scoped.
</code_context> </code_context>
@@ -107,7 +113,7 @@ Phase 10 introduces an admin role and the role-gated Admin Settings surface, and
## Deferred Ideas ## Deferred Ideas
- **Full multi-provider support (Gmail/other)** — backlog 999.1. Phase 10 lands only the generic credential *shape*; actual additional providers + their validation are 999.1. - **Full multi-provider support (Gmail/other)** — backlog 999.1. Phase 10 lands only the generic credential *shape*; actual additional providers + their validation are 999.1.
- **Self-service credential onboarding** (a member adds their own app password on first login) — backlog 999.5; Phase 10 is admin-managed only. - ~~**Self-service credential onboarding**~~ — **folded INTO this phase** (D-07) per the ROADMAP edit (commit bcc9682, 2026-06-11); no longer deferred. The original discuss-phase listed it as deferred without accounting for that ROADMAP fold; reconciled 2026-06-13.
- **Admin audit log / health dashboard / user CRUD** — explicitly out of scope per REQUIREMENTS.md (scope creep for a small self-hosted app). - **Admin audit log / health dashboard / user CRUD** — explicitly out of scope per REQUIREMENTS.md (scope creep for a small self-hosted app).
- **Multiple reminders per event** — v1.2 stretch (noted in REQUIREMENTS.md, unrelated to Phase 10). - **Multiple reminders per event** — v1.2 stretch (noted in REQUIREMENTS.md, unrelated to Phase 10).