Appearance
Notification System Overview
The Notification system is the central service and shared package set used by Microtec services to send, store, query, and operate user-facing notifications.
It has three major parts:
| Part | Responsibility |
|---|---|
Microtec.Notifications.Contracts | Shared DTOs, payloads, enums, metadata keys, and integration events. |
Microtec.Notifications.Client | Consumer-facing client, fluent builders, delivery strategies, proxy controllers, and admin clients. |
InfrastructureServices/Notifications | The actual Notification service: APIs, orchestration, providers, persistence, jobs, and admin operations. |
Architecture
Request Paths
Delivery Modes
| Mode | Contract enum | Behavior |
|---|---|---|
| HTTP | DeliveryMode.Http | The client posts directly to the Notification service and receives a NotificationId when the service persisted and attempted the send. |
| Queue | DeliveryMode.Queue | The client publishes SendNotificationEvent. The service consumes it asynchronously. The client receives publish success, not provider delivery success. |
Use HTTP when the caller needs immediate send feedback, for example OTP-like flows. Use queue mode when the caller should not block on provider latency or when high throughput matters more than immediate feedback.
Channel Selection
The service selects the channel by the concrete payload type:
| Payload type | Channel |
|---|---|
EmailPayload | NotificationChannelType.Email |
SmsPayload | NotificationChannelType.SMS |
PushPayload | NotificationChannelType.PushNotification |
WhatsAppPayload | NotificationChannelType.WhatsApp |
The entry point is NotificationOrchestrator.SendAsync(NotificationPayload payload, CancellationToken ct).
Runtime Context
The notification service uses request context to select tenant or source-system configuration:
| Header | Constant | Purpose |
|---|---|---|
ClientId | NotificationHeaderNames.ClientId | Identifies the calling client. |
InternalApiKey | NotificationHeaderNames.InternalApiKey | Internal API key header. |
X-Correlation-Id | NotificationHeaderNames.CorrelationId | Cross-service trace correlation. |
X-Subdomain | NotificationHeaderNames.Subdomain | Tenant context for tenant-specific channel configs. |
X-User-Id | NotificationHeaderNames.UserId | Current user context, required by user-specific operations. |
X-Source-System | NotificationHeaderNames.SourceSystem | System-sender context where Subdomain can be omitted. |
The client package sets these headers through TenantHeaderDelegatingHandler.
Tenant vs Source-System Configuration
The service has two configuration paths:
| Path | How it is selected | Channel config rule |
|---|---|---|
| Tenant | X-Subdomain or payload Subdomain is present and no source system is used. | Match NotificationChannelConfig.Subdomain and require SourceSystem == null. |
| Source system | X-Source-System or payload SourceSystem is present. | Match NotificationChannelConfig.SourceSystem and require Subdomain == null. |
This allows a system sender to send without tenant subdomain, while tenant-specific sends remain isolated.
Status Model
The system tracks two levels of status:
| Level | Entity | Meaning |
|---|---|---|
| Request | NotificationRequest | The logical notification attempt. Stores original payload JSON, channel, subdomain, user, status, retry count, metadata, and timestamps. |
| Delivery | NotificationDelivery | One provider-recipient attempt. Stores recipient identifier, provider, provider message id, provider request and response payloads, and delivery status. |
See Flow, persistence, and retry for the full lifecycle.