Files
comunidadhll/ai/tasks/done/TASK-155-current-match-live-player-stats.md

9.0 KiB

TASK-155 - Current match live player stats

Status: in-progress

Goal

Investigate and implement live player/statistics rendering for the current-match page using the safest available data source.

Background

The current-match page has an "Estadísticas en vivo" section, but it currently remains a placeholder:

"Las estadísticas en vivo aparecerán cuando haya datos suficientes."

The user reports that players are not being shown.

Known context:

  • /api/current-match exposes players and team player counts from RCON getSession, but those counts may be marked as rcon-session-unverified.
  • Public scoreboard can show player population even when RCON getSession reports 0.
  • AdminLog kill events already expose player names through normalized kill feed rows.
  • Historical materialization already derives player stats from AdminLog data for completed matches.
  • The current-match page should eventually show useful live player rows, but only if data is reliable enough.

Scope

Investigate the available live player data sources and wire the current-match page to a safe current player statistics payload.

Allowed changes:

  • backend/app/routes.py
  • backend/app/payloads.py
  • backend/app/rcon_admin_log_storage.py
  • backend read-model/helper files if needed
  • frontend/assets/js/partida-actual.js
  • frontend/partida-actual.html
  • frontend/assets/css/historico.css or relevant CSS
  • focused backend tests

Constraints - DO NOT BREAK

  • Do not fabricate player stats.
  • Do not show an empty/misleading table as if it were real data.
  • Do not show RCON getSession playerCount=0 as reliable if quality is rcon-session-unverified.
  • Do not expose raw AdminLog lines.
  • Do not expose admin-only/sensitive data.
  • Do not break historical materialization.
  • Do not break historical match detail stats.
  • Do not query RCON directly from the frontend.
  • Do not depend on server #03.
  • Do not scrape the public scoreboard unless explicitly chosen and documented as a safe server-side fallback.
  • Keep current public scoreboard URLs trusted and without /games.

Files to inspect first

Read:

  • frontend/partida-actual.html
  • frontend/assets/js/partida-actual.js
  • backend/app/routes.py
  • backend/app/payloads.py
  • backend/app/rcon_admin_log_storage.py
  • focused tests and historical player stat materialization helpers related to current-match or AdminLog data

Inspect the existing RCON session payload, current kill feed freshness logic, open AdminLog match window support, and historical player stat aggregation before choosing a source.

Required investigation before implementation

Perform RCA first and determine what live player data sources currently exist:

  • RCON session payload
  • any RCON player-list command/wrapper already available in the codebase
  • AdminLog kill/death events
  • existing historical player stat materialization
  • current open AdminLog match window if available

Document the chosen source in the done task notes:

  • what was available
  • what was not available
  • whether stats are complete, partial, or event-derived

Implementation requirements

1. Backend endpoint

Add or extend a backend endpoint for current-match player stats.

Preferred route:

  • GET /api/current-match/players?server=...

2. Supported servers

Support:

  • comunidad-hispana-01
  • comunidad-hispana-02

3. Unknown server values

  • Return a safe 400/404 style response.
  • Do not query arbitrary targets.

4. Data model

The endpoint should return:

  • server_slug
  • server_name
  • scope
  • confidence
  • source
  • captured_at or updated_at
  • items: array of player rows

5. Player row fields

Include only fields that can be supported reliably:

  • player_name
  • team if known
  • kills if known
  • deaths if known
  • teamkills if known
  • deaths_by_teamkill if known
  • favorite_weapon or most_used_weapon if known
  • last_seen_at if known
  • confidence/source if needed

6. AdminLog-derived data

If using AdminLog-derived data:

  • Clearly mark scope/confidence as partial/event-derived.
  • Only include players observed in recent/current match event windows.
  • Do not imply this is the full server roster.
  • Use a freshness threshold consistent with kill feed freshness logic.
  • If no current/open event window exists, return empty items with a clear scope.

7. RCON player-list data

If a real RCON player-list command exists:

  • Prefer it for live roster.
  • Combine it with AdminLog-derived kills/deaths only when safe.
  • Mark fields not supported by RCON as null.
  • Do not block the endpoint indefinitely on RCON timeouts.

