snapshots

This commit is contained in:
devRaGonSa
2026-03-23 12:10:01 +01:00
parent ca4fe2bdd2
commit b33aef55ee
3 changed files with 72 additions and 16 deletions

View File

@@ -0,0 +1,57 @@
# TASK-044-historical-snapshots-api
## Goal
Exponer una API de snapshots históricos precalculados para que el frontend pueda consumir resumen, tops y partidas recientes sin disparar agregaciones costosas en tiempo real.
## Context
Con snapshots ya persistidos y generados periódicamente, el siguiente paso es exponer endpoints ligeros para que la UI histórica lea directamente datos preparados.
## Steps
1. Revisar la capa de snapshots ya creada y el runner de generación.
2. Diseñar endpoints claros para leer snapshots por servidor, tipo y métrica.
3. Cubrir como mínimo:
- resumen de servidor
- tops semanales por métrica
- partidas recientes
4. Asegurar que los endpoints devuelven también información útil de actualización:
- generated_at
- rango fuente
- stale/fresh si aplica
5. Mantener compatibilidad razonable con la UI histórica ya existente o dejar clara la migración.
6. Documentar los endpoints en backend.
7. No cambiar todavía toda la UI 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
- backend/README.md
- backend/app/routes.py
- backend/app/payloads.py
- backend/app/historical_snapshot_storage.py
- backend/app/historical_snapshots.py
## Expected Files to Modify
- backend/app/routes.py
- backend/app/payloads.py
- backend/README.md
- opcionalmente nuevos módulos de payload/query de snapshots
## Constraints
- No usar A2S para esta capa.
- No hacer cálculos pesados on-demand si ya existe snapshot válido.
- No crear UI nueva en esta task.
- No hacer cambios destructivos.
- Mantener el trabajo centrado en una API ligera de snapshots.
## Validation
- Existen endpoints de snapshots para resumen, tops y partidas recientes.
- Los payloads incluyen metadatos de actualización útiles.
- La capa está lista para que la UI deje de depender de agregados pesados en tiempo real.
- Los cambios quedan committeados y se hace push al remoto si el entorno lo permite.
## Change Budget
- Preferir menos de 5 archivos modificados o creados.
- Preferir menos de 220 líneas cambiadas.

View File

@@ -7,9 +7,9 @@ const SERVER_HISTORY_URLS = Object.freeze({
const COMMUNITY_CLANS = Object.freeze([ const COMMUNITY_CLANS = Object.freeze([
{ {
name: "LCM", name: "LCM",
badge: "Comunidad aliada", badge: "Clan CH",
description: description:
"Clan visible dentro de la red comunitaria hispana con acceso confirmado a Discord.", "Clan activo de la comunidad, con acceso directo a su discord.",
logoSrc: "./assets/img/clans/lcm.png", logoSrc: "./assets/img/clans/lcm.png",
logoAlt: "Logo de LCM", logoAlt: "Logo de LCM",
logoClassName: "", logoClassName: "",
@@ -18,9 +18,9 @@ const COMMUNITY_CLANS = Object.freeze([
}, },
{ {
name: "La 129", name: "La 129",
badge: "Discord pendiente", badge: "Clan CH",
description: description:
"Presencia confirmada para la seccion comunitaria mientras se publica su acceso definitivo.", "Clan activo de la comunidad, con acceso directo a su discord.",
logoSrc: "./assets/img/clans/la129.png", logoSrc: "./assets/img/clans/la129.png",
logoAlt: "Logo de La 129", logoAlt: "Logo de La 129",
logoClassName: "clan-card__logo--wide", logoClassName: "clan-card__logo--wide",
@@ -29,9 +29,9 @@ const COMMUNITY_CLANS = Object.freeze([
}, },
{ {
name: "250 Hispania", name: "250 Hispania",
badge: "Comunidad aliada", badge: "Clan CH",
description: description:
"Entrada mostrada con su emblema principal y acceso confirmado al Discord compartido.", "Clan activo de la comunidad, con acceso directo a su discord.",
logoSrc: "./assets/img/clans/250hispania-shield.png", logoSrc: "./assets/img/clans/250hispania-shield.png",
logoAlt: "Escudo de 250 Hispania", logoAlt: "Escudo de 250 Hispania",
logoClassName: "clan-card__logo--shield", logoClassName: "clan-card__logo--shield",
@@ -40,9 +40,9 @@ const COMMUNITY_CLANS = Object.freeze([
}, },
{ {
name: "H9H", name: "H9H",
badge: "Logo pendiente", badge: "Clan CH",
description: description:
"Comunidad incluida en la rotacion mientras se incorpora su identidad visual final.", "Clan activo de la comunidad, con acceso directo a su discord.",
logoSrc: "", logoSrc: "",
logoAlt: "", logoAlt: "",
logoClassName: "", logoClassName: "",
@@ -52,9 +52,9 @@ const COMMUNITY_CLANS = Object.freeze([
}, },
{ {
name: "BxB", name: "BxB",
badge: "Discord pendiente", badge: "Clan CH",
description: description:
"Clan incorporado a la red visible con su emblema actual y enlace aun por confirmar.", "Clan activo de la comunidad, son raretes.",
logoSrc: "./assets/img/clans/bxb.png", logoSrc: "./assets/img/clans/bxb.png",
logoAlt: "Logo de BxB", logoAlt: "Logo de BxB",
logoClassName: "", logoClassName: "",
@@ -63,9 +63,9 @@ const COMMUNITY_CLANS = Object.freeze([
}, },
{ {
name: "7dv", name: "7dv",
badge: "Comunidad aliada", badge: "Clan CH",
description: description:
"Entrada activa dentro de la seccion con acceso disponible a su Discord comunitario.", "Clan activo de la comunidad, con acceso directo a su discord.",
logoSrc: "./assets/img/clans/7dv.png", logoSrc: "./assets/img/clans/7dv.png",
logoAlt: "Logo de 7dv", logoAlt: "Logo de 7dv",
logoClassName: "", logoClassName: "",

View File

@@ -168,12 +168,11 @@
<section class="panel panel--clans" aria-labelledby="clans-title"> <section class="panel panel--clans" aria-labelledby="clans-title">
<div class="panel__shell"> <div class="panel__shell">
<div class="panel__header"> <div class="panel__header">
<p class="eyebrow eyebrow--section">Clanes y comunidades</p> <p class="eyebrow eyebrow--section">Clanes de la comunidad</p>
<h2 id="clans-title">Red de comunidad</h2> <h2 id="clans-title">Grupo de la comunidad</h2>
</div> </div>
<p class="panel__intro"> <p class="panel__intro">
Clanes y comunidades activas de la escena hispana con presencia Clanes activos de la escena hispana con presencia confirmada.
confirmada o en preparacion para esta red compartida.
</p> </p>
<div class="clans-grid" id="community-clans-list"></div> <div class="clans-grid" id="community-clans-list"></div>
</div> </div>