feat: materialize rcon matches and backend detail data
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: TASK-122
|
||||
title: Materialize RCON matches from AdminLog events
|
||||
status: pending
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
@@ -81,3 +81,20 @@ Recent matches need consistent RCON-first scores. AdminLog contains `MATCH START
|
||||
- Stage only intended files.
|
||||
- Commit the completed implementation.
|
||||
- Push the branch to origin.
|
||||
|
||||
## Outcome
|
||||
|
||||
Implemented `backend/app/rcon_admin_log_materialization.py` with idempotent SQLite tables for `rcon_materialized_matches` and the shared materialization command `python -m app.rcon_admin_log_materialization`. Match records are derived from AdminLog `match_start` and `match_end` events, with `MATCH ENDED` results stored as authoritative `admin-log-match-ended` rows. Session windows remain available as partial fallback without deleting the existing competitive-window code.
|
||||
|
||||
The command also exposes `python -m app.rcon_admin_log_materialization status` for materialization diagnostics: materialized match count, matches with player stats, first/last server time by target and event counts by type.
|
||||
|
||||
No server #03 target was reintroduced, Elo/MMR was not reactivated, and no runtime DB files were committed.
|
||||
|
||||
## 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 smoke: `docker compose up -d --build backend rcon-historical-worker`
|
||||
- Passed Docker materialization: `docker compose exec backend python -m app.rcon_admin_log_materialization` reported `matches_seen: 24`, `matches_materialized: 24`, `errors: []`.
|
||||
- Passed diagnostic command: `docker compose exec backend python -m app.rcon_admin_log_materialization status`.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: TASK-123
|
||||
title: Materialize RCON player match stats
|
||||
status: pending
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
@@ -78,3 +78,19 @@ The internal match detail page should eventually show a simplified scoreboard-li
|
||||
- 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: []`.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: TASK-124
|
||||
title: Add internal RCON match detail API
|
||||
status: pending
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
@@ -80,3 +80,19 @@ Expose internal match detail data from materialized RCON matches and player stat
|
||||
- Stage only intended files.
|
||||
- Commit the completed implementation.
|
||||
- Push the branch to origin.
|
||||
|
||||
## Outcome
|
||||
|
||||
Extended the existing RCON historical read model behind `/api/historical/matches/detail?server=...&match=...` to prefer materialized RCON AdminLog match detail when available, while preserving the existing competitive-window and public-scoreboard fallback behavior.
|
||||
|
||||
Materialized detail payloads now include server, match id, map, game mode, start/end, duration, result, winner, confidence/source basis, safe optional `match_url`, player rows and timeline event counts. Player rows expose display names and derived summaries only, not raw player IDs.
|
||||
|
||||
Missing materialized detail remains controlled: the endpoint falls back to the existing paths and returns `found: false` instead of raising a 500 when no detail is available.
|
||||
|
||||
## 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 API smoke: `Invoke-WebRequest "http://localhost:8000/health"`.
|
||||
- Passed API detail check: `Invoke-WebRequest "http://localhost:8000/api/historical/matches/detail?server=comunidad-hispana-02&match=comunidad-hispana-02:1779108337:1779111786:stmariedumontwarfare"` returned `found: true`, `result_source: admin-log-match-ended`, players and timeline counts.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: TASK-125
|
||||
title: Prefer materialized RCON recent matches
|
||||
status: pending
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
@@ -80,3 +80,22 @@ End users should see correct scores as consistently as possible. RCON AdminLog `
|
||||
- Stage only intended files.
|
||||
- Commit the completed implementation.
|
||||
- Push the branch to origin.
|
||||
|
||||
## Outcome
|
||||
|
||||
Updated the RCON historical recent-matches read model to prefer materialized AdminLog matches with authoritative `MATCH ENDED` results before using active/session competitive windows. Public-scoreboard recent matches remain fallback only when RCON read coverage is unavailable or empty.
|
||||
|
||||
Recent match rows now include `result_source` values for the implemented paths:
|
||||
|
||||
- `admin-log-match-ended`
|
||||
- `rcon-session`
|
||||
- `public-scoreboard-fallback`
|
||||
|
||||
The payload builder no longer selects the public scoreboard merely to fill the requested limit when RCON has usable materialized/session results. Stale local historical targets such as `comunidad-hispana-03` are not re-added to configuration or shown as configured RCON targets by this batch.
|
||||
|
||||
## 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 API recent-matches check: `Invoke-WebRequest "http://localhost:8000/api/historical/recent-matches?server=all-servers&limit=10"` returned `selected_source: rcon`, `fallback_used: false`, and materialized rows with `result_source: admin-log-match-ended`.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: TASK-126
|
||||
title: Correlate scoreboard links with RCON materialized matches
|
||||
status: pending
|
||||
status: done
|
||||
type: backend
|
||||
team: Backend Senior
|
||||
supporting_teams:
|
||||
@@ -75,3 +75,19 @@ Match cards should link to the public scoreboard only when safe correlation exis
|
||||
- Stage only intended files.
|
||||
- Commit the completed implementation.
|
||||
- Push the branch to origin.
|
||||
|
||||
## Outcome
|
||||
|
||||
Kept scoreboard correlation as optional enrichment over RCON-backed match data. Materialized RCON recent/detail payloads call the existing correlation path and only expose `match_url` when the persisted public scoreboard candidate belongs to the trusted origin for the active server.
|
||||
|
||||
Hardened trusted scoreboard URL validation so only the known #01 and #02 origins and `/games/<id>` paths are accepted. Arbitrary domains, wrong ports, non-game paths, credentials, query strings and fragments are rejected. Comunidad Hispana #03 was not reintroduced.
|
||||
|
||||
If correlation fails, the internal materialized detail payload still works and simply returns `match_url: null`.
|
||||
|
||||
## 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 safe URL allowlist coverage for Comunidad Hispana #01 and #02 in `backend.tests.test_rcon_materialization_pipeline`.
|
||||
- Passed existing scoreboard correlation regression suite in `backend.tests.test_scoreboard_match_links`.
|
||||
Reference in New Issue
Block a user