Files
comunidadhll/ai/tasks/done/TASK-168-add-annual-ranking-snapshot-generator.md
2026-06-08 14:24:21 +02:00

4.6 KiB
Raw Blame History

id, title, status, type, team, supporting_teams, roadmap_item, priority
id title status type team supporting_teams roadmap_item priority
TASK-168 Add annual ranking snapshot generator done backend Arquitecto de Base de Datos
Backend Senior
Arquitecto Python
foundation medium

TASK-168 - Add annual ranking snapshot generator

Goal

Implementar un generador backend para snapshots anuales top 20 de jugadores sobre datos RCON materializados.

Context

TASK-166 definió el diseño de persistencia, y TASK-167 ya añadió las tablas:

  • rcon_annual_ranking_snapshots
  • rcon_annual_ranking_snapshot_items

Ahora se necesita el generador que rellene esas tablas desde rcon_materialized_matches y rcon_match_player_stats con source_basis = admin-log-match-ended.

Debe mantenerse separado de frontend y sin introducir una API pública todavía.

Files to Read First

  • AGENTS.md
  • ai/repo-context.md
  • ai/architecture-index.md
  • docs/annual-ranking-snapshot-schema-plan.md
  • backend/app/rcon_admin_log_materialization.py
  • backend/app/rcon_historical_leaderboards.py
  • backend/app/rcon_historical_player_stats.py
  • backend/app/postgres_rcon_storage.py
  • backend/app/sqlite_to_postgres_migration.py

Expected Files to Modify

  • backend/app/rcon_annual_rankings.py (crear)
  • backend/app/rcon_admin_log_materialization.py (si hace falta reutilizar inicialización o alcance)
  • backend/app/postgres_rcon_storage.py (solo si detecta ajustes de soporte SQLite/Postgres)
  • backend/app/sqlite_to_postgres_migration.py (solo si detecta ajustes migratorios necesarios)

Steps

  1. Seguir los archivos de Files to Read First y respetar el contrato de datos existente.
  2. Implementar generate_annual_ranking_snapshot con:
    • year, server_key, metric, limit, replace_existing.
    • Soporte inicial para metric='kills'.
  3. Agregar una ruta CLI opcional (python -m app.rcon_annual_rankings generate --year ...).
  4. Reusar conexión SQLite/Postgres con connect_sqlite_readonly/connect_postgres_compat y placeholders ?.
  5. Validar la función con datos existentes y con BD vacía sin crash.
  6. Preparar la Outcome con validación, comportamiento con vacío y limitaciones.

Constraints

  • No crear API pública en esta task.
  • Mantener el cambio pequeño y verificable.
  • No tocar frontend ni archivos frontend/assets/js/partida-actual.js.
  • No tocar frontend/assets/img/clans/bxb.png.
  • No reactivar Elo/MMR.
  • No reintroducir Comunidad Hispana #03.
  • No ampliar workers históricos salvo que sea imprescindible y justificable.
  • No incluir métricas adicionales a kills salvo que no amplíe el alcance de forma razonable y segura.

Validation

  • python -m compileall backend/app
  • scripts/run-integration-tests.ps1 cuando aplique.
  • Validación local con SQLite:
    • inicializar storage,
    • ejecutar generador con un año de prueba (si hay datos),
    • verificar que se inserta el snapshot y hasta limit items.
  • Verificar comportamiento sin datos: debe terminar sin excepción y crear snapshot vacío o sin items cuando corresponda.
  • git diff --name-only y confirmar que no se tocó frontend.

Outcome

  • Archivos modificados:
    • backend/app/rcon_annual_rankings.py (nuevo)
  • Función/comando generado:
    • generate_annual_ranking_snapshot(year: int, server_key: str | None = None, metric: str = "kills", limit: int = 20, replace_existing: bool = True, db_path: Path | None = None) -> dict[str, object].
    • CLI opcional: python -m app.rcon_annual_rankings generate --year <year> [--server-key <server>] [--metric kills] [--limit <n>] [--replace-existing].
  • Validaciones ejecutadas y resultados:
    • python -m compileall backend/app (sin errores).
    • scripts/run-integration-tests.ps1 (pasado).
    • initialize_rcon_materialized_storage() + generate_annual_ranking_snapshot(year=2026, metric='kills', limit=10) con datos existentes: snapshot creado (source_matches_count > 0), items <= 10.
    • generate_annual_ranking_snapshot(year=1990, metric='kills', limit=20) con ventana sin datos: snapshot creado y items: [] sin excepción.
    • replace_existing=False devuelve skipped_regeneration: True y reutiliza snapshot existente.
    • CLI manual ejecutada: python -m app.rcon_annual_rankings generate --year 1990 --metric kills --limit 3.
  • Limitaciones conocidas:
    • Soporte inicial exclusivamente para metric='kills'.
    • No se implementó API pública ni refresco programado.
    • No se modificón workers históricos.
    • No se tocó frontend ni archivos preexistentes frontend/assets/js/partida-actual.js y frontend/assets/img/clans/bxb.png.
  • Siguiente task recomendada: API pública de ranking anual snapshot.