Fix
This commit is contained in:
242
docs/decisions.md
Normal file
242
docs/decisions.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Technical Decisions
|
||||
|
||||
## Decision 001: frontend simple HTML/CSS/JS
|
||||
|
||||
Se adopta una base estatica con HTML, CSS y JavaScript puro para priorizar simplicidad, velocidad de arranque y compatibilidad total al abrir el frontend directamente en navegador.
|
||||
|
||||
## Decision 002: backend previsto en Python
|
||||
|
||||
La estructura del repositorio reserva desde el inicio una carpeta de backend porque la implementacion futura se realizara en Python.
|
||||
|
||||
## Decision 003: estructura preparada para orquestacion por agentes
|
||||
|
||||
Se incluye una carpeta `ai/` y un documento `AGENTS.md` para facilitar una futura organizacion del trabajo por roles, tareas y orquestacion.
|
||||
|
||||
## Decision 004: branding militar Vietnam
|
||||
|
||||
La direccion visual inicial se alinea con una estetica sobria, tactica y militar inspirada en el contexto Vietnam para mantener coherencia tematica desde la primera iteracion.
|
||||
|
||||
## Decision 005: AI Development Platform integrada de forma adaptada
|
||||
|
||||
Se integra una capa de orquestacion por tasks inspirada en la plantilla de AI Development Platform, pero adaptada al contexto real de HLL Vietnam y sin arrastrar supuestos genericos de otros stacks. La plataforma se usa como soporte operativo del repositorio, no como funcionalidad del producto.
|
||||
|
||||
## Decision 006: contrato API pequeno antes de integraciones reales
|
||||
|
||||
Antes de implementar endpoints de comunidad o integraciones externas, se fija un contrato JSON minimo entre frontend y backend para evitar que la landing y el backend evolucionen con supuestos incompatibles.
|
||||
|
||||
La unica ruta implementada hoy es `GET /health`. Las rutas `/api/community`, `/api/trailer`, `/api/discord` y `/api/servers` quedan definidas como contrato previsto o placeholder en `docs/frontend-backend-contract.md`, manteniendo el backend en Python y sin introducir todavia Discord real, servidores reales ni base de datos.
|
||||
|
||||
## Decision 007: estrategia por fases para Discord y servidores
|
||||
|
||||
Los datos de Discord y de servidores de juego se incorporaran por fases para evitar dependencias prematuras de credenciales, APIs externas o consultas de red todavia no validadas.
|
||||
|
||||
La fase inicial debe usar datos manuales o placeholder controlados por el backend para mantener estable el contrato del frontend. Una fase intermedia podra anadir una integracion limitada con fuentes publicas o consultas tecnicas de bajo riesgo. Solo una fase posterior evaluara integraciones mas reales, siempre que queden claras las restricciones de seguridad, disponibilidad, latencia y mantenimiento.
|
||||
|
||||
La estrategia detallada de bloques de datos, fuentes posibles, riesgos y orden recomendado de implementacion queda documentada en `docs/discord-and-server-data-plan.md`.
|
||||
|
||||
## Decision 008: consumo frontend progresivo con fallback estatico
|
||||
|
||||
El frontend no debe depender de datos dinamicos para renderizar la landing base mientras el proyecto siga en fase fundacional.
|
||||
|
||||
Cuando se incorporen endpoints del backend, el consumo debe hacerse con `fetch` y JavaScript simple, priorizando bloques independientes y manteniendo contenido estatico o placeholders visuales si falla una llamada. `GET /health` queda reservado para comprobaciones tecnicas y no debe bloquear el render principal.
|
||||
|
||||
La estrategia detallada de prioridades de endpoints, estados de carga, errores y orden de migracion queda en `docs/frontend-data-consumption-plan.md`.
|
||||
|
||||
## Decision 009: servidores actuales de HLL como referencia provisional
|
||||
|
||||
Mientras no existan datos reales o representativos de HLL Vietnam, la web puede
|
||||
mostrar un bloque provisional con servidores actuales de Hell Let Loose siempre
|
||||
que quede claramente etiquetado como referencia temporal.
|
||||
|
||||
La primera version de ese bloque debe salir de un payload controlado del backend
|
||||
Python, no de una integracion directa desde frontend ni de scraping prematuro.
|
||||
Esto permite fijar campos utiles, preservar el tono del producto y evitar que la
|
||||
landing dependa de una fuente externa aun no validada.
|
||||
|
||||
La estrategia de campos, riesgos, fases y sustitucion futura queda documentada
|
||||
en `docs/current-hll-servers-source-plan.md`.
|
||||
|
||||
## Decision 010: ingesta por snapshots y adaptadores desacoplados
|
||||
|
||||
La evolucion desde payloads placeholder hacia datos mas realistas debe hacerse
|
||||
con una arquitectura de snapshots de servidor, no conectando el frontend a una
|
||||
fuente externa ni acoplando el backend a una integracion unica desde el inicio.
|
||||
|
||||
La unidad tecnica base sera un snapshot con `captured_at` y campos normalizados
|
||||
como estado, jugadores, capacidad y mapa actual cuando exista. La lectura de
|
||||
fuente, la normalizacion y la produccion del snapshot deben quedar separadas
|
||||
para poder sustituir mocks por una fuente publica o consulta tecnica posterior
|
||||
sin romper el contrato interno.
|
||||
|
||||
La estrategia detallada de fuentes, riesgos, fases y limites queda documentada
|
||||
en `docs/current-hll-data-ingestion-plan.md`.
|
||||
|
||||
## Decision 011: modelo de almacenamiento logico antes de fijar tecnologia
|
||||
|
||||
Antes de introducir una base de datos concreta, el proyecto debe fijar un
|
||||
modelo logico minimo para identidad de servidores y snapshots historicos.
|
||||
|
||||
La base inicial se apoya en entidades genericas como `game_sources`, `servers`
|
||||
y `server_snapshots`. Las metricas iniciales deben derivarse primero de esos
|
||||
snapshots en vez de materializar agregados prematuros. Esto mantiene el diseno
|
||||
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`.
|
||||
|
||||
## Decision 013: persistencia historica local separada del flujo live
|
||||
|
||||
El backend mantiene el estado live de servidores y el historico CRCON en el
|
||||
mismo SQLite local de desarrollo para no introducir infraestructura prematura,
|
||||
pero ambas lineas quedan separadas por tablas y contratos distintos.
|
||||
|
||||
El flujo live sigue usando `server_snapshots` via A2S. El flujo historico usa
|
||||
tablas `historical_*` para:
|
||||
|
||||
- servidores historicos configurados
|
||||
- partidas
|
||||
- mapas
|
||||
- jugadores
|
||||
- estadisticas por jugador y partida
|
||||
- ejecuciones de ingesta
|
||||
|
||||
Las claves estables son:
|
||||
|
||||
- servidor: `historical_servers.slug`
|
||||
- partida: `(historical_server_id, external_match_id)`
|
||||
- jugador: `stable_player_key`
|
||||
- estadistica por partida: `(historical_match_id, historical_player_id)`
|
||||
|
||||
Esto permite bootstrap, refresco incremental e idempotencia sin mezclar
|
||||
semanticas de estado actual con historico persistido. El modelo detallado queda
|
||||
en `docs/historical-domain-model.md`.
|
||||
|
||||
## Decision 014: despliegue normal simplificado sin servidor #03
|
||||
|
||||
El despliegue operativo normal vuelve a quedar reducido a `backend` +
|
||||
`frontend`. Los servicios `historical-runner` y `rcon-historical-worker` se
|
||||
mantienen disponibles solo para uso avanzado y explicito mediante el perfil
|
||||
Compose `advanced`.
|
||||
|
||||
Comunidad Hispana #03 deja de formar parte de los targets RCON por defecto
|
||||
porque ya no es una fuente operativa vigente. El codigo historico, los datos
|
||||
persistidos, las migraciones y las piezas Elo/MMR no se eliminan; quedan
|
||||
pausadas operativamente para esta fase y pueden reintroducirse mediante una
|
||||
task futura si se valida de nuevo la fuente y el coste de mantenimiento.
|
||||
|
||||
## Decision 015: historico RCON-first con fallback publico
|
||||
|
||||
La politica por defecto para historico vuelve a ser RCON-first:
|
||||
`HLL_BACKEND_HISTORICAL_DATA_SOURCE=rcon`. El scoreboard publico de CRCON se
|
||||
mantiene como fallback controlado cuando RCON falla, no tiene cobertura util o
|
||||
no soporta todavia una operacion competitiva concreta.
|
||||
|
||||
La arquitectura historica RCON-first se compone de captura de sesiones RCON,
|
||||
ingesta de AdminLog, parser de eventos, almacenamiento de eventos/snapshots y
|
||||
materializacion de partidas y estadisticas por jugador. Los snapshots de perfil
|
||||
procedentes de `MESSAGE` enriquecen lecturas de jugador, pero no sustituyen los
|
||||
hechos de partida derivados de eventos RCON.
|
||||
|
||||
Comandos operativos manuales:
|
||||
|
||||
```powershell
|
||||
docker compose exec backend python -m app.rcon_admin_log_ingestion --minutes 1440
|
||||
docker compose exec backend python -m app.rcon_historical_worker capture
|
||||
```
|
||||
|
||||
Esta decision no reactiva Elo/MMR dentro del arranque normal del backend. Las
|
||||
piezas Elo/MMR, migraciones, datos persistidos y modulos historicos se
|
||||
conservan, pero su operativa compleja sigue pausada y desacoplada salvo task
|
||||
explicita.
|
||||
|
||||
## Decision 016: catalogo confiable de scoreboards publicos activos
|
||||
|
||||
Los origenes publicos de scoreboard que el backend puede exponer o validar se
|
||||
centralizan en un catalogo explicito de servidores activos. En esta fase solo
|
||||
son confiables `comunidad-hispana-01`, con origen
|
||||
`https://scoreboard.comunidadhll.es`, y `comunidad-hispana-02`, con origen
|
||||
`https://scoreboard.comunidadhll.es:5443`.
|
||||
|
||||
`comunidad-hispana-03` no forma parte de ese catalogo ni de los seeds por
|
||||
defecto nuevos. Los datos historicos ya persistidos no se eliminan, pero las
|
||||
URLs publicas de partidas solo se aceptan si el `raw_payload_ref` usa HTTP(S),
|
||||
apunta al origen confiable del servidor activo y mantiene una ruta `/games/`.
|
||||
|
||||
## Decision 017: PostgreSQL phase 1 for RCON historical persistence
|
||||
|
||||
La primera migracion de persistencia a PostgreSQL cubre el camino que sufria
|
||||
contencion SQLite entre `backend`, `historical-runner` y
|
||||
`rcon-historical-worker`:
|
||||
|
||||
- captura prospectiva RCON, muestras y ventanas competitivas
|
||||
- eventos AdminLog deduplicados y snapshots de perfil derivados
|
||||
- partidas RCON materializadas y estadisticas por jugador
|
||||
- candidatos confiables de URL de scoreboard que puedan poblarse para
|
||||
correlacion de detalle
|
||||
|
||||
Docker Compose configura `HLL_BACKEND_DATABASE_URL` y usa PostgreSQL como
|
||||
backend autoritativo para esas tablas. La ejecucion local sin esa variable sigue
|
||||
usando SQLite como fallback temporal para preservar comandos y tests locales.
|
||||
|
||||
Quedan SQLite-backed en esta fase porque no forman parte del lock-prone writer
|
||||
path migrado y siguen cubriendo fallback publico o caches locales:
|
||||
|
||||
- snapshots live y cache de `/api/servers`
|
||||
- tablas `historical_*` de scoreboard publico, rankings y correlacion legacy
|
||||
- snapshots historicos precalculados, ledger player-event y Elo/MMR pausado
|
||||
|
||||
La correlacion de URL publica en detalle usa primero candidatos PostgreSQL
|
||||
confiables cuando existan y puede seguir leyendo filas `historical_*`
|
||||
persistidas en SQLite durante la transicion. El diagnostico operativo se expone
|
||||
con `python -m app.storage_diagnostics`.
|
||||
|
||||
## Decision 018: PostgreSQL phase 2 for displayed historical data
|
||||
|
||||
PostgreSQL pasa a ser la fuente de lectura para los datos historicos visibles:
|
||||
|
||||
- fallback publico `historical_*` de partidas, detalle y rankings
|
||||
- snapshots historicos precalculados que consume `historico.html`
|
||||
- cache live de servidores que consume `/api/servers`
|
||||
- ledger player-event usado para reconstruir snapshots visibles
|
||||
- tablas RCON de AdminLog, perfiles, ventanas, partidas materializadas,
|
||||
estadisticas y candidatos seguros ya migradas en phase 1
|
||||
|
||||
La migracion se ejecuta de forma idempotente con:
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
python -m app.sqlite_to_postgres_migration
|
||||
python -m app.storage_diagnostics
|
||||
```
|
||||
|
||||
El comando conserva IDs y `external_match_id` del scoreboard publico, claves
|
||||
`match_key` materializadas y URLs seguras existentes. Copia SQLite y los JSON
|
||||
historicos de `backend/data/snapshots` como fuentes legacy; no los vuelve a
|
||||
usar como read model visible cuando `HLL_BACKEND_DATABASE_URL` esta definido.
|
||||
Las filas legacy de `comunidad-hispana-03` se omiten en el read model visible
|
||||
de esta migracion para no reactivar ese target.
|
||||
|
||||
Permanecen fuera de phase 2:
|
||||
|
||||
- checkpoints y runs operativos del import publico que no aparecen en frontend
|
||||
- Elo/MMR pausado y oculto en la UI actual
|
||||
|
||||
`app.storage_diagnostics` muestra conteos PostgreSQL, ultimas partidas
|
||||
materializadas, ultimos `match_end`, dominios restantes y un resumen de paridad
|
||||
para verificar la migracion antes de retirar fuentes legacy.
|
||||
Reference in New Issue
Block a user