medOS Messaging
Internal scope:
ever-messaging· Ports: 8084 / 3003 · Modules: ~6
medOS Messaging is the platform's delivery layer. It owns realtime push over
Socket.IO, transactional email (templated, bilingual), SMS and push channels,
and scheduled / deferred message jobs. It is also home to the acknowledgement
dispatcher — the component that fans a single AcknowledgementRequest out
across every configured channel so that orders, notes, and encounters can demand
explicit, tracked sign-off from a user, role, department, or group.
Responsibilities
- Realtime fan-out — a JWT-authenticated Socket.IO gateway that publishes to per-recipient rooms and topics; the frontend subscribes for live updates.
- Email delivery — templated, Handlebars-rendered mail via a pluggable SMTP transporter, with i18n subject/body resolution (English + Thai locales).
- SMS & push — channel adapters for outbound SMS and push notifications, feature-flagged so each can be enabled per deployment.
- Scheduled messaging — deferred and recurring jobs (registration mail, reset-password mail) backed by Agenda on MongoDB.
- Acknowledgement dispatch — turns an
AcknowledgementRequestinto one delivery attempt per channel, records the outcome per attempt, and supports reminder / escalation cycles. - WebRTC signaling — a Socket.IO signaling gateway (proof of concept) that
brokers
offer/answer/ice-candidateexchange for teleconsultation.
Major modules
| Module | Purpose |
|---|---|
notification | Socket.IO realtime gateway plus email / SMS gateway stubs; per-recipient rooms and topic publish. |
acknowledgementDispatcher | Fans an AcknowledgementRequest across socket / email / SMS / push; tracks per-attempt delivery status; drives reminders and escalation. |
mail | High-level email use cases (e.g. reset-password, AR request) that pick a template and hand off to the transporter. |
mail-transporter | Low-level SMTP transport using Nodemailer + Handlebars template compilation. |
schedule | Agenda-backed job definitions for deferred / recurring email jobs, persisted to MongoDB. |
common | Shared utilities, notably the i18n service for locale-aware subjects and body text. |
webrtc | WebRTC signaling gateway (POC) for live audio / video sessions. |
loadTestWorker | Performance / load-testing harness for the messaging path. |
Delivery channels
The acknowledgement dispatcher resolves the channel set from the request record (falling back to a default channel when none is specified) and attempts each one independently, so a failure on one channel never blocks the others.
SMS and push are present as channel stubs and are gated off by default; email is on by default. Toggle them per deployment with the flags below.
| Flag | Default | Effect |
|---|---|---|
ACK_CHANNEL_EMAIL_ENABLED | on | Set to false to skip the email channel. |
ACK_CHANNEL_SMS_ENABLED | off | Set to true to enable the SMS channel. |
ACK_CHANNEL_PUSH_ENABLED | off | Set to true to enable the push channel. |
SERVICE_MESSAGING_WS_PORT | 3003 | WebSocket listen port for the Socket.IO gateways. |
Acknowledgement dispatch flow
The dispatcher is invoked for four event kinds — requested, responded,
escalated, and reminder — and writes back a delivery attempt for each
channel it tries.
AcknowledgementRequest (from any service: orders, notes, encounters)
│
▼
acknowledgementDispatcher.dispatch(record, kind)
│
├── socket ──▶ WebNotificationGateway ──▶ recipient room (live in-app)
├── email ──▶ mail-transporter (SMTP) ──▶ resolved address
├── sms ──▶ (flag-gated channel adapter)
└── push ──▶ (flag-gated channel adapter)
│
▼
per-channel DispatchAttempt { channel, status, providerMessageId?, error? }
When no explicit email resolver is supplied, the dispatcher can fall back to the recipient's display value; the Moleculer mixin injects a resolver that looks the address up against the Auth (AAA) service.
Realtime & signaling
Both the notification gateway and the WebRTC signaling gateway are JWT-authenticated Socket.IO servers on the WebSocket port. The signaling gateway brokers a fixed event contract for call setup:
join-call / offer / answer / ice-candidate / leave-call / call-end
│
▼
peer notifications: joined / peer-joined / peer-left
This contract must match the frontend kit's SIGNAL_EVENTS so that
teleconsultation peers can negotiate a connection.
Integration notes
- Scheduled jobs persist to an
agendaJobscollection in MongoDB, so deferred mail survives restarts. - Email templates are Handlebars layouts resolved from the service's
viewsdirectory; locale strings come from thecommoni18n service. - Other services do not deliver messages themselves — they create an
AcknowledgementRequest(or emit a realtime event) and let Messaging handle channel fan-out and tracking.
Acknowledgement system
Any order, note, or encounter can request explicit sign-off; Messaging is the delivery half.
Auth (AAA)
Recipient email / role resolution for targeted delivery.
NATS + Moleculer
Services reach Messaging over the service mesh; no direct channel coupling.
Related catalog items
SYS-4— Socket.IO RealtimeSYS-5— Email and SMS ServiceCP-12— SMS & Email Templates