Add ranking metric expansion

This commit is contained in:
devRaGonSa
2026-06-09 07:32:29 +02:00
parent f74ac17f48
commit 12a215d11a
13 changed files with 869 additions and 94 deletions

View File

@@ -1,7 +1,7 @@
---
id: TASK-184-define-ranking-metric-expansion-contract
title: Define ranking metric expansion contract
status: pending
status: done
type: documentation
team: Analista
supporting_teams:
@@ -102,17 +102,73 @@ Before completing the task ensure:
## Outcome
Document:
Supported Ranking V1.1 metrics documented in `docs/global-ranking-page-plan.md`:
- supported Ranking V1.1 metrics
- formula for each metric
- ordering and tie-break expectations
- supported timeframes by metric
- annual snapshot limitations and safety rules
- expected payload adjustments, if any
- controlled error behavior for unsupported metrics
- validation performed
- explicit note that no automated tests apply if this remains documentation-only
- `kills`
- `deaths`
- `teamkills`
- `matches_considered`
- `kd_ratio`
- `kills_per_match`
Formula and aggregation rules documented:
- `kills = SUM(kills)`
- `deaths = SUM(deaths)`
- `teamkills = SUM(teamkills)`
- `matches_considered = COUNT(DISTINCT match_key)`
- `kd_ratio = SUM(kills) / SUM(deaths)`
- `kills_per_match = SUM(kills) / COUNT(DISTINCT match_key)`
Safety rules documented:
- `deaths=0` returns finite display-safe `kd_ratio` using kills as the fallback value
- `matches_considered=0` returns `kills_per_match = 0`
Ordering and tie-break expectations documented:
- totals metrics sort by active metric desc, then stable tie-break fields
- `matches_considered` ties break on `kills` desc, then `player_name` asc
- ratio metrics tie-break on `kills` desc, `matches_considered` desc, `player_name` asc
Supported timeframes by metric documented:
- weekly: all V1.1 metrics through the materialized RCON runtime leaderboard
- monthly: all V1.1 metrics through the materialized RCON runtime leaderboard
- annual: snapshot-safe path only; `kills` required, extra metrics only if an explicit snapshot-backed read path exists
Annual snapshot limitations and safety rules documented:
- no runtime annual recomputation on public requests
- unsupported annual metrics must return controlled `400`
- until extra annual snapshots exist, annual remains effectively `kills`-only
Expected payload adjustments documented:
- `metric_value` remains the active display/sort field
- weekly/monthly payloads may include rounded ratio fields and `kills_per_match`
- annual payload shape remains stable and only expands when snapshot-backed safely
Controlled error behavior documented:
- unsupported metric, unsupported timeframe and unsupported annual metric must fail with controlled request-validation errors
- backend must not silently downgrade unsupported requests to `kills`
Validation performed:
- reviewed `docs/global-ranking-page-plan.md`
- reviewed `docs/stats-section-functional-plan.md`
- reviewed `docs/annual-ranking-snapshot-runbook.md`
- reviewed `backend/app/rcon_historical_leaderboards.py`
- reviewed `backend/app/rcon_annual_rankings.py`
- reviewed `backend/app/routes.py`
- reviewed `backend/app/payloads.py`
- reviewed `ai/tasks/done/TASK-183-review-global-ranking-implementation.md`
- confirmed `git diff --name-only` scope stays documentation-only for this task
Automated tests:
- No automated tests apply because this task remained documentation-only.
## Change Budget

View File

@@ -1,7 +1,7 @@
---
id: TASK-185-add-ranking-extra-metrics-backend-support
title: Add ranking extra metrics backend support
status: pending
status: done
type: backend
team: Backend Senior
supporting_teams:
@@ -105,14 +105,72 @@ Before completing the task ensure:
## Outcome
Document:
Metrics added for `GET /api/ranking` weekly/monthly reads:
- metrics added
- formulas applied in backend ranking logic
- annual metric behavior and limitations
- validations executed
- known limitations
- recommended next task: expose the new metrics safely in Ranking frontend UX
- `kills`
- `deaths`
- `teamkills`
- `matches_considered`
- `kd_ratio`
- `kills_per_match`
Backend formulas and ordering applied:
- `kills = SUM(kills)` ordered by `kills` desc, `matches_considered` desc, `player_name` asc
- `deaths = SUM(deaths)` ordered by `deaths` desc, `matches_considered` desc, `player_name` asc
- `teamkills = SUM(teamkills)` ordered by `teamkills` desc, `matches_considered` desc, `player_name` asc
- `matches_considered = COUNT(DISTINCT match_key)` ordered by `matches_considered` desc, `kills` desc, `player_name` asc
- `kd_ratio = SUM(kills) / SUM(deaths)` with `deaths=0 -> kills`, ordered by `kd_ratio` desc, `kills` desc, `matches_considered` desc, `player_name` asc
- `kills_per_match = SUM(kills) / COUNT(DISTINCT match_key)` with `matches_considered=0 -> 0`, ordered by `kills_per_match` desc, `kills` desc, `matches_considered` desc, `player_name` asc
Implementation summary:
- `backend/app/rcon_historical_leaderboards.py` now supports the V1.1 ranking metrics while preserving the existing materialized RCON read model.
- `backend/app/routes.py` now validates the expanded public Ranking metric set without changing the endpoint shape.
- `backend/app/payloads.py` now preserves decimal `metric_value` when needed and exposes `kills_per_match` in normalized ranking items.
- `backend/app/rcon_annual_rankings.py` remains snapshot-safe and returns a controlled annual-specific `400` for unsupported annual metrics.
- `scripts/run-stats-validation.ps1` now covers the new happy paths and annual guardrail failures.
Annual metric behavior and limitations:
- annual remains snapshot-backed only
- `metric=kills` remains supported
- extra annual metrics currently return controlled `400`
- no runtime full-year recomputation was introduced
Validations executed:
- `python -m compileall backend/app/routes.py backend/app/payloads.py backend/app/rcon_historical_leaderboards.py backend/app/rcon_annual_rankings.py`
- `powershell -ExecutionPolicy Bypass -File scripts/run-stats-validation.ps1`
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
Validation notes:
- live backend HTTP validation at `http://127.0.0.1:8000` was not available during execution
- route-contract validation still passed through local Python imports
Scope notes:
- task-owned modifications stayed within:
- `backend/app/rcon_historical_leaderboards.py`
- `backend/app/routes.py`
- `backend/app/payloads.py`
- `backend/app/rcon_annual_rankings.py`
- `scripts/run-stats-validation.ps1`
- `git diff --name-only` also showed pre-existing or previous-task changes outside this task:
- moved task files from `TASK-184` / `TASK-185`
- `docs/global-ranking-page-plan.md` from `TASK-184`
- unrelated existing workspace change `frontend/assets/img/weapons/black/gewehr_black.svg`
- those files were not modified as part of this backend task.
Known limitations:
- annual extra metrics are intentionally blocked until an explicit snapshot-backed implementation exists
- ranking item decimals are validated through route-contract checks, not through a running backend HTTP instance in this run
Recommended next task:
- expose the new metrics safely in the Ranking frontend UX.
## Change Budget

