> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-Time Architecture

> Version: 1.0.0 Last Updated: 2026-03-08 Status: Recommendation / RFC

**Version:** 1.0.0\
**Last Updated:** 2026-03-08\
**Status:** Recommendation / RFC

Single reference for platform real-time strategy and real-time messaging/chatbot (PF-67, PF-68). Replaces the former recommendations in `docs/archive/architecture/recommendations/` (REAL\_TIME\_STRATEGY.md, REAL\_TIME\_MESSAGING\_RECOMMENDATIONS.md).

***

## Table of Contents

1. [Executive Summary](#1-executive-summary)
2. [Current State](#2-current-state)
3. [Supabase Realtime Mechanisms](#3-supabase-realtime-mechanisms)
4. [Platform Realtime Layer](#4-platform-realtime-layer)
5. [Use Cases by Core](#5-use-cases-by-core)
6. [Implementation Tiers](#6-implementation-tiers)
7. [Security & Performance](#7-security--performance)
8. [Real-Time Messaging (PF-67) & Chatbot (PF-68)](#8-real-time-messaging-pf-67--chatbot-pf-68)
9. [Decision Matrix & Risks](#9-decision-matrix--risks)
10. [References](#10-references)

***

## 1. Executive Summary

* **Today:** Supabase Realtime is used for notifications, dashboard widgets, workflow execution monitoring, and SMS conversations. Gaps: no shared `useRealtimeSubscription` hook, multiple channels for the same table, no org filter on some subscriptions.
* **Strategy:** Introduce a **Platform Realtime Layer** (`@/platform/realtime`) with shared hooks, connection management, and channel multiplexing. Then roll out **17 high-value use cases** in three tiers.
* **Messaging:** PF-67 (internal real-time messaging) and PF-68 (website chatbot) build on PF-66, PF-27, PF-60, PF-10. Both are separate specs for phased delivery.

***

## 2. Current State

| Area                   | Location                    | Mechanism                                      | Quality     |
| ---------------------- | --------------------------- | ---------------------------------------------- | ----------- |
| Notifications (toasts) | `useNotificationToasts.tsx` | `postgres_changes` on `pf_notifications`       | Good        |
| Notification list      | `useNotifications.ts`       | `postgres_changes` on `pf_notifications`       | Adequate    |
| Dashboard widgets      | `useRealtimeWidget`         | `postgres_changes` (configurable table)        | Good        |
| Workflow executions    | `useRealtimeExecutions.ts`  | `postgres_changes` on `fw_workflow_executions` | Excellent   |
| SMS conversations      | `useRealtimeSmsMessages.ts` | `postgres_changes` on `ce_sms_messages`        | Excellent   |
| Financial close events | FA wizard                   | `broadcast` on `fa_events`                     | Lightweight |

**Tables in `supabase_realtime` publication:** `pf_notifications`, `rh_*` (beds, attendance, events, etc.), `lo_issues`, `lo_todos`, `fw_workflow_*`, `gr_audit_findings`, `gr_contracts`, `hr_employees`, `hr_credential_renewal_workflows`, and others. Add `ce_sms_messages` for SMS hook migration.

***

## 3. Supabase Realtime Mechanisms

| Mechanism            | Use For                           | Constraints                                        |
| -------------------- | --------------------------------- | -------------------------------------------------- |
| **Postgres Changes** | Data sync, live dashboards        | Table in publication; filters limited; RLS applies |
| **Broadcast**        | Typing, cursor, ephemeral events  | Not persisted; fire-and-forget                     |
| **Presence**         | Who's online, collaborative state | Small payloads (\< 1KB); CRDT sync                 |

***

## 4. Platform Realtime Layer

**Module:** `src/platform/realtime/`

* **Hooks:** `useRealtimeSubscription`, `useRealtimeBroadcast`, `useRealtimePresence`, `useConnectionStatus`
* **Components:** `RealtimeConnectionBadge`, `PresenceAvatars`
* **Provider:** `RealtimeProvider` (connection health, channel limits, cleanup)

**Example:**

```typescript theme={null}
const { isConnected } = useRealtimeSubscription({
  table: 'rh_beds',
  event: '*',
  filter: { organization_id: orgId },
  onEvent: () => queryClient.invalidateQueries({ queryKey: ['rh-beds'] }),
});
```

Channel naming: `{scope}:{table-or-feature}:{discriminator}`. Multiplex handlers on one channel where possible. Max channels per client: 15–20.

***

## 5. Use Cases by Core

**PF:** Notification toasts (done), unread badge (Tier 1), who's online (Tier 2).\
**RH:** Live census (Tier 1), attendance feed, significant events, curfew board.\
**FW:** Workflow executions (done), approval inbox live (Tier 1), form submission feed (Tier 2).\
**HR:** Timesheet/credential alerts (Tier 2), scheduling conflicts (Tier 3).\
**CE:** SMS (done), incoming call screen pop (Tier 1), lead assignment (Tier 2).\
**GR:** Audit/contract updates (Tier 2). **LO:** Todos/issues (Tier 2), live meeting (Tier 3). **FM/IT:** Work order/ticket board (Tier 2).

***

## 6. Implementation Tiers

* **Tier 0:** Build `@/platform/realtime` (useRealtimeSubscription, Broadcast, Presence, RealtimeProvider, badges). 2–3 days.
* **Tier 1:** Approval inbox, RH census/attendance/events, CE call screen pop, PF task updates; migrate existing to shared hooks. 3–5 days. No new migrations.
* **Tier 2:** Presence “who’s online,” HR/LO/GR/FM/IT use cases; add tables to publication as needed (e.g. `hr_timesheets`, `fm_work_orders`, `it_tickets`, `fa_close_tasks`).
* **Tier 3:** Collaborative editing, live meeting, high-complexity features.

***

## 7. Security & Performance

* **Multi-tenant:** Always include `organization_id` in Postgres Changes filters. Broadcast/Presence have no RLS — scope channel names to org and validate.
* **PHI:** Do not broadcast PHI. For Postgres Changes, prefer minimal payload (e.g. REPLICA IDENTITY DEFAULT). Presence state: non-sensitive only.
* **Limits:** Client realtime config: heartbeat 30s, reconnect backoff, `eventsPerSecond: 10`. Lazy subscribe, aggressive cleanup, multiplex channels.

***

## 8. Real-Time Messaging (PF-67) & Chatbot (PF-68)

**PF-67 (Internal messaging):** Staff-to-staff chat using PF-66 (Broadcast for typing/read receipts, Postgres Changes for messages, Presence for online status). Data model: `pf_conversations`, `pf_conversation_members`, `pf_messages`, `pf_message_read_receipts`. Conversation types: DM, group, channel, record thread. Depends on PF-66, PF-10, PF-02, PF-06.

**PF-68 (Website chatbot):** Configurable embeddable widget for external sites. Uses PF-67 (optional), PF-27 (AI), PF-60 (RAG), PF-35 (Integration Hub), CE-01. Anonymous session model, org-specific config, knowledge-base answers.

**Phasing:** PF-67 first (messaging + real-time); PF-68 second (widget + AI/RAG).

***

## 9. Decision Matrix & Risks

**When to use real-time:** Data time-sensitive (\< 30s)? → Postgres Changes or Broadcast. Collaborative? → Presence + Broadcast. Ephemeral only? → Broadcast. High frequency (> 10/s)? → Prefer polling/SSE.

**Risks:** Connection limit (mitigate: multiplexing, max channels); stale state after reconnect (refetch on reconnect); PHI in Broadcast (forbid); Realtime outage (fallback to TanStack Query polling).

***

## 10. References

* [Event Contracts](integrations/EVENT_CONTRACTS.md)
* [Platform Integration Layers](integrations/PLATFORM_INTEGRATION_LAYERS.md)
* [Supabase Realtime Docs](https://supabase.com/docs/guides/realtime)
* [.cursor/rules/quick-reference.mdc](../../.cursor/rules/quick-reference.mdc) — Realtime Subscription, Broadcast, Presence, RealtimeConnectionBadge

**Archived (full detail):** `docs/archive/architecture/recommendations/REAL_TIME_STRATEGY.md`, `REAL_TIME_MESSAGING_RECOMMENDATIONS.md`.
