Add scoreboard-backed weekly historical stats

This commit is contained in:
devRaGonSa
2026-03-20 21:27:45 +01:00
parent abf0890029
commit fc13715abc
11 changed files with 1163 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
# TASK-028-historical-stats-source-and-domain-model
## Goal
Definir la fuente real, el modelo de dominio y la estrategia técnica base para estadísticas históricas de los 2 servidores reales de la comunidad.
## Context
Ya existen páginas de scoreboard/histórico para ambos servidores de la comunidad. El siguiente paso del proyecto es construir una capa histórica propia que permita consultas y rankings agregados, por ejemplo “jugadores con más kills de la última semana” por servidor. Antes de implementar ingesta o endpoints, hay que fijar claramente qué datos se van a extraer, cómo se modelan y cómo se relacionan con cada servidor.
## Steps
1. Revisar las dos fuentes reales de histórico ya disponibles para los servidores de la comunidad.
2. Definir qué entidades de dominio hacen falta como base. Incluir al menos:
- servidor
- partida
- mapa
- modo
- jugador
- participación de jugador en partida
- métricas de partida por jugador
3. Definir qué métricas históricas mínimas interesan en esta primera fase. Incluir al menos:
- kills
- muertes si está disponible
- fecha/hora de partida
- duración
- mapa
- servidor
4. Definir la estrategia de identidad y deduplicación:
- cómo identificar partidas
- cómo identificar jugadores si el scoreboard no da un id perfecto
- cómo evitar duplicados en la ingesta
5. Definir el alcance inicial de analítica histórica. Incluir expresamente:
- top kills de la última semana por servidor
6. Documentar riesgos y límites:
- estructura real del scoreboard
- disponibilidad
- scraping/control de cambios de HTML si aplica
- granularidad de datos
7. Actualizar la documentación técnica del repo con este modelo base.
8. Al completar la implementación:
- dejar el repositorio consistente
- hacer commit
- hacer push al remoto si el entorno lo permite
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/current-hll-servers-source-plan.md
- docs/frontend-backend-contract.md
- backend/README.md
- cualquier código ya existente sobre histórico o scoreboard
- las URLs reales de scoreboard ya usadas por la comunidad
## Expected Files to Modify
- ai/architecture-index.md
- docs/decisions.md
- opcionalmente un nuevo documento técnico, por ejemplo:
- docs/historical-stats-domain-model.md
- opcionalmente backend/README.md si conviene reflejar el nuevo frente técnico
## Constraints
- No implementar todavía scraping/ingesta completa en esta task.
- No introducir UI histórica aún.
- No hacer cambios destructivos.
- Mantener el trabajo centrado en fuente, dominio y estrategia técnica.
- Mantener foco en los 2 servidores reales de la comunidad.
## Validation
- Existe un modelo de dominio claro para histórico.
- Queda definida la fuente real de histórico para ambos servidores.
- Queda definida la métrica inicial prioritaria: top kills de la última semana por servidor.
- La documentación queda utilizable como base directa para las siguientes tasks.
- Los cambios quedan committeados y se hace push si el entorno lo permite.
## Change Budget
- Preferir menos de 5 archivos modificados o creados.
- Preferir menos de 220 líneas cambiadas.
## Outcome
- Se crea `docs/historical-stats-domain-model.md` como documento base para fuente real, entidades de dominio, identidad y deduplicación del histórico.
- `docs/decisions.md` fija que el histórico de scoreboards reales queda separado del estado A2S actual.
- `ai/architecture-index.md` y `backend/README.md` referencian explícitamente el nuevo frente histórico.
## Validation Result
- Verificadas las dos fuentes reales de la comunidad en `https://scoreboard.comunidadhll.es/games` y `https://scoreboard.comunidadhll.es:5443/games`.
- Verificado además que ambas cargan la misma SPA pública `Hell Let Loose Stats`, con referencias visibles a `games`, `players`, `kills`, `deaths`, `matches` y `server`.
- Revisado `git diff --name-only`.
- Resultado: el alcance documental queda limitado a `docs/historical-stats-domain-model.md`, `docs/decisions.md`, `ai/architecture-index.md` y `backend/README.md`.
## Decision Notes
- Se documenta el scoreboard como fuente real del histórico y A2S como fuente del estado live para no mezclar dominios distintos.
- La primera analítica prioritaria se fija en `top kills de la última semana por servidor` y no en un dashboard histórico genérico.

