API Events
Outreach has no Kafka and no BullMQ. It is an event source over WebSocket only. The single async emission is a real-time
INQUIRY_SUBMITTEDbroadcast to admin observation rooms.
1. Inbound — Kafka
None. Outreach does not run a Kafka consumer.
2. Outbound — Kafka
None. Outreach does not produce Kafka events. Downstream systems that need inquiry data poll the REST API or subscribe over WebSocket.
3. Inbound — BullMQ
None. No queue workers.
4. Outbound — BullMQ
None. No jobs enqueued.
5. WebSocket Emissions
| Topic (path) | Rooms | Trigger | Emitter |
|---|---|---|---|
observation/outreach/inquiry/submitted | outreach/inquiries, outreach/inquiries/{id} | POST /inquiries/submit succeeds | OutreachSocketEventService.notifyInquirySubmitted() |
| Property | Value |
|---|---|
| Emitter identifier | outreach-ws-emitter (Redis connection name outreach-ws-redis) |
| Backend | Redis-backed WebSocketEmitter (single or cluster via APP_ENV_WEBSOCKET_REDIS_MODE) |
| Topic builder | WebSocketTopics.build({ paths: ['observation','outreach','inquiry','submitted'] }) |
| Room builder | WebSocketRooms.build({ paths: ['outreach','inquiries'(, id)] }) |
| Delivery | Fire-and-forget; isReady() guard; Promise.allSettled so a failing room does not abort the rest |
6. Payload Schemas
// observation/outreach/inquiry/submitted
export interface InquirySubmittedMessage {
id: string; // inquiry id (Snowflake)
type: string; // InquiryTypes value, e.g. "200_SALES"
firstName: string;
lastName: string | null;
email: string;
businessName: string | null;
subject: string | null;
createdAt: string; // ISO timestamp
}Source of truth:
packages/outreach/src/components/websocket/socket-event.service.ts. Nopackages/core/src/models/messages/entry exists — this is a WS-only payload.
7. Idempotency & Ordering
| Channel | Delivery | Ordering | Recovery |
|---|---|---|---|
observation/outreach/inquiry/submitted | at-most-once (best-effort, not awaited) | none | none — clients re-fetch via GET /inquiries if they miss an event |
The WS emission is intentionally lossy: the inquiry is already persisted before notify runs, so the database is the durable record. A dropped WS event only delays the admin's real-time toast, never loses data.