add-notification
Add a notification users receive by email, in-app, push or SMS, or a new notification category in their preferences. Use when the user wants to notify, remind, alert or email someone about something.
SKILL.md.claude/skills/add-notification/SKILL.md
GitHubAdd a notification
A notification is a template in apps/notifications, queued as a job. Its category decides which channels it may use and whether users can turn it off.
- Payload. Add a
z.object({ template: z.literal("<area>.<name>"), to, data })tonotificationPayloadinpackages/jobs/src/queues.tsand pick its queue innotificationQueue(notifications-criticalonly for codes, security and billing).tois{ userId },{ email, locale }or{ orgId, roles }. - Copy. Every string in
packages/i18n/messages/*.json, every locale:email.<camelCaseName>,notification.<area>.<name>.titleand.body(push and in-app),sms.<camelCaseName>. Comparetodo.reminder:email.todoReminder,notification.todo.reminder. - Email. A component in
packages/email/src/templates/with its subject, exported frompackages/email/src/index.ts, and a preview inpackages/email/src/previews/(bun run --cwd packages/email devserves them on http://localhost:3030). - In-app. Its data schema in
inAppNotificationsinpackages/contracts/src/notifications.ts, so apps can render it. - Template. An entry in
templatesinapps/notifications/src/dispatch/templates.tswith itscategoryand a renderer per channel it uses (email,inApp,push,sms). Thesatisfiesclause failscheck-typesuntil it exists. - Category. Reuse one from
notificationCategoriesinpackages/contracts/src/notifications.ts. A new one gets its default channels there and atitleanddescriptionundernotificationSettings.categories.<name>.mutable: falsemeans users can't turn it off. - Trigger. From a service: a producer for the queue and
add("send", payload, { jobId }). From a domain event: route the event toevents-notificationsineventSubscribersand map it inapps/notifications/src/events/events.processor.ts. - Tests.
bun run test(i18n completeness, email rendering inpackages/email/src/render.test.tsx), thenbun run test:integration(apps/notifications/test/notifications.integration.test.tssends through Mailpit and the fake push and SMS servers). - Finish. The verify skill, then the
i18n-checkeragent on the new copy and therevieweragent on the change (delivery throughDeliveryLog.claim(), preferences, the category'smutableflag).