Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
140 lines
6.5 KiB
Markdown
140 lines
6.5 KiB
Markdown
# Phase 5: Web Push Notifications - Discussion Log
|
||
|
||
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||
|
||
**Date:** 2026-06-09
|
||
**Phase:** 5-web-push-notifications
|
||
**Areas discussed:** Copy & anti-spam, Reminder scope & timing, Onboarding & opt-out
|
||
|
||
---
|
||
|
||
## Area selection
|
||
|
||
| Option | Description | Selected |
|
||
| ----------------------- | ---------------------------------------- | -------- |
|
||
| Copy & anti-spam | Wording per type + coalescing | ✓ |
|
||
| Reminder scope & timing | Whose events, fixed/custom lead, all-day | ✓ |
|
||
| Quiet hours / DND | Suppress non-urgent in a quiet window | |
|
||
| Onboarding & opt-out | When to prompt, toggle granularity | ✓ |
|
||
|
||
**Notes:** Quiet hours/DND left to Claude's discretion (v1 = no quiet hours).
|
||
|
||
---
|
||
|
||
## Copy & anti-spam
|
||
|
||
### List-change batching
|
||
|
||
| Option | Description | Selected |
|
||
| -------------------------- | ------------------------------------------------ | -------- |
|
||
| Coalesce per list | Batch same-list changes in ~30–60s into one push | ✓ |
|
||
| Coalesce + skip check-offs | Same, but check-offs never push | |
|
||
| One push per change | Immediate, no batching | |
|
||
|
||
### Detail level
|
||
|
||
| Option | Description | Selected |
|
||
| ------------------------------ | -------------------------------------- | -------- |
|
||
| Specific details | Full specifics for everything | |
|
||
| Specific events, generic lists | Events show detail; list pings generic | ✓ |
|
||
| Generic only | Everything generic | |
|
||
|
||
### Attribution
|
||
|
||
| Option | Description | Selected |
|
||
| -------------- | ------------------- | -------- |
|
||
| Name the actor | "Wife checked off…" | ✓ |
|
||
| No name | "Milk checked off…" | |
|
||
|
||
### Event-change granularity
|
||
|
||
| Option | Description | Selected |
|
||
| ----------------------- | ------------------------------------------------------- | -------- |
|
||
| Meaningful changes only | new/delete/time/date/title/location; description silent | ✓ |
|
||
| Time/date only | only reschedules + add/delete | |
|
||
| Any change | including description edits | |
|
||
|
||
**User's choice:** Coalesce per list; specific-for-events/generic-for-lists; name the actor; meaningful changes only.
|
||
**Notes:** Generic-list + name-actor reconciled as "Wife made 3 changes to Groceries" (actor + list + count, no item text).
|
||
|
||
---
|
||
|
||
## Reminder scope & timing
|
||
|
||
### Whose events remind
|
||
|
||
| Option | Description | Selected |
|
||
| ------------------ | ------------------------------- | -------- |
|
||
| Own + shared | Own personal + shared Family | |
|
||
| Everything visible | Incl. partner's personal events | |
|
||
| Shared only | Shared Family calendar only | ✓ |
|
||
|
||
### Lead time
|
||
|
||
| Option | Description | Selected |
|
||
| ------------------------ | ---------------------- | -------- |
|
||
| Fixed 15 min (v1) | Always ~15 min | ✓ |
|
||
| User default, changeable | One global offset | |
|
||
| Per-event lead time | Per-event offset field | |
|
||
|
||
### All-day events
|
||
|
||
| Option | Description | Selected |
|
||
| -------------- | -------------- | -------- |
|
||
| Morning-of | Fixed AM time | |
|
||
| No reminder | Never push | ✓ |
|
||
| Evening before | ~6pm prior day | |
|
||
|
||
**User's choice:** Shared-only; fixed 15 min; no all-day reminder.
|
||
**Notes (load-bearing rationale, free-text):** "the native mail client on the device will still send notifications. we dont want to duplicate that." Personal-calendar reminders are already covered by each member's native device calendar app; FamilySync owns reminders for the shared Family calendar only. Confirmed deliberately after a challenge that this narrows NOTIF-01.
|
||
|
||
---
|
||
|
||
## Onboarding & opt-out
|
||
|
||
### Permission prompt timing
|
||
|
||
| Option | Description | Selected |
|
||
| ------------------------- | ----------------------------------- | -------- |
|
||
| Contextual, after install | Explainer + tap right after install | ✓ |
|
||
| On first relevant action | After first event create | |
|
||
| Settings toggle only | No auto-prompt | |
|
||
|
||
### Opt-out granularity
|
||
|
||
| Option | Description | Selected |
|
||
| -------------------- | ----------------------------- | -------- |
|
||
| Single master toggle | One on/off | ✓ |
|
||
| Per-category toggles | reminders/event/list switches | |
|
||
| Master + categories | Both | |
|
||
|
||
### Dead-subscription recovery
|
||
|
||
| Option | Description | Selected |
|
||
| ---------------------------- | --------------------------------------------- | -------- |
|
||
| Silent auto re-subscribe | Background re-subscribe if permission granted | ✓ |
|
||
| Silent, then banner fallback | Banner if silent fails | |
|
||
| Always prompt | Banner on every death | |
|
||
|
||
**User's choice:** Contextual after-install prompt; single master toggle; silent auto re-subscribe.
|
||
|
||
---
|
||
|
||
## Claude's Discretion
|
||
|
||
- No quiet-hours / DND in v1 (reminders/alerts always fire).
|
||
- Tap-to-open deep-link targets (reminder/event-change → event; list-change → `/lists/:id`).
|
||
- Service-worker strategy (generateSW vs injectManifest for push handler).
|
||
- VAPID key generation/storage, push-subscription table schema, reminder-scheduler mechanism, coalescing debounce, event-change detection source (poller vs outbox).
|
||
|
||
## Deferred Ideas
|
||
|
||
- Quiet hours / DND — v1.x
|
||
- Per-event / custom reminder lead time — v1.x
|
||
- Per-category opt-out — v1.x
|
||
- Reminders for personal-calendar events — intentionally excluded (native clients cover these)
|
||
- Notifying on own changes — out of scope
|
||
|
||
**Reviewed todos (not folded):** drizzle generate+migrate (false-positive "push" match, but schema constraint noted); new-project kickoff (stale).
|