4.1 KiB
Team Action Lists API
Purpose
Team action lists let the backend expose checklist-style workflows for teams inside a tournament.
Current example:
group_stage_survivor_playoff_tokens
That list contains all teams that advanced from the group stage and tracks whether each team already collected a playoff token.
Read Flow
Frontend reads team action lists from the normal tournament payload:
GET /tournaments/:id
Example response shape:
{
"id": 123,
"name": "My Tournament",
"team_action_lists": [
{
"id": 9,
"name": "Playoff token collection",
"key": "group_stage_survivor_playoff_tokens",
"action_name": "Collect playoff token",
"source": "group_stage_survivors",
"team_action_items": [
{
"id": 41,
"completed": false,
"completed_at": null,
"team": {
"id": 55,
"name": "Team A"
}
}
]
}
]
}
Write Flow
Only tournament owner may change item status.
Everyone may read status.
Follower tournaments in read_only_mode reject updates with 423.
There are two supported write patterns.
Option 1: update by item id
Use this when frontend already has the item id from tournament payload.
PATCH /team_action_items/:id
Request body:
{
"completed": true
}
Option 2: update by list key + team id
Use this when frontend wants a business-key style request like:
- "tick off team X from list Y in tournament Z"
Endpoint:
PATCH /tournaments/:tournament_id/team_action_lists/:key/teams/:team_id
Example:
PATCH /tournaments/123/team_action_lists/group_stage_survivor_playoff_tokens/teams/55
Request body:
{
"completed": true
}
Response body for both write endpoints is the updated TeamActionItem.
Idempotency Rules
These endpoints are designed to be idempotent if frontend sends explicit target state.
Good:
- send
{"completed": true}to mark complete - send
{"completed": false}to mark incomplete
Avoid:
- toggle-style client behavior such as "invert current state"
Why this is idempotent:
- sending
completed=truemultiple times leaves item in same final state - sending
completed=falsemultiple times leaves item in same final state - backend does not create duplicate items
- backend stores one unique item per
(team_action_list_id, team_id)
completed_at behavior:
- first successful transition to
completed=truesets timestamp if none exists - sending
completed=trueagain keeps same completed state - sending
completed=falseclearscompleted_at
Frontend Implementation Guidance
Recommended frontend flow:
- Load tournament via
GET /tournaments/:id - Find desired list by stable
key - Render
team_action_items - On user action, send explicit target state
- Update local UI from response or refetch tournament
Recommended frontend identifiers:
- use list
keyas stable frontend reference - use
team.idas stable team reference - use
team_action_item.idwhen available for direct item updates
Recommended optimistic UI:
- set checkbox immediately to requested target state
- revert if API returns error
- do not compute next state from stale cached data if multiple clients may edit
Error Handling
Expected statuses:
200update accepted403authenticated but not tournament owner404tournament, list, team, or item not found423follower tournament is read-only401unauthenticated
Sync / Follower Behavior
Team action lists are included in tournament sync snapshots.
That means:
- source tournament owner updates item state
- backend enqueues tournament sync
- follower tournament receives updated list state
- follower users can view but not mutate item state while read-only
Future Extension Guidance
When new lists are added, frontend should not hardcode backend internals beyond:
- stable list
key - user-facing
name - user-facing
action_name
New list types should automatically fit the same frontend rendering model:
- list metadata
- list items
- explicit
completedstate - idempotent set-state requests