Architecture
Every escrow has a conversation. The conversation feed merges two data sources:| Source | Description |
|---|---|
messages | Human chat messages sent by participants |
notifications | Escrow lifecycle events (funded, disputed, milestone released, etc.) |
GET /message-feed endpoint returns both, sorted by created_at ASC, so your UI renders a single chronological thread.
Sending a message
message_type can be text or attachment.
Fetching the feed
type field:
message— human chatnotification— escrow lifecycle event
action_label for CTA buttons. If null, the notification is informational only.
Notifications
Lifecycle events are automatically written to thenotifications table via DB triggers — one row per participant per event. You don’t write notifications; you only read them.
Conversations list
last_message and unread_count, combining both messages and notifications so the badge count is always accurate.
Realtime subscriptions
Subscribe to these Supabase Realtime channels for live updates:| Channel | Filter | Use for |
|---|---|---|
messages | conversation_id=eq.<id> | Live chat in an open conversation |
message_reads | conversation_id=eq.<id> | Read receipt ticks |
notifications | conversation_id=eq.<id>&user_id=eq.<uid> | Live escrow events in open chat |
notifications | user_id=eq.<uid> | Global unread badge |