Files
comunidadhll/docs/annual-ranking-snapshot-runbook.md
2026-06-09 13:50:18 +02:00

7.5 KiB

Runbook: annual ranking snapshot top 20 (Stats)

Objetivo: operar el ranking anual top 20 de Stats de forma reproducible, usando snapshots precomputados para no recalcular anualmente por cada request.

1) Proposito del snapshot anual top 20

El snapshot anual proporciona la tabla de posiciones de jugadores para el bloque de ranking anual de Stats con impacto bajo en latencia y costo de consulta.

Objetivos del diseno:

  • entregar top 20 de la temporada por metrica (V1: kills);
  • consumir un resultado estable desde API publica sin recalcular toda la historia anual en cada request;
  • permitir validacion operativa clara de si el ranking esta disponible o no;
  • soportar regeneracion controlada por proceso de mantenimiento.

2) Fuente de datos

La fuente oficial para este ranking es materializada RCON:

  • rcon_materialized_matches
  • rcon_match_player_stats

Filtro principal:

  • matches.source_basis = admin-log-match-ended

Reglas clave de calculo:

  • ventanas por ano (YYYY-01-01T00:00:00Z a YYYY+1-01-01T00:00:00Z);
  • acumulado de kills, deaths, teamkills por player_id;
  • orden por metric_value desc, matches_considered desc, player_name asc;
  • solo posiciones con actividad valida y player_name no vacio.

3) Endpoint consumidor

Desde Stats se consume:

  • GET /api/stats/rankings/annual?year=<year>&server_id=<server-or-all>&metric=kills&limit=20

En V1:

  • metric soporta solo kills;
  • server_id acepta all o identificador de servidor.

4) Como generar snapshot anual

La generacion se hace fuera de la API (job/comando) para precomputar:

  1. Definir ano objetivo year.
  2. Definir alcance server_id (all para global o servidor especifico).
  3. Ejecutar generador de snapshot anual con la configuracion necesaria.
  4. Generador:
    • elimina snapshot previo del mismo (year, server_id, metric) si existe;
    • recalcula top-k desde datos materializados RCON;
    • guarda cabecera + items del ranking en tablas snapshots;
    • persiste metadatos (generated_at, ventana y conteo fuente).

Comando recomendado

python -m app.rcon_annual_rankings generate --year 2026 --server-key all-servers --metric kills --limit 30 --replace-existing

Notas:

  • Cuando HLL_BACKEND_DATABASE_URL esta configurado, el comando usa PostgreSQL por defecto.
  • SQLite queda solo como override explicito mediante --sqlite-path <path>.
  • El comando puede fallar si la capa de datos local no esta inicializada.
  • En entornos manuales, validar entorno y storage objetivo antes de ejecutar.
  • Si no hay datos, se puede generar un snapshot vacio (ready con items=[]).

Override local SQLite

python -m app.rcon_annual_rankings generate --year 2026 --server-key all-servers --metric kills --limit 30 --replace-existing --sqlite-path backend/data/hll_vietnam_dev.sqlite3

Comando Docker recomendado

docker compose exec backend python -m app.rcon_annual_rankings generate --year 2026 --server-key all-servers --metric kills --limit 30 --replace-existing

5) Como regenerarlo

Regenerar cuando:

  • cambie la cobertura de datos anual;
  • se detecte snapshot incompleto;
  • se requiera refrescar fecha generated_at.

Procedimiento:

  1. Ejecutar nuevamente el generador con el mismo year y server_id.
  2. Aceptar reemplazo seguro del snapshot existente.
  3. Validar que el snapshot nuevo refleje el recuento de partidas fuente actualizado.

Recomendacion:

  • programar recalculo en ventanas de mantenimiento (idealmente cierre anual o rutina periodica definida por operaciones).

6) Como validar que existe un snapshot

