Domain: notifications
Curated entry point for the
notificationsbounded context.
Owner
Founder + agents (Phase 1).
Mission
Owns delivering messages to traders and admins: transactional email rendering and delivery via Resend, in-app notifications, breach alerts, and webhook fanout to Centrifugo channels for real-time push (per Q-E11). Boundary: notifications delivers messages; the content templates and trigger rules are owned here, but the signals that drive notifications (breaches, payouts, fills, etc.) come from other domains via Kafka events.
Code paths
- Application code:
apps/api/src/modules/notifications/ - Domain logic (pure):
packages/domain/notifications/(template rendering, trigger evaluation) - Contracts:
packages/contracts/events/notifications.ts - External clients:
packages/clients/resend/ - Database schemas owned:
notifications(NotificationTemplate, NotificationDelivery, NotificationPreference, WebhookFanout) - Email templates: React Email components per Q-E4 frontend baseline
PRD chapters that touch this domain
04-trader-dashboard.md- in-app notifications, breach alerts UI16-open-questions.md- Q-E11 (Centrifugo as the WebSocket fanout)10-integrations.md- Resend integration, Discord/Intercom hooks (V1+)
TDD chapters
(Empty - will populate.)
ADRs that affected this domain
- ADR-0001 (transversally applies)
Service interfaces this domain exposes
export interface NotificationsService {
// sendTransactional(template, to, data): Promise<DeliveryId>
// publishRealtime(channel: string, payload: object): Promise<void>
// updatePreferences(userId, preferences): Promise<NotificationPreference>
// listInAppForUser(userId): Promise<InAppNotification[]>
// markRead(notificationId, userId): Promise<void>
// (full surface defined during notifications TDD)
}
Events this domain produces / consumes
| Direction | Topic | Triggered by |
|---|---|---|
| produces | notifications.email.sent | Resend confirmed delivery |
| produces | notifications.email.bounced | Bounce / complaint |
| produces | notifications.realtime.published | Confirmation that a Centrifugo publish occurred |
| consumes | risk.evaluation.breach_detected | Triggers breach alert email + Centrifugo push |
| consumes | accounts.account.state_changed | State-transition emails (e.g., "you passed evaluation") |
| consumes | payouts.transfer.completed | Payout confirmation email |
| consumes | billing.payment.completed | Receipt email |
| consumes | identity.user.signed_in | Suspicious-signin email if flagged |
External integrations
- Resend - transactional email rendering + delivery
- Centrifugo - WebSocket channel publishes (per Q-E11)
- Discord (V1+) - community webhook fanout
- Intercom (V1+) - in-app messaging
Runbooks for this domain
(Empty - will populate. Expected high-priority: email delivery rate drop, Centrifugo publish failure burst.)
On-call
To be filled in Section 17.6.
Cross-domain dependencies
- This domain consumes events from: every other domain (it is a leaf consumer).
- This domain emits events consumed by:
audit(every notification is logged),admin(notification delivery dashboards). - No synchronous outbound dependencies.