Document CRCON historical source discovery

This commit is contained in:
devRaGonSa
2026-03-20 21:48:31 +01:00
parent 687c7a926d
commit 26ba1159de
4 changed files with 383 additions and 0 deletions

View File

@@ -67,5 +67,7 @@ Community website repository with a static landing in the current phase and a pl
- The phased source strategy for that provisional block is documented in `docs/current-hll-servers-source-plan.md`.
- The ingestion strategy for converting that provisional block into normalized server snapshots is documented in `docs/current-hll-data-ingestion-plan.md`.
- The logical storage foundation for persisting server snapshots is documented in `docs/stats-database-schema-foundation.md`.
- Historical match and player statistics must come from the public CRCON scoreboard JSON layer, not from A2S or the `/games` HTML shell.
- The validated discovery for those historical sources is documented in `docs/historical-crcon-source-discovery.md`.
- Frontend data consumption should remain progressive, endpoint by endpoint, with static fallbacks preserved during migration.
- The frontend integration strategy is documented in `docs/frontend-data-consumption-plan.md`.

View File

@@ -0,0 +1,125 @@
# TASK-027-historical-crcon-source-discovery
## Goal
Descubrir y documentar la fuente historica real mas estable para los 2 servidores de la comunidad, basada en CRCON/scoreboard, dejando claro como obtener datos historicos reutilizables para futuras estadisticas semanales y evitando depender de una implementacion previa ya descartada.
## Context
El proyecto ya tiene resuelta la parte de estado actual de servidores mediante A2S para la landing. La siguiente fase es historico y estadisticas agregadas, por ejemplo "jugadores con mas kills de la ultima semana por servidor".
Se parte de dos hechos importantes:
1. El historico NO debe construirse con A2S como fuente principal, porque A2S sirve para estado actual y no para historico retroactivo de partidas.
2. Cualquier intento previo de historico semanal basado directamente en la pagina de la comunidad debe considerarse deshecho, invalido o no reutilizable como base de arquitectura para esta nueva fase.
Ademas, el analisis tecnico previo apunta a que la fuente correcta para historico debe venir de la capa CRCON/scoreboard publico de los servidores de la comunidad, o de la fuente estructurada que alimenta dicho scoreboard.
## Goal Detail
Esta task NO debe implementar todavia la ingesta historica final ni endpoints de rankings. Su mision es descubrir con precision de donde salen los datos historicos, como se accede a ellos y cual es la estrategia tecnica mas estable para las siguientes tasks.
## Steps
1. Revisar el estado actual del proyecto para confirmar que la parte historica previa basada directamente en la pagina comunitaria no debe tomarse como base valida.
2. Analizar las dos fuentes reales de historico asociadas a los servidores de la comunidad:
- `https://scoreboard.comunidadhll.es/games`
- `https://scoreboard.comunidadhll.es:5443/games`
3. Investigar como cargan los datos esas paginas:
- peticiones XHR/fetch
- posibles endpoints JSON
- paginacion
- URLs de detalle de partida
- identificadores de match
- identificadores o claves de jugador
- filtros o parametros relevantes
4. Determinar si la fuente utilizable mas estable es:
- una API/JSON expuesta por el scoreboard
- una estructura HTML parseable
- otra capa accesible derivada de CRCON
5. Documentar que datos historicos parecen estar realmente disponibles y estables. Incluir al menos:
- servidor
- partida
- fecha/hora
- mapa
- jugador
- kills
- otras metricas relevantes si aparecen
6. Documentar riesgos y limites:
- cambios de HTML
- dependencia de endpoints privados o fragiles
- ausencia de ids estables
- paginacion o limites de historico
- datos historicos posiblemente incompletos
7. Proponer la estrategia recomendada para las siguientes fases, distinguiendo claramente entre:
- fuente historica ideal
- plan operativo inicial realista
- fallback si no existe API estructurada
8. Dejar explicito que NO debe hacerse:
- no basar la arquitectura historica en A2S
- no asumir como valida una implementacion previa ya revertida
- no disenar todavia la UI historica
9. Actualizar la documentacion tecnica del repositorio con el resultado del discovery.
10. Al completar la implementacion:
- 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/decisions.md
- docs/current-hll-servers-source-plan.md
- docs/frontend-backend-contract.md
- backend/README.md
- cualquier documentacion o codigo existente relacionado con historico, scoreboard o CRCON
- cualquier rastro de implementacion historica previa que haya quedado en el repositorio, solo para confirmar su descarte
## Expected Files to Modify
- ai/architecture-index.md
- docs/decisions.md
- opcionalmente backend/README.md si conviene reflejar el nuevo frente tecnico
- un nuevo documento tecnico, por ejemplo:
- `docs/historical-crcon-source-discovery.md`
## Constraints
- No implementar todavia ingesta historica completa.
- No implementar todavia endpoints de rankings.
- No implementar todavia UI historica.
- No basar la arquitectura historica en A2S.
- No dar por buena ninguna implementacion historica previa que ya haya sido revertida o descartada.
- No hacer cambios destructivos.
- Mantener el trabajo centrado en discovery tecnico y documentacion solida.
## Validation
- Existe documentacion clara sobre la fuente historica real de los 2 servidores.
- Queda claro si la fuente reutilizable es JSON/API, HTML parseable u otra capa.
- Quedan identificados los datos historicos realmente disponibles.
- Quedan documentados riesgos, limites y estrategia recomendada.
- No se ha implementado todavia ingesta o UI prematura.
- 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 lineas cambiadas.
## Outcome
- Se documento que ambas URLs de scoreboard sirven una SPA y que la fuente historica reutilizable real es JSON bajo `baseURL: "/api"`.
- Se verificaron y documentaron los endpoints historicos observados:
- `GET /api/get_public_info`
- `GET /api/get_scoreboard_maps?page={page}&limit={limit}`
- `GET /api/get_map_scoreboard?map_id={map_id}`
- Se confirmo que `get_scoreboard_maps` aporta listado paginado de partidas y que `get_map_scoreboard` aporta detalle de partida con `player_stats` y metricas como `kills`, `deaths`, `teamkills`, `kills_per_minute`, `weapons`, `team.side` y `level`.
- Se dejo documentado que el HTML de `/games` no debe ser la base tecnica de ingesta y que A2S sigue limitado al estado actual.
- Se dejo constancia de que un intento previo de historico semanal no es base valida porque `backend/app/payloads.py` referencia `.historical_storage` pero ese modulo ya no existe.
- Se actualizo `docs/decisions.md` y `ai/architecture-index.md` para alinear la arquitectura con esta discovery.
## Validation Result
- Ejecutado fuera del sandbox: inspeccion directa de `https://scoreboard.comunidadhll.es/games` y `https://scoreboard.comunidadhll.es:5443/games`.
- Resultado: ambas rutas devuelven la misma SPA shell con bundle `index-DvMfaBhO.js`.
- Ejecutado fuera del sandbox: extraccion del bundle frontend.
- Resultado: el helper HTTP usa `axios.create({ baseURL: "/api" })`.
- Ejecutado fuera del sandbox: `GET /api/get_public_info`, `GET /api/get_scoreboard_maps?page=1&limit=5` y `GET /api/get_map_scoreboard?map_id=...` en ambos scoreboards.
- Resultado: se confirmaron identificacion por servidor, paginacion, ids de partida y metricas historicas por jugador.
- Ejecutado localmente: revision de `backend/app/payloads.py` y busqueda de restos historicos con `rg`.
- Resultado: se detecto un rastro previo no reutilizable de `weekly_top_kills` apoyado en un modulo ausente.
## Decision Notes
- La siguiente fase debe ingerir primero el listado de partidas por scoreboard y despues el detalle por `map_id`, manteniendo separados los dos origenes de la comunidad.
- El plan operativo inicial debe persistir partidos y estadisticas por jugador en backend propio para calcular agregados semanales sin consultar el scoreboard en cada request.

