12 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-267 | Investigate current match live data staleness and clean copy | in-progress | investigation | Backend Senior |
|
current-match | high |
TASK-267 - Investigate current match live data staleness and clean copy
Goal
Determine whether the current match killfeed and live player statistics are stale in the API, stale in frontend rendering, or mismatched against CRCON/RCON live data. Apply only the requested visible copy cleanup unless the diagnosis proves a safe code fix is required.
Context
The current match page can show older live stats than CRCON/RCON live view. For example, CRCON may show a player with many more kills while the page still displays an older count. The killfeed may also appear stale.
Potential causes include stale /api/current-match/players, stale /api/current-match/kills, AdminLog ingestion issues, current-match window filtering, frontend signature/dedupe behavior, browser cache, or a source mismatch between live RCON scoreboard and derived event-based stats.
Files to Read First
AGENTS.mdai/architecture-index.mdai/repo-context.mdai/orchestrator/frontend-senior.mdai/orchestrator/backend-senior.mdfrontend/assets/js/partida-actual.jsbackend/app/payloads.pybackend/app/rcon_admin_log_storage.pybackend/app/postgres_rcon_storage.py
Investigation Steps
- Repeatedly sample killfeed endpoints for
comunidad-hispana-01andcomunidad-hispana-02with cache busters and no-cache headers. - Repeatedly sample current-match player endpoints for
comunidad-hispana-01andcomunidad-hispana-02with cache busters and no-cache headers. - Audit frontend polling, fetch cache behavior, render signatures, in-flight guards and dedupe logic.
- Audit backend payload, storage and query paths for current-match kills and players.
- Run read-only DB checks for recent AdminLog events where available.
- Inspect local service/container availability and logs where available.
- Classify the stale-display cause before applying any staleness fix.
- Apply requested visible copy cleanup.
- Validate syntax and document the result.
Constraints
- Do not execute
ai-platform run. - Do not commit or push.
- Do not touch physical assets or
frontend/assets/img/. - Do not touch maps, weapons, clans or brands.
- Do not change RCON hosts/ports,
27001, or server configuration. - Do not reactivate Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Do not touch
ai/system-metrics.md. - Do not include
tmp/, TASK-204 or unrelated pending changes. - Do not use
git add .. - Do not introduce technical backend wording into visible UI copy.
Required Copy Changes
- Remove visible text:
Estadisticas derivadas de los eventos recientes. - Remove visible text:
Mostrando las ultimas 12 bajas detectadas. - Replace visible text:
Leyendo eventos recientes para esta partida.withLeyendo los enfrentamientos recientes de la partida.
Validation
If frontend changes:
node --check frontend/assets/js/partida-actual.js
If backend changes:
python -m compileall backend/appcd backend; python -m unittest tests.test_current_match_payload
Functional checks:
- Repeated endpoint samples identify whether kills and players change over time.
- Public endpoints return 200 for kills and players on #01 and #02.
- UI copy no longer contains the removed text.
- No unrelated pending changes are included.
Findings
Repeated Production Endpoint Samples
All repeated samples used cache busters and no-cache request headers.
Killfeed samples:
GET /api/current-match/kills?server=comunidad-hispana-01&limit=18- 10 samples over roughly 100 seconds.
scope=open-admin-log-match-window.count=0for all samples.- No first/last event id because the endpoint returned no kill rows.
GET /api/current-match/kills?server=comunidad-hispana-02&limit=18- 10 samples over roughly 100 seconds.
scope=open-admin-log-match-window.count=18for all samples.- First event stayed
rcon-admin-log:comunidad-hispana-02:4246587. - Last event stayed
rcon-admin-log:comunidad-hispana-02:4246570. - Top rows stayed identical. Top event was
Jack -> AleixCommanderwithSMLE No.1 Mk III.
Player-stat samples:
GET /api/current-match/players?server=comunidad-hispana-01- 10 samples over roughly 100 seconds.
count=1for all samples.- Only visible row stayed
Core.D | Axis | K=0 | D=0.
GET /api/current-match/players?server=comunidad-hispana-02- 10 samples over roughly 100 seconds.
count=12for all samples.- Top row stayed
Jack | Allies | K=16 | D=6 | SMLE No.1 Mk III. - Full single follow-up sample confirmed Jack had
kills=16,last_seen_at=2026-06-17T15:34:14.312Z, and sourceconnected,kill,message,team_switch.
Public endpoint status validation:
current-match-kills-comunidad-hispana-01: 200.current-match-kills-comunidad-hispana-02: 200.current-match-players-comunidad-hispana-01: 200.current-match-players-comunidad-hispana-02: 200.
Frontend Analysis
CURRENT_MATCH_KILL_FEED_POLL_INTERVAL_MSis1500; killfeed fetch is scheduled every 1.5 seconds.CURRENT_MATCH_PLAYER_STATS_POLL_INTERVAL_MSis3000; player stats fetch is scheduled every 3 seconds.killFeedRefreshInFlightandplayerStatsRefreshInFlightare reset infinally, so normal request failures should not leave either flag stuck.- Killfeed rendering consumes
data.itemsdirectly, filters invalid events, dedupes by event id/semantic key, and renders the latest visible window after TASK-262 style dedupe. - Killfeed visible signature includes event/window key, killer/victim names, teams, weapon and teamkill flag.
- Player stats rendering consumes
data.items, dedupes rows, sorts by kills/deaths/name, and renders the table from the current endpoint payload. - Player stats visible signature includes player name, team, kills, deaths, teamkills, deaths by teamkill, favorite weapon and last seen.
- If endpoint data changes in any of those fields, the frontend should re-render.
fetchJsoncurrently uses plainfetch(url)and does not setcache: "no-store". The repeated cache-busted production samples still stayed stable, so cache was not proven as the cause in this run.- No evidence was found that visibleSignature would block a real kills/stat change from the endpoint.
Backend Analysis
/api/current-match/killsis routed inbackend/app/routes.pytobuild_current_match_kill_feed_payload(...)./api/current-match/playersis routed inbackend/app/routes.pytobuild_current_match_player_stats_payload(...).- Both payload builders read from AdminLog storage through:
list_current_match_kill_feed(...)list_current_match_player_stats(...)
- Neither endpoint queries live RCON directly during the public GET.
- Killfeed source table is
rcon_admin_log_events. - Player stat source is also
rcon_admin_log_events; it derives kills/deaths/teamkills/favorite weapon by replaying current-window AdminLog events. - Current match window is selected from the latest
match_start/match_endboundary for the target server. - If the latest boundary is
match_start, the endpoints useserver_time >= open_start_time. - If no open match boundary exists, fallback mode uses recent AdminLog rows and filters by freshness.
- Target matching uses
(target_key = ? OR external_server_id = ?), so both target fields are considered forcomunidad-hispana-01andcomunidad-hispana-02.
DB / Service Checks
- Local config reports:
use_postgres_rcon_storage=Falsedatabase_url_set=Falsestorage_path=D:\Proyectos\HLL Vietnam\backend\data\hll_vietnam_dev.sqlite3historical_data_source_kind=rcon
- Local SQLite schema confirms
rcon_admin_log_eventsstores the current-match event source. - Local SQLite data is not production-current:
- Latest local
comunidad-hispana-01events are from May 20, 2026. - Latest local
comunidad-hispana-02events are from May 20, 2026. - Production endpoint rows sampled during this task are from June 17, 2026.
- Latest local
- Local DB max samples repeated after 60 seconds did not change, which only proves local ingestion was not running in this workspace.
- Docker is not available locally:
docker ps --format "{{.Names}}"failed because Docker Desktop/Linux engine is not running.- Container logs could not be inspected from this workspace.
- Production DB/container access was not available from this workspace, so production ingestion status and worker logs could not be directly verified.
Classification
- During the sample window, both production endpoints were stable. This does not prove a bug by itself because there may have been no new kills/events during the 100-second window.
- A later real-world check found that the server had changed map and the new match had no kills yet, so
/api/current-match/killsreturningcount=0in that state is expected and does not prove a bug. - The concrete stale-display example described by the user was not reproduced in the sampled state: production
playersfor #02 reported Jack with 16 kills, which is newer than the example of 15 in CRCON and much newer than the stale UI example of 5. - The active data source for both current-match feed and player stats is stored AdminLog, not direct live scoreboard state.
- If CRCON live changes while these endpoints do not, the cause is backend/source-side: AdminLog ingestion, AdminLog query/window filtering, or mismatch between live scoreboard data and derived event data.
- No evidence was found that frontend visibleSignature/dedupe would ignore changed endpoint values.
- No backend staleness fix was applied because production DB/log access was unavailable and the current endpoint samples did not prove a specific query/window bug.
Exact Cause
For the stale display reported by the user, the exact confirmed cause is not a frontend render blocker. The current page displays exactly what /api/current-match/kills and /api/current-match/players return, and the render signatures include the fields needed to refresh changed rows.
The most precise verified cause is source-model mismatch and/or AdminLog read-model freshness: current-match player stats are derived from stored AdminLog events, while CRCON live can show direct live scoreboard state. If stored AdminLog ingestion or the current-match AdminLog window lags behind CRCON live, both killfeed and player stats will appear stale even though the frontend polling continues.
Root-cause confirmation still requires a future validation window where CRCON/RCON live shows new kills after a map change and the current-match endpoints can be sampled at the same time.
Changes Applied
frontend/partida-actual.html- Replaced visible copy:
- From
Leyendo eventos recientes para esta partida. - To
Leyendo los enfrentamientos recientes de la partida.
- From
- Replaced visible copy:
frontend/assets/js/partida-actual.js- Removed the visible feed status/count line when kill rows exist.
- Removed the visible player-stats line
Estadisticas derivadas de los eventos recientes.when stat rows exist. - Empty/error states remain visible.
No backend, scheduler, RCON, server configuration, physical asset or image files were changed.
Validation Results
- Repeated production endpoint sampling for kills #01/#02 and players #01/#02.
- Public endpoint status checks for kills #01/#02 and players #01/#02 returned 200.
- Frontend polling/render/signature audit completed.
- Backend route/payload/storage audit completed.
- Local SQLite read-only schema/data checks completed.
- Docker/service log inspection attempted; Docker engine was unavailable locally.
node --check frontend/assets/js/partida-actual.jspassed.- Verified the requested removed/replaced visible text with
rg. - Reviewed
git diff -- frontend/assets/js/partida-actual.js frontend/partida-actual.html.