Skip to main content

Notification Development Seeding

Summary

One seeder exists: DefaultTemplateSeeder. It inserts built-in global default templates at startup and is idempotent. No other table is seeded by any reviewed code path.

Audience

Engineers, QA, DevOps engineers, architects and support.

Reference Content

The verified reference material for this topic is set out in the sections below.

What is seeded

Built-in subject and body templates covering 87 rows across 29 event keys, each row targeting one event key and one channel.

The event keys span the platform: employee creation; leave approval and rejection; payroll freeze and payslip generation; expense approval, rejection and payment; helpdesk ticket lifecycle including creation, assignment, comment, attachment, status change, escalation, SLA breach, resolution, closure and reopening; training assignment, start, completion, session scheduling and rescheduling; assessment pass and failure; certificate issue and expiry warning; document generation; and tenant provisioning.

Bodies use a double-brace placeholder convention resolved at render time.

Seeding rules

Every seeded row is inserted with a null tenant, making it a global default that any tenant inherits until it creates its own override. Each is inserted at version 1, marked active, and given a fixed description identifying it as a built-in default.

Idempotency

Before each insert the seeder checks whether a row already exists for the null tenant, that template key and that channel. When one exists it is skipped, so an existing row is never overwritten — including one an operator has edited. The seeder saves once at the end, and only if at least one row was added, so a fully seeded database incurs no write on restart.

The existence check deliberately ignores the version column, so the seeder will not re-add a key and channel that has advanced beyond version 1.

When it runs

Seeding runs at startup immediately after migration, inside the same service scope, and only when the seeding option is enabled. That option defaults to true.

Because the whole block is inside the migration guard, setting the skip-migrations environment variable suppresses seeding as well.

Not seeded

Six of the seven tables are never seeded: recipients, messages, delivery attempts, preferences, audit and the idempotency ledger. Notably preferences are not seeded, and no runtime path writes them either, so the preference table is empty unless populated externally.

Verified absence

There is no per-tenant seeder, no demo or sample data seeder, no environment-conditional seed set, no HasData model seeding and no seed data embedded in the migration.

Classification

Implemented.

Requires confirmation

Whether seeded defaults should be updated in place when the built-in content changes requires confirmation.

See Also

Keywords

  • Notification database
  • Development Seeding
  • Draft database documentation

Source References

  • microservices/src/notification-service/Seed/DefaultTemplateSeeder.cs
  • microservices/src/notification-service/Program.cs
  • microservices/src/notification-service/Application/NotificationOptions.cs
  • microservices/src/notification-service/Infrastructure/NotificationDbContext.cs

Revision Information

  • Status: Draft
  • Last reviewed: 2026-07-21
  • Review cycle: Quarterly