Skip to content

Flow, Persistence, And Retry

This page explains what happens after a notification is sent and how the database records should be interpreted.

HTTP Flow

Queue Flow

Request Lifecycle

NotificationRequest is the logical send attempt.

StatusMeaning
PendingCreated but not processing.
ScheduledScheduled for future processing.
ProcessingPersisted and being sent.
SentProvider accepted the send attempt.
DeliveredProvider or status job confirmed delivery.
FailedSend attempt failed.
CancelledReserved status for cancelled requests.

Important fields:

FieldMeaning
ChannelTypeNotification channel.
SubdomainTenant context. Empty string can appear for source-system or missing tenant paths.
UserIdTarget or current user when available.
ApplicationTargetTarget application for push.
PayloadJsonOriginal serialized payload.
MetadataJsonExtracted searchable metadata.
RenderedContentRendered email body when set.
SourceSystemSource-system sender identity as string.
RetryCountIncremented when the request fails.
ErrorSummaryFailure summary.

Delivery Lifecycle

NotificationDelivery is the provider-recipient attempt.

StatusMeaning
PendingDelivery row exists but provider has not accepted it.
SentProvider accepted it.
DeliveredProvider confirmed delivery.
FailedProvider or service failed the delivery.
ExpiredDelivery expired.
RejectedProvider rejected it.
BouncedEmail-style bounce.
OpenedRecipient opened it.
ClickedRecipient clicked it.

Important fields:

FieldMeaning
NotificationRequestIdParent request.
RecipientTypeDevice token, email address, or phone number.
RecipientIdentifierEmail, phone number, or device token.
ProviderTypeProvider enum or string.
ProviderMessageIdProvider message identifier when available.
RequestPayloadProvider-facing request payload snapshot.
ResponsePayloadProvider response snapshot.
ErrorMessage, ErrorCodeFailure diagnostics.

Tables

Entities are mapped under the SQL Server schema:

text
Notification

Core tables:

TableEntity
[Notification].[NotificationRequest]NotificationRequest
[Notification].[NotificationDelivery]NotificationDelivery
[Notification].[NotificationChannelConfig]NotificationChannelConfig
[Notification].[DeviceRegistration]DeviceRegistration
[Notification].[WhatsAppTemplate]WhatsAppTemplate
[Notification].[WhatsAppProvisioningOperation]WhatsAppProvisioningOperation

Metadata Extraction

When a NotificationRequest is added, NotificationMetadataInterceptor extracts metadata by channel:

ChannelExtracted examples
Pushtitle, Arabic title, body, route URL, module, service, setting type.
Emailsubject, body, module, service, setting type.
SMSbody, module, service, setting type.
WhatsAppmodule, service, setting type, entity id/type, template metadata.

Notification Center queries use this metadata to build list responses and filters.

Retry Behavior

Retry is handled by RetryNotificationCommandHandler.

Rules:

  • The original notification must exist.
  • The selected channel config must exist.
  • NotificationChannelConfig.EnableRetry must be true.
  • The original persisted payload is deserialized by channel-specific deserializers.
  • The orchestrator sends the payload again.
  • A new NotificationRequest is created for the retry attempt.
  • The response includes both the original notification id and the new notification id.

Email retry has one special behavior: if RenderedContent exists, retry uses that rendered body and disables template rendering/layout to avoid rendering the template differently later.

Push Persistence Detail

Push creates a request per target user. Device-token deliveries are created after device resolution. If no matching active and valid devices exist, the request is marked failed.

When FCM returns invalid-token errors, matching DeviceRegistration rows are marked invalid so future sends skip them.

WhatsApp Status Detail

When WhatsApp send succeeds and T2 returns a provider message id, the service:

  1. updates the delivery with the provider message id
  2. schedules WhatsAppMessageStatusJob
  3. checks status later through T2

This is why WhatsApp may be Sent before it becomes Delivered or Failed.

Troubleshooting Checklist

If a notification fails:

  1. Find the NotificationRequest by id.
  2. Check Status, ErrorSummary, ChannelType, Subdomain, SourceSystem, and RetryCount.
  3. Check related NotificationDelivery rows.
  4. Inspect provider RequestPayload and ResponsePayload.
  5. Verify an active channel config exists for the effective context.
  6. Verify provider credentials are valid.
  7. For push, verify active valid device tokens exist for the user, platform, and application target.
  8. For WhatsApp, verify the template exists locally, has SyncStatus = Approved, and has a T2 template id.

Internal Documentation — Microtec