- pnpm 10 workspace + TypeScript strict + ESLint flat + Prettier - CLAUDE.md as canonical brief - docs/tasks/ — 22 task briefs broken out by phase for sub-sessions - docs/decisions/ — ADR scaffold Implements task 01 (repo-init).
29 lines
1.2 KiB
Markdown
29 lines
1.2 KiB
Markdown
# 40 — Web Push (VAPID)
|
|
|
|
## Goal
|
|
|
|
Subscribe browsers to web push and deliver notifications to them.
|
|
|
|
## Depends on
|
|
|
|
- 06 (auth), 50 (PWA shell — needed for iOS to allow push). If 50 isn't done, this task can land but iOS won't fire until then.
|
|
|
|
## Scope
|
|
|
|
- `pnpm add web-push` for server, use built-in `PushManager` on client.
|
|
- VAPID keys generated once (script: `pnpm vapid:generate`), stored in `.env` as `VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY`. Document in README.
|
|
- Schema: `push_subscriptions` (`id`, `user_id`, `endpoint` unique, `p256dh`, `auth`, `user_agent`, `created_at`).
|
|
- Service worker registers on app load; on user opt-in (button in `/settings`), prompts permission and stores subscription via server action.
|
|
- Server helper `sendPush(userId, { title, body, url })` iterates subscriptions, removes any returning 404/410.
|
|
|
|
## Out of scope
|
|
|
|
- Notification preferences per category (defer).
|
|
- ntfy fallback (task 42).
|
|
|
|
## Acceptance criteria
|
|
|
|
- [ ] Opt-in flow works in Chrome desktop and mobile, plus iOS Safari (when PWA installed).
|
|
- [ ] Stale subscriptions are pruned on send failure.
|
|
- [ ] Sending a test notification from `/settings` reaches all of the current user's subscribed devices.
|