Unified Messaging Journey
This document explains how unified messaging works in Image Factory and how to exercise the end-to-end event and notification flow.
Overview
Unified messaging provides a single event pipeline for domain changes (builds, projects, tenants) and notification delivery. It combines:
- Local bus for in-process events
- Optional NATS bus for distributed consumers
- Dedicated workers for asynchronous delivery (notifications)
The key goal is predictable information flow: every meaningful domain change becomes an event, and consumers react consistently.
๐งญ Information Flow (Conceptual)
flowchart LR
API[HTTP API / Services] --> BUS[Event Bus]
BUS --> AUDIT[Audit Subscriber]
BUS --> WS[WebSocket Subscriber]
BUS --> NATS[(NATS)]
NATS --> NOTIF_WORKER[Notification Worker]
NOTIF_WORKER --> QUEUE[(Email Queue)]
QUEUE --> EMAIL_WORKER[Email Worker]
EMAIL_WORKER --> SMTP[SMTP / Mailpit]
EMAIL_WORKER --> BUS
๐ Information Flow (Detailed)
1) Domain Event Path (Build / Project / Tenant)
- Service emits
build.*,project.*, ortenant.*on the bus. - Audit subscriber writes an audit log entry.
- WebSocket subscriber pushes build status to live clients.
- If NATS is enabled, the event is published to NATS for external consumers.
2) Notification Path (Email)
- API emits
notification.requested(channel =email). - Notification worker subscribes and enqueues a row in
email_queue. - Email worker dequeues, delivers via SMTP, then emits:
notification.senton successnotification.failedon failure
๐งช Test Scenarios (Manual)
Scenario A: Local-Only Flow (No NATS)
Goal: Verify bus + audit + WS work without external dependencies.
- Ensure
messaging.enable_nats=false. - Create a build or project update.
- Confirm:
- Audit log entry created
- WebSocket events appear for build status
- No NATS connection attempt in logs
Scenario B: NATS Enabled + Notification Requested
Goal: Ensure notification.requested flows to queue.
- Enable NATS:
IF_MESSAGING_ENABLE_NATS=true. - Start
notification-workerandemail-worker. - Trigger an action that sends an email (user invite, tenant onboarding).
- Confirm:
notification.requestedloggedemail_queuerow created- Email worker processes and delivers
Scenario C: Notification Outcome Events
Goal: Verify notification.sent / notification.failed.
- Run with NATS enabled.
- Trigger an email.
- Confirm:
notification.sentis published with duration metadata
- Force SMTP failure (bad SMTP host).
- Confirm:
notification.failedis published with error details
๐งช Test Scenarios (Automated)
Unit Tests
- Event bus publish/subscribe (already covered).
- Notification event payload validation.
- Email worker publishes outcome events.
Integration Tests
- Publish
notification.requestedevent โ verifyemail_queueinsertion. - Simulate send failure โ verify
notification.failedpayload.
โ Success Criteria
- Domain events appear in audit and WS without direct coupling.
- Notification request results in a queued email.
- Notification outcomes (
sent/failed) are published. - No duplicate delivery when both local + NATS are active.
โ Testing Checklist (Quick)
Environment
- NATS running (if enabled)
- Backend server running
- Notification worker running
- Email worker running
- Mailpit or SMTP target reachable
Domain Events
- Create project โ audit entry appears
- Start build โ WS update appears
- Update project โ audit entry appears
Notifications
- Trigger user invite โ
notification.requestedlogged -
email_queuerow created - Email worker sends โ
notification.sentemitted - Simulated SMTP failure โ
notification.failedemitted
No Duplicates
- With NATS on, no double audit logs
- With NATS off, behavior remains unchanged
๐ Troubleshooting
- No events published: confirm
messaging.enable_natsand server logs. - No emails sent: verify
email-workeris running and SMTP config is valid. - No notification events: verify
notification-workeris running and subscribed.
๐ Related Docs
docs/architecture/design/UNIFIED_MESSAGING_PROPOSAL.mddocs/architecture/design/UNIFIED_MESSAGING_EVENT_CATALOG.mddocs/phases/PHASE_UNIFIED_MESSAGING_PLAN.md