6.9 KiB
Requirements: FamilySync — v1.2 "Multi-Provider, Theming & Zero-Setup"
Defined: 2026-06-19 Milestone: v1.2 (continues from v1.1 "Operability & Polish", shipped 2026-06-18) Core Value: The household can see and co-edit one color-coded family calendar (shared + each member's personal) and shared lists from a single low-friction PWA — cross-ecosystem, no app store. v1.2 opens the app beyond Fastmail (Google Calendar as a first-class provider behind a provider abstraction, with self-service per-provider onboarding), adds dark mode and multiple reminders per event, and makes the database bootstrap itself with no manual setup.
REQ-IDs continue prior numbering (CAL ≤15, SETUP ≤04, TEST ≤02 already used). New categories: PROV (providers & onboarding), THEME (PWA theming), DEP (dependency maintenance).
v1.2 Requirements
Each requirement maps to exactly one roadmap phase (see Traceability).
Providers — abstraction & self-service onboarding
- PROV-01: All calendar read, write-back, and reminder operations flow through a single
CalendarProviderabstraction; the existing Fastmail/CalDAV broker is refactored behind it as one implementation with no behavior regression to the working Fastmail path (outbox durability, RRULE/VALARM preservation, optimistic-202, per-uid exactly-once all preserved). - PROV-02: A member can connect a Google account via a "Connect Google" OAuth flow (self-service, no admin involvement); the OAuth refresh token is stored encrypted (AES-256-GCM, same path as Fastmail app passwords) and
member_credentialssupports one credential per provider per user (UNIQUE(user_id, provider_type)). - PROV-03: A member can self-service connect or re-enter their own provider credential using each provider's native mechanism — Fastmail = app-password entry, Google = OAuth consent — without an admin rotating it for them (generalizes the v1.1 admin-managed ADMIN-01 path).
- PROV-04: When a provider connection expires or is revoked, the user sees a clear, in-calendar banner (not hidden in settings) and can reconnect in one tap by re-running the provider's auth flow, without removing and re-adding the account.
Calendar — Google parity & multiple reminders
- CAL-16: Events from a connected Google calendar appear in the unified color-coded calendar (read sync), with recurring events expanded correctly (Google recurrence/cancelled-instance model reconciled to the app's RRULE/EXDATE model) and all-day events not shifted.
- CAL-17: A user can create / edit / delete events on a connected Google calendar from the app, written back to Google — full parity with the Fastmail write path, including recurring-event create and whole-series delete.
- CAL-18: A user can set multiple reminders on a single event (up to 5), each firing independently; the set serializes to the connected provider's native model (multiple VALARMs for Fastmail / multiple
overridesfor Google), preserves reminders authored in another client on edit, and the scheduler fires each lead exactly once (dedup key includes the lead).
Theming — PWA dark mode
- THEME-01: A user can switch the PWA between Light / Dark / System, the choice is persisted, there is no flash-of-wrong-theme on load, and the dark theme renders cleanly across every route (calendar, lists, admin, settings sheet, login) including the Schedule-X calendar component's
--sx-color-*variables.
Setup — zero-manual-setup database bootstrap
- SETUP-05: On boot, the app auto-creates and migrates the full schema against a bring-your-own MariaDB — the operator supplies only DB credentials and a database name — running drizzle migrations programmatically (
drizzle-orm/mysql2/migrator, neverdrizzle-kit push), idempotently and concurrency-safely (migration-lock sentinel), completing before requests are served, so no manualdb:migratestep is required.
Test — dev/mock provider (full-app exercise without a live calendar)
- TEST-03: A mock/in-memory
CalendarProviderlets the dev-bypass user and the Playwright CI harness exercise the full app — calendar create/edit/delete, reminders, and lists — with no live calendar account, producing deterministic seed data covering recurring, all-day, past, and future events.
Dependencies — apply CI-surfaced updates
- DEP-01: Apply the outdated/vulnerable dependency upgrades surfaced by CI (
pnpm audit/pnpm outdated), respecting the existing version pins and constraints (ESLint held at 9.x untileslint-plugin-reactsupports 10; Drizzle/drizzle-kit kept coupled; Schedule-X minor-only and not bumped before dark mode is locked), with all CI gates green after the update.
Future Requirements (deferred, not in v1.2)
- Additional calendar providers beyond Fastmail + Google (the PROV-01 abstraction makes them cheaper to add later).
- Google Calendar webhook push (
events.watch) for lower-latency sync — the existing 5-min ctag/poll model is sufficient for a two-person household; evaluate only if latency becomes a problem. - Wizard re-run / reconfigure flow after first setup (carried from v1.1 backlog).
- Android PWA install walkthrough verified on a real device (carried from v1.0).
- Tablet / touchscreen UX — explicitly reserved for v1.3.
Out of Scope (explicit exclusions)
- Modern visual styling refresh (backlog 999.21) — current UX is satisfactory; this is a separate future redesign track, not v1.2.
- Per-event Google color (
colorId) honoring — FamilySync uses its own per-calendar colors for consistency; Google's per-event colors are ignored. - CalDAV/JMAP for Google — Google integration uses the Google Calendar API + OAuth2; no CalDAV bridge.
- Notification-preferences UI / reminder snooze — the per-event multi-reminder selector (CAL-18) is sufficient for a 2-member household.
googleapismonolith — use the scoped@googleapis/calendar+google-auth-libraryto avoid the ~50 MB footprint.drizzle-kit pushat boot — emits a false destructive diff on populated MariaDB 11; boot migration uses themigrate()API only.- Bulk
pnpm upfor DEP-01 — selective, pin-aware updates only.
Traceability
Maps each REQ-ID to its phase. v1.2 phases continue prior numbering (v1.1 ended at Phase 20) → v1.2 starts at Phase 21. Filled by the roadmapper.
| REQ-ID | Phase | Status |
|---|---|---|
| SETUP-05 | TBD | Not started |
| PROV-01 | TBD | Not started |
| PROV-02 | TBD | Not started |
| PROV-03 | TBD | Not started |
| PROV-04 | TBD | Not started |
| CAL-16 | TBD | Not started |
| CAL-17 | TBD | Not started |
| CAL-18 | TBD | Not started |
| THEME-01 | TBD | Not started |
| TEST-03 | TBD | Not started |
| DEP-01 | TBD | Not started |
Coverage: 11 requirements, mapping pending roadmap creation.