5.7 KiB
context, phase, task, total_tasks, status, last_updated
| context | phase | task | total_tasks | status | last_updated |
|---|---|---|---|---|---|
| phase | 05-web-push-notifications | null | null | awaiting_device_uat | 2026-06-10T02:49:45.903Z |
Critical Anti-Patterns
| Pattern | Description | Severity | Prevention Mechanism |
|---|---|---|---|
await before pushManager.subscribe() in a tap handler |
The iOS user-gesture gate breaks if ANY async/await (network fetch, navigator.serviceWorker.ready) runs between the user tap and pushManager.subscribe() → NotAllowedError. This recurred TWICE this phase (original CR-04, then the fixer's own await serviceWorker.ready). |
advisory | When touching push opt-in UI, pre-resolve BOTH the SW registration and VAPID public key into component state via useEffect, disable the Enable control until both are non-null, and call subscribe(registration, vapidKey) synchronously — zero await before pushManager.subscribe(). See usePushSubscription.ts / PushPermissionPrompt.tsx / SettingsSheet.tsx. |
db:push on populated MariaDB |
drizzle-kit push emits a false destructive diff and can truncate tables. |
advisory | New tables/columns via db:generate + db:migrate only (migrations 0003 + 0004 followed this). |
| Silent pushes on iOS | A push that does not display a visible notification counts toward iOS's ~3-strike silent-revocation. | advisory | Every push path uses event.waitUntil(showNotification(...)) in sw.ts; keep it that way. |
Root .env is permission-blocked from the assistant |
Read/Write/grep of .env are denied in this harness; secrets cannot be written by the agent. |
advisory | Hand secret values to the user to paste, or read the dev DB password from the container: docker exec familysync-mariadb-1 printenv MARIADB_PASSWORD. |
<current_state>
Phase 5 (Web Push Notifications) is code-complete and verified at the code level (12/12 must-haves). All 8 plans (05-01..05-08) executed and committed; code review ran --fix --all --auto (14 findings fixed across 3 iterations, 05-REVIEW.md status clean); phase verification produced 05-VERIFICATION.md with status human_needed (no gaps). Working tree clean.
The ONLY remaining work is on-device UAT — the phase goal says "reliably on iOS and Android," which cannot be automated. ROADMAP was reverted from a premature [x] to [ ] pending device UAT.
</current_state>
<completed_work>
- All 8 plans executed (Wave 1: 05-01 foundation; W2: 05-02 dispatchPush, 05-03 coalescer; W3: 05-04 push spine; W4: 05-05 list-change/NOTIF-02, 05-06 reminder scheduler/NOTIF-01, 05-08 opt-out+health UI; W5: 05-07 event-change/NOTIF-03 + title population). Each has a SUMMARY.md.
- Packages installed (web-push 3.6.7, workbox 7.4.1); VAPID keypair generated + placed in root
.envby user; wired into docker-compose.yml + .env.example. - Migrations 0003 (push_subscriptions + calendar_events.title) + 0004 (endpoint→varchar(2048), p256dh→varchar(512)) generated and applied.
- Code review fixes (CR-01..04, WR-01..05, IN-01..03, NEW-CR-01, NEW-WR-01) all committed as
fix(05-review):. - Test state: API 213/214 (1 flaky real-DB timeout in lists.test.ts under parallel load — passes 59/59 isolated), PWA 160/160, both typecheck clean, PWA builds, no schema drift. </completed_work>
<remaining_work>
- Run
/gsd-verify-work 5and complete the 5 device-only UAT items in05-UAT.md:- iOS PWA install → subscribe → 15-min reminder receipt
- iOS subscribe without NotAllowedError
- iOS health-check survives 1+ week inactivity
- Android event-change push arrives
- List-change coalescing observable (5 edits → 1 push)
- After UAT passes, verify-work auto-transitions the phase to complete; then milestone can advance to Phase 6. </remaining_work>
<decisions_made>
- VAPID config env-injected (docker-compose env + root .env), never baked into image — for container transposability.
- Reminders are SHARED Family-calendar timed events ONLY (D-05), enforced in SQL.
- Reverted premature ROADMAP completion to pending; completion gated on device UAT. </decisions_made>
Required Reading (in order)
.planning/phases/05-web-push-notifications/05-VERIFICATION.md— what was verified in code + the 5 human items..planning/phases/05-web-push-notifications/05-UAT.md— the device test script to run via verify-work..planning/phases/05-web-push-notifications/05-REVIEW.md— code review resolution (esp. the iOS gesture-gate fix).CLAUDE.md§"React PWA Stack" — iOS push constraints.
Infrastructure State
- Dev MariaDB container
familysync-mariadb-1is UP, host port 3306 bound. DB password:docker exec familysync-mariadb-1 printenv MARIADB_PASSWORD. - VAPID keys present in gitignored root
.env; documented in.env.example; wired into docker-compose.yml. - No running API/PWA dev servers from this session.
- Migrations 0003 + 0004 applied to the dev DB.
<next_action>
Start with: /gsd-verify-work 5 — walk the 5 items in 05-UAT.md on a physical iOS (16.4+, Home-Screen-installed) device and an Android device. Ensure the shared "Family" calendar exists with is_shared=1 first so reminders have events to fire on.
</next_action>