Referees and administrators manage live match data through a set of dedicated endpoints. The workflow is linear: lock the match to prevent concurrent edits, start it, record every event as it happens, then finalize to commit standings and prediction points. The system enforces this order and protects data integrity at every step.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Danielsl4/TFG_DAM_2526_Consulta2/llms.txt
Use this file to discover all available pages before exploring further.
Locking prevents concurrent edits. The lock is per-referee and must be explicitly released via
POST /matches/:id/unlock, or it expires automatically after 2 minutes of inactivity. Admins can force-release any lock by passing ?force=true.Match locking
Before any edit — changing status, adding events, or finalizing — a referee must acquire a lock on the match. This is a mutual-exclusion mechanism backed by two database columns:locked_by (the user ID holding the lock) and locked_at (the timestamp of the last lock renewal).
Acquiring a lock — POST /matches/:id/lock
- If the match is unlocked or was locked more than 2 minutes ago, the lock is granted to the calling referee.
- If the same referee already holds the lock, the
locked_attimestamp is renewed. - If another referee holds an unexpired lock, the response returns HTTP
409with the locking referee’susername.
POST /matches/:id/unlock releases the lock held by the calling user. Admins can add ?force=true to release any lock regardless of ownership.
Updating match status
A match moves through three statuses in sequence:| Status | Meaning |
|---|---|
pendiente | Scheduled, not yet started |
en_curso | Match is in progress |
finalizado | Match is over; standings are committed |
PUT /matches/:id/status with { "status": "en_curso" } in the request body. The match must be locked by the calling referee before this endpoint accepts the request. Only the three values above are valid; any other value returns HTTP 400.
Recording events
Events are added one at a time viaPOST /matches/:id/events. Each request requires:
| Field | Description |
|---|---|
type | One of the event types listed below |
playerId | ID of the player who performed the action |
teamSide | "home" or "away" — which side the player belongs to |
| Type | Effect |
|---|---|
gol | Increments home_goals or away_goals; adds to player_stats.goals |
tarjeta_amarilla | Adds to player_stats.yellow_cards and team_stats.yellow_cards |
tarjeta_roja | Adds to player_stats.red_cards and team_stats.red_cards |
penalti_tanda_marcado | Increments home_penalty_goals or away_penalty_goals |
penalti_tanda_fallado | Recorded in the event log only; no score changes |
Finalizing a match
PUT /matches/:id/finish transitions the match to finalizado and triggers several cascading updates in a single atomic transaction:
- Sets
status = 'finalizado'and clears the lock. - Optionally saves
observationstext passed in the request body. - Increments
matches_playedinplayer_statsfor every player with at least one event in the match. - Calculates win/draw/loss and updates
team_statsfor both teams (goals for, goals against, points). - Determines the correct prediction outcome (
local,empate, orvisitante) and awards 1 point to each user who voted correctly, updatinguser_pointsfor the season. - Clears the Redis cache entries for the match and the global match list.
Removing events
Individual events can be deleted viaDELETE /matches/:matchId/events/:eventId. The match must be locked by the calling referee. Removing an event automatically reverses all stat changes that were applied when the event was first recorded:
- A deleted
goldecrements the team’s goal tally (minimum 0). - A deleted
tarjeta_amarillaortarjeta_rojadecrements the player’s and team’s card counts. - A deleted
penalti_tanda_marcadodecrements the penalty shootout score. - Player stats are decremented in
player_statsfor all regular event types.
Referee workflow
Lock the match
Call
POST /matches/:id/lock. If the response returns success: true, you hold the lock. If another referee is editing, wait or ask them to release it.Set status to en_curso
Call
PUT /matches/:id/status with { "status": "en_curso" } to signal that the match has started. The lock must be held.Record goals and cards
For each event during the match, call
POST /matches/:id/events with the event type, player ID, and team side. Review the running score in the match detail view to catch mistakes early.