Add ranking performance optimization tasks
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
id: TASK-188-audit-ranking-and-stats-query-performance
|
||||||
|
title: Audit ranking and stats query performance
|
||||||
|
status: pending
|
||||||
|
type: research
|
||||||
|
team: Arquitecto de Base de Datos
|
||||||
|
supporting_teams:
|
||||||
|
- Backend Senior
|
||||||
|
- Arquitecto Python
|
||||||
|
roadmap_item: foundation
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-188 - Audit ranking and stats query performance
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Measure and document the real performance of the public Ranking and Stats endpoints before applying any optimization.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
`/api/ranking` weekly/monthly currently reads runtime aggregates over materialized RCON/AdminLog tables, while annual ranking already uses snapshots. `Stats` search and player detail also depend on runtime reads over the same materialized domain. HLL Vietnam needs a concrete baseline for latency, query shape, table size and execution plan so follow-up work can target the real bottlenecks instead of guessing.
|
||||||
|
|
||||||
|
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. Read the listed files first.
|
||||||
|
2. Identify the exact queries and tables used by the target endpoints.
|
||||||
|
3. Measure request time and, if possible, approximate SQL time for each target endpoint.
|
||||||
|
4. Inspect relevant row counts, current indexes and execution plans when the engine allows it.
|
||||||
|
5. Document the slowest endpoint and provide a concrete index/snapshot recommendation without changing runtime code.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `backend/app/routes.py`
|
||||||
|
- `backend/app/rcon_historical_leaderboards.py`
|
||||||
|
- `backend/app/rcon_historical_player_stats.py`
|
||||||
|
- `backend/app/rcon_annual_rankings.py`
|
||||||
|
- `docs/global-ranking-page-plan.md`
|
||||||
|
- `scripts/run-stats-validation.ps1`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- `docs/ranking-stats-performance-audit.md`
|
||||||
|
- `ai/tasks/done/TASK-188-audit-ranking-and-stats-query-performance.md`
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- No modificar lógica de backend.
|
||||||
|
- No modificar frontend.
|
||||||
|
- No crear migraciones.
|
||||||
|
- No crear índices todavía.
|
||||||
|
- No cambiar APIs.
|
||||||
|
- No reactivar Elo/MMR.
|
||||||
|
- No reintroducir Comunidad Hispana #03.
|
||||||
|
- Mantener el trabajo limitado a medición y documentación.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Before completing the task ensure:
|
||||||
|
|
||||||
|
- the audit covers:
|
||||||
|
- `/api/ranking` weekly `kills`
|
||||||
|
- `/api/ranking` weekly `kd_ratio`
|
||||||
|
- `/api/ranking` monthly `kills_per_match`
|
||||||
|
- `/api/ranking` annual `kills`
|
||||||
|
- `/api/stats/players/search`
|
||||||
|
- `/api/stats/players/{player_id}`
|
||||||
|
- the document records:
|
||||||
|
- total request time
|
||||||
|
- approximate SQL time if measurable
|
||||||
|
- row counts for relevant tables
|
||||||
|
- existing indexes
|
||||||
|
- current query shapes
|
||||||
|
- execution plan if available
|
||||||
|
- slowest endpoint
|
||||||
|
- concrete recommendation for indexes and/or snapshots
|
||||||
|
- executed commands are documented
|
||||||
|
- inability to obtain `EXPLAIN` is documented if the environment blocks it
|
||||||
|
- `git diff --name-only` stays within scope
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document:
|
||||||
|
|
||||||
|
- measured baseline results
|
||||||
|
- environment limitations
|
||||||
|
- the most likely root cause of slow public reads
|
||||||
|
- the follow-up recommendation that should feed `TASK-189` and `TASK-190`
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split the work into follow-up tasks if limits are exceeded.
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
id: TASK-189-add-ranking-materialized-read-indexes
|
||||||
|
title: Add ranking materialized read indexes
|
||||||
|
status: pending
|
||||||
|
type: backend
|
||||||
|
team: Arquitecto de Base de Datos
|
||||||
|
supporting_teams:
|
||||||
|
- Backend Senior
|
||||||
|
roadmap_item: foundation
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-189 - Add ranking materialized read indexes
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Add safe indexes on the materialized tables used by Ranking and Stats to reduce scans and improve join performance.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The current Ranking and Stats runtime reads depend on `rcon_materialized_matches`, `rcon_match_player_stats` and annual snapshot tables. After `TASK-188` documents the real bottlenecks, HLL Vietnam needs a narrow indexing pass that improves read performance without changing API contracts, recalculating rankings or introducing a second architecture.
|
||||||
|
|
||||||
|
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. Read the listed files first.
|
||||||
|
2. Use `docs/ranking-stats-performance-audit.md` as the primary justification source.
|
||||||
|
3. Add only the indexes supported by the audit findings and the existing storage initialization/migration pattern.
|
||||||
|
4. Keep SQLite/Postgres compatibility if both storage modes are supported in the current backend.
|
||||||
|
5. Re-run the validation scripts and, if possible, compare before/after timing for one or two representative endpoints.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `docs/ranking-stats-performance-audit.md`
|
||||||
|
- `backend/app/rcon_admin_log_materialization.py`
|
||||||
|
- `backend/app/rcon_historical_leaderboards.py`
|
||||||
|
- `backend/app/rcon_historical_player_stats.py`
|
||||||
|
- `backend/app/rcon_annual_rankings.py`
|
||||||
|
- `backend/app/postgres_rcon_storage.py`
|
||||||
|
- `backend/app/sqlite_utils.py`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- `backend` storage/migration/init module correspondiente, según patrón existente
|
||||||
|
- `docs/ranking-stats-performance-audit.md`, solo si se documenta índice aplicado
|
||||||
|
- `ai/tasks/done/TASK-189-add-ranking-materialized-read-indexes.md`
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- No cambiar contratos API.
|
||||||
|
- No cambiar frontend.
|
||||||
|
- No recalcular rankings.
|
||||||
|
- No crear snapshots en esta task.
|
||||||
|
- No reactivar Elo/MMR.
|
||||||
|
- No reintroducir Comunidad Hispana #03.
|
||||||
|
- Mantener compatibilidad SQLite/Postgres si el proyecto usa ambos.
|
||||||
|
- Basar los índices en evidencia documentada por `TASK-188`, no en suposiciones.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Before completing the task ensure:
|
||||||
|
|
||||||
|
- the chosen indexes are justified by `TASK-188`
|
||||||
|
- candidate coverage explicitly considers:
|
||||||
|
- `target_key + match_key`
|
||||||
|
- `source_basis + ended_at/started_at`
|
||||||
|
- `target_key + ended_at/started_at`
|
||||||
|
- `player_id`
|
||||||
|
- `player_name` if search benefits from it
|
||||||
|
- `snapshot_id + ranking_position` in snapshot tables if applicable
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-stats-validation.ps1`
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
|
||||||
|
- if possible, before/after timing is captured for one or two endpoints
|
||||||
|
- any measurement limitations are documented
|
||||||
|
- `git diff --name-only` stays within scope
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document:
|
||||||
|
|
||||||
|
- indexes added
|
||||||
|
- why each index was chosen
|
||||||
|
- observed improvement or inability to measure it
|
||||||
|
- residual performance gaps that still require snapshot-based reads
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split the work into follow-up tasks if limits are exceeded.
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
id: TASK-190-design-weekly-monthly-ranking-snapshots
|
||||||
|
title: Design weekly monthly ranking snapshots
|
||||||
|
status: pending
|
||||||
|
type: documentation
|
||||||
|
team: Arquitecto de Base de Datos
|
||||||
|
supporting_teams:
|
||||||
|
- Backend Senior
|
||||||
|
- PM
|
||||||
|
roadmap_item: foundation
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-190 - Design weekly monthly ranking snapshots
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Design a weekly/monthly ranking snapshot read model, equivalent in philosophy to the annual snapshot model, so public ranking requests do not depend on expensive runtime aggregation.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Annual ranking already follows a snapshot-backed read path, but weekly/monthly public ranking still depends on runtime aggregation over materialized match stats. HLL Vietnam needs a documented snapshot model for weekly and monthly ranking windows that preserves the current RCON-first policy, keeps annual behavior intact and defines a controlled fallback strategy during transition.
|
||||||
|
|
||||||
|
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. Read the listed files first.
|
||||||
|
2. Use the performance audit and the annual snapshot runbook as reference points.
|
||||||
|
3. Define the proposed tables, keys, metadata and item payload needed for weekly/monthly ranking snapshots.
|
||||||
|
4. Define refresh cadence and lifecycle rules for current and closed windows.
|
||||||
|
5. Define the public fallback policy without reintroducing heavy recomputation on every request.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `docs/ranking-stats-performance-audit.md`
|
||||||
|
- `docs/global-ranking-page-plan.md`
|
||||||
|
- `docs/annual-ranking-snapshot-runbook.md`
|
||||||
|
- `backend/app/rcon_historical_leaderboards.py`
|
||||||
|
- `backend/app/rcon_annual_rankings.py`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- `docs/ranking-snapshot-read-model-plan.md`
|
||||||
|
- `ai/tasks/done/TASK-190-design-weekly-monthly-ranking-snapshots.md`
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- Documentación-only.
|
||||||
|
- No modificar backend.
|
||||||
|
- No modificar frontend.
|
||||||
|
- No crear migraciones.
|
||||||
|
- No implementar snapshots todavía.
|
||||||
|
- No reactivar Elo/MMR.
|
||||||
|
- No reintroducir Comunidad Hispana #03.
|
||||||
|
- Mantener el diseño alineado con Python backend y con el snapshot anual existente.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Before completing the task ensure:
|
||||||
|
|
||||||
|
- the plan defines `ranking_snapshots`
|
||||||
|
- the plan defines `ranking_snapshot_items`
|
||||||
|
- the model covers:
|
||||||
|
- `timeframe` weekly/monthly/annual
|
||||||
|
- `server_id`
|
||||||
|
- `metric`
|
||||||
|
- `window_start` and `window_end`
|
||||||
|
- `generated_at`
|
||||||
|
- `source`
|
||||||
|
- `snapshot_status`
|
||||||
|
- `item_count`
|
||||||
|
- `limit_size`
|
||||||
|
- `ranking_position`
|
||||||
|
- `player_id`
|
||||||
|
- `player_name`
|
||||||
|
- `metric_value`
|
||||||
|
- `matches_considered`
|
||||||
|
- `kills`
|
||||||
|
- `deaths`
|
||||||
|
- `teamkills`
|
||||||
|
- `kd_ratio`
|
||||||
|
- `kills_per_match`
|
||||||
|
- the refresh policy is explicit:
|
||||||
|
- weekly current every 5-15 minutes
|
||||||
|
- monthly current every 15-30 minutes
|
||||||
|
- previous week/month closed and stable
|
||||||
|
- annual manual or daily
|
||||||
|
- the fallback policy is explicit:
|
||||||
|
- serve snapshot if present
|
||||||
|
- return controlled missing or use runtime fallback only by configuration if missing
|
||||||
|
- never recalculate by default on every public request
|
||||||
|
- the plan names impacted endpoints and expected response metadata
|
||||||
|
- `git diff --name-only` stays within scope
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document:
|
||||||
|
|
||||||
|
- the proposed read-model schema
|
||||||
|
- refresh policy
|
||||||
|
- fallback policy
|
||||||
|
- transition notes for implementation in `TASK-191`
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split the work into follow-up tasks if limits are exceeded.
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
---
|
||||||
|
id: TASK-191-serve-ranking-from-snapshots-with-runtime-fallback
|
||||||
|
title: Serve ranking from snapshots with runtime fallback
|
||||||
|
status: pending
|
||||||
|
type: backend
|
||||||
|
team: Backend Senior
|
||||||
|
supporting_teams:
|
||||||
|
- Arquitecto de Base de Datos
|
||||||
|
- Arquitecto Python
|
||||||
|
roadmap_item: foundation
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-191 - Serve ranking from snapshots with runtime fallback
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Implement the `/api/ranking` read path so weekly and monthly ranking are served from snapshots when available, with a controlled runtime fallback only when configured and only when the snapshot is missing.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Public Ranking requests currently pay the cost of runtime aggregation for weekly and monthly windows, while annual ranking already reads from snapshots. After `TASK-190` defines the snapshot read model, HLL Vietnam needs the public ranking endpoint to prefer snapshot-backed reads, preserve annual snapshot behavior and expose enough metadata for frontend and operations to understand source, freshness and fallback usage.
|
||||||
|
|
||||||
|
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. Read the listed files first.
|
||||||
|
2. Implement weekly/monthly snapshot lookup according to `docs/ranking-snapshot-read-model-plan.md`.
|
||||||
|
3. Keep annual requests on the existing annual snapshot path.
|
||||||
|
4. Add controlled runtime fallback only for missing weekly/monthly snapshots when configuration allows it.
|
||||||
|
5. Expose response metadata needed to distinguish snapshot-ready, snapshot-missing and runtime-fallback responses.
|
||||||
|
6. Validate weekly, monthly, annual and invalid-request behavior.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `docs/ranking-snapshot-read-model-plan.md`
|
||||||
|
- `backend/app/routes.py`
|
||||||
|
- `backend/app/payloads.py`
|
||||||
|
- `backend/app/rcon_historical_leaderboards.py`
|
||||||
|
- `backend/app/rcon_annual_rankings.py`
|
||||||
|
- `scripts/run-stats-validation.ps1`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- `backend/app/rcon_historical_leaderboards.py`
|
||||||
|
- `backend/app/routes.py`
|
||||||
|
- `backend/app/payloads.py`
|
||||||
|
- `scripts/run-stats-validation.ps1`
|
||||||
|
- `docs/ranking-snapshot-read-model-plan.md`, solo si se documenta comportamiento final
|
||||||
|
- `ai/tasks/done/TASK-191-serve-ranking-from-snapshots-with-runtime-fallback.md`
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- No cambiar frontend salvo que sea imprescindible y esté documentado.
|
||||||
|
- No crear nuevas features visuales.
|
||||||
|
- No reactivar Elo/MMR.
|
||||||
|
- No reintroducir Comunidad Hispana #03.
|
||||||
|
- No usar scoreboard público como fuente primaria.
|
||||||
|
- No recalcular rankings pesados si snapshot `ready` existe.
|
||||||
|
- Mantener fallback runtime controlado para transición.
|
||||||
|
- La task depende del diseño de `TASK-190`.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Before completing the task ensure:
|
||||||
|
|
||||||
|
- `/api/ranking` weekly/monthly:
|
||||||
|
- attempts snapshot read first
|
||||||
|
- returns snapshot when status is `ready`
|
||||||
|
- uses runtime materialized fallback only when snapshot is missing and fallback is allowed
|
||||||
|
- returns controlled missing when snapshot is missing and fallback is not allowed
|
||||||
|
- `/api/ranking` annual keeps current snapshot behavior
|
||||||
|
- response metadata includes:
|
||||||
|
- `source`
|
||||||
|
- `snapshot_status`
|
||||||
|
- `generated_at`
|
||||||
|
- `freshness`
|
||||||
|
- `fallback_used`
|
||||||
|
- `window_start`
|
||||||
|
- `window_end`
|
||||||
|
- run:
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-stats-validation.ps1`
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
|
||||||
|
- probe:
|
||||||
|
- `/api/ranking` weekly
|
||||||
|
- `/api/ranking` monthly
|
||||||
|
- `/api/ranking` annual
|
||||||
|
- snapshot-missing behavior
|
||||||
|
- invalid `metric`
|
||||||
|
- invalid `timeframe`
|
||||||
|
- invalid `limit`
|
||||||
|
- confirm annual still works
|
||||||
|
- document if snapshots are not yet generated automatically
|
||||||
|
- `git diff --name-only` stays within scope
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document:
|
||||||
|
|
||||||
|
- final read-path behavior
|
||||||
|
- fallback conditions
|
||||||
|
- validation results
|
||||||
|
- any remaining operational dependency for snapshot generation
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split the work into follow-up tasks if limits are exceeded.
|
||||||
Reference in New Issue
Block a user