Add internal match detail links for recent matches without safe external URLs while preserving external links when available.
10 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-113 | Add internal match detail links | pending | frontend | Frontend Senior |
|
historical | high |
TASK-113 - Add internal match detail links
Goal
Add implementation support so every card in "Ultimas partidas registradas" links to available match data without fabricating unsafe external scoreboard URLs for synthetic RCON competitive-window match IDs.
Context
The historical page now renders recent matches, but the latest backend response for /api/historical/snapshots/recent-matches?server=all-servers&limit=5 can return selected_source: "rcon" and items with capture_basis: "rcon-competitive-window" and no match_url.
The previous implementation correctly renders external "Ver partida" links only when a safe source URL exists. However, current RCON competitive-window matches can use synthetic IDs such as 31:2026-04-13T13:59:26.174488Z, which are not direct scoreboard /games/{id} URLs.
Product decision:
- Keep using a safe external
match_urlwhen one exists. - For matches without a safe external URL, provide an internal match detail page/link.
- Do not invent external scoreboard URLs for synthetic RCON match IDs.
- Preserve HLL Vietnam's military, Vietnam, tactical and sober visual identity.
- Do not reintroduce paused MVP/Elo UI.
- Do not reintroduce Comunidad Hispana #03.
Steps
- Move this task from
ai/tasks/pending/toai/tasks/in-progress/. - Inspect the listed files first.
- Confirm the recent matches response shape for
/api/historical/snapshots/recent-matches?server=all-servers&limit=5, including RCON competitive-window items withoutmatch_url. - Keep the existing safe external
match_urlbehavior:- If a recent match item has a safe external
match_url, render "Ver partida" or "Abrir en scoreboard". - Keep
target="_blank"andrel="noopener noreferrer".
- If a recent match item has a safe external
- Add internal match detail links for recent matches without an external URL:
- Render a visible link/button, for example "Ver detalles".
- Point it to an internal frontend route/page, for example
historico-partida.html?server={serverSlug}&match={encodedMatchId}. - URL-encode the match ID.
- Add a simple internal match detail frontend page:
- Suggested file:
frontend/historico-partida.html. - Preserve the current visual identity.
- Read
serverandmatchfrom the query string. - Call a backend endpoint to get available match details.
- Show a graceful unavailable or partial-data state if only limited RCON data exists.
- Suggested file:
- Add or reuse a backend endpoint for match details:
- Prefer
/api/historical/matches/detail?server={serverSlug}&match={matchId}. - Return available data for both persisted scoreboard matches and RCON competitive-window matches when available.
- At minimum return
server,match_id,map,started_at,ended_atorclosed_at,duration_secondsif available,player_countorpeak_playersif available,resultorscoreif available,capture_basisorcapabilitiesif available, and externalmatch_urlif a safe one exists. - Do not fabricate external scoreboard URLs for synthetic RCON IDs.
- Prefer
- Preserve the existing historical page sections and selector behavior:
- summary
- basic rankings
- recent matches
- server selector with only Todos, Comunidad Hispana #01 and Comunidad Hispana #02
- Keep these blocks paused or hidden:
- MVP mensual V1
- MVP mensual V2
- Comparativa V1 vs V2
- Elo/MMR mensual
- Validate the result with all checks listed below.
- Move this task to
ai/tasks/done/only after validation is complete and document the outcome in this file. - Commit and push the completed implementation branch.
Files to Read First
ai/architecture-index.mdai/repo-context.mdai/orchestrator/frontend-senior.mdai/orchestrator/backend-senior.mdfrontend/historico.htmlfrontend/assets/js/historico.jsfrontend/assets/css/historico.cssbackend/app/routes.pybackend/app/payloads.pybackend/app/historical_storage.pybackend/app/historical_snapshots.py- any RCON competitive/recent match read model modules
scripts/run-integration-tests.ps1docs/decisions.md
Expected Files to Modify
frontend/historico.htmlfrontend/assets/js/historico.jsfrontend/assets/css/historico.css- possibly new
frontend/historico-partida.html - possibly new
frontend/assets/js/historico-partida.js - possibly
backend/app/routes.py - possibly
backend/app/payloads.py - possibly
backend/app/historical_storage.py - possibly historical snapshot/read model modules
- possibly tests under
backend/tests/ - this task file, moved to
ai/tasks/done/
If additional files become necessary, explain why in the task outcome and commit message.
Expected Files Not to Modify
- Docker/Compose config
- local
.env - database migrations unless absolutely required and justified
- persisted data
- Elo/MMR backend implementation files
- unrelated frontend pages
Constraints
- Keep the change focused on internal detail links and match detail data.
- Do not delete backend code, migrations, persisted data, snapshots or endpoints.
- Do not change historical ingestion policy.
- Do not reintroduce Comunidad Hispana #03.
- Do not reintroduce MVP/Elo UI.
- Do not add real credentials.
- Do not introduce unnecessary frontend frameworks or dependencies.
- Preserve direct browser compatibility where applicable.
- Preserve HLL Vietnam branding and product identity.
- Do not use public "snapshot" wording in user-facing copy.
- Confirm
backend/runtime/is not created or committed.
Validation
Before completing the task, run:
git statusnode --check frontend/assets/js/historico.js- If a new frontend JS file is added, run
node --checkon it too. powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1docker compose downdocker compose up -d --builddocker compose psInvoke-WebRequest http://localhost:8000/health | Select-Object -ExpandProperty ContentInvoke-WebRequest http://localhost:8080 | Select-Object -ExpandProperty StatusCodeInvoke-WebRequest "http://localhost:8000/api/historical/snapshots/recent-matches?server=all-servers&limit=5" | Select-Object -ExpandProperty Content- Validate the new match detail endpoint for at least one recent match ID.
Manual or served HTML verification:
- Recent match cards show either external "Ver partida" or internal "Ver detalles".
- The internal detail page opens and displays available data.
- No server #03 appears.
- No paused MVP/Elo blocks appear.
- No public "snapshot" wording appears.
- No migrations or persisted data changed unless explicitly justified.
backend/runtime/is not created or committed.
Before committing, also review:
git diff --name-only- changed files match the expected scope
Commit And Push Requirements
- Run validation before committing.
- Run
git status. - Stage only intended files.
- Commit with a clear message, for example
feat: add internal match detail links. - Push the branch to origin.
- Do not leave completed work only in local.
Outcome
Document the validation performed, notable implementation decisions, and any follow-up task that should be created instead of expanding this task.
Completed.
Validation performed:
- Confirmed
/api/historical/snapshots/recent-matches?server=all-servers&limit=5returnsselected_source: "rcon"with RCON competitive-window items such as31:2026-04-13T13:59:26.174488Z,capture_basis: "rcon-competitive-window"and nomatch_url. - Ran
node --check frontend/assets/js/historico.js. - Ran
node --check frontend/assets/js/historico-partida.js. - Ran Python syntax compilation for the touched backend modules.
- Ran
powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1; the script reports no product integration tests are configured for this platform-only scope and passed the backend startup import check. - Ran
docker compose down. - Ran
docker compose up -d --build. - Ran
docker compose ps; backend and frontend were up on ports 8000 and 8080. - Verified
http://localhost:8000/health. - Verified
http://localhost:8080. - Verified
http://localhost:8000/api/historical/snapshots/recent-matches?server=all-servers&limit=5. - Verified
http://localhost:8000/api/historical/matches/detail?server=comunidad-hispana-01&match=31%3A2026-04-13T13%3A59%3A26.174488Zreturns the RCON detail internally withmatch_url: null. - Used headless Chrome against
http://localhost:8080/historico.html; recent RCON cards renderVer detalles. - Used headless Chrome against
http://localhost:8080/historico-partida.html?...; the internal detail page renders available RCON data and theVentana competitiva RCONcapture basis. - Confirmed no
backend/runtime/path exists.
Implementation decisions:
- Preserved the existing safe external
match_urlbehavior and addedVer detallesonly when no safe external URL exists. - Added
frontend/historico-partida.htmlandfrontend/assets/js/historico-partida.jsas a direct-browser-compatible internal detail page. - Added
/api/historical/matches/detail?server={serverSlug}&match={matchId}. - Added persisted public-scoreboard detail lookup and exact RCON competitive-window detail lookup.
- Kept synthetic RCON match IDs internal and did not fabricate external scoreboard URLs.
- Did not reintroduce paused MVP/Elo UI or Comunidad Hispana #03 in the frontend selector.
Scope note:
- The task exceeded the preferred 5-file/200-line budget because it required both a new internal frontend page and a backend detail endpoint/read path for two historical sources. No migrations, persisted data, Docker config,
.env, Elo/MMR implementation files or unrelated frontend pages were changed.
Follow-up:
- No follow-up task is required from this implementation. A future task could add richer player-level detail if the RCON historical model later exposes player stats.
Change Budget
- Prefer fewer than 5 modified files.
- Prefer changes under 200 lines when feasible.
- Split the work into follow-up tasks if limits are exceeded.