feat: materialize rcon matches and backend detail data
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
---
|
||||
id: TASK-123
|
||||
title: Materialize RCON player match stats
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
- Arquitecto de Base de Datos
|
||||
- Arquitecto Python
|
||||
roadmap_item: rcon-full-data
|
||||
priority: high
|
||||
---
|
||||
|
||||
# TASK-123 - Materialize RCON player match stats
|
||||
|
||||
## Goal
|
||||
|
||||
Build first-pass per-match player statistics from RCON AdminLog kill, team and presence events.
|
||||
|
||||
## Background
|
||||
|
||||
The internal match detail page should eventually show a simplified scoreboard-like view backed by RCON. AdminLog includes `KILL`, `TEAMSWITCH`, `CONNECTED` and `DISCONNECTED` events that can produce kills, deaths, teamkills, weapon counts and player presence.
|
||||
|
||||
## Constraints
|
||||
|
||||
- No UI changes.
|
||||
- Do not expose raw player IDs in frontend work.
|
||||
- Do not reactivate Elo/MMR.
|
||||
- Do not reintroduce Comunidad Hispana #03.
|
||||
- Do not store secrets, runtime DB files or `backend/runtime`.
|
||||
- Keep rematerialization deterministic and idempotent.
|
||||
|
||||
## Allowed Changes
|
||||
|
||||
- backend materialization/storage code for RCON player match stats
|
||||
- optional structured event timeline table or read logic
|
||||
- backend tests and fixtures
|
||||
- this task file when moving it through the workflow
|
||||
|
||||
## Implementation Requirements
|
||||
|
||||
- Work from a dedicated branch for this task.
|
||||
- Read first:
|
||||
- `AGENTS.md`
|
||||
- `ai/architecture-index.md`
|
||||
- `ai/repo-context.md`
|
||||
- `ai/orchestrator/backend-senior.md`
|
||||
- `ai/orchestrator/database-architect.md`
|
||||
- `backend/app/rcon_admin_log_parser.py`
|
||||
- `backend/app/rcon_admin_log_storage.py`
|
||||
- materialized match code from TASK-122
|
||||
- Use parsed events from `rcon_admin_log_events`.
|
||||
- Associate events to matches by target and server-time range between `match_start` and `match_end`.
|
||||
- Create a table such as `rcon_match_player_stats` with target, match, player identity/display, team, kills, deaths, teamkills, deaths by teamkill, weapon JSON, death-by weapon JSON, most-killed JSON, death-by JSON and first/last seen server time.
|
||||
- Optionally create `rcon_match_events` for structured timeline rows, or read directly from AdminLog events.
|
||||
- For `KILL`, add one kill to the killer when teams differ, add one death to the victim, and count same-team kills as teamkills plus victim deaths by teamkill.
|
||||
- Track weapon counts and killer-victim counts.
|
||||
- Use connected/disconnected/team switch events to improve presence and team attribution.
|
||||
- Handle missing or non-Steam-style player IDs robustly.
|
||||
|
||||
## Validation Commands
|
||||
|
||||
- `python -m compileall backend/app`
|
||||
- `python -m pytest backend/tests/<new_or_relevant_player_stats_tests>.py`
|
||||
|
||||
## Manual Verification Steps
|
||||
|
||||
- Validate offline fixtures containing `KILL`, `TEAMSWITCH`, `CONNECTED` and `DISCONNECTED`.
|
||||
- Confirm kills, deaths, teamkills, weapons, most killed and death-by summaries.
|
||||
- Confirm repeated materialization does not duplicate or inflate stats.
|
||||
- Confirm `/health` still works.
|
||||
- Confirm `git diff --name-only` matches the allowed scope.
|
||||
|
||||
## Git Requirements
|
||||
|
||||
- Create a dedicated branch for this task, for example `codex/task-123-rcon-player-stats`.
|
||||
- Run relevant validation before committing.
|
||||
- Stage only intended files.
|
||||
- Commit the completed implementation.
|
||||
- Push the branch to origin.
|
||||
|
||||
## Outcome
|
||||
|
||||
Implemented AdminLog-derived `rcon_match_player_stats` materialization in `backend/app/rcon_admin_log_materialization.py`. The materializer associates kill/presence events to materialized matches by target and server-time range, rebuilds stats deterministically on each run, and handles Steam-style and non-Steam player identifiers without exposing them in the match-detail read model.
|
||||
|
||||
Kill logic now records kills, deaths, teamkills, deaths by teamkill, weapon counts, death-by weapon counts, most-killed summaries and death-by summaries. Presence events are used when they include stable player identity, while team-switch rows without player IDs are ignored for identity creation to avoid duplicate display-name-only player rows.
|
||||
|
||||
Non-blocking follow-up note: suspicious live/session queue fields remain worth reviewing separately. In previous worker output, `vip_queue_count` appeared as `464/434` while `max_vip_queue_count` was `2`; this batch did not change that parser path.
|
||||
|
||||
## Validation Result
|
||||
|
||||
- Passed: `python -m compileall backend/app`
|
||||
- Pytest was not installed in the local Python environment.
|
||||
- Passed deterministic fallback: `$env:PYTHONPATH='backend'; python -m unittest backend.tests.test_rcon_materialization_pipeline backend.tests.test_scoreboard_match_links`
|
||||
- Passed Docker AdminLog ingestion: `docker compose exec backend python -m app.rcon_admin_log_ingestion --minutes 1440` reported `events_seen: 143`, `errors: []`.
|
||||
- Passed Docker materialization: `docker compose exec backend python -m app.rcon_admin_log_materialization` reported `player_stats_seen: 22`, `player_stats_materialized: 22`, `errors: []`.
|
||||
Reference in New Issue
Block a user