Skip to content

Notification System

@nx/helpdesk ships its own notification subsystem with digest batching, quiet hours, multi-channel delivery, and full send-status tracking.

Architecture

Data Model

Notification

ColumnTypeDescription
idbigintSnowflake ID
eventCodevarcharEvent type code (e.g. TICKET_ASSIGNED)
recipientIdbigintRecipient ID
recipientTypeenumUSER / AGENT / SYSTEM
merchantIdbigintTenant scope
contextTypevarcharContext entity type (e.g. Ticket)
contextIdbigintContext entity ID
titlejsonbNotification title (i18n)
contentjsonbNotification body (i18n)
templateDatajsonbData used to render the template
channelsvarchar[]Selected delivery channels
statusenumPENDING / PROCESSING / DELIVERED / PARTIALLY_DELIVERED / FAILED
isReadbooleanWhether the recipient has read it
readAttimestampRead timestamp
batchIdbigintFK → NotificationBatch (if digest)
actionUrlvarcharAction URL when recipient clicks the notification

NotificationTemplate

Template per event type and channel:

ColumnTypeDescription
eventCodevarcharEvent code
channelenumChannel this template applies to
subjectjsonbEmail subject (i18n)
bodyHtmljsonbHTML body (i18n)
bodyTextjsonbPlain-text body (i18n)
isActivebooleanWhether the template is in use

NotificationPreference

Per-user/agent notification preferences:

ColumnTypeDescription
userIdbigintUser or Agent ID
eventCodevarcharEvent type
channelsvarchar[]Preferred delivery channels
quietHoursStarttimeStart of quiet hours (no notifications)
quietHoursEndtimeEnd of quiet hours
digestEnabledbooleanBatch notifications into a digest
digestIntervalMinutesintInterval between digest deliveries

NotificationDeliveryLog

Delivery history per channel:

ColumnTypeDescription
notificationIdbigintFK → Notification
channelvarcharDelivery channel
statusenumSUCCESS / FAILED
errorMessagetextError detail on failure
sentAttimestampSend timestamp

NotificationBatch

Digest batching — aggregates multiple notifications into a single delivery:

ColumnTypeDescription
idbigintSnowflake ID
recipientIdbigintRecipient
statusenumPENDING / PROCESSING / SENT
scheduledAttimestampWhen the digest will be sent
sentAttimestampActual send timestamp
itemCountintNumber of notifications in the batch

Delivery Channels

ChannelImplementationDescription
EMAILNodemailerComponentSMTP with HTML/text templates
WEBSOCKETApplicationWebSocketComponentReal-time via Signal service
PUSHPush adapterMobile push notifications
SMSSMS adapterText message delivery

Quiet Hours

ProcessNotificationService checks NotificationPreference.quietHoursStart/End before delivery. If the current time falls within a recipient's quiet hours, the notification is deferred until quiet hours end.

Digest Batching

NotificationBatchService aggregates notifications into a digest:

Workers

WorkerQueueFunction
notification.workerhelpdesk.notificationProcesses each notification, calls ProcessNotificationService (jobs: notification, notification-batch, notification-digest)

Notification Trigger Events

EventRecipientDescription
TICKET_CREATEDAssigned agentNew ticket waiting
TICKET_ASSIGNEDAgentTicket has been assigned
STATUS_CHANGEDReporterTicket status updated
MESSAGE_ADDEDAgent / ReporterNew message in ticket
SLA_WARNINGAgentSLA deadline approaching (75%)
SLA_BREACHEDAgent + ManagerSLA violated (100%)
SLA_CRITICALManager + LeadershipCritical SLA breach (150%)
TICKET_RESOLVEDReporterTicket has been resolved
TICKET_CLOSEDAgentCustomer confirmed closure

WebSocket Rooms & Topics

ApplicationWebSocketComponent (with socket-event.service.ts) emits on a single helpdesk topic, into rooms scoped per ticket + message. Built from @nx/core helpers:

BuilderValueDescription
HelpdeskWebSocketTopics.HELP_DESKobservation/helpdeskHelpdesk observation topic
HelpdeskWebSocketRooms.getHelpdeskRooms({ ticketId, messageId })helpdesk/:ticketId/:messageIdPer-ticket, per-message room

Source: src/components/websocket/topics.ts, src/components/websocket/rooms.ts.

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.