75 lines
4.7 KiB
Markdown
75 lines
4.7 KiB
Markdown
---
|
|
context: phase
|
|
phase: 05-web-push-notifications
|
|
task: null
|
|
total_tasks: null
|
|
status: paused
|
|
last_updated: 2026-06-09T19:14:03.727Z
|
|
---
|
|
|
|
<current_state>
|
|
Phase 5 (Web Push Notifications, MVP mode, depends on Phase 3 + Phase 4) just
|
|
completed **discuss-phase**. `05-CONTEXT.md` and `05-DISCUSSION-LOG.md` are written
|
|
and committed (e74f24d); STATE.md session recorded (3bbfbbc). Working tree clean.
|
|
|
|
This is a clean stop **between discuss and plan** — no plans/tasks exist yet,
|
|
nothing is mid-edit. Resume by planning the phase.
|
|
</current_state>
|
|
|
|
<completed_work>
|
|
|
|
- Task 1: discuss-phase 5 → `05-CONTEXT.md` + `05-DISCUSSION-LOG.md` (decisions D-01..D-14). Done (e74f24d).
|
|
- Task 2: STATE.md session recorded. Done (3bbfbbc).
|
|
</completed_work>
|
|
|
|
<remaining_work>
|
|
|
|
- Task 3 (optional): `/gsd-ui-phase 5` — UI design contract for the permission prompt, settings master toggle, and notification flow. This phase has real frontend surface.
|
|
- Task 4: `/gsd-plan-phase 5` — research + plan (reads `05-CONTEXT.md`).
|
|
- Task 5: execute the plans.
|
|
</remaining_work>
|
|
|
|
<decisions_made>
|
|
|
|
- **D-05 (most consequential): reminders fire for the SHARED Family calendar ONLY** — not personal events. Deliberate, because each member's native device calendar app already reminds for personal events and FamilySync must not duplicate. This narrows a literal reading of NOTIF-01; flagged for planner + verification.
|
|
- Coalesce list-change pushes per list; events show specifics, list pings stay generic (actor + list + count, no item text); name the actor; only meaningful event-changes push (description-only edits stay silent).
|
|
- Contextual permission prompt right after install; single master on/off toggle (v1); silent auto re-subscribe when a subscription dies but OS permission is still granted.
|
|
- Fixed 15-min lead; no all-day reminders.
|
|
</decisions_made>
|
|
|
|
<blockers>
|
|
- None blocking planning/implementation. (Human action — non-blocking: the shared "Family" calendar must be created + shared + `is_shared=1` per Phase 2 D-16 before reminders have real events to fire on for live verification.)
|
|
</blockers>
|
|
|
|
## Required Reading (in order)
|
|
1. `.planning/phases/05-web-push-notifications/05-CONTEXT.md` — the source of truth; decisions, canonical refs, code-context, deferred items.
|
|
2. `CLAUDE.md` §"React PWA Stack" — iOS push constraints (16.4 min, install required, gesture subscribe, visible-notification mandatory) + web-push/VAPID stack entry.
|
|
3. `.planning/STATE.md` (Phase 5 note) — iOS revokes after ~3 silent pushes; health-check + `event.waitUntil()` mandatory.
|
|
4. `apps/api/src/lib/listEmitter.ts`, `apps/api/src/broker/poller.ts`, `apps/api/src/broker/outboxWorker.ts` — push-dispatch hook points + change-detection sources.
|
|
|
|
## Critical Anti-Patterns (do NOT repeat these)
|
|
| Pattern | Description | Severity | Prevention Mechanism |
|
|
|---------|-------------|----------|---------------------|
|
|
| `db:push` on populated MariaDB | The new push-subscription table must NOT be created via `drizzle-kit push` — it emits a false destructive diff and can truncate tables on populated MariaDB | advisory | Use `drizzle-kit generate` + `migrate` for all new tables this phase |
|
|
| Silent pushes on iOS | Any push that does not display a visible notification counts toward iOS's ~3-strike silent-revocation; subscriptions die silently | advisory | Every push MUST show a visible notification; SW uses `event.waitUntil()`; implement the subscription health-check from day one |
|
|
| Introducing Redis for fan-out | The API is a single Node process; `ioredis` is not installed | advisory | Push dispatch reuses the in-memory `listEmitter` publish points — do not add Redis (matches Ph4 decision) |
|
|
|
|
## Infrastructure State
|
|
- `web-push` and `ioredis`: NOT installed. VAPID keys not yet generated. No Redis (single Node process).
|
|
- Service worker: vite-plugin-pwa `generateSW` + `autoUpdate` — adding a `push`/`notificationclick` handler likely requires switching to `injectManifest` (planner's call; preserve Workbox precache + autoupdate).
|
|
- react-router installed (Ph4 D-17) — enables tap-to-open deep links (`/lists/:id`, event URLs).
|
|
- No running background services from this session.
|
|
|
|
<context>
|
|
Discussion is done and committed; nothing is in flight. Three gray areas were
|
|
discussed (Copy & anti-spam, Reminder scope & timing, Onboarding & opt-out);
|
|
Quiet-hours/DND was left to discretion (v1 = none). The shared-only reminder
|
|
scope (D-05) is the decision most worth re-examining before committing the plan
|
|
if the household's mental model is "remind me about everything."
|
|
</context>
|
|
|
|
<next_action>
|
|
Start with: `/clear` then `/gsd-plan-phase 5` (optionally `/gsd-ui-phase 5` first
|
|
for the notification UI design contract). Read `05-CONTEXT.md` before acting.
|
|
</next_action>
|