Verificacion local:

  1. Consultar API de ranking anual del ano objetivo.
  2. Revisar snapshot_status en respuesta:
    • ready: existe snapshot;
    • missing: no existe snapshot.
  3. Verificar generated_at, window_start, window_end, source_matches_count.
  4. Verificar metadatos de limite:
    • requested_limit: limite pedido por el cliente;
    • snapshot_limit: limite persistido en snapshot;
    • effective_limit: limite realmente servido;
    • item_count: filas actualmente disponibles.

Se considera snapshot existente si API responde snapshot_status="ready".

7) Como validar desde API

Usar llamadas directas a backend para validar estado y contenido:

  • GET /api/stats/rankings/annual?year=2026&server_id=all&metric=kills&limit=20
  • GET /api/stats/rankings/annual?year=1999&server_id=all&metric=kills&limit=20
  • GET /api/stats/rankings/annual?year=2026&server_id=all&metric=deaths&limit=20

Checklist:

  • HTTP 200 esperado para parametros validos de V1.
  • status debe ser "ok" con estructura de data consistente.
  • Para snapshots ready, effective_limit puede ser menor que requested_limit cuando el snapshot fue generado con un limite menor o contiene menos filas.
  • En V1 con metric no soportada, esperar error de request (400) sin recomputar ranking.

8) Como validar desde frontend Stats

Desde frontend/stats.html:

  1. Abrir la pestana Stats.
  2. Ejecutar consulta anual usando year.
  3. Confirmar:
    • estado de mensaje de carga/success/empty/error;
    • render de filas cuando haya items;
    • texto explicito cuando el snapshot esta missing;
    • texto explicito cuando el snapshot existe pero no tiene items.
  4. Confirmar que no rompe bloque semanal/mensual ni busqueda cuando el anual no esta disponible.
  5. Si endpoint retorna metricas invalidas, validar estado de warning en UI y que no cambia el resto del flujo.

9) Casos esperados

9.1 snapshot_status=ready con items

Respuesta tipica:

  • status: "ok"
  • data.snapshot_status: "ready"
  • data.items con ranking ordenado.

Debe mostrarse top 20 con campos minimos:

  • ranking_position
  • player_name
  • metric_value
  • matches_considered
  • kills
  • deaths
  • teamkills
  • kd_ratio

9.2 snapshot_status=ready sin items

Respuesta tipica:

  • snapshot_status: "ready"
  • items: []
  • generated_at puede estar presente

Debe renderizar estado "snapshot ready vacio" y no tratarlo como error de sistema.

9.3 snapshot_status=missing

Respuesta tipica:

  • snapshot_status: "missing"
  • items: []

Debe mostrar estado informativo claro de que el ranking no fue generado aun.

9.4 Metrica no soportada

Respuesta tipica:

  • error request (400) con mensaje de metrica invalida/no soportada.

La UI/backend no debe intentar recalcular ni degradar a comportamiento inesperado.

10) Advertencias operativas

  • No reactivar Elo/MMR ni logica dependiente en este bloque.
  • No reintroducir Comunidad Hispana #03 como alcance normal.
  • No usar scoreboard publico como fuente primaria si RCON materializado esta disponible.
  • No recalcular ranking anual completo en cada request publico; siempre leer snapshot.
  • No tocar frontend/assets/js/partida-actual.js ni frontend/assets/img/clans/bxb.png en este runbook.

Checklist de operacion

  • Definir ano/servidor/limite.
  • Ejecutar generacion o regeneracion.
  • Confirmar respuesta de API por ano objetivo.
  • Confirmar estado en UI de Stats.
  • Registrar fecha/hora de generacion y responsable.
  • Si faltan datos esperados, revisar pipeline RCON materializado.

Validacion de la task

  • docs/annual-ranking-snapshot-runbook.md actualizado.
  • Cambios esperados unicamente de documentacion.
  • No se aplican tests automaticos en este runbook; la validacion real se ejecuta en la task de backend correspondiente.

Proximos pasos recomendados

  • Si el bloque muestra estados esperados y refrescos, conectar este runbook con operacion de mantenimiento programada.
  • Mantener la misma politica de fuentes en futuros reportes o automatizaciones de jobs.