Complete Stats validation, comparison cards, and annual ranking hardening

This commit is contained in:
devRaGonSa
2026-06-08 18:12:36 +02:00
parent b27fbb024b
commit cdfaf6f28f
12 changed files with 796 additions and 61 deletions

View File

@@ -0,0 +1,97 @@
---
id: TASK-175-add-stats-regression-validation-script
title: Add Stats regression validation script
status: done
type: platform
team: PM
supporting_teams:
- Backend Senior
- Frontend Senior
roadmap_item: foundation
priority: high
---
# TASK-175-add-stats-regression-validation-script - Add Stats regression validation script
## Goal
Add a small, repeatable validation for the existing Stats frontend/backend surfaces that protects current endpoints and assets, without changing behavior.
## Context
The Stats section already has public-facing pages, JS assets, and backend endpoints that can regress independently. This task should add a lightweight executable validation flow (script-based) that is tolerant to envs with no local data and can still verify expected behavior and error states.
## Steps
1. Read the listed files first.
2. Define a focused Stats validation workflow without changing any application behavior.
3. Add/update a script that checks key assets and endpoints, including supported and empty/missing states.
4. Ensure the validation outputs clear status and actionable next steps when backend is unavailable.
5. Document endpoint behavior, known environment limits, and the recommended follow-up task.
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/stats-section-functional-plan.md
- docs/annual-ranking-snapshot-runbook.md
- frontend/stats.html
- frontend/assets/js/stats.js
- backend/app/routes.py
- scripts/run-integration-tests.ps1
## Expected Files to Modify
- scripts/run-stats-validation.ps1 (or equivalent repo-preferred validation script)
- scripts/run-integration-tests.ps1 only if a safe integration point is justified
- ai/tasks/done/TASK-175-add-stats-regression-validation-script.md
## Constraints
- No behavior change in Stats.
- No UI redesign.
- No ranking logic changes.
- No database schema changes.
- Do not re-enable Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Keep validation tolerant to environments without positive local data.
- If backend is unavailable, document the expected validation behavior instead of failing with ambiguous output.
## Validation
- Run `node --check frontend/assets/js/stats.js`.
- Run `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`.
- Run the new Stats validation script.
- Run `git diff --name-only` and verify scope is within the task plan.
## Outcome
Validated surfaces:
- `frontend/stats.html` asset wiring and required Stats UI anchors
- `GET /health`
- `GET /api/stats/players/search`
- `GET /api/stats/players/{player_id}`
- `GET /api/stats/rankings/annual`
Implemented validation:
- Added `scripts/run-stats-validation.ps1` to check Stats asset presence, route-contract behavior, invalid parameter handling, and controlled backend-unavailable messaging.
- Wired `scripts/run-integration-tests.ps1` to execute the Stats validation and fail on non-zero child process exit codes.
Controlled limitations observed during validation:
- The local live backend was not running during task validation, so live HTTP checks reported the expected offline guidance instead of ambiguous failure.
- Current normalized all-server scope is returned as `all-servers`.
- Annual ranking `data.limit` currently reflects the effective stored snapshot size when a ready snapshot contains fewer rows than the requested limit; the validator accepts that current behavior without changing runtime logic.
Validation run:
- `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`
Immediate follow-up recommendation:
- Continue with `TASK-176-add-stats-player-comparison-cards`, using the new Stats validation script as the regression guard for the existing Stats surface.

View File