View File

@@ -1,7 +1,7 @@
---
id: TASK-186-polish-ranking-metric-ux-and-limits
title: Polish ranking metric UX and limits
status: pending
status: done
type: frontend
team: Frontend Senior
supporting_teams:
@@ -101,14 +101,88 @@ Before completing the task ensure:
## Outcome
Document:
Metrics exposed in Ranking UI:
- metrics exposed in UI
- annual behavior in the UX
- UI limit choices
- error states covered
- validations executed
- recommended follow-ups, if any
- `kills`
- `deaths`
- `teamkills`
- `matches_considered`
- `kd_ratio`
- `kills_per_match`
Frontend UX changes delivered:
- `frontend/ranking.html` now exposes the expanded metric selector and wider limit options.
- the ranking table now highlights the active metric dynamically while still showing the core supporting stats (`kills`, `deaths`, `teamkills`, `matches_considered`, `kd_ratio`, `kills_per_match`)
- the metadata strip now shows the active timeframe, active server, active metric, limit, window and source more explicitly
- `frontend/assets/js/ranking.js` now restores filter state from URL parameters and keeps the URL synced as filters change
- `frontend/stats.html` now includes a minimal direct link back to `Ranking`
Annual behavior in the UX:
- annual keeps `kills` as the only selectable active metric
- when the user switches to annual, non-snapshot-safe metrics are disabled in the selector
- the page shows an explicit note that annual remains `kills`-only until additional safe snapshots exist
- annual unsupported-metric and missing-snapshot states remain clearly differentiated
UI limit choices:
- `Top 5`
- `Top 10`
- `Top 20`
- `Top 50`
- `Top 100`
Error and state coverage improved:
- dedicated invalid-limit message for manual URL or parameter manipulation
- dedicated annual kills-only warning
- preserved unsupported metric message
- preserved unsupported timeframe message
- preserved backend offline fallback path
- preserved annual snapshot missing state
- preserved empty-ready states
Validation updates:
- `scripts/run-stats-validation.ps1` now asserts the new Ranking metric options, annual kills-only guidance, URL-state handling and the Stats-to-Ranking link
Validations executed:
- `node --check frontend/assets/js/ranking.js`
- `node --check frontend/assets/js/stats.js`
- `powershell -ExecutionPolicy Bypass -File scripts/run-stats-validation.ps1`
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
- temporary static serving with `python -m http.server 8081`
- confirmed HTTP `200` for:
- `ranking.html`
- `assets/js/ranking.js`
- `stats.html`
- `index.html`
Validation notes:
- local backend HTTP validation at `http://127.0.0.1:8000` was unavailable during the run
- offline fallback behavior was therefore validated through the existing frontend logic plus route-contract checks from the shared validation script
Scope notes:
- task-owned frontend changes stayed within:
- `frontend/ranking.html`
- `frontend/assets/js/ranking.js`
- `frontend/assets/css/styles.css`
- `frontend/stats.html`
- `scripts/run-stats-validation.ps1`
- `git diff --name-only` also shows previous-task backend/docs changes and an unrelated existing workspace change:
- moved task files from `TASK-184` / `TASK-185` / `TASK-186`
- `backend/app/*` and `docs/global-ranking-page-plan.md` from prior tasks in this run
- `frontend/assets/img/weapons/black/gewehr_black.svg`
- those files were not modified as part of this frontend task.
Recommended follow-ups:
- if a live backend session becomes available, run an explicit browser-side validation pass for every supported metric against real responses
- if annual extra metrics are introduced later, keep the current UX branch but switch from disabled options to active snapshot-backed support only when backend snapshots exist.
## Change Budget