Overview
Encore OS uses 5 distinct event delivery paths to handle the full spectrum of reactive behavior across the platform — from real-time UI updates to durable business automation to external system integration. Each path makes different trade-offs around durability, latency, retry semantics, and auditability. Choosing the wrong path leads to subtle bugs: lost events, duplicate processing, blocked request cycles, or audit gaps that surface during compliance reviews. This document gives developers a clear framework for selecting the right delivery path for any given use case. Key principle: prefer the least powerful path that satisfies your requirements. UI updates do not need durable queues. Business workflows should not depend on WebSocket connectivity. External integrations must not block database triggers.Event Delivery Paths
Path 1: Table-Driven Domain Events (Primary)
Role: The backbone of Encore OS business automation. Domain events are the canonical mechanism for triggering workflows, automation rules, and cross-core reactions. Flow:- Business automation triggers (e.g., “when a resident moves in, create billing record”)
- Workflow execution that must survive server restarts
- Cross-core reactions that need an audit trail
- Any event that compliance or governance may need to review
Key tables:
Latency: 10-30 seconds (pg_cron poll interval). Not suitable for user-facing
real-time feedback.
Example event types:
resident.moved_in,resident.moved_out,resident.status_changedinvoice.created,payment.received,claim.submittedstaff.onboarded,credential.expiring,shift.completed
Path 2: HTTP Event Consumer (Synchronous)
Role: Immediate, request-scoped side effects that must complete before responding to the user. Flow:- Immediate side effects needed in the request cycle (e.g., send welcome email on signup)
- Real-time validation against external systems
- Operations where the caller needs confirmation of completion
- Simple request-response patterns that do not fan out
Latency: < 2 seconds for typical operations.
When NOT to use:
- Long-running workflows (> 10 seconds)
- Fan-out to multiple consumers
- Operations that must retry on failure without user intervention
Path 3: Supabase Realtime (UI Updates Only)
Role: Push updates to connected browser clients for live UI reactivity. This path is strictly for display purposes and must never drive business logic. Flow (Postgres Changes):- Notification badge counts and live notification feeds
- Dashboard widgets that reflect latest data
- Presence indicators (who is online, who is editing)
- Collaborative editing cursors or selection highlights
- Live list/table updates without polling
Latency: < 500 milliseconds (WebSocket push).
NOT suitable for:
- Business logic execution
- Data consistency enforcement
- Audit-required operations
- Anything that must happen even if no client is connected
Path 4: External Event Forwarding (PF-35 Phase 2)
Role: Deliver events to external systems (EHR platforms, clearinghouses, payer portals, partner organizations) via outbound webhooks with compliance safeguards. Flow:- External EHR system integration (HL7 FHIR event notifications)
- Clearinghouse claim status callbacks
- Payer portal authorization updates
- Partner organization data sharing
- Webhook-based integrations with third-party platforms
Key tables:
Compliance:
- 42 CFR Part 2: Before forwarding any event involving substance abuse treatment data, the consent guard verifies that appropriate patient consent exists for the receiving organization. Events without valid consent are blocked and logged.
- HIPAA: Payload transformation strips internal identifiers and limits PHI to the minimum necessary for the subscriber’s stated purpose.
- Audit: Every forwarding attempt (success or failure) is logged with timestamp, subscriber ID, response status, and payload hash.
- Glob pattern matching on event types (e.g.,
resident.*,billing.payment.*) - JSONPath payload transformation for per-subscriber field selection
- Per-subscriber retry configuration
- Webhook signature verification (HMAC-SHA256)
Path 5: pgmq Direct Queue (Internal Async)
Role: General-purpose internal async processing with guaranteed delivery and backpressure support. Used when work must happen asynchronously but does not fit the domain event / workflow model. Flow:
Use when:
- Guaranteed async processing with backpressure
- Batch operations (e.g., nightly report generation, bulk imports)
- Rate-limited external API calls (e.g., clearinghouse submissions)
- Work that benefits from visibility timeout to prevent double-processing
- Fan-out from a single event to multiple independent work items
Latency: Depends on consumer poll interval. Typically 5-60 seconds.
Decision Tree
Use this flowchart to select the appropriate event delivery path:Path Comparison Matrix
Composed Patterns
Many real-world scenarios combine multiple paths. Here are common compositions:Resident Move-In (Paths 1 + 3 + 5)
Claim Submission (Paths 1 + 4 + 2)
Anti-Patterns
1. Using Realtime (Path 3) for Business Logic
Wrong:2. Using HTTP Consumer (Path 2) for Long-Running Workflows
Wrong:3. Bypassing Domain Events for Automatable Triggers
Wrong:4. Calling External APIs Synchronously from DB Triggers
Wrong:5. Using pgmq for User-Facing Real-Time Feedback
Wrong:Failure Handling Summary
Monitoring and Observability
Each path has different monitoring needs:Multi-Tenancy Considerations
All event delivery paths enforce tenant isolation:- Path 1:
fw_domain_events.organization_idscopes events; RLS policies prevent cross-tenant reads; trigger matching is org-scoped. - Path 2: Edge Function receives
organization_idfrom authenticated JWT; all queries are tenant-filtered. - Path 3: Realtime channels include org ID in channel name (e.g.,
org:{uuid}:notifications); RLS on underlying tables. - Path 4:
pf_event_subscriptions.organization_idensures subscribers only receive their own events; consent checks are per-org. - Path 5: pgmq messages include
organization_idin payload; consumers filter and validate.