8. Frontend rendering

Replace the static "Estadísticas en vivo" placeholder with dynamic rendering.

If items exist:

  • Show a compact table or cards with player stats.
  • Sort by kills descending, then deaths ascending, then name.
  • Indicate if stats are partial.

If items are empty, show:

  • "Todavía no hay estadísticas fiables de jugadores para esta partida."

If data is partial, show:

  • "Estadísticas parciales derivadas de eventos recientes."

9. Frontend polling

  • Poll player stats with the current-match page refresh cycle or a safe separate interval.
  • Avoid overlapping requests.
  • Do not flicker table rows on every poll.
  • Avoid duplicate player rows.

10. Tests

Add focused backend tests for:

  • unsupported server rejection
  • empty current stats response
  • AdminLog-derived player aggregation if used
  • stale event filtering
  • no raw AdminLog exposure
  • stable sorting
  • partial confidence metadata

Validation

Run:

  • python -m compileall backend/app
  • focused backend tests if available
  • node --check frontend/assets/js/partida-actual.js

Manual verification checklist

  • Call Invoke-RestMethod "http://localhost:8000/api/current-match/players?server=comunidad-hispana-01" | ConvertTo-Json -Depth 20.
  • Call Invoke-RestMethod "http://localhost:8000/api/current-match/players?server=comunidad-hispana-02" | ConvertTo-Json -Depth 20.
  • Verify unsupported server values are rejected safely.
  • Open http://localhost:8080/partida-actual.html?server=comunidad-hispana-01.
  • Open http://localhost:8080/partida-actual.html?server=comunidad-hispana-02.
  • Verify the "Estadísticas en vivo" section no longer remains permanently empty when current reliable/partial player data exists.
  • Verify the UI clearly says when stats are partial or unavailable.
  • Verify no fake players are shown.
  • Verify no raw AdminLog lines are shown.
  • Verify existing historical detail stats still work.

Expected outcome

The current-match page can show live or partial player statistics when supported by reliable/current data, and otherwise shows a clear honest empty state.

AI Platform lifecycle

After implementation and validation:

  • Move this task according to the lifecycle defined in AGENTS.md.
  • Do not mark unrelated tasks as done automatically.

Outcome

RCA and source choice

  • RCON getSession remains available for the current-match header but its current player count is explicitly marked rcon-session-unverified.
  • No dedicated RCON player-list wrapper or route exists in the current rcon_client implementation.
  • AdminLog kill events already expose safe normalized player names, teams, weapons and current-match window/freshness handling through the kill-feed read model.
  • The historical AdminLog materializer derives player combat stats from the same kind of kill events for closed matches.
  • Chosen source: current/fresh normalized AdminLog kill rows. The new current-match player projection is intentionally event-derived-partial, not a complete live roster.

Change summary

  • Added GET /api/current-match/players?server=... for trusted active current-match servers only.
  • Added a safe AdminLog-derived player aggregator with kills, deaths, teamkills, teamkill deaths, team, last-seen timestamp and favorite weapon when observed.
  • Kept stale fallback filtering aligned with the current kill feed and kept raw AdminLog messages out of the payload.
  • Replaced the static current-match player placeholder with a polled partial-stat table and an honest empty state.

Validation

  • Ran python -m compileall backend/app.
  • Ran node --check frontend/assets/js/partida-actual.js.
  • Attempted python -m pytest backend/tests/test_current_match_payload.py backend/tests/test_rcon_admin_log_storage.py; the active Python environment does not have pytest installed.
  • Ran a direct Python smoke harness for trusted/unsupported route resolution, AdminLog aggregation, teamkill handling, stale filtering and raw-log exclusion.
  • Ran scripts/run-historical-ui-regression-tests.ps1.
  • Ran git diff --check and git diff --name-only.
  • Task-specific changed product files are backend/app/routes.py, backend/app/payloads.py, backend/app/rcon_admin_log_storage.py, backend/tests/test_current_match_payload.py and frontend/assets/js/partida-actual.js. The current worktree also contains frontend/assets/css/historico.css from completed TASK-154.
  • Rendered Browser QA remains to be repeated when the Browser automation entry point is exposed in-session.