docs: create milestone v1.1 roadmap (6 phases)
This commit is contained in:
+22
-20
@@ -39,13 +39,13 @@ Each requirement maps to exactly one roadmap phase (see Traceability).
|
|||||||
|
|
||||||
### CI — Gitea continuous integration
|
### CI — Gitea continuous integration
|
||||||
|
|
||||||
- [ ] **CI-01**: Every pull request targeting `main` runs full regression — lint, typecheck (both apps), unit tests, and API integration tests against a MariaDB service container — and the result gates the merge.
|
- [ ] **CI-01**: Every pull request targeting `main` runs full regression — lint, typecheck (both apps), unit tests, API integration tests against a MariaDB service container, **and the Phase 7 mobile Playwright harness as a UI-regression step (CI brings up the API + PWA dev servers + MariaDB service container with `DEV_AUTH_BYPASS` in the runner and runs the harness specs headlessly against the authed PWA)** — and the result gates the merge.
|
||||||
- [ ] **CI-02**: On merge to `main`, the API Docker image is built and published to the Gitea container registry.
|
- [ ] **CI-02**: On merge to `main`, the API Docker image is built and published to the Gitea container registry.
|
||||||
|
|
||||||
### Test — Mobile-emulated authed browser harness
|
### Test — Mobile-emulated authed browser harness
|
||||||
|
|
||||||
- [ ] **TEST-01**: The assistant can drive the PWA in a **mobile-emulated viewport** (device profile + mobile UA + touch) for automated UI/layout verification.
|
- [ ] **TEST-01**: The assistant can drive the PWA in a **mobile-emulated viewport** (device profile + mobile UA + touch) for automated UI/layout verification.
|
||||||
- [ ] **TEST-02**: Automated runs reach the **authenticated** PWA via the existing `DEV_AUTH_BYPASS` on the host-side dev stack (no manual login, no Authelia/OIDC mocking). Targets the dev build; real prod-service-worker mobile testing is out of scope (see below).
|
- [ ] **TEST-02**: Automated runs reach the **authenticated** PWA via the existing `DEV_AUTH_BYPASS` on the host-side dev stack (no manual login, no Authelia/OIDC mocking). Targets the dev build; real prod-service-worker mobile testing is out of scope (see below). The harness specs are also consumed by Phase 8 (Gitea CI) as the PR UI-regression step.
|
||||||
|
|
||||||
## Future Requirements (deferred, not in v1.1)
|
## Future Requirements (deferred, not in v1.1)
|
||||||
|
|
||||||
@@ -67,24 +67,26 @@ Each requirement maps to exactly one roadmap phase (see Traceability).
|
|||||||
|
|
||||||
## Traceability
|
## Traceability
|
||||||
|
|
||||||
Filled by the roadmapper — maps each REQ-ID to its phase.
|
Maps each REQ-ID to its phase. v1.1 phases continue v1.0 numbering (v1.0 ended at Phase 6) → v1.1 starts at Phase 7. **Coverage: 17/17 v1.1 requirements mapped, no orphans, no duplicates.**
|
||||||
|
|
||||||
| REQ-ID | Phase | Status |
|
| REQ-ID | Phase | Status |
|
||||||
|--------|-------|--------|
|
|--------|-------|--------|
|
||||||
| CAL-13 | TBD | Pending |
|
| TEST-01 | Phase 7 (Mobile Test Harness) | Pending |
|
||||||
| CAL-14 | TBD | Pending |
|
| TEST-02 | Phase 7 (Mobile Test Harness) | Pending |
|
||||||
| CAL-15 | TBD | Pending |
|
| CI-01 | Phase 8 (Gitea CI) | Pending |
|
||||||
| NOTIF-04 | TBD | Pending |
|
| CI-02 | Phase 8 (Gitea CI) | Pending |
|
||||||
| NOTIF-05 | TBD | Pending |
|
| CAL-15 | Phase 9 (Faster Write-Back) | Pending |
|
||||||
| NOTIF-06 | TBD | Pending |
|
| ADMIN-01 | Phase 10 (Admin Role & Settings) | Pending |
|
||||||
| ADMIN-01 | TBD | Pending |
|
| ADMIN-02 | Phase 10 (Admin Role & Settings) | Pending |
|
||||||
| ADMIN-02 | TBD | Pending |
|
| ADMIN-03 | Phase 10 (Admin Role & Settings) | Pending |
|
||||||
| ADMIN-03 | TBD | Pending |
|
| CAL-13 | Phase 11 (Per-Event Reminders) | Pending |
|
||||||
| SETUP-01 | TBD | Pending |
|
| CAL-14 | Phase 11 (Per-Event Reminders) | Pending |
|
||||||
| SETUP-02 | TBD | Pending |
|
| NOTIF-04 | Phase 11 (Per-Event Reminders) | Pending |
|
||||||
| SETUP-03 | TBD | Pending |
|
| NOTIF-05 | Phase 11 (Per-Event Reminders) | Pending |
|
||||||
| SETUP-04 | TBD | Pending |
|
| NOTIF-06 | Phase 11 (Per-Event Reminders) | Pending |
|
||||||
| CI-01 | TBD | Pending |
|
| SETUP-01 | Phase 12 (Initial Setup Wizard) | Pending |
|
||||||
| CI-02 | TBD | Pending |
|
| SETUP-02 | Phase 12 (Initial Setup Wizard) | Pending |
|
||||||
| TEST-01 | TBD | Pending |
|
| SETUP-03 | Phase 12 (Initial Setup Wizard) | Pending |
|
||||||
| TEST-02 | TBD | Pending |
|
| SETUP-04 | Phase 12 (Initial Setup Wizard) | Pending |
|
||||||
|
|
||||||
|
**DB foundation note:** The v1.1 schema migration (`users.is_admin`, `calendar_events.reminder_lead_minutes`, `app_config` table) is not a standalone requirement — it is carried by **Phase 10 (Admin Role & Settings)** (which owns is_admin + app_config) and consumed by **Phase 11 (Per-Event Reminders)** (reminder_lead_minutes) and **Phase 12 (Initial Setup Wizard)** (app_config.setup_complete). Folded per ARCHITECTURE.md ordering rather than created as a migration-only phase. This makes Phase 10 the head of the admin chain (10 → 11, 10 → 12).
|
||||||
|
|||||||
+151
-2
@@ -3,6 +3,7 @@
|
|||||||
## Milestones
|
## Milestones
|
||||||
|
|
||||||
- ✅ **v1.0 MVP** — Phases 1–6 (shipped 2026-06-10) — see [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROADMAP.md)
|
- ✅ **v1.0 MVP** — Phases 1–6 (shipped 2026-06-10) — see [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROADMAP.md)
|
||||||
|
- 🚧 **v1.1 Operability & Polish** — Phases 7–12 (planning) — mobile test harness, Gitea CI (runs the harness), faster write-back, in-app admin, per-event reminders, guided setup
|
||||||
|
|
||||||
## Phases
|
## Phases
|
||||||
|
|
||||||
@@ -20,9 +21,131 @@ Full phase detail archived in [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROA
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### 🚧 v1.x (Planned)
|
### 🚧 v1.1 Operability & Polish (Phases 7–12)
|
||||||
|
|
||||||
No phases planned yet. Promote items from the Backlog with `/gsd-review-backlog`, or start the next cycle with `/gsd-new-milestone`.
|
Make FamilySync configurable, administrable, and maintainable for real multi-member use — without hand-editing env files or the database. The new critical path runs **mobile test harness → Gitea CI** (CI consumes the harness specs for UI regression), and the **admin role → reminders / setup wizard** chain (a single `/api/admin` + `/api/setup` route surface carrying the v1.1 DB migration). Faster write-back is a fully independent track.
|
||||||
|
|
||||||
|
- [ ] **Phase 7: Mobile Test Harness** - Mobile-emulated, authenticated PWA browser harness so the assistant (and CI) can catch mobile-only defects
|
||||||
|
- [ ] **Phase 8: Gitea CI** - Full regression on PR to main (lint/typecheck/unit/API-integration vs a MariaDB service container **+ the Phase 7 mobile harness as a UI-regression step against a CI-hosted dev stack**) + Docker image publish on merge
|
||||||
|
- [ ] **Phase 9: Faster Write-Back** - Event-driven outbox drain so edits land in ~1-2s instead of ~15s, preserving every outbox durability guarantee
|
||||||
|
- [ ] **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
|
||||||
|
- [ ] **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
|
||||||
|
- [ ] **Phase 12: Initial Setup Wizard** - First-run validated bootstrap of env/VAPID/DB/OIDC + first app password, reusing the admin route surface
|
||||||
|
|
||||||
|
## Phase Details
|
||||||
|
|
||||||
|
> v1.0 phase detail (Phases 1–6) is archived in [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROADMAP.md).
|
||||||
|
|
||||||
|
### Phase 7: Mobile Test Harness
|
||||||
|
**Goal**: The assistant can drive the PWA in a mobile-emulated, authenticated browser context against the host-side dev stack, so mobile-only layout and flow defects can be caught automatically instead of only by the operator on real devices. This harness is also the artifact Phase 8 (CI) runs for UI regression.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Nothing (fully independent; goes first. One new dev dependency `@playwright/test` in `apps/pwa`; no backend changes).
|
||||||
|
**Requirements**: TEST-01, TEST-02
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. An automated run can load the PWA in a mobile-emulated viewport (device profile + mobile UA + touch) and assert on responsive layout / tap targets.
|
||||||
|
2. The automated run reaches the authenticated PWA via the existing `DEV_AUTH_BYPASS` on the host-side dev stack — no manual login and no Authelia/OIDC mocking.
|
||||||
|
3. The harness runs repeatably day-over-day without re-capturing any session state (no stale storage-state failures).
|
||||||
|
4. The harness specs are structured so they can run headlessly in CI (Phase 8) against a dev stack the runner brings up — no dependence on a developer's already-running host stack.
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **No stale storage-state** (Pitfall 14): use `DEV_AUTH_BYPASS=true` for the automated harness rather than a checked-in storage-state.json with an expiring session cookie; decide the auth strategy before the first test.
|
||||||
|
- **Service worker block** (Pitfall 15): set `serviceWorkers: 'block'` (or explicitly unregister) in the context so a previous run's SW does not intercept requests / return stale cached responses; verify no SW-sourced responses in the trace.
|
||||||
|
- Hard constraints: targets the dev build via `DEV_AUTH_BYPASS` (DEV_AUTH_BYPASS user 1 has no CalDAV credential/calendars — verify layout/flows, not live event-create); real prod-service-worker / iOS-Safari-standalone mobile testing stays a human/device gate (out of scope).
|
||||||
|
**Plans**: TBD
|
||||||
|
**UI hint**: yes
|
||||||
|
|
||||||
|
### Phase 8: Gitea CI
|
||||||
|
**Goal**: Every PR to `main` runs a full regression that gates the merge — lint, typecheck, unit, API-integration against a MariaDB service container, **and the Phase 7 mobile Playwright harness as a UI-regression step against a CI-hosted dev stack** — and a merge to `main` builds and publishes the API Docker image, all on the existing self-hosted Gitea Actions runner.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Phase 7 (the PR regression runs the Phase 7 mobile harness specs as its UI-regression step; without the harness there is nothing to run). No other code dependencies. Start with a runner-probe step.
|
||||||
|
**Requirements**: CI-01, CI-02
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. Opening or updating a PR targeting `main` triggers a workflow that runs lint, typecheck (both apps), unit tests, and API integration tests against a MariaDB service container — and a failing run blocks the merge.
|
||||||
|
2. The API integration tests connect to the service-container MariaDB (DB_HOST=127.0.0.1, service creds) and pass reliably on a cold first run, not only on re-run.
|
||||||
|
3. The same PR workflow brings up the dev stack inside the runner — the API dev server, the PWA dev server, and the MariaDB service container, with `DEV_AUTH_BYPASS=true` — and runs the Phase 7 mobile Playwright harness specs headlessly against that authed PWA; a harness failure blocks the merge.
|
||||||
|
4. The harness step waits for both the API and PWA dev servers to be ready (readiness probe / poll) before launching Playwright, so it does not flake on startup races.
|
||||||
|
5. On merge to `main`, the API Docker image is built and pushed to the Gitea container registry under a sensible tag.
|
||||||
|
6. Registry credentials never appear in plaintext in the CI logs.
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **Runner-probe first** (Pitfall 12): the first workflow only probes `node --version` / `pnpm --version` / Docker access on the `self-hosted` runner before any test or build steps are designed; pin Node 22 explicitly, do not assume `actions/setup-node` works as on GitHub.
|
||||||
|
- **MariaDB readiness wait** (Pitfall 11): add an explicit readiness loop (e.g. `healthcheck.sh --connect --innodb_initialized`, NOT `mysqladmin ping` which is removed in MariaDB 11) before any `drizzle-kit migrate` / integration test step; healthy ≠ accepting connections.
|
||||||
|
- **Dev-stack readiness races (NEW for the harness step):** running the PWA and API dev servers *inside* CI adds startup/readiness races on top of the MariaDB-11 readiness race. The harness step must wait for **both** the API and PWA dev servers to be accepting connections (poll their URLs / health endpoints) before Playwright launches — do not race the browser against a not-yet-listening server. Run with `DEV_AUTH_BYPASS=true` so the harness reaches the authed PWA exactly as in Phase 7.
|
||||||
|
- **--password-stdin** (Pitfall 13): `docker login` via `--password-stdin` with the token piped from a registered Gitea secret (PAT with `write:package`); never `-p $TOKEN` on the command line.
|
||||||
|
- Hard constraints: API integration tests need a real MariaDB and live in `apps/api/tests/` (never `src/`); cache the pnpm store; Drizzle generate+migrate to set up the CI DB schema; the harness step reuses the Phase 7 specs unchanged (CI owns only the stack bring-up + readiness wait, not the spec content).
|
||||||
|
**Plans**: TBD
|
||||||
|
**UI hint**: yes
|
||||||
|
|
||||||
|
### Phase 9: Faster Write-Back
|
||||||
|
**Goal**: A created, edited, or deleted event reaches Fastmail within ~1-2 seconds (event-driven outbox drain) instead of waiting up to ~15s for the next interval tick — with every existing durability guarantee intact.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Nothing (fully independent; the only new artifact is a zero-dependency in-process EventEmitter, `lib/outboxTrigger.ts`). Can run in parallel with any other v1.1 track.
|
||||||
|
**Requirements**: CAL-15
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. After creating/editing/deleting an event, the change lands in Fastmail in ~1-2s in the common case (drain is signalled on enqueue, not waited-for on the interval) — observable as the change appearing in the Fastmail native app well before the old ~15s window.
|
||||||
|
2. The route handler still returns an optimistic 202 immediately and never makes a CalDAV call inline — the event-driven signal is fire-and-forget.
|
||||||
|
3. Edit-as-move still writes the new event before deleting the old one (create-before-delete ordering preserved); no event is ever lost when a move drains under rapid enqueues.
|
||||||
|
4. No duplicate CalDAV PUTs occur for the same outbox row when the signal and the 15s fallback interval overlap (exactly-once per uid preserved).
|
||||||
|
5. The 15s `setInterval` fallback still runs and recovers any rows missed by the signal path (startup catch-up, transient errors).
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **No double-drain** (Pitfall 5): the trigger must set a `drainRequested` flag funnelled through the single setInterval-controlled path / the existing `isDraining` guard — never call `runOutboxDrain()` directly from the signal in a way that bypasses the guard or escapes the error-caught wrapper.
|
||||||
|
- **Create-before-delete under concurrent enqueues** (Pitfall 6): enqueue CREATE before DELETE; do not fire the signal between the two inserts of a move (publish after both inserts / after the transaction commits).
|
||||||
|
- Hard constraints: `setInterval` only (no node-cron); single-process by design — **no Redis** for the drain (Redis stays for list SSE); all outbox guarantees (fresh-etag-before-PUT, 412 conflict flow, per-uid exactly-once) unchanged.
|
||||||
|
**Plans**: TBD
|
||||||
|
|
||||||
|
### Phase 10: Admin Role & Settings
|
||||||
|
**Goal**: An admin can manage household configuration that previously required manual DB writes — rotating a member's Fastmail app password and designating the shared family calendar — from a role-gated in-app Settings section, on top of the v1.1 DB foundation this phase introduces.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Nothing required upstream; this phase **carries the v1.1 DB migration** (users.is_admin, calendar_events.reminder_lead_minutes, app_config table) that Phases 11 and 12 build on. It is the head of the admin chain (10 → 11, 10 → 12).
|
||||||
|
**Requirements**: ADMIN-01, ADMIN-02, ADMIN-03
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. An admin sees an Admin section in Settings and can list household members with their credential status; a non-admin member never sees it and cannot invoke any `/api/admin/*` route (gets 403).
|
||||||
|
2. An admin can enter or rotate a member's Fastmail app password; it is validated against CalDAV (PROPFIND) before saving and stored encrypted — and the password is never displayed, echoed in a response, or logged.
|
||||||
|
3. An admin can pick which synced calendar is the shared family calendar from a list, and the `calendars.is_shared` flag updates accordingly (replacing the manual `UPDATE calendars SET is_shared=1` step).
|
||||||
|
4. The role check is role-agnostic and member-count-agnostic: it gates on `users.is_admin`, so more admins can be added later without reworking the guard.
|
||||||
|
5. The DB migration (is_admin, reminder_lead_minutes, app_config) is applied via generate+migrate and is in place for downstream phases (reminder_lead_minutes for Phase 11, app_config.setup_complete for Phase 12).
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **Admin role check inside the sub-router** (Pitfall 9): apply `requireAdmin` with `.use('*', ...)` inside `adminRouter`, not only at the parent mount; integration test must assert 403 for a non-admin authenticated user.
|
||||||
|
- **App password never logged/echoed** (Pitfall 7): custom zod-validator `hook` returns a generic 400 (no Zod `received`/`value` field); no `console.log` of request bodies in `routes/admin*`.
|
||||||
|
- Hard constraints: Drizzle **generate+migrate, never push** (false destructive diff on populated MariaDB); reuse `broker/crypto.ts` `encryptPassword` (no changes to crypto); `/api/admin/credentials` and `/api/admin/calendars/:id/shared` are the single shared surface — do NOT duplicate them into `/api/setup/*` in Phase 12.
|
||||||
|
**Plans**: TBD
|
||||||
|
**UI hint**: yes
|
||||||
|
|
||||||
|
### Phase 11: Per-Event Reminders
|
||||||
|
**Goal**: A user can choose a reminder lead time per event (None / 5m / 10m / 15m / 30m / 1h / 2h / 1d / 2d, default None), serialized as a VALARM on the event, and the push scheduler fires at that exact lead — firing nothing when there is no alarm and never stripping reminders set in other clients.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Phase 10 (the `calendar_events.reminder_lead_minutes` column from the v1.1 migration is the scheduler's ground truth). Independent of Phases 7/8/9/12.
|
||||||
|
**Requirements**: CAL-13, CAL-14, NOTIF-04, NOTIF-05, NOTIF-06
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. When creating or editing a timed event, the user can pick a reminder lead from the preset list (None default); the choice round-trips to Fastmail as a VALARM and is visible/honored on re-open.
|
||||||
|
2. Editing an event that already has a reminder set in another client (Fastmail / Apple Calendar) preserves that VALARM — it is never silently dropped on round-trip.
|
||||||
|
3. A reminder push fires at the event's chosen lead time (e.g. T-30 for a 30-minute lead), not a hardcoded 15-minute lead.
|
||||||
|
4. An event with no reminder set produces no reminder push (no default 15-minute fire).
|
||||||
|
5. An all-day event's reminder fires at a sensible local time (9 AM on the alert day), not midnight; the reminder selector is disabled/hidden for all-day events in the UI; and reminder delivery stays exactly-once across catch-up scans and rescheduled events.
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **Preserve-on-edit** (Pitfall 1): the update path extracts and preserves existing VALARM sub-components from `rawVevent` (mirroring the WR-01 RRULE-preserve pattern) — never rebuild-from-scratch and silently strip; `outboxPayloadSchema` distinguishes "no change" from explicit "no reminder".
|
||||||
|
- **No TRIGGER VALUE=TEXT** (Pitfall 2): build the trigger with `ICAL.Duration.fromSeconds(-n*60)`, not a bare string; unit-test that the ICS emits a DURATION trigger with no `VALUE=TEXT`.
|
||||||
|
- **All-day 9AM semantics** (Pitfall 3): guard `buildVeventString` (`if (!allDay && reminderMinutes > 0)`), disable the selector when allDay, keep the scheduler's all-day handling at 9 AM local.
|
||||||
|
- **uid:dtstartMs dedup** (Pitfall 4): change the scheduler dedup key from bare `uid` to compound `uid:dtstartMs` and widen the scan to a variable per-event window so long leads fire and rescheduled events re-fire; keep `eventFieldsSchema` and `outboxPayloadSchema` in sync (IN-03).
|
||||||
|
- Hard constraints: `setInterval` only; scheduler reads `reminder_lead_minutes` from the DB (ground truth), not the outbox payload; drop the `isShared`-only reminder restriction (a user who set an alarm wants it regardless of calendar).
|
||||||
|
**Plans**: TBD
|
||||||
|
**UI hint**: yes
|
||||||
|
|
||||||
|
### Phase 12: Initial Setup Wizard
|
||||||
|
**Goal**: On first run (no admin/credentials configured), the operator is guided through a validated, step-by-step wizard to bootstrap the app — env presence, generated secrets to copy, DB/OIDC/VAPID/app-password validation — instead of hand-editing `.env` / `docker-compose.yml`; once complete, the setup endpoints lock.
|
||||||
|
**Mode:** standard
|
||||||
|
**Depends on**: Phase 10 (reuses the admin role + `/api/admin/credentials` and `/api/admin/calendars/:id/shared` routes; the wizard is the second frontend consumer of that surface, and `app_config` from the Phase 10 migration holds `setup_complete`). Goes last. Independent of Phases 7/8/9/11.
|
||||||
|
**Requirements**: SETUP-01, SETUP-02, SETUP-03, SETUP-04
|
||||||
|
**Success Criteria** (what must be TRUE):
|
||||||
|
1. On a fresh install with nothing configured, the operator reaches a setup wizard (via `GET /api/setup/status` mounted before the OIDC guard) and walks through bootstrap steps instead of editing files by hand.
|
||||||
|
2. Each input is validated before the step can complete: DB connects, VAPID private key decodes to exactly 32 bytes and pairs with the public key, OIDC discovery resolves, and the Fastmail app password reaches CalDAV (PROPFIND).
|
||||||
|
3. Generated secrets (session secret, encryption key, VAPID keypair) are displayed for the operator to copy into env; they are never written to the DB or returned in a way that persists, and `APP_PASSWORD_ENCRYPTION_KEY`/`VAPID_PRIVATE_KEY` never enter the DB at all.
|
||||||
|
4. After completion, the wizard-completing user is promoted to admin (`is_admin`), `app_config.setup_complete` is set, and any further call to a setup endpoint returns 423 Locked.
|
||||||
|
5. The 423 guard is enforced on every invocation (checked against member-credentials + VAPID env present), not only at startup.
|
||||||
|
**Pitfalls this phase owns** (from PITFALLS.md):
|
||||||
|
- **Guard on every invocation** (Pitfall 8): the "already set up" guard returns 423 from all setup routes once configured — implement and test the guard before the happy path; a second POST after completion must return 423, not 200.
|
||||||
|
- **Secrets stay in env, never in DB** (Pitfalls 8 & 10): the wizard validates secrets by performing a test operation (test encrypt/decrypt, structural VAPID check), never by accepting/storing the key value; no DB column for `vapid_private_key` or `app_password_encryption_key`; never log/echo the app password.
|
||||||
|
- Hard constraints: `GET /api/setup/status` mounts **before** the OIDC guard (like `/health`); do NOT create `/api/setup/credentials` — reuse the Phase 10 admin routes; Drizzle generate+migrate (any `app_config` seeding via migration).
|
||||||
|
**Plans**: TBD
|
||||||
|
**UI hint**: yes
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
|
|
||||||
@@ -34,6 +157,12 @@ No phases planned yet. Promote items from the Backlog with `/gsd-review-backlog`
|
|||||||
| 4. Shared Lists + Live Sync | v1.0 | 7/7 | Complete | 2026-06-09 |
|
| 4. Shared Lists + Live Sync | v1.0 | 7/7 | Complete | 2026-06-09 |
|
||||||
| 5. Web Push Notifications | v1.0 | 8/8 | Complete | 2026-06-10 |
|
| 5. Web Push Notifications | v1.0 | 8/8 | Complete | 2026-06-10 |
|
||||||
| 6. UX Polish | v1.0 | 6/6 | Complete | 2026-06-10 |
|
| 6. UX Polish | v1.0 | 6/6 | Complete | 2026-06-10 |
|
||||||
|
| 7. Mobile Test Harness | v1.1 | 0/? | Not started | - |
|
||||||
|
| 8. Gitea CI | v1.1 | 0/? | Not started | - |
|
||||||
|
| 9. Faster Write-Back | v1.1 | 0/? | Not started | - |
|
||||||
|
| 10. Admin Role & Settings | v1.1 | 0/? | Not started | - |
|
||||||
|
| 11. Per-Event Reminders | v1.1 | 0/? | Not started | - |
|
||||||
|
| 12. Initial Setup Wizard | v1.1 | 0/? | Not started | - |
|
||||||
|
|
||||||
|
|
||||||
## Backlog
|
## Backlog
|
||||||
@@ -62,6 +191,8 @@ Plans:
|
|||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 11 (Per-Event Reminders) — CAL-13/CAL-14/NOTIF-04/05/06.** Backlog entry retained for history.
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
|
|
||||||
- [ ] TBD (promote with /gsd-review-backlog when ready)
|
- [ ] TBD (promote with /gsd-review-backlog when ready)
|
||||||
@@ -81,6 +212,9 @@ Plans:
|
|||||||
- Security: never log/echo the app password; member-scoped; T-03-19 style scoping.
|
- Security: never log/echo the app password; member-scoped; T-03-19 style scoping.
|
||||||
|
|
||||||
**Severity:** high for true multi-member use — without it the second member has no personal calendar. Tags: phase-03, onboarding, auth, caldav, per-member-credential, D-09.
|
**Severity:** high for true multi-member use — without it the second member has no personal calendar. Tags: phase-03, onboarding, auth, caldav, per-member-credential, D-09.
|
||||||
|
|
||||||
|
> **Note:** v1.1 covers the *admin-managed* counterpart (ADMIN-01, Phase 10) — an admin can set any member's app password. *Self-service* member onboarding (member adds their own) stays deferred here.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
@@ -96,6 +230,9 @@ Plans:
|
|||||||
- **Designate which synced calendar is the "shared" calendar** by toggling `calendars.is_shared` from the UI. Today this is a manual DB write: e.g. `UPDATE calendars SET is_shared=1 WHERE id=<row>` — done by hand on 2026-06-10 to mark the "FamilySync" calendar (id 10) shared after the poller synced it (D-16). The admin should pick the shared calendar from a list of synced collections instead of relying on a backend process. (The poller's upsert already leaves `is_shared` untouched, so a UI-set flag persists.)
|
- **Designate which synced calendar is the "shared" calendar** by toggling `calendars.is_shared` from the UI. Today this is a manual DB write: e.g. `UPDATE calendars SET is_shared=1 WHERE id=<row>` — done by hand on 2026-06-10 to mark the "FamilySync" calendar (id 10) shared after the poller synced it (D-16). The admin should pick the shared calendar from a list of synced collections instead of relying on a backend process. (The poller's upsert already leaves `is_shared` untouched, so a UI-set flag persists.)
|
||||||
|
|
||||||
**Context:** Motivated by the manual D-16 resolution (2026-06-10). **Related:** 999.5 (per-member first-login app-password onboarding) — this is the ongoing admin-managed counterpart; and 999.11 (initial setup wizard) — bootstrap-time vs. ongoing config. Tags: admin, settings, calendar, app-passwords, D-16.
|
**Context:** Motivated by the manual D-16 resolution (2026-06-10). **Related:** 999.5 (per-member first-login app-password onboarding) — this is the ongoing admin-managed counterpart; and 999.11 (initial setup wizard) — bootstrap-time vs. ongoing config. Tags: admin, settings, calendar, app-passwords, D-16.
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 10 (Admin Role & Settings) — ADMIN-01/ADMIN-02/ADMIN-03.** Backlog entry retained for history.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
@@ -114,6 +251,9 @@ Plans:
|
|||||||
Wizard should **validate inputs before completing** — e.g. VAPID private key decodes to 32 bytes AND pairs with the public key, OIDC discovery resolves, DB connects, app-password reaches CalDAV.
|
Wizard should **validate inputs before completing** — e.g. VAPID private key decodes to 32 bytes AND pairs with the public key, OIDC discovery resolves, DB connects, app-password reaches CalDAV.
|
||||||
|
|
||||||
**Context:** Motivated by setup friction observed 2026-06-10 — a VAPID private key truncated on paste into `.env` silently broke push (`setVapidDetails failed — 32 bytes`), and `DB_HOST` / dev overrides must currently be set by hand. A guided + validated wizard would have caught these. **Related:** 999.10 (ongoing admin Settings) and 999.5 (member onboarding). Tags: onboarding, setup, install, env, vapid, mariadb, oidc.
|
**Context:** Motivated by setup friction observed 2026-06-10 — a VAPID private key truncated on paste into `.env` silently broke push (`setVapidDetails failed — 32 bytes`), and `DB_HOST` / dev overrides must currently be set by hand. A guided + validated wizard would have caught these. **Related:** 999.10 (ongoing admin Settings) and 999.5 (member onboarding). Tags: onboarding, setup, install, env, vapid, mariadb, oidc.
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 12 (Initial Setup Wizard) — SETUP-01/02/03/04.** Backlog entry retained for history.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
@@ -133,6 +273,9 @@ Plans:
|
|||||||
**Boundary:** genuinely device-only behaviour (iOS-Safari standalone push, real APNs/FCM delivery, OS notification-channel importance) still needs a human — this item is about everything SHORT of that (responsive layout, tap flows, in-page notification UI states, auth redirects) which a mobile-emulated authed browser *could* cover but currently can't.
|
**Boundary:** genuinely device-only behaviour (iOS-Safari standalone push, real APNs/FCM delivery, OS notification-channel importance) still needs a human — this item is about everything SHORT of that (responsive layout, tap flows, in-page notification UI states, auth redirects) which a mobile-emulated authed browser *could* cover but currently can't.
|
||||||
|
|
||||||
**Context:** Surfaced 2026-06-10 during Phase 5 UAT — repeated mobile-only bugs were caught only by the operator because the assistant had no mobile, authenticated browser to test in. **Related:** [[feedback-playwright-verify]] (use playwright-cli over manual verification — this extends it to mobile/authed). Tags: testing, playwright, mobile, pwa, oidc, dx.
|
**Context:** Surfaced 2026-06-10 during Phase 5 UAT — repeated mobile-only bugs were caught only by the operator because the assistant had no mobile, authenticated browser to test in. **Related:** [[feedback-playwright-verify]] (use playwright-cli over manual verification — this extends it to mobile/authed). Tags: testing, playwright, mobile, pwa, oidc, dx.
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 7 (Mobile Test Harness) — TEST-01/TEST-02.** v1.1 scopes the `DEV_AUTH_BYPASS` dev-build path; the prod-SW authed-mobile target stays deferred. Backlog entry retained for history.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
@@ -152,6 +295,9 @@ Plans:
|
|||||||
**Boundary:** the optimistic 202 + outbox durability design (create-before-delete, drain concurrency guard, fresh-etag-before-PUT) must be preserved — this is a latency tune, not a rewrite of the write path.
|
**Boundary:** the optimistic 202 + outbox durability design (create-before-delete, drain concurrency guard, fresh-etag-before-PUT) must be preserved — this is a latency tune, not a rewrite of the write path.
|
||||||
|
|
||||||
**Context:** Surfaced 2026-06-10. Tags: calendar, write-back, outbox, latency, redis, performance.
|
**Context:** Surfaced 2026-06-10. Tags: calendar, write-back, outbox, latency, redis, performance.
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 9 (Faster Write-Back) — CAL-15.** In-process EventEmitter chosen (not Redis); the drain is single-process by design. Backlog entry retained for history.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
@@ -173,6 +319,9 @@ Plans:
|
|||||||
**Likely shape:** a `.gitea/workflows/ci.yml` — `on: pull_request` (to `main`) → install (pnpm), lint, typecheck, unit, API integration vs. a `mariadb` service container, PWA build; `on: push` to `main`/tag → `docker build apps/api/Dockerfile`, login, push tagged image.
|
**Likely shape:** a `.gitea/workflows/ci.yml` — `on: pull_request` (to `main`) → install (pnpm), lint, typecheck, unit, API integration vs. a `mariadb` service container, PWA build; `on: push` to `main`/tag → `docker build apps/api/Dockerfile`, login, push tagged image.
|
||||||
|
|
||||||
**Context:** Promoted from STATE.md pending todo (`.planning/todos/pending/2026-06-10-gitea-ci-regression-and-docker-publish.md`), surfaced 2026-06-10. Tags: tooling, ci, gitea, docker, mariadb, monorepo.
|
**Context:** Promoted from STATE.md pending todo (`.planning/todos/pending/2026-06-10-gitea-ci-regression-and-docker-publish.md`), surfaced 2026-06-10. Tags: tooling, ci, gitea, docker, mariadb, monorepo.
|
||||||
|
|
||||||
|
> **Promoted into v1.1 Phase 8 (Gitea CI) — CI-01/CI-02.** v1.1 also extends CI-01 to run the Phase 7 mobile harness as a UI-regression step (CI brings up the dev stack in the runner). Backlog entry retained for history.
|
||||||
|
|
||||||
**Requirements:** TBD
|
**Requirements:** TBD
|
||||||
**Plans:** 0 plans
|
**Plans:** 0 plans
|
||||||
|
|
||||||
|
|||||||
+20
-11
@@ -3,10 +3,10 @@ gsd_state_version: 1.0
|
|||||||
milestone: v1.1
|
milestone: v1.1
|
||||||
milestone_name: Operability & Polish
|
milestone_name: Operability & Polish
|
||||||
status: planning
|
status: planning
|
||||||
last_updated: "2026-06-10T22:50:59.197Z"
|
last_updated: "2026-06-10T23:30:00.000Z"
|
||||||
last_activity: 2026-06-10
|
last_activity: 2026-06-10
|
||||||
progress:
|
progress:
|
||||||
total_phases: 0
|
total_phases: 6
|
||||||
completed_phases: 0
|
completed_phases: 0
|
||||||
total_plans: 0
|
total_plans: 0
|
||||||
completed_plans: 0
|
completed_plans: 0
|
||||||
@@ -20,14 +20,14 @@ progress:
|
|||||||
See: .planning/PROJECT.md (updated 2026-06-10)
|
See: .planning/PROJECT.md (updated 2026-06-10)
|
||||||
|
|
||||||
**Core value:** One color-coded family calendar (shared + personal) and shared lists from a single low-friction PWA — cross-ecosystem, no app store
|
**Core value:** One color-coded family calendar (shared + personal) and shared lists from a single low-friction PWA — cross-ecosystem, no app store
|
||||||
**Current focus:** v1.0 MVP shipped + archived — planning next milestone (v1.x). Run `/gsd-new-milestone` or promote backlog via `/gsd-review-backlog`.
|
**Current focus:** v1.1 Operability & Polish — roadmap reordered (Phases 7–12). Next: plan Phase 7 with `/gsd-plan-phase 7` (Mobile Test Harness — independent, goes first; Phase 8 CI consumes its specs) or Phase 9 (Faster Write-Back — independent, lowest risk) or Phase 10 (Admin Role & Settings — carries the DB migration that Phases 11 & 12 need).
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: Not started (defining requirements)
|
Phase: Not started (roadmap reordered — Phases 7–12)
|
||||||
Plan: —
|
Plan: —
|
||||||
Status: Defining requirements
|
Status: Roadmap complete, awaiting phase planning
|
||||||
Last activity: 2026-06-10 — Milestone v1.1 started
|
Last activity: 2026-06-10 — v1.1 roadmap reordered (6 phases, 17/17 requirements mapped)
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -129,13 +129,15 @@ Recent decisions affecting current work:
|
|||||||
- Phase 6 added (2026-06-07): UX Polish — all-day visual distinction, event-form date/recurrence behavior, recurring-series edit, auth-flow smoothing. Candidate scope pulls from backlog 999.2/999.3/999.6/999.7/999.8/999.9.
|
- Phase 6 added (2026-06-07): UX Polish — all-day visual distinction, event-form date/recurrence behavior, recurring-series edit, auth-flow smoothing. Candidate scope pulls from backlog 999.2/999.3/999.6/999.7/999.8/999.9.
|
||||||
- Phase 6 complete (2026-06-10): all 6 plans executed + 2 phase-level UX fixes (AppNav persistence + BottomTabBar desktop hide). Residual device-only checkpoints documented above.
|
- Phase 6 complete (2026-06-10): all 6 plans executed + 2 phase-level UX fixes (AppNav persistence + BottomTabBar desktop hide). Residual device-only checkpoints documented above.
|
||||||
- Backlog reviewed (2026-06-10, /gsd-review-backlog): removed 6 stale duplicates (999.2/3/6/7/8/9 — already promoted into Phase 6) from the Backlog section + deleted the 999.2 dir; kept 999.1/4/5/10/11/12/13; added 999.14 (Gitea CI, promoted from STATE pending todo); archived stale kickoff-new-project todo.
|
- Backlog reviewed (2026-06-10, /gsd-review-backlog): removed 6 stale duplicates (999.2/3/6/7/8/9 — already promoted into Phase 6) from the Backlog section + deleted the 999.2 dir; kept 999.1/4/5/10/11/12/13; added 999.14 (Gitea CI, promoted from STATE pending todo); archived stale kickoff-new-project todo.
|
||||||
|
- **v1.1 roadmap created (2026-06-10):** 6 phases (7–12), continuing v1.0 numbering. 17/17 requirements mapped, no orphans. Promotions: 999.13→Faster Write-Back (CAL-15), 999.10→Admin Role & Settings (ADMIN-01/02/03), 999.11→Setup Wizard (SETUP-01/02/03/04), 999.4→Per-Event Reminders (CAL-13/14 + NOTIF-04/05/06), 999.14→Gitea CI (CI-01/02), 999.12→Mobile Test Harness (TEST-01/02). The v1.1 DB migration (users.is_admin, calendar_events.reminder_lead_minutes, app_config) is folded into the Admin phase (per ARCHITECTURE.md ordering), not a standalone migration phase; the reminders + wizard phases consume it. Backlog 999.5 (self-service onboarding) and 999.1 (provider abstraction) stay deferred — ADMIN-01 covers the admin-managed credential gap in the interim.
|
||||||
|
- **v1.1 roadmap reordered (2026-06-10):** same 6 phases / 17 mappings, new order/numbering. Phase 7 = Mobile Test Harness (was 12), Phase 8 = Gitea CI (was 11), Phase 9 = Faster Write-Back (was 7), Phase 10 = Admin Role & Settings (was 8, carries the DB migration), Phase 11 = Per-Event Reminders (was 10), Phase 12 = Initial Setup Wizard (was 9). **Phase 8 (CI) scope extended:** the PR regression now also runs the Phase 7 mobile harness as a UI-regression step, bringing up the dev stack (API + PWA dev servers + MariaDB service container + DEV_AUTH_BYPASS) in the runner — so **Phase 8 now depends on Phase 7**. New critical path: **7 → 8** (CI consumes the harness); **9** independent; **10 → 11** and **10 → 12** (admin migration precedes reminders + wizard). Parallelizable once prerequisites met: 9 anytime; 11 and 12 in parallel after 10; 7 then 8.
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
- ~~**Fix `docs/deployment.md` local-dev command**~~ DONE 2026-06-10 (quick 260610-czd) — added a "Running locally (host-side, no Docker)" subsection with the correct two-terminal command (`set -a; source .env; set +a && DEV_AUTH_BYPASS=true DB_HOST=localhost pnpm --filter @familysync/api dev` + `pnpm --filter @familysync/pwa dev`). `--env-file` deliberately NOT baked into the dev script (root `.env` sets `DB_HOST=mariadb`; auto-load would break host-side dev).
|
- ~~**Fix `docs/deployment.md` local-dev command**~~ DONE 2026-06-10 (quick 260610-czd) — added a "Running locally (host-side, no Docker)" subsection with the correct two-terminal command (`set -a; source .env; set +a && DEV_AUTH_BYPASS=true DB_HOST=localhost pnpm --filter @familysync/api dev` + `pnpm --filter @familysync/pwa dev`). `--env-file` deliberately NOT baked into the dev script (root `.env` sets `DB_HOST=mariadb`; auto-load would break host-side dev).
|
||||||
- ~~**REQUIREMENTS.md traceability gap**~~ DONE 2026-06-10 (gsd-fast) — added the 6 deferred REQ-IDs to the Traceability table: CAL-09…CAL-12 (v1.x, Deferred), DISP-01/DISP-02 (v2, Deferred). v1 coverage stays 20/20; deferred IDs tracked separately.
|
- ~~**REQUIREMENTS.md traceability gap**~~ DONE 2026-06-10 (gsd-fast) — added the 6 deferred REQ-IDs to the Traceability table: CAL-09…CAL-12 (v1.x, Deferred), DISP-01/DISP-02 (v2, Deferred). v1 coverage stays 20/20; deferred IDs tracked separately.
|
||||||
- **DST spring-forward spot-check (Phase 2)** — recurring/DST is implemented and code-verified (VTIMEZONE before expansion + local display TZ), and operator approved general times; navigating to March 2026 to eyeball the spring-forward transition is a recommended future spot-check.
|
- **DST spring-forward spot-check (Phase 2)** — recurring/DST is implemented and code-verified (VTIMEZONE before expansion + local display TZ), and operator approved general times; navigating to March 2026 to eyeball the spring-forward transition is a recommended future spot-check.
|
||||||
- ~~**Gitea CI — regression on PR to main + Docker build/publish**~~ PROMOTED TO BACKLOG 999.14 (2026-06-10, /gsd-review-backlog) — self-hosted Gitea runner exists but no CI yet. Full regression (lint/typecheck/unit + API integration vs a MariaDB service container + PWA build) gating PRs to `main`, plus build/publish the Docker image to the Gitea registry. Detail retained in pending todo `2026-06-10-gitea-ci-regression-and-docker-publish.md` (backing the backlog entry).
|
- ~~**Gitea CI — regression on PR to main + Docker build/publish**~~ PROMOTED TO BACKLOG 999.14 → now **v1.1 Phase 8** (Gitea CI, CI-01/CI-02). Detail retained in pending todo `2026-06-10-gitea-ci-regression-and-docker-publish.md`. Scope extended in the reorder: CI also runs the Phase 7 mobile harness as a UI-regression step.
|
||||||
|
|
||||||
### Blockers/Concerns
|
### Blockers/Concerns
|
||||||
|
|
||||||
@@ -145,6 +147,8 @@ Recent decisions affecting current work:
|
|||||||
- Phase 2/3 dev: build behind a documented dev-auth bypass until Gate 2 deploy (D-14).
|
- Phase 2/3 dev: build behind a documented dev-auth bypass until Gate 2 deploy (D-14).
|
||||||
- Phase 5: iOS push subscriptions silently revoked after 3 silent pushes. Subscription health-check and event.waitUntil() are mandatory from day one.
|
- Phase 5: iOS push subscriptions silently revoked after 3 silent pushes. Subscription health-check and event.waitUntil() are mandatory from day one.
|
||||||
- Phase 06 residual device-only items (not drivable in desktop Chromium): (1) PushPermissionPrompt spinner visible only in an installed iOS/standalone PWA — code-confirmed uses global @keyframes spin; spot-check at go-live. (2) iOS-Safari standalone cold-load and Authelia redirect — per 06-VALIDATION.md Manual-Only table; not yet verified. (3) Dev-bypass user (id 1) has no CalDAV credential/calendars; live event-create via the form requires user 2 or a dev-seed fix before go-live testing.
|
- Phase 06 residual device-only items (not drivable in desktop Chromium): (1) PushPermissionPrompt spinner visible only in an installed iOS/standalone PWA — code-confirmed uses global @keyframes spin; spot-check at go-live. (2) iOS-Safari standalone cold-load and Authelia redirect — per 06-VALIDATION.md Manual-Only table; not yet verified. (3) Dev-bypass user (id 1) has no CalDAV credential/calendars; live event-create via the form requires user 2 or a dev-seed fix before go-live testing.
|
||||||
|
- **v1.1 Phase 7 (Mobile Test Harness):** DEV_AUTH_BYPASS user 1 has no CalDAV credential/calendars — the harness verifies layout/flows, not live event-create. Confirm SW-block + bypass strategy before the first test (PITFALLS 14/15). These specs become Phase 8's CI UI-regression step, so structure them to run headlessly against a runner-hosted dev stack.
|
||||||
|
- **v1.1 Phase 8 (Gitea CI):** Unraid Gitea runner Docker-socket/Node/pnpm state unknown — runner-probe is the first CI task (PITFALLS 12); MariaDB 11 readiness uses `healthcheck.sh --connect`, not `mysqladmin ping` (removed in MariaDB 11). NEW: the harness step brings up the API + PWA dev servers in the runner — added startup/readiness races on top of the MariaDB race; the step must wait for **both** dev servers to be ready before launching Playwright. Depends on Phase 7.
|
||||||
|
|
||||||
### Quick Tasks Completed
|
### Quick Tasks Completed
|
||||||
|
|
||||||
@@ -170,15 +174,20 @@ Recent decisions affecting current work:
|
|||||||
| Calendar | Apple Calendar native subscribe URL docs | v1.x | Roadmap |
|
| Calendar | Apple Calendar native subscribe URL docs | v1.x | Roadmap |
|
||||||
| Calendar | Secondary timezone display toggle | v1.x | Roadmap |
|
| Calendar | Secondary timezone display toggle | v1.x | Roadmap |
|
||||||
| Display | Wall-display / kiosk dashboard | v2 | PROJECT.md |
|
| Display | Wall-display / kiosk dashboard | v2 | PROJECT.md |
|
||||||
|
| Reminders | Multiple reminders per event (2× VALARM) | v1.2 | v1.1 REQUIREMENTS.md |
|
||||||
|
| Onboarding | Self-service member app-password setup (999.5) — v1.1 covers admin-managed (ADMIN-01) | Backlog | v1.1 roadmap |
|
||||||
|
| Calendar | Provider abstraction (999.1) — Fastmail as one of several backends | Backlog | v1.1 roadmap |
|
||||||
|
| Setup | Wizard re-run / reconfigure flow after first setup | Backlog | v1.1 REQUIREMENTS.md |
|
||||||
| Notifications | **Android event-change push delivery (Phase 5 UAT Test 4)** — confirm member B's Android device receives a non-silent "A updated an event" push after member A edits a shared event. Blocking bugs already fixed + deployed (quick 260610-jlp how-to-enable link, 260610-ka9 silent-notification options); server-side FCM delivery proven (FCM 201). Remaining: on-device confirmation + operator raises the Edge/Android notification-channel importance. See 05-UAT.md Test 4. | Phase 6 verification | 2026-06-10 |
|
| Notifications | **Android event-change push delivery (Phase 5 UAT Test 4)** — confirm member B's Android device receives a non-silent "A updated an event" push after member A edits a shared event. Blocking bugs already fixed + deployed (quick 260610-jlp how-to-enable link, 260610-ka9 silent-notification options); server-side FCM delivery proven (FCM 201). Remaining: on-device confirmation + operator raises the Edge/Android notification-channel importance. See 05-UAT.md Test 4. | Phase 6 verification | 2026-06-10 |
|
||||||
| ~~Calendar~~ | ~~Mark shared-family calendar `is_shared=1`~~ **RESOLVED 2026-06-10** — operator created the "FamilySync" calendar on the primary Fastmail account; poller synced it as calendars.id=10 (user 2); ran `UPDATE calendars SET is_shared=1 WHERE id=10`. Shared color lane now populated; Phase 5 reminders now fire on its events. Poller upsert does not touch is_shared, so the flag persists. | ~~Phase 2 (deferred, D-16)~~ DONE | 2026-06-05 → 2026-06-10 |
|
| ~~Calendar~~ | ~~Mark shared-family calendar `is_shared=1`~~ **RESOLVED 2026-06-10** — operator created the "FamilySync" calendar on the primary Fastmail account; poller synced it as calendars.id=10 (user 2); ran `UPDATE calendars SET is_shared=1 WHERE id=10`. Shared color lane now populated; Phase 5 reminders now fire on its events. Poller upsert does not touch is_shared, so the flag persists. (ADMIN-02 in v1.1 Phase 10 replaces this manual step with a UI toggle.) | ~~Phase 2 (deferred, D-16)~~ DONE | 2026-06-05 → 2026-06-10 |
|
||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-06-10T15:20:02.349Z
|
Last session: 2026-06-10T23:30:00.000Z
|
||||||
Stopped at: Completed 06-03: hasRrule server-side exposure
|
Stopped at: v1.1 roadmap reordered (Phases 7–12; 17/17 requirements mapped)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|
||||||
## Operator Next Steps
|
## Operator Next Steps
|
||||||
|
|
||||||
- Start the next milestone with /gsd-new-milestone
|
- Review the reordered v1.1 roadmap in `.planning/ROADMAP.md` (Phases 7–12).
|
||||||
|
- Plan the first phase with `/gsd-plan-phase 7` (Mobile Test Harness — independent, goes first; Phase 8 CI runs its specs). Alternatives that can start in parallel: `/gsd-plan-phase 9` (Faster Write-Back — independent, lowest risk) or `/gsd-plan-phase 10` (Admin Role & Settings — carries the DB migration that Phases 11 & 12 depend on).
|
||||||
|
|||||||
Reference in New Issue
Block a user