Realtime operations
V1 uses Supabase Realtime for workbench awareness and stream updates. See Upstream docs for the latest Realtime contract.
Transport
Section titled “Transport”V1 uses Postgres Changes only, not broadcast channels. The workbench subscribes to row changes filtered by tenant_id, and RLS on the underlying tables enforces visibility — the channel itself does not need a separate auth model.
Only these tables are in the supabase_realtime publication:
frame_eventsframe_submissionsframesframe_media
Everything else (API keys, policies, members) is fetched on demand.
Events
Section titled “Events”Realtime payloads should be small. Event names use dotted form and match the canonical list in Realtime events:
frame.submission.createdframe.submission.status_changedframe.media.status_changed(intermediate transitions)frame.media.ready(terminal success)frame.media.failed(terminal failure)frame.approval.changedframe.promotedframe.rejectedapi_key.usedapi_key.revoked
The event payload carries IDs, status, actor, and timestamp — plus the originating request_id (see Observability). The UI fetches full records from Supabase when it needs detail.
Subscription discipline
Section titled “Subscription discipline”- The workbench opens one subscription per active screen.
- A client holds at most a small, documented number of channels concurrently; route changes close stale subscriptions.
- Stream
readywebhooks come from Cloudflare to an Edge Function, which writes a row and lets Postgres Changes fan it out — the workbench never subscribes to Cloudflare directly.
Why small payloads
Section titled “Why small payloads”Frame metadata can be large and flexible. Broadcasting full metadata would make every update expensive and fragile. IDs and state transitions are enough for live UI updates.