Functional
- Accept notification intents and templates.
- Apply user consent, locale, quiet hours, and channel preferences.
- Deliver email, SMS, push, and inbox with status history.
Deliver user notifications across channels with preferences, retries, and auditability.
Plan for campaign peaks far above average.
Queue references templates/data instead of copying large assets.
Cache versioned preference snapshots.
Separate operational and compliance stores.
These are reference assumptions, not universal facts. In an interview or architecture review, change them when the product context changes.
/v1/notificationsSubmit intent with recipient, template, data, priority, and idempotency key./v1/notifications/{id}Return per-channel delivery state./v1/preferences/{user}Update versioned consent and channel rules.notification_id, tenant, recipient, template_version, priority, expires_atImmutable intent is the deduplication anchor.notification_id+channel+attempt, provider_id, status, error, occurred_atAppend attempts for diagnosis and audit.Validate and deduplicate intents
Apply consent and channel rules
Buffer each channel independently
Send email, SMS, push, or inbox messages
Persist the intent before publishing channel tasks. A transactional outbox or log-derived publisher closes the database/queue dual-write gap. Each channel evaluates expiry before sending.
Deduplicate client submissions by tenant and idempotency key. Consumers use notification/channel as their processing key. Where providers support idempotency, forward the same stable token.
Track latency, error codes, and quotas by provider. Circuit-break failing routes, shift only eligible traffic, and prevent retries from consuming the entire provider recovery budget.
Open its circuit, retain bounded backlog, and apply channel-specific expiry.
Deduplicate on notification intent, recipient, and policy version.
Move here when: Initial transactional notifications.
Move here when: Different consent and retry semantics emerge.
Move here when: Campaign peaks and regional provider failures.
Strong answer signal: Transactional outbox, CDC, or log-first intent storage.
Strong answer signal: Tie TTL to business meaning; do not deliver stale OTPs or alerts.
Strong answer signal: Versioned preference snapshot and immutable decision audit.