View File

@@ -0,0 +1,83 @@
# TASK-029-historical-stats-ingestion-bootstrap
## Goal
Preparar una base de ingesta histórica para los 2 servidores de la comunidad a partir de sus páginas de scoreboard, persistiendo datos suficientes para alimentar rankings semanales posteriores.
## Context
Ya se ha definido o se va a definir el modelo histórico base. El siguiente paso técnico es arrancar la ingesta real desde las páginas de scoreboard de ambos servidores, guardando datos históricos estructurados de forma incremental y reutilizable.
## Steps
1. Revisar el modelo de dominio/documentación histórica ya definida.
2. Implementar una base mínima de ingesta para los 2 scoreboards reales de la comunidad.
3. Extraer y persistir, como mínimo, datos suficientes sobre:
- servidor
- partida
- fecha/hora
- mapa
- jugador
- kills
- otras métricas disponibles que puedan ser útiles y estables
4. Diseñar la ingesta para poder ejecutarse varias veces sin duplicar datos.
5. Mantener la solución preparada para refresco incremental futuro.
6. Documentar cómo ejecutar la ingesta localmente.
7. No implementar todavía dashboards o UI histórica.
8. Al completar la implementación:
- dejar el repositorio consistente
- hacer commit
- hacer push al remoto si el entorno lo permite
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/historical-stats-domain-model.md
- backend/README.md
- backend/app/config.py
- cualquier almacenamiento o capa de persistencia ya existente
- cualquier módulo collector existente
- las URLs reales de scoreboard de ambos servidores
## Expected Files to Modify
- backend/app/config.py
- backend/README.md
- uno o varios archivos nuevos de backend para ingesta histórica, por ejemplo:
- backend/app/historical_ingestion.py
- backend/app/historical_storage.py
- backend/app/historical_parsers.py
- opcionalmente archivos de datos o esquema local si la implementación lo requiere
## Constraints
- No romper el flujo actual de estado en tiempo real.
- No añadir UI histórica en esta task.
- No introducir complejidad innecesaria.
- No hacer cambios destructivos.
- Mantener el trabajo centrado en ingesta, persistencia e idempotencia.
## Validation
- Existe una ingesta histórica mínima para ambos servidores.
- La ingesta persiste datos estructurados.
- La ingesta puede reejecutarse sin duplicación grave.
- La documentación explica cómo ejecutarla localmente.
- Los cambios quedan committeados y se hace push al remoto si el entorno lo permite.
## Change Budget
- Preferir menos de 8 archivos modificados o creados.
- Preferir menos de 320 líneas cambiadas.
## Outcome
- `backend/app/historical_ingestion.py` implementa una ingesta mínima sobre los 2 scoreboards reales usando `GET /api/get_public_info` y `GET /api/get_live_game_stats`.
- `backend/app/historical_storage.py` añade persistencia idempotente en SQLite para partidas, jugadores y estadísticas por jugador en partida.
- `backend/app/config.py` centraliza las dos fuentes reales de scoreboard.
- `backend/README.md` documenta cómo ejecutar la ingesta localmente y qué tablas/payloads alimenta.
## Validation Result
- Ejecutado desde `backend/`: `python -m app.historical_ingestion`.
- Resultado: `capture_count: 2`, sin errores, con persistencia para `comunidad-hispana-01` y `comunidad-hispana-02`.
- Revisada la SQLite local `backend/data/hll_vietnam_dev.sqlite3`.
- Resultado: existen filas en `historical_matches`, `historical_players` y `historical_player_match_stats`.
- Reejecutada la ingesta tras un ajuste menor de sanitización temporal.
- Resultado: los upserts mantienen idempotencia básica y `time_seconds` queda no negativo en persistencia.
## Decision Notes
- Se usa la API JSON real descubierta detrás del scoreboard en lugar de hacer scraping de la shell SPA.
- La identidad de partida se basa en `server + start timestamp + map slug`, suficiente para la fase actual mientras no aparezca un `match id` público más fuerte.

