docs: clarify websocket contract

This commit is contained in:
Daniel Schädler 2026-04-23 13:18:02 +02:00
parent 0f4ed8a0c3
commit e913eb215b
2 changed files with 23 additions and 0 deletions

View File

@ -166,6 +166,7 @@ That means:
## Websocket Live Updates ## Websocket Live Updates
Team-action-list live updates use Rails ActionCable at `/cable`. Team-action-list live updates use Rails ActionCable at `/cable`.
This is websocket push from backend to clients, not a webhook callback model.
Practical rule: Practical rule:
@ -176,8 +177,11 @@ Practical rule:
For team action lists specifically: For team action lists specifically:
- subscribe by tournament id - subscribe by tournament id
- channel name is `TournamentTeamActionListsChannel`
- broadcast full current list snapshot for that tournament - broadcast full current list snapshot for that tournament
- event payload type is `team_action_lists.updated`
- keep write APIs idempotent and item-scoped - keep write APIs idempotent and item-scoped
- keep websocket read-only; item state changes still go through HTTP `PATCH`
- cover both direct-app websocket updates and follower-sync websocket propagation in E2E - cover both direct-app websocket updates and follower-sync websocket propagation in E2E
## Practical Expectation ## Practical Expectation

View File

@ -164,6 +164,12 @@ That means:
Team action lists also support live updates over ActionCable. Team action lists also support live updates over ActionCable.
This is a websocket flow, not a webhook flow.
- backend pushes updates to subscribed clients over websocket
- frontend does not register callback URLs
- writes still happen over normal HTTP `PATCH` requests
Endpoint: Endpoint:
- `GET /cable` for websocket upgrade - `GET /cable` for websocket upgrade
@ -188,6 +194,9 @@ Behavior:
- same broadcast path is used for: - same broadcast path is used for:
- direct source updates - direct source updates
- follower sync imports - follower sync imports
- both write endpoints trigger the same backend update path before broadcast:
- `PATCH /team_action_items/:id`
- `PATCH /tournaments/:tournament_id/team_action_lists/:key/teams/:team_id`
Payload shape: Payload shape:
@ -225,6 +234,16 @@ Frontend guidance:
- keep writes item-scoped through HTTP - keep writes item-scoped through HTTP
- use websocket only for read/live propagation - use websocket only for read/live propagation
Practical frontend pattern:
1. load initial tournament state over HTTP
2. open websocket subscription for same tournament id
3. render incoming websocket payload as latest live snapshot
4. when user checks or unchecks one team, send one idempotent HTTP `PATCH` for that item only
5. let websocket keep other viewers in sync
This avoids whole-list writebacks and reduces race-condition risk between multiple clients.
## Future Extension Guidance ## Future Extension Guidance
When new lists are added, frontend should not hardcode backend internals beyond: When new lists are added, frontend should not hardcode backend internals beyond: