4.1 KiB
TASK-251 - Investigate teamkills ranking zeroes
Summary
This task audits why annual teamkills ranking data is missing or zeroed in practice.
No fix was implemented because the issue is upstream from the public ranking UI and needs a source decision first.
Files Read First
backend/app/rcon_admin_log_parser.pybackend/app/rcon_admin_log_storage.pybackend/app/rcon_admin_log_materialization.pybackend/app/rcon_historical_player_stats.pybackend/app/rcon_annual_rankings.pybackend/app/routes.pybackend/tests/test_rcon_materialization_pipeline.py
Findings
1. Parser support exists
The parser already extracts:
killer_teamvictim_team
The materialization code already increments:
teamkillsdeaths_by_teamkill
when killer_team == victim_team.
Tests already cover this logic.
2. Local match facts contain no positive teamkills
Read-only local checks on backend/data/hll_vietnam_dev.sqlite3 show:
rcon_admin_log_eventshas manykillrowsrcon_match_player_stats where teamkills > 0returns zero rowsrcon_annual_ranking_snapshot_items where teamkills > 0returns zero rows
3. Local kill events contain no same-team kills
Read-only checks on parsed event payloads show:
- kill payloads include
killer_teamandvictim_team - but the local dataset contains zero
killrows where both teams are equal
That means the materialized player facts never receive a positive teamkills increment in this dataset.
4. Player profile snapshots do contain teamkill totals
rcon_player_profile_snapshots contains positive values for:
teamkills_doneteamkills_received
So the broader AdminLog/profile ecosystem does know about teamkills somewhere, but those totals are:
- lifetime-oriented
- not tied to one exact closed match window
- not directly usable for annual or per-match ranking backfills without a separate design
5. Annual public ranking payload currently returns empty for teamkills
Production and local checks both show:
/api/ranking?timeframe=annual&metric=teamkills&...returnsitems = []
So the user-visible issue is not a frontend parse bug. It is a data-source gap for annual teamkill ranking inputs.
Cause Probable
The annual ranking consumes rcon_match_player_stats.teamkills.
That field is derived from same-team kill events in the materialized AdminLog match stream.
In the audited dataset:
- same-team
killevents are not present - therefore
rcon_match_player_stats.teamkillsstays at zero - therefore annual
teamkillsranking has no rows
Meanwhile, profile snapshots expose lifetime teamkill totals, but they are not an annual closed-match ranking source.
Decision
Do not patch the public ranking UI.
Do not inject lifetime teamkills_done into annual ranking, because that would mix incompatible time models.
Do not fabricate teamkills from unrelated signals.
Follow-up Direction
The next correct task should choose one of these paths explicitly:
- Confirm whether the real RCON/AdminLog kill stream should include same-team kills and why they are absent.
- If same-team kills are absent by product/API behavior, define a separate ranking source for teamkills.
- If an alternate raw source exists, backfill
rcon_match_player_stats.teamkillsfrom that source with tests.
Validation
Read-only checks executed:
- local SQLite schema audit for:
rcon_admin_log_eventsrcon_match_player_statsrcon_annual_ranking_snapshotsrcon_annual_ranking_snapshot_items
- local count of
event_type='kill' - local count of
teamkills > 0in materialized player stats - local count of same-team parsed kill events
- local inspection of
parsed_payload_jsonsamples - local inspection of
rcon_player_profile_snapshots.teamkills_done/teamkills_received - production endpoint checks for:
- annual all-servers teamkills ranking
- annual comunidad-hispana-01 teamkills ranking
- annual comunidad-hispana-02 teamkills ranking
Notes
- No backend code changed.
- No frontend code changed for this audit.
- No migrations or data writes were performed.