View File

@@ -0,0 +1,76 @@
# TASK-030-weekly-top-kills-api
## Goal
Exponer una primera API histórica útil que devuelva el ranking de jugadores con más kills de la última semana para cada uno de los 2 servidores de la comunidad.
## Context
La primera necesidad histórica expresada para el proyecto es mostrar estadísticas como “jugadores con más kills de la última semana de cada servidor”. Una vez exista base mínima de ingesta y persistencia, la primera capa de valor debe ser un endpoint sencillo, estable y listo para alimentar futuras vistas o paneles.
## Steps
1. Revisar la estructura histórica persistida y la documentación del modelo de dominio.
2. Diseñar e implementar un endpoint o conjunto mínimo de endpoints para top kills semanales por servidor.
3. Definir un payload claro que incluya, como mínimo:
- servidor
- rango
- jugador
- kills semanales
- rango temporal usado
4. Asegurar que la consulta se limita a la última semana real según la definición elegida por el proyecto.
5. Mantener una implementación clara y preparada para futuras métricas históricas.
6. Documentar el endpoint en backend.
7. No implementar todavía UI histórica en esta task.
8. Al completar la implementación:
- dejar el repositorio consistente
- hacer commit
- hacer push al remoto si el entorno lo permite
## Files to Read First
- AGENTS.md
- ai/repo-context.md
- ai/architecture-index.md
- docs/historical-stats-domain-model.md
- backend/README.md
- backend/app/routes.py
- backend/app/payloads.py
- cualquier módulo de persistencia histórica creado en tasks previas
## Expected Files to Modify
- backend/app/routes.py
- backend/app/payloads.py
- backend/README.md
- opcionalmente nuevos módulos de consulta histórica en backend
## Constraints
- No romper endpoints actuales.
- No añadir UI histórica todavía.
- No introducir librerías nuevas salvo necesidad muy justificada.
- No hacer cambios destructivos.
- Mantener el trabajo centrado en una primera API histórica útil y estable.
## Validation
- Existe un endpoint histórico usable para top kills semanales por servidor.
- El endpoint funciona para los 2 servidores reales de la comunidad.
- El payload es claro y reutilizable.
- La documentación backend queda alineada.
- Los cambios quedan committeados y se hace push al remoto si el entorno lo permite.
## Change Budget
- Preferir menos de 6 archivos modificados o creados.
- Preferir menos de 240 líneas cambiadas.
## Outcome
- `backend/app/historical_storage.py` añade la consulta agregada semanal de kills por servidor.
- `backend/app/payloads.py` expone un payload estable para `top kills` semanales.
- `backend/app/routes.py` añade `GET /api/historical/top-kills/weekly?limit=10` con soporte opcional para `server_id`.
- `backend/README.md` documenta el endpoint y su payload.
## Validation Result
- Ejecutado desde `backend/`: `python -` resolviendo `/api/historical/top-kills/weekly?limit=5` vía `resolve_get_payload(...)`.
- Resultado: `HTTP 200` y rankings útiles para ambos servidores reales.
- Ejemplo validado:
- `comunidad-hispana-01` devuelve ranking encabezado por `[LCM] Vask0`
- `comunidad-hispana-02` devuelve ranking encabezado por `Juanko`
## Decision Notes
- Se expone primero un endpoint agregado por servidor para cubrir el caso de uso real expresado por el proyecto sin multiplicar rutas históricas prematuras.
- La ventana temporal queda definida como rodante de 7 días usando UTC.