Mermaid zdroj
Diagram je ponechany ako zdrojovy text, ale otvoren v plnohodnotnom HTML obale, ktory sedí s overview dizajnom.
sequenceDiagram
actor Player
actor Admin
participant API as App Server (API)
participant DB as PostgreSQL
participant RT as Supabase Realtime
participant Notify as Notification Service
Note over Player,Notify: Phase 1 — Prediction Window (before deadline)
Player->>API: GET /groups/:id/matches
API->>DB: SELECT matches + deadlines
DB-->>API: matches list
API-->>Player: matches with countdown timers
Player->>API: POST /predictions\n{match_id, group_id, answers}
API->>DB: Validate: deadline not passed,\nuser is group member,\nanswers match template
DB-->>API: validation OK
API->>DB: UPSERT predictions\n(user_id, match_id, group_id)
DB-->>API: prediction saved
API-->>Player: 200 OK — prediction confirmed
Player->>API: PUT /predictions/:id (edit before deadline)
API->>DB: UPSERT with new answers\n(submitted_at updated)
DB-->>API: updated
API-->>Player: 200 OK — last prediction applies
Note over Player,Notify: Phase 2 — Match Goes Live
Admin->>API: PUT /matches/:id/status {status: "live"}
API->>DB: UPDATE matches SET status = live
DB->>RT: Postgres Change event (matches)
RT-->>Player: WebSocket push — match is LIVE\n(UI locks prediction form)
Admin->>API: PUT /matches/:id/result\n{home_score, away_score, is_final: false}
API->>DB: UPSERT match_results (in-progress)
DB->>RT: Postgres Change event (match_results)
RT-->>Player: WebSocket push — live score update
Note over Player,Notify: Phase 3 — Final Result & Scoring
Admin->>API: PUT /matches/:id/result\n{home_score, away_score, is_final: true}
API->>DB: UPSERT match_results\n(is_final=true, result_version=1)
API->>DB: CALL calculateScores(match_id, result_version=1)
DB->>DB: For each prediction:\n evaluate winner / exact_score / advancing_team\n INSERT prediction_scores with breakdown
DB->>DB: Leaderboard recalculated
DB->>RT: Postgres Change events\n(prediction_scores, match status=finished)
RT-->>Player: WebSocket push — scores updated,\nleaderboard refreshed, all predictions visible
API->>Notify: Trigger: send result emails
Notify-->>Player: Email: "Result X:Y — You earned N points"
Note over Player,Notify: Phase 4 — Result Correction (if needed)
Admin->>API: PUT /matches/:id/result\n{corrected scores, is_final: true}
API->>DB: UPDATE match_results\n(result_version++)
API->>DB: CALL calculateScores(match_id, result_version=2)\n(old version retained as audit trail)
DB->>RT: Postgres Change events
RT-->>Player: WebSocket push — corrected scores & leaderboard
API->>Notify: Trigger: send correction emails
Notify-->>Player: Email: "Result corrected — scores updated"