Notification
Data Entity
Description
Represents a single notification record sent or queued for delivery to a user. Captures the full lifecycle of a notification from creation through delivery and user acknowledgement, supporting push, email, SMS, and in-app channels. Serves as the audit trail for all notification activity and as the data source for the in-app notification inbox.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Surrogate primary key, generated server-side at creation time | PKrequiredunique |
user_id |
uuid |
Foreign key reference to the users table — the intended recipient of the notification | required |
organization_id |
uuid |
Foreign key to the organizations table. Used for multi-tenant scoping and ensuring notifications are only accessible within the correct org context | required |
type |
enum |
Business-level notification type identifying the triggering scenario. Used by deep-link routing and inbox categorization | required |
channel |
enum |
Delivery channel used for this notification record. A single business event may produce multiple notification rows — one per channel attempted | required |
title |
string |
Short notification headline, max 100 characters. Displayed as the push notification title or email subject line | required |
body |
text |
Full notification body text. Used as push notification body, email plain-text body, or SMS message content | required |
entity_type |
enum |
The type of domain entity this notification refers to. Used by the deep-link router to determine navigation target on tap | - |
entity_id |
uuid |
The UUID of the domain entity this notification refers to. Combined with entity_type by deep-link router to resolve navigation destination | - |
data |
json |
Arbitrary key-value payload for additional context. Used by push notification service to embed entity_type and entity_id in FCM/APNs data payload, and by email templates for variable substitution | - |
status |
enum |
Current delivery lifecycle status of the notification | required |
rule_id |
string |
Identifier of the notification rule that triggered this record. Used by notification-deduplication-service to enforce per-rule cooldown windows and prevent duplicate delivery | - |
template_id |
string |
Identifier of the email/SMS template used to render this notification. References notification-template-store for audit trail | - |
sent_at |
datetime |
Timestamp when the notification was dispatched to the delivery provider (FCM, APNs, email/SMS gateway). NULL if still pending | - |
delivered_at |
datetime |
Timestamp of confirmed delivery receipt from the push or email provider. NULL if delivery not yet confirmed | - |
read_at |
datetime |
Timestamp when the user opened or acknowledged the notification in the inbox. NULL for unread notifications | - |
dismissed_at |
datetime |
Timestamp when the user explicitly dismissed the notification without reading its linked entity | - |
failure_reason |
string |
Human-readable error message if status is failed. Populated from FCM/APNs or email provider error responses | - |
retry_count |
integer |
Number of delivery attempts made for this notification. Used by retry logic to enforce max-retry limits | required |
created_at |
datetime |
Record creation timestamp, set server-side on INSERT | required |
updated_at |
datetime |
Record last-modification timestamp, updated on every status change | required |
Database Indexes
idx_notification_user_created
Columns: user_id, created_at
idx_notification_user_status
Columns: user_id, status
idx_notification_org_created
Columns: organization_id, created_at
idx_notification_rule_user_created
Columns: rule_id, user_id, created_at
idx_notification_entity
Columns: entity_type, entity_id
idx_notification_status
Columns: status
idx_notification_unread
Columns: user_id, read_at
Validation Rules
user_id_exists
error
Validation failed
title_not_empty
error
Validation failed
body_not_empty
error
Validation failed
entity_type_entity_id_pair
error
Validation failed
valid_channel_enum
error
Validation failed
valid_status_transitions
error
Validation failed
data_valid_json
error
Validation failed
retry_count_non_negative
error
Validation failed
Business Rules
opt_out_enforcement
A notification must not be created for a channel if the user's notification_settings record has that channel disabled for the given notification type. The rule engine checks opt-out before enqueuing any delivery payload
deduplication_cooldown
If a notification with the same rule_id was already sent to the same user within the configured cooldown window, the new notification must not be created. Cooldown is rule-specific and stored in the rule registry
tenant_isolation
A notification's organization_id must match the user's organization. The notification inbox query always applies a user_id filter — cross-org notification reads are never permitted
read_receipt_immutability
Once read_at is set it must not be cleared or overwritten. A notification marked as read remains read regardless of subsequent status changes
max_retry_limit
If retry_count reaches the configured maximum (default 3), status must be set to 'failed' and no further delivery attempts are made. failure_reason must be populated
push_token_required_for_push_channel
A push channel notification can only be created if at least one active push token exists for the target user. If no token is found the rule engine falls back to the in_app channel only
assignment_read_receipt
When a notification with type=assignment_dispatched transitions to status=read, the Assignment Dispatch Service must be notified to record the read receipt on the corresponding assignment record