- 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).
984 B
984 B
42 — Notification bus + ntfy adapter
Goal
Single notify() entrypoint that fans out to web push, in-app inbox, and (optionally) ntfy.
Depends on
- 40
Scope
_core/notify.ts—notify(userId, { title, body, url, channels? }).- Channels:
push,inapp,ntfy. Default:['push', 'inapp']. - In-app inbox:
notificationstable (id,user_id,title,body,url,read_at,created_at); bell icon in header with unread count and dropdown. - ntfy adapter: if
NTFY_URLandNTFY_TOPICenv are set, also POSTs there. Off by default; Matt opts in. - Per-user toggles in
/settingsfor each channel.
Out of scope
- Email notifications.
- Per-event-type routing rules (Matt can add later as a module).
Acceptance criteria
notify()with default channels delivers push + in-app and ignores ntfy.- Setting
NTFY_URL+NTFY_TOPICand toggling on in settings adds ntfy delivery. - Unread count is accurate and clears on read.