Communication Service — Domain Model
Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 02 DDD · 04 Event-Driven
1. Aggregates
| Aggregate | Root entity | Responsibility | Invariants |
|---|---|---|---|
MessageThread | MessageThread | Ordered conversation between ≥ 2 participants, optional patient/encounter linkage | A thread MUST have ≥ 1 active participant; archived threads reject new messages; patient-linked thread visibility requires chart read permission |
Message (inside MessageThread) | Message | One utterance in a thread with body, urgency, sender, optional attachments | Cannot edit a message once sent (only retract); body non-empty; urgency ∈ {routine, urgent, emergent} |
NotificationIntent | NotificationIntent | One dispatch request keyed by (tenantId, correlationId, category, channel, recipientRef) | Idempotent on its key; never contains PHI in structured fields once persisted |
DispatchRecord | DispatchRecord | Per-channel outcome ledger for a NotificationIntent | Append-only; DLR callback upserts status but never removes a record |
VirtualSession | VirtualSession | Virtual encounter with participants, waiting room, active session, end state | State machine enforced; terminal states are ended, cancelled, failed; cannot re-open a terminal session |
VirtualParticipant (inside VirtualSession) | VirtualParticipant | One invitee with role (provider/patient/observer) and admit state | Only ADMITTED participants receive a valid join token |
2. Entities & Value Objects
| Type | Kind | Notes |
|---|---|---|
ThreadId | VO (branded ULID thr_) | |
MessageId | VO (branded ULID msg_) | |
NotificationIntentId | VO (branded ULID nti_) | |
DispatchRecordId | VO (branded ULID dsp_) | |
SessionId | VO (branded ULID vcs_) | |
ParticipantId | VO (branded ULID vcp_) | |
JoinToken | VO | Short-lived (≤ 5 min) signed token; one-time use |
Urgency | VO enum | routine / urgent / emergent |
Channel | VO enum | push / sms / email / in_app |
Category | VO enum | secure_message / appointment_reminder / critical_result / marketing / operational |
Participant | Entity | {userId, role, addedAt, mutedUntil?} |
ReadReceipt | Entity | {messageId, userId, readAt} |
Attachment | Entity | {fileRef, mimeType, sizeBytes, hash, scanStatus} |
DeliveryOutcome | VO | delivered / failed / deferred / unknown; with providerMessageId, errorCode? |
3. State machines
3.1 MessageThread
3.2 VirtualSession
3.3 NotificationIntent dispatch
4. Domain events
| Event | When | Canonical type |
|---|---|---|
| ThreadCreated | Thread opened | ghasi.digital_communication.thread.created |
| MessageSent | First message in thread | ghasi.digital_communication.message.sent |
| MessageReplied | Subsequent message | ghasi.digital_communication.message.replied |
| MessagesRead | Read receipts applied | ghasi.digital_communication.message.read |
| ThreadEscalated | Escalation triggered | ghasi.digital_communication.thread.escalated |
| ThreadArchived | Archived | ghasi.digital_communication.thread.archived |
| NotificationQueued | Intent accepted | ghasi.digital_communication.notification.queued |
| NotificationDispatched | Provider accepted | ghasi.digital_communication.notification.dispatched |
| NotificationDelivered | DLR success | ghasi.digital_communication.notification.delivered |
| NotificationFailed | DLR failed or adapter error | ghasi.digital_communication.notification.failed |
| VirtualSessionCreated | ghasi.digital_communication.virtual_session.created | |
| VirtualSessionStarted | First admit | ghasi.digital_communication.virtual_session.started |
| VirtualSessionEnded | ghasi.digital_communication.virtual_session.ended | |
| VirtualSessionFailed | Infra failure | ghasi.digital_communication.virtual_session.failed |
| VirtualSessionFallbackInitiated | Fallback thread spawned | ghasi.digital_communication.virtual_session.fallback.initiated |
5. Ubiquitous language
| Term | Definition |
|---|---|
| Thread | Conversation container; the Communication FHIR resource maps to a message within this container. |
| Participant | Any user (provider, patient, system) listed on a thread or virtual session. |
| Urgency | Policy-controlled classification that may short-circuit notification channel defaults. |
| Intent | A request-to-dispatch; carries no PHI beyond opaque ids and template keys. |
| Dispatch | A concrete attempt at delivery through a single channel + provider. |
| DLR | Delivery Receipt / Delivery Report returned by the channel provider. |
| Fallback thread | Messaging thread automatically created when a virtual session cannot complete. |
| Join token | Short-lived signed token permitting one participant to enter a virtual session. |
| Category | Business classification of a notification driving channel policy. |