Skip to main content

Notification Service — Domain Model

Status: populated Owner: Platform Engineering Last updated: 2026-04-18

1. Aggregates

NotificationLog (root)

Immutable record of a delivery attempt.

FieldTypeNotes
notificationIdUUIDv4Identity
tenantIdUUIDv4
accountIdUUIDv4
recipientIdstringuserId or platform identifier
recipientAddressstringEmail address or E.164 MSISDN; masked in logs
channelNotificationChannelEMAIL, SMS
categoryNotificationCategorye.g. ACCOUNT, BILLING, OPERATOR_ALERT, SYSTEM
templateIdUUIDv4FK to notification_templates
sourceEventTypestringe.g. billing.invoice.generated.v1
sourceEventIdstringFrom event header Nats-Msg-Id
statusDeliveryStatusPENDING, SENT, FAILED, SUPPRESSED
providerMessageIdstring | nullSendGrid message ID or sms-orchestrator messageId
errorMessagestring | nullOn FAILED
attemptCountnumber1..3
sentAtInstant | null
createdAtInstant

NotificationPreference (root)

Per-account opt-out settings.

FieldTypeNotes
preferenceIdUUIDv4
accountIdUUIDv4
categoryNotificationCategory
channelNotificationChannel
optedOutboolean
updatedBystringuserId
updatedAtInstant

NotificationTemplate (root)

Versioned template for a notification type + channel.

FieldTypeNotes
templateIdUUIDv4
typestringe.g. USER_REGISTERED, INVOICE_GENERATED, OPERATOR_DOWN
channelNotificationChannelEMAIL or SMS
subjectstring | nullEmail subject (Handlebars); null for SMS
bodyHtmlstringHandlebars + Mjml source for email; Handlebars for SMS body
bodyTextstringPlain-text fallback
variablesSchemaJSON SchemaValidated at save time and at render time
isActivebooleanOnly active templates are used
versionnumberAuto-increment on update
updatedBystringAdmin userId
updatedAtInstant

2. Value Objects

VOInvariant
NotificationChannelEnum: EMAIL, SMS
NotificationCategoryEnum: ACCOUNT, BILLING, OPERATOR_ALERT, SYSTEM_SECURITY, SYSTEM_INFO
DeliveryStatusEnum: PENDING, SENT, FAILED, SUPPRESSED
RecipientAddressNon-empty; email regex for EMAIL channel; E.164 for SMS channel

3. Domain Services

ServicePurpose
PreferenceResolverGiven (accountId, category, channel)boolean opted-out
TemplateRendererRenders Handlebars + Mjml template with variable map; validates against variablesSchema
EmailDeliveryPortSendGrid adapter
SmsDeliveryPortsms-orchestrator adapter
NotificationDispatcherOrchestrates preference check → render → deliver → log

4. Domain Events

This service publishes no NATS events. All output is side-effect (email/SMS delivery + PG log).

5. Notification Type → Category → Opt-out Policy

Notification TypeCategoryOpt-out Allowed?
USER_REGISTEREDACCOUNTNo (security)
INVOICE_GENERATEDBILLINGNo (contractual)
OPERATOR_DOWNOPERATOR_ALERTYes (admin preference)
SYSTEM_SECURITY_ALERTSYSTEM_SECURITYNo (mandatory)
SYSTEM_INFO_ALERTSYSTEM_INFOYes

6. Invariants

  • A NotificationLog row is created for every dispatch attempt, including suppressed ones.
  • SYSTEM_SECURITY category ignores notification_preferences opt-out — always delivered.
  • templateId must reference an active template at time of dispatch.
  • recipientAddress is never stored in plaintext in application logs (masked as ***@domain.tld or hash).