View File

@@ -83,3 +83,19 @@ reutilizable para HLL actual y para futuras fuentes mas cercanas a HLL Vietnam.
El modelo base y las preguntas abiertas quedan documentados en
`docs/stats-database-schema-foundation.md`.
## Decision 012: historico de partidas desde CRCON scoreboard JSON
El historico reutilizable para estadisticas por partida y por jugador debe
salir de la capa JSON publica expuesta por los scoreboards CRCON de la
comunidad, no de A2S ni del HTML renderizado de `/games`.
La discovery tecnica confirma que ambos scoreboards sirven una SPA cuya fuente
real de datos usa `baseURL: "/api"` y endpoints como
`/get_scoreboard_maps` y `/get_map_scoreboard`. Esa capa permite obtener listas
de partidas, detalle por `map_id` y metricas por jugador suficientes para una
futura agregacion semanal por servidor.
A2S se mantiene como fuente de estado actual de servidores. El historico de
partidas y rankings debe construirse en una linea separada basada en CRCON. La
discovery detallada queda en `docs/historical-crcon-source-discovery.md`.

View File

@@ -0,0 +1,240 @@
# Historical CRCON Source Discovery
## Objective
Documentar la fuente historica real y mas estable para los 2 servidores de la comunidad a partir de sus scoreboards publicos basados en CRCON, dejando claro que el historico reutilizable debe venir de esa capa y no de A2S ni de una implementacion previa ya descartada.
## Discovery Date
- Verificado el 2026-03-20 contra:
- `https://scoreboard.comunidadhll.es/games`
- `https://scoreboard.comunidadhll.es:5443/games`
## Main Finding
La fuente historica reutilizable mas estable disponible hoy es una API JSON publica expuesta por cada scoreboard, no el HTML renderizado de `/games`.
Las dos URLs de historial cargan una SPA con el mismo bundle frontend. Ese bundle usa `axios` con `baseURL: "/api"` y consulta endpoints JSON concretos:
- `GET /api/get_public_info`
- `GET /api/get_live_scoreboard`
- `GET /api/get_live_game_stats`
- `GET /api/get_scoreboard_maps?page={page}&limit={limit}`
- `GET /api/get_map_scoreboard?map_id={map_id}`
Por tanto, la estrategia recomendada no es parsear HTML de `/games`, sino consumir la capa JSON que alimenta ese frontend.
## Server Mapping
Cada scoreboard representa un servidor distinto:
- `https://scoreboard.comunidadhll.es`
- `GET /api/get_public_info` identifica `#01 [ESP] Comunidad Hispana - discord.comunidadhll.es - Spa Onl`
- `public_stats_port`: `7010`
- `public_stats_port_https`: `7011`
- `https://scoreboard.comunidadhll.es:5443`
- `GET /api/get_public_info` identifica `#02 [ESP] Comunidad Hispana - discord.comunidadhll.es - Spa Onl`
- `public_stats_port`: `7012`
- `public_stats_port_https`: `7013`
## How Historical Data Is Loaded
### 1. History list
`GET /api/get_scoreboard_maps?page=1&limit=5`
Devuelve una lista paginada de partidas finalizadas con estructura JSON. Campos verificados:
- `page`
- `page_size`
- `total`
- `maps[]`
Cada item de `maps[]` incluye al menos:
- `id`
- `creation_time`
- `start`
- `end`
- `server_number`
- `map.id`
- `map.pretty_name`
- `map.image_name`
- `map.game_mode`
- `result.axis`
- `result.allied`
Observacion importante:
- `player_stats` aparece vacio en la lista. Para metricas de jugadores hay que ir al endpoint de detalle.
### 2. Match detail
`GET /api/get_map_scoreboard?map_id={map_id}`
Devuelve el detalle historico de una partida concreta. Ejemplos verificados:
- servidor `#01`: `map_id=1561077`
- servidor `#02`: `map_id=1561076`
Campos verificados a nivel de partida:
- `id`
- `creation_time`
- `start`
- `end`
- `server_number`
- `map_name`
- `map.pretty_name`
- `result.axis`
- `result.allied`
- `player_stats[]`
Campos verificados a nivel de jugador dentro de `player_stats[]`:
- `id`
- `player_id`
- `player`
- `steaminfo.id`
- `steaminfo.profile.steamid` cuando existe
- `map_id`
- `kills`
- `kills_by_type`
- `kills_streak`
- `deaths`
- `deaths_by_type`
- `teamkills`
- `time_seconds`
- `kills_per_minute`
- `deaths_per_minute`
- `kill_death_ratio`
- `longest_life_secs`
- `shortest_life_secs`
- `combat`
- `offense`
- `defense`
- `support`
- `most_killed`
- `death_by`
- `weapons`
- `death_by_weapons`
- `team.side`
- `level`
Esto confirma que el scoreboard ya expone la base necesaria para rankings semanales por servidor como "top kills", junto con otras metricas reutilizables.
## Detail URLs And IDs
- La UI publica usa rutas tipo `/games/{id}`.
- `GET https://scoreboard.comunidadhll.es/games/1561077` responde `200`.
- `GET https://scoreboard.comunidadhll.es:5443/games/1561076` responde `200`.
Inferencia razonable:
- `/games/{id}` es la URL publica de detalle de partida.
- el dato real se resuelve desde frontend llamando a `GET /api/get_map_scoreboard?map_id={id}`.
## Stable Historical Data Actually Available
A dia 2026-03-20, la capa JSON permite obtener de forma estable:
- servidor
- por host del scoreboard
- por `server_number`
- por `get_public_info.name`
- partida
- `id`
- `start`
- `end`
- `creation_time`
- mapa
- `map.id`
- `map.pretty_name`
- `game_mode`
- `environment`
- jugador
- `player_id`
- `player`
- `steaminfo` parcial cuando existe
- metricas
- `kills`
- `deaths`
- `teamkills`
- `kills_per_minute`
- `kill_death_ratio`
- `combat`
- `offense`
- `defense`
- `support`
- desglose por armas y tipos cuando aparece
## Pagination And Historical Depth
- La lista historica es paginada mediante `page` y `limit`.
- El bundle observado usa por defecto `page=1` y `limit=50`.
- En la verificacion:
- servidor `#01` reporto `total: 23027`
- servidor `#02` reporto `total: 18219`
Esto sugiere una profundidad historica amplia y apta para ingesta incremental paginada.
## Risks And Limits
- La fuente es publica, pero no hay contrato formal versionado publicado; sigue siendo una API no documentada externamente.
- El frontend depende de rutas `/api/...` observadas en el bundle actual `v11.9.0`; una actualizacion futura podria renombrarlas.
- `player_id` no parece homogeneo al 100%:
- a veces coincide con SteamID
- a veces aparece como hash o identificador alternativo
- `steaminfo` puede venir completo, parcial o `null`; no debe asumirse como obligatorio.
- Existen valores de calidad irregular en algunas partidas:
- `shortest_life_secs` negativos
- jugadores con tiempos atipicos
- campos vacios o `unknown`
- El HTML de `/games` no debe tomarse como base tecnica porque solo sirve la SPA shell y es mas fragil que consumir el JSON directo.
- A2S sigue siendo util para estado actual, no para reconstruir historico de partidas ni ranking semanal retroactivo.
## Recommended Strategy For Following Tasks
### Ideal historical source
Usar directamente la API JSON publica de cada scoreboard CRCON:
- listar partidas con `GET /api/get_scoreboard_maps`
- obtener detalle por partida con `GET /api/get_map_scoreboard`
### Realistic initial operating plan
1. Mantener separados los 2 orígenes:
- `https://scoreboard.comunidadhll.es/api`
- `https://scoreboard.comunidadhll.es:5443/api`
2. Registrar por servidor:
- host base del scoreboard
- nombre publico devuelto por `get_public_info`
- `server_number`
3. Ingerir paginas historicas de forma incremental.
4. Persistir una entidad de partida externa con `match_id = id`.
5. Persistir filas de estadistica por jugador asociadas a `match_id` y servidor.
6. Calcular agregados semanales desde esos datos persistidos, no consultando el scoreboard en cada request de frontend.
### Fallback if the JSON layer changes
- primer fallback: revalidar el bundle SPA para localizar las nuevas rutas `/api`
- segundo fallback: parsear HTML solo como ultimo recurso y solo si el JSON deja de ser accesible
## Explicitly Not Recommended
- No basar el historico en A2S.
- No reutilizar como base de arquitectura una implementacion historica previa ya descartada.
- No tomar el HTML de `/games` como fuente principal.
- No disenar todavia la UI historica final.
## Repository Impact
El repositorio ya tenia una pista correcta en la landing al enlazar ambos scoreboards, pero no existia documentacion tecnica del origen real de historico.
Tambien se detecto un rastro de implementacion previa no reutilizable:
- `backend/app/payloads.py` importa `.historical_storage` para un flujo de `weekly_top_kills`
- el archivo `backend/app/historical_storage.py` no existe
Ese estado confirma que cualquier intento previo de ranking historico no debe considerarse base valida para la siguiente fase. La nueva fase debe reconstruirse desde la fuente CRCON JSON documentada aqui.