From fa90b7cf866dee9425d049db8952f76242884692 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Wed, 10 Jun 2026 16:30:01 -0400 Subject: [PATCH] docs(phase-06): finalize 06-04/05/06 summaries + tracking - 06-04-SUMMARY: pulse keyframe checkpoint PASS (playwright-cli); CP-04.3 iOS device-only noted - 06-05-SUMMARY: TDD RED/GREEN + dead-end guard follow-up fix; playwright-cli cold-load + 401 PASS - 06-06-SUMMARY: end-tracking/recurrence-bound/series-prompt/all-day-pill; Schedule-X selector fix noted - ROADMAP: mark 06-04/05/06 complete; phase 6 row updated to 6/6 Complete 2026-06-10 - STATE: phase 06 position/status updated; 3 new metric rows; 6 new decisions; phase-level UX fixes (AppNav/BottomTabBar) documented; residual device-only items added to Blockers --- .planning/ROADMAP.md | 10 +- .planning/STATE.md | 27 ++- .../phases/06-ux-polish/06-04-SUMMARY.md | 82 +++++++++ .../phases/06-ux-polish/06-05-SUMMARY.md | 166 ++++++++++++++++++ .../phases/06-ux-polish/06-06-SUMMARY.md | 151 ++++++++++++++++ 5 files changed, 423 insertions(+), 13 deletions(-) create mode 100644 .planning/phases/06-ux-polish/06-04-SUMMARY.md create mode 100644 .planning/phases/06-ux-polish/06-05-SUMMARY.md create mode 100644 .planning/phases/06-ux-polish/06-06-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 7a4be99..4dc24c1 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -18,7 +18,7 @@ Decimal phases appear between their surrounding integers in numeric order. - [x] **Phase 3: Event Write-Back + PWA Install** - Full event CRUD written back to Fastmail, PWA manifest + service worker, guided iOS install flow (completed 2026-06-07) - [x] **Phase 4: Shared Lists + Live Sync** - Named collaborative lists with item CRUD and real-time SSE co-edit sync (completed 2026-06-09) - [x] **Phase 5: Web Push Notifications** - VAPID push for event reminders, event changes, and list-change alerts (completed 2026-06-10; on-device UAT 1/2/5 PASS, T3 dropped as non-gating, T4 Android event-change push deferred to Phase 6 verification — see 05-UAT.md) -- [ ] **Phase 6: UX Polish** - All-day visual distinction, event-form date/recurrence behavior, recurring-series edit, and auth-flow smoothing +- [x] **Phase 6: UX Polish** - All-day visual distinction, event-form date/recurrence behavior, recurring-series edit, and auth-flow smoothing (completed 2026-06-10) ## Phase Details @@ -238,12 +238,12 @@ Plans: - [x] 06-01-PLAN.md — TDD: duration-preserving end-tracking math (computeNewTimedEnd/computeNewAllDayEnd) in eventDateTime.ts (D-04) - [x] 06-02-PLAN.md — TDD: RRULE UNTIL/COUNT serialization + Zod acceptance + FREQ-persistence regression (vevent/outboxWorker/events route) (D-06/D-07) - [x] 06-03-PLAN.md — TDD: hasRrule on CalendarOccurrence + bounded-expansion lock (expand.ts) (D-06/D-08) -- [ ] 06-04-PLAN.md — Spinner/pulse: global @keyframes pulse + remove redundant spin redefinition (D-13) -- [ ] 06-05-PLAN.md — Auth gating slice: SessionExpiredError + AuthSplash + global QueryCache/MutationCache error handler; client.ts type mirrors (D-10/D-11, + D-06/D-08 type carriers) +- [x] 06-04-PLAN.md — Spinner/pulse: global @keyframes pulse + remove redundant spin redefinition (D-13) +- [x] 06-05-PLAN.md — Auth gating slice: SessionExpiredError + AuthSplash + global QueryCache/MutationCache error handler; client.ts type mirrors (D-10/D-11, + D-06/D-08 type carriers) **Wave 2** *(blocked on 06-01/02/03/05)* -- [ ] 06-06-PLAN.md — EventForm integration slice: end-tracking wiring + recurrence-bound control + series-edit prompt + all-day pill (D-03/D-04/D-05/D-06/D-07/D-08/D-09/D-12) +- [x] 06-06-PLAN.md — EventForm integration slice: end-tracking wiring + recurrence-bound control + series-edit prompt + all-day pill (D-03/D-04/D-05/D-06/D-07/D-08/D-09/D-12) **UI hint**: yes @@ -260,7 +260,7 @@ Note: Phase 4 depends only on Phase 1 and can begin as soon as Phase 1 is comple | 3. Event Write-Back + PWA Install | 12/12 | Complete | 2026-06-07 | | 4. Shared Lists + Live Sync | 6/6 | Complete | 2026-06-09 | | 5. Web Push Notifications | 8/8 | Complete | 2026-06-10 | -| 6. UX Polish | 3/6 | In Progress| | +| 6. UX Polish | 6/6 | Complete | 2026-06-10 | ## Backlog diff --git a/.planning/STATE.md b/.planning/STATE.md index dc48022..8ea1ac2 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,9 +3,9 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: "Completed 06-03: hasRrule server-side exposure" -last_updated: "2026-06-10T15:20:02.358Z" -last_activity: "2026-06-10 -- Completed 06-02: RRULE UNTIL/COUNT serialization + FREQ persistence" +stopped_at: "Completed 06-06: Phase 06 all 6 plans complete" +last_updated: "2026-06-10T18:00:00.000Z" +last_activity: "2026-06-10 -- Completed 06-04/05/06: sync animations, auth gating, EventForm integration + phase-level UX fixes" progress: total_phases: 17 completed_phases: 5 @@ -25,10 +25,10 @@ See: .planning/PROJECT.md (updated 2026-06-07) ## Current Position -Phase: 06 (ux-polish) — EXECUTING -Plan: 4 of 6 -Status: Ready to execute -Last activity: 2026-06-10 -- Completed 06-02: RRULE UNTIL/COUNT serialization + FREQ persistence +Phase: 06 (ux-polish) — COMPLETE (all 6 plans executed) +Plan: 6 of 6 +Status: Phase 06 complete — pending final phase-level verification (06-VALIDATION.md) +Last activity: 2026-06-10 -- Completed 06-04/05/06: sync animations, auth gating, EventForm integration + phase-level UX fixes Progress: [█████████░] 89% @@ -76,6 +76,9 @@ Progress: [█████████░] 89% | Phase 06-ux-polish P01 | 2 | 2 tasks | 2 files | | Phase 06-ux-polish P02 | 8 | 2 tasks | 4 files | | Phase 06-ux-polish P03 | 11 | 2 tasks | 3 files | +| Phase 06-ux-polish P04 | 5 | 2 tasks | 2 files | +| Phase 06-ux-polish P05 | 35 | 4 tasks | 6 files | +| Phase 06-ux-polish P06 | 45 | 4 tasks | 5 files | ## Accumulated Context @@ -118,17 +121,24 @@ Recent decisions affecting current work: - [Phase ?]: D-05-06-crossjoin: Drizzle cross-join in reminderScheduler pairs shared events with all pushSubscriptions; grouping by uid post-join ensures full fan-out per deduped event (reminderScheduler.ts) - [Phase ?]: D-03 actor exclusion: ne() at DB level + filter() in application code (defence-in-depth for eventChangeDispatcher tests) - [Phase ?]: D-08: hasRrule derived from event.isRecurring() in expand.ts — no DB query change needed; captured once before branch +- [Phase 06-04]: @keyframes pulse added globally to tokens.css; redundant local spin redefinition removed from PushPermissionPrompt.tsx — all sync-animation consumers now resolve from the global stylesheet (D-13) +- [Phase 06-05]: TanStack Query v5 global error handler: QueryCache({onError})/MutationCache({onError}) constructor pattern; defaultOptions.onError removed in v5 (NOT used); confirmed via Context7 /tanstack/query +- [Phase 06-05]: AuthSplash state machine: loading/redirecting/dead-end; CalendarContent renders only on meQuery.isSuccess (D-10); sessionExpired flag via Zustand + global QueryCache/MutationCache onError (D-11); one-shot redirect guard re-armed only on explicit user tap +- [Phase 06-06]: Schedule-X all-day CSS: .sx__all-day-event does not exist in v4.6.0; real selectors are .sx__date-grid-event (week/day) + .sx__month-grid-event:not(:has(.sx__month-grid-event-time)) (month); --sx-color-primary-container remapped as fallback +- [Phase 06]: Phase-level UX fixes (surfaced during UAT, not in any single plan): AppNav made persistent across routes — nav no longer disappears on /lists (commits 6070437 RED + 051874b fix); BottomTabBar hidden on desktop — no longer overlaps sidebar Settings affordance (commits 740e342 RED + 089b53d fix) ### Roadmap Evolution - 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. +- 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. ### 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). - ~~**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. -- **Gitea CI — regression on PR to main + Docker build/publish** — self-hosted Gitea runner exists but no CI yet. Add `.gitea/workflows/`: full regression (lint/typecheck/unit + API integration tests against a MariaDB service container + PWA build) gating PRs to `main`, plus build/publish the Docker image to the Gitea registry. Decide image matrix (API-only vs API+PWA — only `apps/api/Dockerfile` exists today) and tag policy. See pending todo `2026-06-10-gitea-ci-regression-and-docker-publish.md`. +- ~~**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). ### Blockers/Concerns @@ -137,6 +147,7 @@ Recent decisions affecting current work: - Phase 3: iOS standalone-PWA + Authelia login is load-bearing for the wife and is the first real external auth test (carried Gate 2 item, D-14). Also: iOS install guide is load-bearing — she gets no push notifications if she does not install the PWA. - 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 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. ### Quick Tasks Completed diff --git a/.planning/phases/06-ux-polish/06-04-SUMMARY.md b/.planning/phases/06-ux-polish/06-04-SUMMARY.md new file mode 100644 index 0000000..03bc891 --- /dev/null +++ b/.planning/phases/06-ux-polish/06-04-SUMMARY.md @@ -0,0 +1,82 @@ +--- +phase: 06-ux-polish +plan: "04" +subsystem: pwa/styles +tags: [css, animation, d-13] +dependency_graph: + requires: [] + provides: + - "@keyframes pulse (apps/pwa/src/styles/tokens.css)" + affects: + - LiveSyncIndicator (reconnecting dot now resolves the global pulse keyframe) + - PushPermissionPrompt (redundant local spin redefinition removed) +tech_stack: + added: [] + patterns: + - Global keyframe resolution: all animation consumers reference tokens.css keyframes, not local