Socket.IO event model
¶ Realtime Events
ReplyBox uses realtime as the last-mile state lane from the API to open web clients. Every emit is scoped to an organisation room, then folded into React Query caches in place.
org:{id}
One Socket.IO room per organisation. A connected client only receives events for the org it belongs to.
- Transport
- Socket.IO
- Events
- 5 typed emits
- Client action
- Patch cache
Delivery path
¶ API emit to org room to cache patch
The room boundary is the important invariant. Emit once to the organisation, let every eligible web client apply the payload locally, and avoid any realtime-triggered pull cycle.
org:{id}Routes it through the organisation room.Event catalog
¶ Five events, two jobs
Channel events keep connection state honest. Inbox events keep open conversations and lists current without polling.
channel.qrQR updates for pairing.channel.statusConnection status changes.channel.syncSync progress updates.
message.createdNew messages and message state changes.conversation.updatedConversation list and summary updates.
Pairing queue
¶ Queue changes ride on channel.status
Because positions move when other imports finish, the channels list polls while any channel is queued, so UI positions stay up to date even if a socket event was missed.
pairing_queued_atPresent while the channel waits in line, possibly null.pairing_promotedMarks queued, left queue, or promoted to import.
pairing_queue_positionQueue-change events patch this andpairing_queued_at, and avoid stamping connect or disconnect clocks.last_qrpairing_promotedmay clear it as the channel begins its import.
Client rule
¶ Fold events into caches. Never refetch on them.
The web client folds events directly into React Query caches. Realtime-driven refetch loops turn message bursts into request storms.