swap-notification-templates
Load email templates from a database or CMS instead of code (editable copy, per-tenant branding). Use when the user wants non-developers to edit notification content or brand it per workspace. Not for
SKILL.md.claude/skills/swap-notification-templates/SKILL.md
GitHubSwap the notification template source
- Interface:
TemplateSource(abstract class,bind(payload): Promise<BoundTemplate>) inapps/notifications/src/dispatch/templates.ts. - Today:
CodeTemplateSource: thetemplatesregistry in the same file, rendering React Email components frompackages/emailwith copy frompackages/i18n. - Bound in:
apps/notifications/src/dispatch/notifications.module.ts({ provide: TemplateSource, useClass: CodeTemplateSource }). - Env: none today.
Swap
- Store templates (db-change skill; the
notificationsschema is the service's own). - Implement
TemplateSource: look up the stored template forpayload.template(and the organization, for branding), cache it in Redis, and return aBoundTemplatethat renders it. Fall back toCodeTemplateSourcewhen no stored version exists, so every template keeps working. - Bind the new class in
notifications.module.ts. The dispatcher and the email channel don't change. - Validate stored content before rendering: the fields it may use are the template's
payload schema in
packages/jobs/src/queues.ts.
Tests
apps/notifications/test/notifications.integration.test.ts sends through Mailpit; add
cases for a stored template and for the
fallback. packages/email/src/render.test.tsx covers the code templates.
Finish
- The verify skill.
- Ask the
revieweragent to review the change, and thesecurity-revieweragent: a new implementation brings its own credentials and sends data somewhere new. If you wrote a migration, themigration-revieweragent too. - Update the seam's row in the README's "Scaling path" table if what's "Now" changed.