@@ -0,0 +1,124 @@
---
id: TASK-176-add-stats-player-comparison-cards
title: Add stats player comparison cards
status: done
type: frontend
team: Frontend Senior
supporting_teams:
- Experto en interfaz
- Backend Senior
roadmap_item: foundation
priority: high
---
# TASK-176-add-stats-player-comparison-cards - Add stats player comparison cards
## Goal
Improve the Stats UI with comparison cards that help a selected player quickly understand personal metrics and weekly/monthly position, using already available backend data and without creating new endpoints.
## Context
The Stats page already exposes player lookup and detail payloads. This task should improve clarity and trust by surfacing key performance values in cards, while preserving empty/loading/error behavior and the existing visual identity.
## Steps
1. Read the listed files first.
2. Add UI card components in the existing Stats section for selected-player context.
3. Consume existing fields from current responses only, without changing API contracts.
4. Show explicit states for missing ranking, insufficient ranking depth, or missing player in weekly/monthly snapshots.
5. Keep design aligned with military/Vietnam/tactical sober style and keep existing empty/loading/error states intact.
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/stats-section-functional-plan.md
- frontend/stats.html
- frontend/assets/js/stats.js
- frontend/assets/css/styles.css
- backend/app/rcon_historical_player_stats.py
- ai/tasks/done/TASK-172-polish-stats-section-empty-states-and-copy.md
## Expected Files to Modify
- frontend/stats.html
- frontend/assets/js/stats.js
- frontend/assets/css/styles.css
- ai/tasks/done/TASK-176-add-stats-player-comparison-cards.md
## Constraints
- No backend modifications.
- No new endpoints.
- No database changes.
- Do not change existing API contracts.
- Do not re-enable Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Do not introduce frameworks.
- Keep vanilla HTML/CSS/JS implementation.
- Keep military/Vietnam/tactical/sober visual identity.
- Preserve existing empty/loading/error states and avoid regressions.
## Validation
- Run `node --check frontend/assets/js/stats.js`.
- Run `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`.
- Serve frontend with `python -m http.server` and verify HTTP 200 for `stats.html` and `assets/js/stats.js`.
- If possible, visually validate with local backend.
- Run `git diff --name-only` and verify scope is limited to this task.
## Outcome
Implemented comparison cards:
- Added a dedicated comparison-card grid inside the selected-player profile panel.
- Added weekly and monthly window cards using only existing profile payload fields.
- Added a comparison card that contrasts weekly vs monthly KPM, K/D, kills delta, and matches delta.
Payload fields consumed:
- `player_id`
- `player_name`
- `matches_considered`
- `kills`
- `deaths`
- `teamkills`
- `kd_ratio`
- `kills_per_match`
- `deaths_per_match`
- `weekly_ranking`
- `monthly_ranking`
- `window_kind`
- `window_start`
- `window_end`
Behavior with no data or limited ranking:
- If both weekly and monthly windows have zero matches, the existing warning state remains and the comparison cards show explicit "Sin actividad" messaging.
- If a ranking block is absent, the cards show `Ranking ausente`.
- If a ranking exists but `ranking_position` is empty and the active window is a fallback `previous-*` window, the cards show `Profundidad insuficiente`.
- If a ranking exists but the player is not positioned in the visible ranking, the cards show `Fuera del ranking visible`.
Implementation notes:
- The frontend now fetches the existing player profile endpoint twice in parallel, once for `weekly` and once for `monthly`, without adding endpoints or changing backend contracts.
- The tactical visual style stays within the current Stats surface and reuses the existing palette and panel language.
Validation run:
- `node --check frontend/assets/js/stats.js`
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
- Local static server:
- `http://127.0.0.1:8091/stats.html` -> 200
- `http://127.0.0.1:8091/assets/js/stats.js` -> 200
Known limitations:
- Visual validation against a live local backend was not possible because `http://127.0.0.1:8000` was unavailable during this task.
- The Browser plugin surface was not available as `iab` in this session, so browser-level visual inspection could not be completed through the in-app browser.
Immediate follow-up improvements:
- Continue with `TASK-177-harden-annual-ranking-snapshot-operations` so the annual ranking endpoint behavior around effective limits and missing years is better defined and easier for the Stats UI to explain.

View File

