%%{init: {'theme': 'forest', 'flowchart': { 'curve': 'linear' }}}%% flowchart LR classDef page fill:#e0f2fe,stroke:#0369a1,color:#0c4a6e; classDef admin fill:#dcfce7,stroke:#16a34a,color:#065f46; classDef api fill:#eef2ff,stroke:#6366f1,color:#312e81; classDef pub fill:#f1f5f9,stroke:#334155,color:#0f172a; classDef db fill:#fde68a,stroke:#ca8a04,color:#7c2d12; classDef ext fill:#faf5ff,stroke:#a855f7,color:#6b21a8; subgraph FE_Pages["Frontend Pages"] direction TB p_admin["Admin Scoreboard Page"]:::page p_mobile["Mobile Scoreboard Control Page"]:::page p_overlay_sb["Overlay Scoreboard Page"]:::page p_overlay_sp["Overlay Sponsors Page"]:::page end subgraph BE_API["Backend API /api/v1"] direction TB a_pub["Public"]:::api a_admin["Admin"]:::api %% Public endpoints e_sb_get["GET /scoreboard"]:::pub e_sb_colors["GET /scoreboard/colors/derive"]:::pub e_sb_sponsors["GET /scoreboard/sponsors"]:::pub e_sb_qr_get["GET /scoreboard/qr"]:::pub %% Admin endpoints e_admin_get["GET /admin/scoreboard"]:::admin e_admin_put["PUT /admin/scoreboard"]:::admin e_timer_start["POST /admin/scoreboard/timer/start"]:::admin e_timer_pause["POST /admin/scoreboard/timer/pause"]:::admin e_timer_reset["POST /admin/scoreboard/timer/reset"]:::admin e_swap_sides["POST /admin/scoreboard/swap-sides"]:::admin e_second_half["POST /admin/scoreboard/second-half"]:::admin e_save["POST /admin/scoreboard/save"]:::admin e_saves_list["GET /admin/scoreboard/saves"]:::admin e_load["POST /admin/scoreboard/load"]:::admin e_sp_list["GET /admin/scoreboard/sponsors"]:::admin e_sp_upload["POST /admin/scoreboard/sponsors/upload"]:::admin e_sp_prefill["POST /admin/scoreboard/sponsors/prefill"]:::admin e_sp_delete["DELETE /admin/scoreboard/sponsors"]:::admin e_qr_get["GET /admin/scoreboard/qr"]:::admin e_qr_upload["POST /admin/scoreboard/qr"]:::admin end subgraph DATA["Data Storage"] direction TB d_state["ScoreboardState (DB)"]:::db d_sponsor_files["UploadedFile + FileUsage (Sponsors)"]:::db end %% FE -> Public p_overlay_sb --> e_sb_get p_overlay_sp --> e_sb_sponsors p_overlay_sb -. derive colors .-> e_sb_colors p_overlay_sb -. QR overlay uses .-> e_sb_qr_get %% FE -> Admin (both pages use same admin endpoints) p_admin --> e_admin_get p_admin --> e_admin_put p_admin --> e_timer_start p_admin --> e_timer_pause p_admin --> e_timer_reset p_admin --> e_swap_sides p_admin --> e_second_half p_admin --> e_save p_admin --> e_saves_list p_admin --> e_load p_admin --> e_sp_list p_admin --> e_sp_upload p_admin --> e_sp_prefill p_admin --> e_sp_delete p_admin --> e_qr_get p_admin --> e_qr_upload p_mobile --> e_timer_start p_mobile --> e_timer_pause p_mobile --> e_timer_reset p_mobile --> e_swap_sides p_mobile --> e_second_half %% API -> Data e_admin_put --> d_state e_timer_start --> d_state e_timer_pause --> d_state e_timer_reset --> d_state e_swap_sides --> d_state e_second_half --> d_state e_save --> d_state e_load --> d_state e_sp_upload --> d_sponsor_files e_sp_delete --> d_sponsor_files e_sp_prefill --> d_sponsor_files %% Public reads from DB-backed state/caches e_sb_get -. read .- d_state e_sb_sponsors -. read .- d_state e_sb_qr_get -. read .- d_state