@@ -0,0 +1,118 @@
---
id: TASK-177-harden-annual-ranking-snapshot-operations
title: Harden annual ranking snapshot operations
status: done
type: backend
team: Backend Senior
supporting_teams:
- Arquitecto de Base de Datos
- PM
roadmap_item: foundation
priority: medium
---
# TASK-177-harden-annual-ranking-snapshot-operations - Harden annual ranking snapshot operations
## Goal
Improve annual ranking snapshot reliability for production use without recalculating on public requests or changing visible frontend behavior.
## Context
The annual snapshot flow is implemented and documented, but edge cases around missing data, empty years, unsupported years/metrics, and limit normalization should be hardened with small, verifiable backend improvements.
## Steps
1. Read the listed files first.
2. Review generation and read flow for annual ranking snapshots.
3. Apply small validation and response consistency improvements in backend code.
4. Ensure snapshot behavior remains stable for ready/empty/missing and unsupported metric states.
5. Document any follow-up work that should remain a separate task instead of broadening this one.
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/stats-section-functional-plan.md
- docs/annual-ranking-snapshot-runbook.md
- backend/app/routes.py
- backend/app/rcon_annual_rankings.py
- backend/app/rcon_historical_leaderboards.py
- ai/tasks/done/TASK-171-validate-stats-section-with-backend-data.md
- ai/tasks/done/TASK-173-add-annual-ranking-snapshot-runbook.md
## Expected Files to Modify
- backend/app/rcon_annual_rankings.py
- backend/app/routes.py only if endpoint mapping/validation requires changes
- docs/annual-ranking-snapshot-runbook.md only if documented operations change
- ai/tasks/done/TASK-177-harden-annual-ranking-snapshot-operations.md
## Constraints
- No frontend modifications unless a strict critical backend-related bug requires it (and document the reason).
- No new architecture.
- No major migrations.
- Do not re-enable Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Do not use public scoreboard as primary source.
- Do not recalculate annual ranking in each public request.
- Keep changes small and independently verifiable.
## Validation
- Run `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`.
- Test annual ranking endpoint for:
- current year with `metric=kills`
- past year with no data
- future year missing snapshot
- unsupported metric
- low limit, e.g. `3`
- high limit, verifying normalization if applicable
- Run `git diff --name-only` and verify scoped files only.
## Outcome
Applied hardening:
- Added explicit annual year normalization in `backend/app/rcon_annual_rankings.py` for supported `1..9999` values.
- Added reusable limit normalization in the annual snapshot reader/generator with a bounded cap of `100`.
- Added response metadata for annual snapshot reads:
- `requested_limit`
- `effective_limit`
- `snapshot_limit`
- `item_count`
- Hardened effective-limit resolution so a ready snapshot serves no more rows than:
- the requested limit,
- the persisted snapshot limit,
- and the actual stored item count.
- Wrapped the annual route payload build in a `ValueError` guard so invalid annual requests return controlled `400` payloads.
Documentation updated:
- `docs/annual-ranking-snapshot-runbook.md` now documents annual limit metadata and explains why `effective_limit` can be lower than `requested_limit` for ready snapshots.
Validated responses:
- current year with `metric=kills` -> `200`
- past year with no guaranteed data -> controlled `200` with `ready` or `missing` depending on stored snapshot presence
- future year without snapshot -> `200` with `snapshot_status="missing"`
- unsupported metric -> `400`
- low limit `3` -> `200`, `requested_limit=3`, `effective_limit<=3`
- high limit `101` -> `400`
- unsupported year `10000` -> `400`
Validation run:
- Inline Python route validation for the annual endpoint cases above
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
Known limits:
- The API still keeps `limit` aligned with the served effective limit for ready snapshots so current frontend behavior remains unchanged.
- This task does not add scheduling or regeneration automation; it only hardens the existing read/generate contract.
Future task recommendation:
- If operations need stronger guarantees, create a follow-up task for scheduled annual snapshot generation/audit reporting rather than broadening this read-path hardening further.