67 KiB
Full Application Request Audit
Fecha: 2026-06-10
Task: TASK-224-full-application-request-audit
Alcance: auditoria de peticiones publicas frontend/backend/API sin aplicar fixes funcionales.
Resumen ejecutivo
La auditoria encontro 36 patrones HTTP publicos en backend/app/routes.py, 12 ocurrencias fetch( en JavaScript publico, 15 literales /api/... en frontend y 13 referencias localhost/127.0.0.1 en HTML/JS publico. No se encontro XMLHttpRequest.
Se ejecuto la auditoria contra https://comunidadhll.devzamode.es con 191 probes automaticos y 4 probes manuales dependientes de player_id. Resultado combinado:
| Severidad | Cantidad |
|---|---|
| OK | 77 |
| WARNING | 112 |
| CRITICAL | 6 |
Los fallos criticos actuales no estan en rankings/snapshots ni en el match detail historico probado. Estan en:
/api/stats/players/search?q=Medu&server_id=all&limit=10: timeout a 30s./api/stats/players/{player_id}?timeframe=weekly|monthly&server_id=all: timeout a 30s./api/current-match/kills?server=comunidad-hispana-01&limit=30: timeout a 30s./api/current-match/players?server=comunidad-hispana-01: timeout a 30s./api/current-match/kills?server=comunidad-hispana-02&limit=30: 500 en una ejecucion y timeout en una repeticion manual.
/api/historical/matches/detail con el match real comunidad-hispana-01:1781023156:1781028555:purpleheartlanewarfare respondio 200 en 120.47 ms y 125580 B. Sigue teniendo deuda de inicializacion en lectura en la cadena estatica, pero ya no es el endpoint publico mas critico segun la medicion de produccion de esta auditoria.
Siguiente fix prioritario recomendado: aislar o eliminar inicializacion/fallback runtime de /api/stats/players/search y /api/stats/players/{player_id}. Despues, corregir /api/current-match/kills y /api/current-match/players. /api/historical/matches/detail debe quedar en cola de hardening para hacerlo estrictamente read-only, pero no aparece como el primer incendio operativo en esta medicion.
Estado post-fix TASK-225
Fecha: 2026-06-10
Alcance aplicado: Fase 1, estabilizacion de lecturas publicas no dependientes de RCON live.
Cambios de codigo aplicados:
/api/stats/players/search: el builder sigue llamando al mismo helper, perosearch_rcon_materialized_players()ahora es lectura estricta deplayer_search_index. Ya no inicializaplayer_search_indexni cae a busqueda runtime sobrercon_match_player_statsdurante un GET publico. Si el read model no existe o esta vacio, devuelveitems: [],source.read_model: player-search-index,source.status: unavailable,fallback_used: false./api/stats/players/{player_id}semanal/mensual:get_rcon_materialized_player_stats()usaplayer_period_statscomo read model publico. Si falta el read model o el jugador no esta en el periodo, devuelve una respuesta controlada con contadores a cero,source.read_model: player-period-stats,source.status: unavailable,fallback_used: false. El modotimeframe=allconserva el camino runtime interno existente./api/historical/matches/detail:get_materialized_rcon_match_detail()aceptaensure_storage=Falsepor defecto y la ruta publica lo usa en modo read-only. PostgreSQL puede abrirse sininitialize_postgres_rcon_storage()y SQLite se abre enmode=ro. Si falta la tabla/read model, la lectura devuelveNoney el payload publico RCON respondefound: false,fallback_used: false, sin fallback legacy pesado ni inicializacion.scripts/audit_public_requests.py: se anadieron--filtery--player-idpara medir subconjuntos afectados sin lanzar toda la matriz.
Validacion local de codigo:
python -m compileall backend\app
python -m py_compile scripts\audit_public_requests.py
cd backend
python -m unittest tests.test_rcon_materialization_pipeline
python -m unittest tests.test_current_match_payload tests.test_rcon_admin_log_storage tests.test_historical_snapshot_refresh
Resultado:
compileall: OK.py_compile: OK.tests.test_rcon_materialization_pipeline: OK, 12 tests. La suite mantieneResourceWarningSQLite ya presentes en tests existentes.- Tests relacionados de current match, admin log storage y historical snapshot refresh: OK, 13 tests.
Medicion HTTP local:
http://127.0.0.1:8000/healthno estaba disponible desde el host.- Las ejecuciones parciales del script contra
http://127.0.0.1:8000seleccionaron los probes esperados, pero fallaron por falta de backend local. No miden rendimiento del cambio.
Comandos de medicion recomendados tras redeploy:
python scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter stats-player-search --output tmp\task225_prod_player_search_audit.json
python scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --player-id 76561198092154180 --filter stats-player-profile --output tmp\task225_prod_player_profile_audit.json
python scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter historical-match-detail --output tmp\task225_prod_match_detail_audit.json
Estado de severidad esperado tras deploy:
| Endpoint | Severidad TASK-224 | Estado TASK-225 en codigo | Severidad esperada tras deploy |
|---|---|---|---|
/api/stats/players/search |
CRITICAL | Sin initialize ni fallback runtime pesado en GET publico | OK o WARNING si falta read model |
/api/stats/players/{player_id} weekly/monthly |
CRITICAL | Sin initialize ni recalculo runtime pesado en GET publico | OK o WARNING si falta read model |
/api/historical/matches/detail |
WARNING por deuda estatica | Read-only sin initialize_*; sin fallback legacy en modo RCON |
OK o WARNING si falta read model |
/api/current-match/kills |
CRITICAL | No abordado en Fase 1 | CRITICAL pendiente |
/api/current-match/players |
CRITICAL | No abordado en Fase 1 | CRITICAL pendiente |
/api/servers |
WARNING | No abordado en Fase 1 | WARNING pendiente |
Siguiente fix prioritario actualizado: Fase 2 de TASK-225 en task separada o continuacion autorizada, centrada en hardening de /api/current-match/kills y /api/current-match/players sin cambiar configuracion RCON. La validacion final debe repetirse en el entorno donde RCON este local.
Estado post-fix TASK-226
Fecha: 2026-06-10
Alcance aplicado: hardening de endpoints publicos RCON/live pendientes, sin cambiar hosts, puertos, 27001, variables de entorno ni configuracion de servidores.
Cambios de codigo aplicados:
/api/current-match/kills: el payload usa AdminLog en modo lectura publica sin inicializar storage (ensure_storage=False). Si falta el read model, hay timeout o falla la lectura, devuelvestatus: ok,items: [],confidence: unavailable,fallback_used: trueyfallback_reasoncontrolado (admin-log-read-model-unavailable,admin-log-read-timeoutoadmin-log-read-failed)./api/current-match/players: aplica el mismo patron de degradacion controlada sobre player stats de AdminLog. Una excepcion de storage ya no se propaga como 500 sin cuerpo./api/servers: el builder publico deja de llamar_try_collect_real_time_snapshot()y no refresca RCON/A2S en cada GET publico. Sirve snapshots persistidos, marcafreshness/is_staley exponerefresh_status: "cache-only".
Estado de severidad esperado tras deploy:
| Endpoint | Severidad TASK-224 | Estado TASK-226 en codigo | Severidad esperada tras deploy |
|---|---|---|---|
/api/current-match/kills |
CRITICAL | Read-only AdminLog, degradacion JSON controlada | OK o WARNING si falta read model |
/api/current-match/players |
CRITICAL | Read-only AdminLog, degradacion JSON controlada | OK o WARNING si falta read model |
/api/servers |
WARNING | Snapshot/cache-only; sin refresh RCON live en request publica | OK o WARNING si snapshot stale |
Notas:
/api/current-matchconserva deuda separada porque todavia puede intentar muestra RCON directa antes de caer a snapshot.- La frescura de
/api/serversdepende ahora del proceso/runner que mantenga snapshots calientes fuera del request publico. - Auditoria parcial contra produccion ejecutada el 2026-06-10 antes de desplegar este codigo:
current-matchtodavia mostro los timeouts/500 previos y/api/serversmidio 4249.71 ms. Repetir tras deploy para confirmar los tiempos post-fix reales.
Estado post-fix TASK-227
Fecha: 2026-06-10
Alcance aplicado: correccion especifica de /api/current-match/kills y /api/current-match/players despues de que la auditoria real post-TASK-226 siguiera mostrando timeouts de 26-30 s en esos endpoints.
Causa confirmada:
- Los payloads ya llamaban
list_current_match_kill_feed(..., ensure_storage=False)ylist_current_match_player_stats(..., ensure_storage=False). - En la rama SQLite eso abria el storage en modo lectura.
- En la rama PostgreSQL,
backend/app/rcon_admin_log_storage.pyllamabaconnect_postgres_compat()sin pasar el flag. connect_postgres_compat()usainitialize=Truepor defecto, por lo que kills/players seguian ejecutandoinitialize_postgres_rcon_storage()en el GET publico.
Cambios de codigo aplicados:
/api/current-match/kills: la lectura PostgreSQL de AdminLog ahora propagainitialize=ensure_storage; conensure_storage=Falseno ejecuta bootstrap/DDL./api/current-match/players: aplica el mismo fix para el resumen de jugadores.- Tests de regresion verifican que ambos caminos PostgreSQL publicos llaman
connect_postgres_compat(initialize=False).
Diferencia con /api/current-match general:
/api/current-matchusa_query_current_match_rcon_sample()y fallback a snapshot de servidores; no pasa por el read model AdminLog de kills/players.- Kills/players son vistas derivadas de AdminLog y el problema estaba en la inicializacion PostgreSQL de esa capa, no en host/puerto RCON.
Estado esperado tras redeploy:
| Endpoint | Estado TASK-227 en codigo | Severidad esperada tras deploy |
|---|---|---|
/api/current-match/kills |
PostgreSQL read-only real; sin initialize_postgres_rcon_storage() en GET publico |
OK o WARNING si falta read model |
/api/current-match/players |
PostgreSQL read-only real; sin initialize_postgres_rcon_storage() en GET publico |
OK o WARNING si falta read model |
Comando de validacion de produccion tras redeploy:
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter current-match --output tmp\task227_current_match_audit_after.json
Estado post-fix TASK-228
Fecha: 2026-06-10
Alcance aplicado: restauracion de /api/servers como endpoint near-real-time controlado para la home.
Causa confirmada:
TASK-226hizo que/api/serversdejara de llamar_try_collect_real_time_snapshot().- La ruta quedo en modo
cache-only, conrefresh_attempted: falseyrefresh_status: cache-only. - Cuando no existian snapshots persistidos, respondia rapido pero con
source: no-snapshot-availableeitems: [], aunque la fuente live pudiera estar disponible en produccion.
Cambios de codigo aplicados:
/api/serversvuelve a usar la politica live/casi-live:- sirve snapshot fresco si existe.
- intenta refresh live si no hay snapshot o el snapshot esta stale.
- devuelve live RCON/A2S si hay items.
- cae a snapshot stale si live falla y existe ultimo estado conocido.
- devuelve JSON controlado con error/fallback si live falla y no hay snapshot.
- El refresh publico usa timeout corto interno (
2.5s) propagado a RCON/A2S sin cambiar variables de entorno, hosts, puertos ni configuracion de servidores. - No se persiste desde el GET publico para evitar inicializaciones/DDL pesadas en lectura.
Estado esperado tras redeploy:
| Endpoint | Estado TASK-228 en codigo | Severidad esperada tras deploy |
|---|---|---|
/api/servers |
Near-real-time controlado; live si cache falta/stale, stale fallback si live falla | OK o WARNING si live no disponible |
/api/servers/latest |
Sigue leyendo almacenamiento local | OK o WARNING si no hay snapshots persistidos |
/api/servers/history |
Sigue leyendo almacenamiento local | OK o WARNING si no hay snapshots persistidos |
Comando de validacion de produccion tras redeploy:
$base = "https://comunidadhll.devzamode.es"
Invoke-WebRequest "$base/api/servers" |
Select-Object -ExpandProperty Content
Invoke-WebRequest "$base/api/servers/latest" |
Select-Object -ExpandProperty Content
Invoke-WebRequest "$base/api/servers/history" |
Select-Object -ExpandProperty Content
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter servers --output tmp\task228_servers_audit_after.json
Estado post-fix TASK-229
Fecha: 2026-06-10
Alcance aplicado: endpoints historicos legacy agregados que seguian agotando timeout tras TASK-228.
URLs afectadas:
GET /api/historical/server-summary?server=all-serversGET /api/historical/recent-matches?server=all-servers&limit=20
Causa confirmada:
scripts/audit_public_requests.pyetiqueta esas rutas comohistorical-server-summary-all-serversyhistorical-recent-matches-all-servers.backend/app/routes.pylas mapea abuild_historical_server_summary_payload()ybuild_recent_historical_matches_payload().- Antes del fix, esos builders legacy intentaban read model RCON y, si no habia cobertura suficiente, caian a storage CRCON/PostgreSQL legacy.
- Para
server=all-servers, el fallback ejecutaba agregaciones globales o inicializacion de display storage en lectura publica. En produccion esa cadena agotaba el timeout de 30 s. - Los endpoints snapshot equivalentes ya respondian rapido porque solo leen snapshots precomputados.
Cambios aplicados:
build_historical_server_summary_payload(server_slug="all-servers")delega enbuild_historical_server_summary_snapshot_payload().build_recent_historical_matches_payload(server_slug="all-servers")delega enbuild_recent_historical_matches_snapshot_payload().- Ambos mantienen
contextlegacy yitems, pero declaransource: historical-precomputed-snapshotsylegacy_endpoint_policy: snapshot-read-only-fast-path. - Si falta snapshot, la respuesta sigue siendo JSON controlado y rapido, sin RCON live, sin fallback runtime pesado y sin
initialize_*de storage historico desde estos paths agregados.
Estado esperado tras redeploy:
| Endpoint | Estado TASK-229 en codigo | Severidad esperada tras deploy |
|---|---|---|
/api/historical/server-summary?server=all-servers |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin timeout |
/api/historical/recent-matches?server=all-servers&limit=20 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin timeout |
/api/historical/snapshots/server-summary?server=all-servers |
Snapshot read-only | OK o WARNING si snapshot missing |
/api/historical/snapshots/recent-matches?server=all-servers&limit=100 |
Snapshot read-only | OK o WARNING si snapshot missing |
Comando de validacion de produccion tras redeploy:
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter servers --output tmp\task229_servers_recheck_after.json
Estado post-fix TASK-230
Fecha: 2026-06-10
Alcance aplicado: ultimo CRITICAL de la auditoria global posterior a TASK-229.
URL afectada:
GET /api/historical/server-summary?server=comunidad-hispana-01
Evidencia de produccion previa al fix:
- Probe:
historical-server-summary-comunidad-hispana-01. - HTTP 200.
10120.89 ms.fallback=False.historical-server-summary-comunidad-hispana-02respondia en139.37 ms.- El snapshot equivalente de CH01 respondia en
42.14 ms.
Causa confirmada:
scripts/audit_public_requests.pyetiqueta la ruta comohistorical-server-summary-comunidad-hispana-01.backend/app/routes.pyla mapea abuild_historical_server_summary_payload(server_slug="comunidad-hispana-01").- Tras
TASK-229, soloserver=all-serverstenia snapshot fast-path. - CH01 y CH02 seguian entrando en
get_rcon_historical_read_model().list_server_summaries(...). - El read model RCON construye cada resumen con
_build_server_summary(), que llama alist_rcon_historical_recent_activity(server_key=..., limit=1)para enriquecer actividad reciente. - Esa lectura intenta materialized RCON/AdminLog (
list_materialized_rcon_matches) antes del fallback de ventanas. En CH01 ese camino fue lento aunque exitoso (fallback=False); CH02 uso el mismo flujo pero con coste bajo.
Cambios aplicados:
build_historical_server_summary_payload()usa snapshot fast-path para cualquierserver_slugexplicito.- CH01, CH02 y
all-serversquedan como wrappers legacy sobrebuild_historical_server_summary_snapshot_payload(). - El contrato conserva
context: historical-server-summary,items,summary_basis,weekly_ranking_window_daysylegacy_endpoint_policy: snapshot-read-only-fast-path. - Si falta snapshot, responde JSON controlado con
items: [], sin RCON live, sin scoreboard externo, sininitialize_*y sin fallback runtime pesado.
Estado esperado tras redeploy:
| Endpoint | Estado TASK-230 en codigo | Severidad esperada tras deploy |
|---|---|---|
/api/historical/server-summary?server=comunidad-hispana-01 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin timeout |
/api/historical/server-summary?server=comunidad-hispana-02 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin empeorar |
/api/historical/server-summary?server=all-servers |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin empeorar |
Comando de validacion de produccion tras redeploy:
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --output tmp\full_audit_after_task230.json
Estado post-fix TASK-231
Fecha: 2026-06-10
Alcance aplicado: dos CRITICAL restantes de recent-matches legacy por servidor tras TASK-230.
URLs afectadas:
GET /api/historical/recent-matches?server=comunidad-hispana-01&limit=20GET /api/historical/recent-matches?server=comunidad-hispana-02&limit=20
Evidencia de produccion previa al fix:
historical-recent-matches-comunidad-hispana-01: timeout30032.24 ms.historical-recent-matches-comunidad-hispana-02: timeout30027.15 ms.snapshot-recent-matches-comunidad-hispana-01:77.50 ms, OK.snapshot-recent-matches-comunidad-hispana-02:51.11 ms, OK.historical-recent-matches-all-servers:50.66 ms, OK.
Causa confirmada:
scripts/audit_public_requests.pyetiqueta esas rutas comohistorical-recent-matches-comunidad-hispana-01yhistorical-recent-matches-comunidad-hispana-02.backend/app/routes.pylas mapea abuild_recent_historical_matches_payload(limit=20, server_slug=...).- Tras
TASK-229, soloserver=all-serverstenia snapshot fast-path. - CH01 y CH02 seguian entrando en
get_rcon_historical_read_model().list_recent_activity(...). - El read model llama a
list_rcon_historical_recent_activity(), que intenta materialized RCON/AdminLog (list_materialized_rcon_matches) antes del fallback por ventanas. - Si RCON no cubria o no alcanzaba el
limit, el builder podia intentar completar conlist_recent_historical_matches()desde storage legacy CRCON/PostgreSQL display.
Cambios aplicados:
build_recent_historical_matches_payload()usa snapshot fast-path para cualquierserver_slugexplicito.- CH01, CH02 y
all-serversquedan como wrappers legacy sobrebuild_recent_historical_matches_snapshot_payload(). - El contrato conserva
context: historical-recent-matches,items,limit,server_slug,historical_data_source,coverage_basisylegacy_endpoint_policy: snapshot-read-only-fast-path. - Si falta snapshot, responde JSON controlado con
items: [], sin RCON live, sin scoreboard externo, sininitialize_*y sin fallback runtime pesado.
Estado esperado tras redeploy:
| Endpoint | Estado TASK-231 en codigo | Severidad esperada tras deploy |
|---|---|---|
/api/historical/recent-matches?server=comunidad-hispana-01&limit=20 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin timeout |
/api/historical/recent-matches?server=comunidad-hispana-02&limit=20 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin timeout |
/api/historical/recent-matches?server=all-servers&limit=20 |
Wrapper legacy sobre snapshot read-only | OK o WARNING si snapshot missing, sin empeorar |
Comando de validacion de produccion tras redeploy:
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --output tmp\full_audit_after_task231.json
Evidencia ejecutada
Comandos ejecutados:
python -m compileall backend\app
python -m py_compile scripts\audit_public_requests.py
cd backend
python -m unittest tests.test_rcon_materialization_pipeline
Resultado:
compileall: OK.py_compile: OK.unittest: OK, 9 tests en 0.588s. El test existente emitioResourceWarningpor conexiones SQLite sin cerrar, sin fallo de test.
Auditoria local:
http://127.0.0.1:8000/healthno estaba disponible desde el host, por lo que no se lanzo la matriz completa local.
Auditoria produccion:
python scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --output tmp\public_request_audit.json
Resultado automatico:
- Probes lanzados: 191.
OK: 77.WARNING: 110.CRITICAL: 4.- HTTP 200: 187.
- HTTP 500: 1.
- Timeout/error sin status: 3.
- Warnings con
fallback_used=true: 109. - Snapshots con
snapshot_status=missing: 75.
Probes manuales adicionales dependientes de player_id:
| Endpoint | Resultado | Tiempo | Severidad |
|---|---|---|---|
/api/stats/players/76561198092154180?timeframe=weekly&server_id=all |
timeout | 30094.15 ms | CRITICAL |
/api/stats/players/76561198092154180?timeframe=monthly&server_id=all |
timeout | 30046.21 ms | CRITICAL |
/api/historical/player-profile?player=76561198092154180 |
200 | 4736.64 ms | WARNING |
/api/historical/elo-mmr/player?server=all-servers&player=76561198092154180 |
200 | 46.87 ms | WARNING |
El player_id se obtuvo desde /api/ranking?timeframe=weekly&server_id=all&metric=kills&limit=1.
Inventario backend
Rutas HTTP publicas extraidas de backend/app/routes.py: 36 patrones.
| ID | Metodo | Path | Handler/payload builder | Parametros | Fuente/modelo esperado |
|---|---|---|---|---|---|
| B001 | GET | /health |
build_health_payload |
ninguno | config/runtime status |
| B002 | GET | /api/community |
build_community_payload |
ninguno | payload estatico |
| B003 | GET | /api/trailer |
build_trailer_payload |
ninguno | payload estatico |
| B004 | GET | /api/discord |
build_discord_payload |
ninguno | payload estatico |
| B005 | GET | /api/servers |
build_servers_payload |
ninguno | latest snapshots; si stale refresca RCON/A2S |
| B006 | GET | /api/servers/latest |
build_server_latest_payload |
ninguno | list_latest_snapshots |
| B007 | GET | /api/servers/history |
build_server_history_payload |
limit |
list_snapshot_history |
| B008 | GET | /api/servers/{id}/history |
build_server_detail_history_payload |
id, limit |
list_server_history |
| B009 | GET | /api/stats/players/search |
build_stats_player_search_payload |
q, server_id/server, limit |
player search read model; fallback runtime RCON materialized |
| B010 | GET | /api/stats/rankings/annual |
build_annual_ranking_snapshot_payload |
year, metric=kills, server_id/server, limit |
annual ranking snapshot |
| B011 | GET | /api/ranking |
build_global_ranking_payload |
timeframe, server_id/server, metric, limit, year for annual |
ranking snapshots; annual snapshots |
| B012 | GET | /api/current-match |
build_current_match_payload |
server |
direct RCON sample; fallback /api/servers path |
| B013 | GET | /api/current-match/kills |
build_current_match_kill_feed_payload |
server, limit, since_event_id |
AdminLog storage |
| B014 | GET | /api/current-match/players |
build_current_match_player_stats_payload |
server |
AdminLog storage |
| B015 | GET | /api/stats/players/{player_id} |
build_stats_player_profile_payload |
player_id, timeframe, server_id/server |
player period stats read model; fallback runtime |
| B016 | GET | /api/historical/weekly-top-kills |
build_weekly_top_kills_payload |
limit, server |
legacy historical storage |
| B017 | GET | /api/historical/leaderboard |
build_historical_leaderboard_payload |
limit, server, metric, timeframe |
RCON read model plus public-scoreboard fallback |
| B018 | GET | /api/historical/weekly-leaderboard |
build_weekly_leaderboard_payload |
limit, server, metric |
legacy weekly storage |
| B019 | GET | /api/historical/monthly-leaderboard |
build_monthly_leaderboard_payload |
limit, server, metric |
legacy monthly storage |
| B020 | GET | /api/historical/monthly-mvp |
build_monthly_mvp_payload |
limit, server |
legacy monthly storage |
| B021 | GET | /api/historical/monthly-mvp-v2 |
build_monthly_mvp_v2_payload |
limit, server |
legacy monthly storage |
| B022 | GET | /api/historical/player-events |
build_player_event_payload |
limit, server, view |
legacy player event storage |
| B023 | GET | /api/historical/snapshots/leaderboard |
build_leaderboard_snapshot_payload |
limit, server, metric, timeframe |
displayed historical snapshots |
| B024 | GET | /api/historical/snapshots/monthly-leaderboard |
build_monthly_leaderboard_snapshot_payload |
limit, server, metric |
displayed historical snapshots |
| B025 | GET | /api/historical/snapshots/monthly-mvp |
build_monthly_mvp_snapshot_payload |
limit, server |
displayed historical snapshots |
| B026 | GET | /api/historical/snapshots/monthly-mvp-v2 |
build_monthly_mvp_v2_snapshot_payload |
limit, server |
displayed historical snapshots |
| B027 | GET | /api/historical/snapshots/player-events |
build_player_event_snapshot_payload |
limit, server, view |
displayed historical snapshots |
| B028 | GET | /api/historical/snapshots/weekly-leaderboard |
build_weekly_leaderboard_snapshot_payload |
limit, server, metric |
displayed historical snapshots |
| B029 | GET | /api/historical/recent-matches |
build_recent_historical_matches_payload |
limit, server |
RCON read model plus scoreboard merge |
| B030 | GET | /api/historical/snapshots/recent-matches |
build_recent_historical_matches_snapshot_payload |
limit, server |
displayed historical snapshots |
| B031 | GET | /api/historical/matches/detail |
build_historical_match_detail_payload |
server, match |
RCON materialized detail; fallback scoreboard detail |
| B032 | GET | /api/historical/server-summary |
build_historical_server_summary_payload |
server |
RCON read model plus fallback |
| B033 | GET | /api/historical/snapshots/server-summary |
build_historical_server_summary_snapshot_payload |
server |
displayed historical snapshots |
| B034 | GET | /api/historical/player-profile |
build_historical_player_profile_payload |
player |
legacy historical profile |
| B035 | GET | /api/historical/elo-mmr/leaderboard |
build_elo_mmr_leaderboard_payload |
limit, server |
Elo/MMR engine/read storage, currently fallback/paused in public payload |
| B036 | GET | /api/historical/elo-mmr/player |
build_elo_mmr_player_payload |
player, server |
Elo/MMR engine/read storage, currently fallback/paused in public payload |
Matriz completa de peticiones
La tabla usa rangos cuando una ruta se lanzo con varias combinaciones representativas. El JSON probe-a-probe esta en tmp/public_request_audit.json.
| ID | Tipo | Archivo origen | Pagina/contexto | Metodo | Endpoint/path | Parametros requeridos | Ejemplo de URL real | Handler/backend function | Fuente de datos | Usa snapshot/read-model/materialized/legacy/RCON/directo | Ejecuta initialize/ensure/bootstrap en lectura publica | Riesgo fallback pesado | Riesgo timeout | Loading/error frontend | Validacion ejecutada | Resultado HTTP | Tiempo medido | Tamano respuesta | Observaciones | Severidad | Recomendacion |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| M001 | backend-api | backend/app/routes.py |
health | GET | /health |
ninguno | /health |
build_health_payload |
config | status directo | no | no | bajo | n/a | produccion | 200 | 210.37 ms | 264 B | OK | OK | mantener |
| M002 | backend-api | backend/app/routes.py |
landing metadata | GET | /api/community |
ninguno | /api/community |
build_community_payload |
estatico | directo | no | no | bajo | n/a | produccion | 200 | 22.33 ms | 203 B | OK | OK | mantener |
| M003 | backend-api | backend/app/routes.py |
trailer | GET | /api/trailer |
ninguno | /api/trailer |
build_trailer_payload |
estatico | directo | no | no | bajo | main usa error controlado | produccion | 200 | 33.08 ms | 139 B | OK | OK | mantener |
| M004 | backend-api | backend/app/routes.py |
discord | GET | /api/discord |
ninguno | /api/discord |
build_discord_payload |
estatico | directo | no | no | bajo | n/a | produccion | 200 | 47.26 ms | 137 B | OK | OK | mantener |
| M005 | backend-api | backend/app/routes.py |
server cards | GET | /api/servers |
ninguno | /api/servers |
build_servers_payload |
latest snapshots + live refresh | snapshot/RCON/A2S | no DDL, pero red externa en lectura si stale | si | medio | main tiene fallback visual | produccion | 200 | 4311.38 ms | 1751 B | source=real-time-rcon-refresh |
WARNING | servir snapshot estricto y mover refresh fuera de request |
| M006 | backend-api | backend/app/routes.py |
server history | GET | /api/servers/latest |
ninguno | /api/servers/latest |
build_server_latest_payload |
local snapshot storage | snapshot legacy | posible initialize_storage por storage local |
no | bajo | n/a | produccion | 200 | 42.17 ms | 184 B | OK | OK | mantener |
| M007 | backend-api | backend/app/routes.py |
server history | GET | /api/servers/history |
limit |
/api/servers/history?limit=20 |
build_server_history_payload |
local snapshot storage | snapshot legacy | posible initialize_storage por storage local |
no | bajo | n/a | produccion | 200 | 40.59 ms | 167 B | OK | OK | mantener |
| M008 | backend-api | backend/app/routes.py |
server history detail | GET | /api/servers/{id}/history |
id, limit |
/api/servers/comunidad-hispana-01/history?limit=20 |
build_server_detail_history_payload |
local snapshot storage | snapshot legacy | posible initialize_storage por storage local |
no | bajo | n/a | produccion | 200 | 46.53-78.34 ms | 194 B | OK | OK | mantener |
| M009 | backend-api | backend/app/routes.py |
stats search | GET | /api/stats/players/search |
q, server_id/server, limit |
/api/stats/players/search?q=Medu&server_id=all&limit=10 |
build_stats_player_search_payload |
player search index | read-model + runtime materialized fallback | si: initialize_player_search_index_storage -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage |
si | alto | stats puede quedar esperando hasta timeout navegador | produccion | timeout | 30019.46 ms | 0 B | probe CRITICAL | CRITICAL | primer fix: read-only estricto, sin inicializar ni fallback runtime |
| M010 | backend-api | backend/app/routes.py |
stats annual ranking | GET | /api/stats/rankings/annual |
year, metric=kills, server_id/server, limit |
/api/stats/rankings/annual?year=2026&metric=kills&server_id=all&limit=10 |
build_annual_ranking_snapshot_payload |
annual ranking snapshot | snapshot | no en lectura normal | no | bajo | stats tiene error controlado | produccion | 200 | 60.07 ms | 5236 B | OK | OK | mantener |
| M011 | backend-api | backend/app/routes.py |
ranking | GET | /api/ranking |
timeframe, server_id/server, metric, limit, year anual |
/api/ranking?timeframe=weekly&server_id=all&metric=kills&limit=20 |
build_global_ranking_payload |
ranking snapshots | snapshot/read-model | no en lectura snapshot; fallback runtime opcional por env | si si env fallback esta activo | bajo | ranking usa AbortController/requestId | produccion | 200 | 31.40-129.56 ms | 755-5668 B | 55 probes OK | OK | mantener fallback runtime desactivado en publico |
| M012 | backend-api | backend/app/routes.py |
partida actual resumen | GET | /api/current-match |
server |
/api/current-match?server=comunidad-hispana-01 |
build_current_match_payload |
RCON live | directo RCON + fallback /api/servers |
no DDL | si, por fallback live | medio | partida actual tiene in-flight guard, sin timeout | produccion | 200 | 1242.08-2155.20 ms | 808-820 B | OK pero red externa en request | OK | mover a snapshot/read-model publico |
| M013 | backend-api | backend/app/routes.py |
partida actual kills | GET | /api/current-match/kills |
server, limit, since_event_id |
/api/current-match/kills?server=comunidad-hispana-01&limit=30 |
build_current_match_kill_feed_payload |
AdminLog | materialized AdminLog | si: initialize_rcon_admin_log_storage -> initialize_postgres_rcon_storage |
desconocido | alto | polling 1.5s con in-flight guard, sin timeout | produccion | timeout/500 | 6268.78-30024.86 ms | 0-58 B | CH01 timeout, CH02 500 y luego timeout manual | CRITICAL | segundo fix: read-only connection y query/index audit |
| M014 | backend-api | backend/app/routes.py |
partida actual jugadores | GET | /api/current-match/players |
server |
/api/current-match/players?server=comunidad-hispana-01 |
build_current_match_player_stats_payload |
AdminLog | materialized AdminLog | si: initialize_rcon_admin_log_storage -> initialize_postgres_rcon_storage |
desconocido | alto | polling 3s con in-flight guard, sin timeout | produccion | timeout/200 | 1090.32-30096.62 ms | 0-72280 B | CH01 timeout; CH02 OK | CRITICAL | segundo fix junto con kills |
| M015 | backend-api | backend/app/routes.py |
stats player detail | GET | /api/stats/players/{player_id} |
player_id, timeframe, server_id/server |
/api/stats/players/76561198092154180?timeframe=weekly&server_id=all |
build_stats_player_profile_payload |
player period stats | read-model + runtime fallback | si: initialize_player_period_stats_storage -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage |
si | alto | stats sin AbortController/timeout | manual produccion | timeout | 30046.21-30094.15 ms | 0 B | weekly/monthly CRITICAL | CRITICAL | primer fix junto con player search |
| M016 | backend-api | backend/app/routes.py |
legacy historical top kills | GET | /api/historical/weekly-top-kills |
limit, server |
/api/historical/weekly-top-kills?server=all-servers&limit=10 |
build_weekly_top_kills_payload |
historical storage | legacy/fallback | si en Postgres display fallback paths | si | bajo | n/a | produccion | 200 | 53.72-75.73 ms | 806 B | fallback_used=true |
WARNING | convertir a snapshot estricto o marcar legacy |
| M017 | backend-api | backend/app/routes.py |
legacy historical leaderboard | GET | /api/historical/leaderboard |
limit, server, metric, timeframe |
/api/historical/leaderboard?server=all-servers&timeframe=weekly&metric=kills&limit=10 |
build_historical_leaderboard_payload |
RCON/historical storage | read-model + legacy fallback | si en legacy display paths | si | bajo | n/a | produccion | 200 | 38-132 ms | ~1375-1414 B | fallback_used=true en muchos probes |
WARNING | documentar deprecacion o hacer snapshot-only |
| M018 | backend-api | backend/app/routes.py |
legacy weekly leaderboard | GET | /api/historical/weekly-leaderboard |
limit, server, metric |
/api/historical/weekly-leaderboard?server=comunidad-hispana-01&metric=kills&limit=10 |
build_weekly_leaderboard_payload |
historical storage | legacy | si en Postgres display paths | si | bajo | n/a | produccion | 200 | 55-58 ms | ~1380 B | fallback | WARNING | snapshot-only o mantener como legacy controlado |
| M019 | backend-api | backend/app/routes.py |
legacy monthly leaderboard | GET | /api/historical/monthly-leaderboard |
limit, server, metric |
/api/historical/monthly-leaderboard?server=comunidad-hispana-02&metric=kills&limit=10 |
build_monthly_leaderboard_payload |
historical storage | legacy | si en Postgres display paths | si | bajo | n/a | produccion | 200 | 57-116 ms | ~1360 B | fallback | WARNING | snapshot-only o mantener como legacy controlado |
| M020 | backend-api | backend/app/routes.py |
monthly MVP | GET | /api/historical/monthly-mvp |
limit, server |
/api/historical/monthly-mvp?server=all-servers&limit=10 |
build_monthly_mvp_payload |
historical storage | legacy | si en Postgres display paths | si | bajo | n/a | produccion | 200 | 43-58 ms | 1470 B | fallback | WARNING | snapshot-only |
| M021 | backend-api | backend/app/routes.py |
monthly MVP V2 | GET | /api/historical/monthly-mvp-v2 |
limit, server |
/api/historical/monthly-mvp-v2?server=all-servers&limit=10 |
build_monthly_mvp_v2_payload |
historical storage | legacy | si en Postgres display paths | si | bajo | n/a | produccion | 200 | 40-72 ms | 1509 B | fallback | WARNING | snapshot-only |
| M022 | backend-api | backend/app/routes.py |
player events | GET | /api/historical/player-events |
limit, server, view |
/api/historical/player-events?server=comunidad-hispana-01&view=duels&limit=10 |
build_player_event_payload |
player event storage | legacy | posible initialize legacy storage | si | bajo | n/a | produccion | 200 | 38-67 ms | ~1144-1156 B | fallback | WARNING | snapshot-only |
| M023 | backend-api | backend/app/routes.py |
snapshot leaderboard | GET | /api/historical/snapshots/leaderboard |
limit, server, metric, timeframe |
/api/historical/snapshots/leaderboard?server=all-servers&timeframe=weekly&metric=kills&limit=10 |
build_leaderboard_snapshot_payload |
displayed snapshots | snapshot | si en Postgres: get_snapshot -> initialize_postgres_display_storage |
no pesado hoy | bajo | historico muestra fallback visual | produccion | 200 | 40-110 ms | ~1596-1646 B | muchos snapshot_status=missing |
WARNING | quitar DDL/init de get_snapshot; completar snapshots |
| M024 | backend-api | backend/app/routes.py |
snapshot monthly leaderboard | GET | /api/historical/snapshots/monthly-leaderboard |
limit, server, metric |
/api/historical/snapshots/monthly-leaderboard?server=comunidad-hispana-02&metric=kills&limit=10 |
build_monthly_leaderboard_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no pesado hoy | bajo | n/a | produccion | 200 | 41-116 ms | ~1612 B | snapshot missing/fallback | WARNING | completar snapshots y read-only |
| M025 | backend-api | backend/app/routes.py |
snapshot monthly MVP | GET | /api/historical/snapshots/monthly-mvp |
limit, server |
/api/historical/snapshots/monthly-mvp?server=all-servers&limit=10 |
build_monthly_mvp_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no pesado hoy | bajo | n/a | produccion | 200 | 42-78 ms | 1506 B | snapshot missing/fallback | WARNING | completar snapshots |
| M026 | backend-api | backend/app/routes.py |
snapshot monthly MVP V2 | GET | /api/historical/snapshots/monthly-mvp-v2 |
limit, server |
/api/historical/snapshots/monthly-mvp-v2?server=all-servers&limit=10 |
build_monthly_mvp_v2_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no pesado hoy | bajo | n/a | produccion | 200 | 40-41 ms | 1539 B | snapshot missing/fallback | WARNING | completar snapshots |
| M027 | backend-api | backend/app/routes.py |
snapshot player events | GET | /api/historical/snapshots/player-events |
limit, server, view |
/api/historical/snapshots/player-events?server=all-servers&view=duels&limit=10 |
build_player_event_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no pesado hoy | bajo | n/a | produccion | 200 | 40-57 ms | ~1176-1188 B | snapshot missing/fallback | WARNING | completar snapshots |
| M028 | backend-api | backend/app/routes.py |
snapshot weekly leaderboard | GET | /api/historical/snapshots/weekly-leaderboard |
limit, server, metric |
/api/historical/snapshots/weekly-leaderboard?server=comunidad-hispana-01&metric=kills&limit=10 |
build_weekly_leaderboard_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no pesado hoy | bajo | n/a | produccion | 200 | 44-70 ms | ~1610 B | snapshot missing/fallback | WARNING | completar snapshots |
| M029 | backend-api | backend/app/routes.py |
historico recent matches legacy | GET | /api/historical/recent-matches |
limit, server |
/api/historical/recent-matches?server=comunidad-hispana-01&limit=20 |
build_recent_historical_matches_payload |
snapshot recent matches | wrapper legacy sobre snapshot para cualquier server= explicito |
no | no | bajo | n/a | pendiente redeploy TASK-231 | pendiente | pendiente | pendiente | legacy_endpoint_policy=snapshot-read-only-fast-path |
OK o WARNING sin timeout | mantener como compatibilidad legacy |
| M030 | backend-api | backend/app/routes.py |
historico recent snapshot | GET | /api/historical/snapshots/recent-matches |
limit, server |
/api/historical/snapshots/recent-matches?server=all-servers&limit=20 |
build_recent_historical_matches_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no | bajo | historico handles error | produccion | 200 | 48-82 ms | ~24185 B | OK | OK | mantener, quitar init display despues |
| M031 | backend-api | backend/app/routes.py |
historico match detail | GET | /api/historical/matches/detail |
server, match |
/api/historical/matches/detail?server=comunidad-hispana-01&match=comunidad-hispana-01:1781023156:1781028555:purpleheartlanewarfare |
build_historical_match_detail_payload |
RCON materialized detail; scoreboard fallback | materialized/read-model + fallback legacy | si: get_materialized_rcon_match_detail -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage; fallback display init |
si | medio | historico-partida muestra error, sin timeout | produccion | 200 | 120.47 ms | 125580 B | hoy OK, deuda de init persiste | OK | hardening posterior read-only estricto |
| M032 | backend-api | backend/app/routes.py |
historico server summary legacy | GET | /api/historical/server-summary |
server |
/api/historical/server-summary?server=comunidad-hispana-01 |
build_historical_server_summary_payload |
snapshot server summary | wrapper legacy sobre snapshot para cualquier server= explicito |
no | no | bajo | n/a | pendiente redeploy TASK-230 | pendiente | pendiente | pendiente | legacy_endpoint_policy=snapshot-read-only-fast-path |
OK o WARNING sin timeout | mantener como compatibilidad legacy |
| M033 | backend-api | backend/app/routes.py |
historico server summary snapshot | GET | /api/historical/snapshots/server-summary |
server |
/api/historical/snapshots/server-summary?server=all-servers |
build_historical_server_summary_snapshot_payload |
displayed snapshots | snapshot | si en Postgres display | no | bajo | historico handles missing | produccion | 200 | 50.03-62.60 ms | ~1042 B | fallback_used=true |
WARNING | completar snapshot/read-only |
| M034 | backend-api | backend/app/routes.py |
historical player profile | GET | /api/historical/player-profile |
player |
/api/historical/player-profile?player=76561198092154180 |
build_historical_player_profile_payload |
legacy historical profile | legacy | si en Postgres display/historical fallback | si | medio | n/a | manual produccion | 200 | 4736.64 ms | no capturado | fallback true | WARNING | no cargar de inicio; optimizar si se mantiene publico |
| M035 | backend-api | backend/app/routes.py |
Elo/MMR leaderboard | GET | /api/historical/elo-mmr/leaderboard |
limit, server |
/api/historical/elo-mmr/leaderboard?server=all-servers&limit=10 |
build_elo_mmr_leaderboard_payload |
Elo/MMR storage | legacy/paused | posible initialize_elo_mmr_storage si engine carga |
si | bajo | no usado por frontend actual | produccion | 200 | 58.35 ms | 2257 B | fallback/paused | WARNING | no reactivar; mantener fuera de UI |
| M036 | backend-api | backend/app/routes.py |
Elo/MMR player | GET | /api/historical/elo-mmr/player |
player, server |
/api/historical/elo-mmr/player?server=all-servers&player=76561198092154180 |
build_elo_mmr_player_payload |
Elo/MMR storage | legacy/paused | posible initialize_elo_mmr_storage si engine carga |
si | bajo | no usado por frontend actual | manual produccion | 200 | 46.87 ms | no capturado | fallback true | WARNING | no reactivar; mantener fuera de UI |
| M037 | frontend-fetch | frontend/assets/js/main.js |
index.html |
GET | /health |
ninguno | ${backendBaseUrl}/health |
backend B001 | config status | directo | no | no | bajo | usa try/catch; no bloquea pagina completa |
codigo + produccion | 200 | 210.37 ms | 264 B | usado para estado backend | OK | mantener |
| M038 | frontend-fetch | frontend/assets/js/main.js |
index.html |
GET | /api/trailer |
ninguno | ${backendBaseUrl}/api/trailer |
backend B003 | estatico | directo | no | no | bajo | error controlado | codigo + produccion | 200 | 33.08 ms | 139 B | OK | OK | mantener |
| M039 | frontend-fetch | frontend/assets/js/main.js |
index.html |
GET | /api/servers |
ninguno | ${backendBaseUrl}/api/servers |
backend B005 | snapshots/live | RCON refresh posible | no DDL, si red live | si | medio | fallback visual; Promise.allSettled |
codigo + produccion | 200 | 4311.38 ms | 1751 B | puede ralentizar landing | WARNING | no refrescar live en request publica |
| M040 | frontend-fetch | frontend/assets/js/historico.js |
historico.html |
GET | /api/historical/snapshots/server-summary |
server |
/api/historical/snapshots/server-summary?server=comunidad-hispana-01 |
backend B033 | snapshot | snapshot | si display init | no | bajo | requestId/cache/error | codigo + produccion | 200 | 50-63 ms | ~1042 B | snapshot missing/fallback | WARNING | completar snapshot y read-only |
| M041 | frontend-fetch | frontend/assets/js/historico.js |
historico.html |
GET | /api/historical/snapshots/recent-matches |
server, limit |
/api/historical/snapshots/recent-matches?server=comunidad-hispana-01&limit=20 |
backend B030 | snapshot | snapshot | si display init | no | bajo | requestId/cache/error | codigo + produccion | 200 | 48-82 ms | ~24 KB | OK | OK | mantener |
| M042 | frontend-fetch | frontend/assets/js/historico.js |
historico.html |
GET | /api/historical/snapshots/leaderboard |
server, timeframe, metric, limit |
/api/historical/snapshots/leaderboard?server=comunidad-hispana-01&timeframe=weekly&metric=kills&limit=10 |
backend B023 | snapshot | snapshot | si display init | no | bajo | requestId/cache/error | codigo + produccion | 200 | 40-110 ms | ~1.6 KB | snapshot missing/fallback | WARNING | completar snapshots |
| M043 | frontend-fetch | frontend/assets/js/historico-recent-live.js |
historico.html |
GET | /api/historical/snapshots/recent-matches |
server, limit |
/api/historical/snapshots/recent-matches?server=comunidad-hispana-02&limit=20 |
backend B030 | snapshot | snapshot | si display init | no | bajo | try/catch; cache no-store |
codigo + produccion | 200 | 48-82 ms | ~24 KB | duplicable con historico.js | OK | revisar si ambos scripts piden lo mismo |
| M044 | frontend-fetch | frontend/assets/js/historico-partida.js |
historico-partida.html |
GET | /api/historical/matches/detail |
server, match |
/api/historical/matches/detail?server=...&match=... |
backend B031 | materialized/fallback | materialized RCON | si | si | medio | error visual; sin timeout/abort | codigo + produccion | 200 | 120.47 ms | 125580 B | fallback localhost corregido previamente | OK | hardening read-only despues |
| M045 | frontend-fetch | frontend/assets/js/partida-actual.js |
partida-actual.html |
GET | /api/current-match |
server |
/api/current-match?server=comunidad-hispana-01 |
backend B012 | RCON live | directo RCON | no | si | medio | in-flight guard; sin timeout | codigo + produccion | 200 | 1242-2155 ms | ~820 B | polling | OK | mover a snapshot |
| M046 | frontend-fetch | frontend/assets/js/partida-actual.js |
partida-actual.html |
GET | /api/current-match/kills |
server, limit, since_event_id |
/api/current-match/kills?server=comunidad-hispana-01&limit=30 |
backend B013 | AdminLog | materialized | si | desconocido | alto | in-flight guard; sin timeout | codigo + produccion | timeout/500 | 6269-30025 ms | 0-58 B | polling frecuente | CRITICAL | corregir backend y agregar timeout frontend |
| M047 | frontend-fetch | frontend/assets/js/partida-actual.js |
partida-actual.html |
GET | /api/current-match/players |
server |
/api/current-match/players?server=comunidad-hispana-01 |
backend B014 | AdminLog | materialized | si | desconocido | alto | in-flight guard; sin timeout | codigo + produccion | timeout/200 | 1090-30097 ms | 0-72 KB | polling frecuente | CRITICAL | corregir backend y agregar timeout frontend |
| M048 | frontend-fetch | frontend/assets/js/ranking.js |
ranking.html |
GET | /api/ranking |
timeframe, server_id, metric, limit, year |
/api/ranking?timeframe=weekly&server_id=all&metric=kills&limit=100 |
backend B011 | ranking snapshots | snapshot | no en fast path | no | bajo | AbortController + requestId + error | codigo + produccion | 200 | 31-130 ms | variable | OK | OK | mantener |
| M049 | frontend-fetch | frontend/assets/js/stats.js |
stats.html |
GET | /health |
ninguno | ${backendBaseUrl}/health |
backend B001 | config status | directo | no | no | bajo | error controlado | codigo + produccion | 200 | 210 ms | 264 B | OK | OK | mantener |
| M050 | frontend-fetch | frontend/assets/js/stats.js |
stats.html |
GET | /api/stats/players/search |
q, opcional server_id, limit |
/api/stats/players/search?q=Medu&server_id=all&limit=10 |
backend B009 | player read model | read-model/fallback | si | si | alto | sin abort/timeout; loading puede durar mucho | codigo + produccion | timeout | 30019 ms | 0 B | CRITICAL | CRITICAL | primer fix |
| M051 | frontend-fetch | frontend/assets/js/stats.js |
stats.html |
GET | /api/stats/rankings/annual |
year, metric, server_id, limit |
/api/stats/rankings/annual?year=2026&metric=kills&server_id=all&limit=10 |
backend B010 | annual snapshot | snapshot | no | no | bajo | error controlado | codigo + produccion | 200 | 60 ms | 5236 B | OK | OK | mantener |
| M052 | frontend-fetch | frontend/assets/js/stats.js |
stats.html |
GET | /api/stats/players/{player_id} |
player_id, timeframe, server_id |
/api/stats/players/76561198092154180?timeframe=weekly&server_id=all |
backend B015 | player period stats | read-model/fallback | si | si | alto | sin abort/timeout; puede quedarse cargando hasta timeout navegador | codigo + manual produccion | timeout | 30046-30094 ms | 0 B | CRITICAL | CRITICAL | primer fix |
| M053 | static-asset | frontend/*.html, frontend/assets/css, frontend/assets/js |
paginas publicas | GET | assets estaticos | path estatico | /assets/js/ranking.js |
servidor estatico | filesystem/web server | n/a | no | no | bajo | navegador gestiona error de asset | no medida HTTP individual | n/a | n/a | n/a | no se tocaron assets | OK | mantener cache headers fuera de esta task |
| M054 | static-asset | frontend/assets/img/** |
imagenes publicas | GET | assets imagen | path estatico | /assets/img/... |
servidor estatico | filesystem/web server | n/a | no | no | bajo | navegador gestiona error de asset | no medida HTTP individual | n/a | n/a | n/a | no se tocaron imagenes, SVGs, weapons ni clans | OK | sin cambios |
| M055 | internal-runner | backend/app/historical_runner.py |
worker historico | n/a | no publico | args CLI/env | n/a | runner | RCON/public scoreboard/storage | ingestion/fallback | si, por diseno de worker | si | n/a | n/a | lectura estatica | n/a | n/a | n/a | fuera de superficie publica | OK | no mezclar con fixes publicos |
| M056 | internal-runner | backend/app/historical_ingestion.py |
ingestion historica | n/a | no publico | args CLI/env | n/a | runner | public scoreboard/RCON | ingestion/fallback | si, por diseno de worker | si | n/a | n/a | lectura estatica | n/a | n/a | n/a | fuera de superficie publica | OK | no ejecutar desde request publica |
| M057 | internal-runner | backend/app/database_maintenance.py |
mantenimiento DB | n/a | no publico | args CLI/env | n/a | runner | DB | maintenance | si, por diseno de worker | n/a | n/a | n/a | lectura estatica | n/a | n/a | n/a | fuera de superficie publica | OK | mantener separado de GET |
| M058 | internal-runner | scripts/audit_public_requests.py |
auditoria publica | GET | endpoints publicos | --base-url, --timeout |
produccion/local | script stdlib | HTTP publico | n/a | no modifica app | no | configurable | n/a | ejecutado | 191 probes | ver JSON | ver JSON | artefacto de auditoria | OK | usar antes/despues de fixes |
Endpoints OK
| Endpoint/familia | Evidencia |
|---|---|
/health, /api/community, /api/trailer, /api/discord |
200, menos de 211 ms |
/api/servers/latest, /api/servers/history, /api/servers/{id}/history |
200, 40-78 ms |
/api/ranking semanal/mensual/anual, metricas kills, deaths, teamkills, matches_considered, kd_ratio, kills_per_match, scopes all, comunidad-hispana-01, comunidad-hispana-02 |
55 probes OK, 31-130 ms |
/api/stats/rankings/annual |
200, 60.07 ms |
/api/current-match |
200, 1.2-2.2 s; OK funcional, riesgo arquitectonico por RCON directo |
/api/historical/recent-matches |
200, 278-1286 ms |
/api/historical/snapshots/recent-matches |
200, 48-82 ms |
/api/historical/matches/detail con match conocido |
200, 120.47 ms |
/api/historical/server-summary |
200, 95-145 ms |
Endpoints WARNING
| Endpoint/familia | Motivo |
|---|---|
/api/servers |
200 pero 4311.38 ms y source=real-time-rcon-refresh: red live durante lectura publica |
/api/historical/weekly-top-kills |
fallback_used=true |
/api/historical/leaderboard, /weekly-leaderboard, /monthly-leaderboard |
fallback_used=true y legacy fallback |
/api/historical/monthly-mvp, /monthly-mvp-v2 |
fallback_used=true |
/api/historical/player-events |
fallback_used=true |
/api/historical/snapshots/* salvo recent-matches |
snapshot_status=missing frecuente, fallback_used=true |
/api/historical/player-profile |
200 pero 4736.64 ms manual y fallback |
/api/historical/elo-mmr/* |
endpoints expuestos pero fallback/pausados; no reactivar ni poner en UI |
frontend data-backend-base-url/fallback local |
13 referencias a localhost/127.0.0.1 en HTML/JS publico; config.js mitiga en produccion pero el residuo existe |
Endpoints CRITICAL
| Endpoint | Evidencia | Recomendacion |
|---|---|---|
/api/stats/players/search?q=Medu&server_id=all&limit=10 |
timeout 30019.46 ms | read-only estricto del player search index; no inicializar storage ni fallback runtime en request publica |
/api/stats/players/{player_id}?timeframe=weekly&server_id=all |
timeout 30094.15 ms | igual que search; revisar player_period_stats |
/api/stats/players/{player_id}?timeframe=monthly&server_id=all |
timeout 30046.21 ms | igual que search; revisar player_period_stats |
/api/current-match/kills?server=comunidad-hispana-01&limit=30 |
timeout 30024.86 ms | quitar init de AdminLog en lectura; revisar indices/query |
/api/current-match/players?server=comunidad-hispana-01 |
timeout 30096.62 ms | quitar init de AdminLog en lectura; revisar ventana actual e indices |
/api/current-match/kills?server=comunidad-hispana-02&limit=30 |
500 en 6268.78 ms; repeticion manual hizo timeout | capturar error backend y estabilizar query |
Inicializacion en lectura publica
Rutas donde una peticion publica puede acabar ejecutando inicializacion, DDL o bootstrap de storage:
| Ruta publica | Cadena | Tiempo observado/potencial | Estado | Recomendacion |
|---|---|---|---|---|
/api/historical/matches/detail |
build_historical_match_detail_payload -> get_rcon_historical_match_detail -> get_materialized_rcon_match_detail -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage |
historico reciente midio 14s antes; esta auditoria 120 ms para match conocido | funcional pero no limpio | mantener como fix posterior: conexion read-only sin init y fallback estricto |
/api/stats/players/search |
build_stats_player_search_payload -> search_rcon_materialized_players -> _search_player_search_index -> initialize_player_search_index_storage -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage; fallback _search_rcon_materialized_players_runtime |
30s timeout | CRITICAL | primer fix |
/api/stats/players/{player_id} |
build_stats_player_profile_payload -> get_rcon_materialized_player_stats -> _get_player_period_stats_read_model -> initialize_player_period_stats_storage -> initialize_rcon_materialized_storage -> initialize_postgres_rcon_storage; fallback runtime |
30s timeout | CRITICAL | primer fix junto a search |
/api/current-match/kills |
build_current_match_kill_feed_payload -> list_current_match_kill_feed -> initialize_rcon_admin_log_storage -> initialize_postgres_rcon_storage |
30s timeout / 500 | CRITICAL | segundo fix |
/api/current-match/players |
build_current_match_player_stats_payload -> list_current_match_player_stats -> initialize_rcon_admin_log_storage -> initialize_postgres_rcon_storage |
30s timeout en CH01 | CRITICAL | segundo fix |
/api/historical/snapshots/* |
snapshot builder -> get_historical_snapshot -> Postgres get_snapshot -> initialize_postgres_display_storage |
rapido hoy, 40-116 ms | WARNING | read-only snapshot connection |
legacy /api/historical/* |
payloads -> historical_storage -> Postgres display fallback functions |
rapido hoy salvo player-profile 4.7s | WARNING | snapshot-only o legacy explicit |
/api/ranking |
weekly/monthly fast path uses read-only snapshot connection; initialize_ranking_snapshot_storage solo deberia ocurrir en generation/fallback. Runtime fallback existe por env |
31-130 ms | OK con condicion | mantener fallback runtime apagado en publico |
| annual ranking | get_annual_ranking_snapshot usa read connection |
31-88 ms | OK | mantener |
Fallbacks pesados detectados
| Endpoint | Fallback | Activacion | Coste estimado | Lo muestra frontend | Recomendacion |
|---|---|---|---|---|---|
/api/stats/players/search |
runtime search en rcon_match_player_stats |
indice vacio/no disponible/error | alto, timeout 30s | no claramente | eliminar fallback runtime en publico o devolver estado snapshot_missing rapido |
/api/stats/players/{player_id} |
runtime player stats desde materialized matches | player_period_stats vacio/no disponible |
alto, timeout 30s | no claramente | eliminar fallback runtime publico |
/api/current-match/kills/players |
AdminLog init + queries sobre ventana actual | siempre entra por helper actual | alto en CH01 | UI queda esperando | read-only + indices; respuesta vacia rapida si no hay ventana |
/api/servers |
RCON live refresh y A2S fallback si snapshots stale | snapshots ausentes/stale | medio, 4.3s medido | no como fallback tecnico | snapshot estricto en publico; refresh asincrono |
/api/historical/recent-matches |
merge con public-scoreboard persisted fallback | RCON insuficiente | medio, 1.3s max | no | frontend ya debe preferir snapshot |
legacy /api/historical/* |
public-scoreboard/display fallback | RCON no soporta o snapshot missing | bajo hoy pero acoplado | parcialmente por metadata | deprecar o snapshot-only |
/api/historical/matches/detail |
public-scoreboard detail fallback | RCON detail no encontrado | potencial alto si display init se repite | no destacado | fallback estricto y rapido |
Auditoria frontend
Paginas publicas revisadas:
frontend/index.htmlfrontend/historico.htmlfrontend/historico-partida.htmlfrontend/partida-actual.htmlfrontend/ranking.htmlfrontend/stats.html
Scripts publicos revisados:
frontend/assets/js/config.jsfrontend/assets/js/main.jsfrontend/assets/js/historico.jsfrontend/assets/js/historico-recent-live.jsfrontend/assets/js/historico-partida.jsfrontend/assets/js/partida-actual.jsfrontend/assets/js/ranking.jsfrontend/assets/js/stats.js
Hallazgos frontend:
| Pagina | Fetchs | Loading/error | Timeout/abort/requestId | Riesgo |
|---|---|---|---|---|
index.html |
/health, /api/trailer, /api/servers |
error controlado; no bloquea todo por Promise.allSettled |
sin timeout | WARNING por /api/servers lento |
historico.html |
snapshots server-summary/recent/leaderboard y recent-live | requestId/cache/error visual | requestId; sin timeout generico | WARNING por snapshots missing/fallback |
historico-partida.html |
/api/historical/matches/detail |
error visual si falla | sin timeout/abort | OK hoy, deuda si endpoint vuelve lento |
partida-actual.html |
current match, kills, players | in-flight guards; no abort | sin timeout; polling frecuente | CRITICAL por endpoints kills/players |
ranking.html |
/api/ranking |
loading/error correcto | AbortController + requestId | OK |
stats.html |
/health, player search, annual ranking, player profile |
errores visibles pero search/profile pueden esperar demasiado | sin AbortController/requestId robusto para search/profile; sin timeout | CRITICAL por search/profile |
Referencias localhost/127.0.0.1 en frontend publico:
frontend/assets/js/config.js: default dev backend y deteccion localhost.frontend/assets/js/historico-recent-live.jsfrontend/assets/js/historico.jsfrontend/assets/js/main.jsfrontend/assets/js/partida-actual.jsfrontend/assets/js/ranking.jsfrontend/assets/js/stats.jsfrontend/historico.htmlfrontend/index.htmlfrontend/partida-actual.htmlfrontend/ranking.htmlfrontend/stats.html
frontend/historico-partida.html ya no conserva data-backend-base-url local. La mitigacion en config.js evita que un host no local use el default dev, pero la deuda sigue existiendo porque hay HTML/JS publico con fallback local.
Top 10 riesgos actuales
/api/stats/players/searchhace inicializacion/read-model/fallback runtime en lectura publica y vence a 30s./api/stats/players/{player_id}hace inicializacion/read-model/fallback runtime en lectura publica y vence a 30s./api/current-match/killsvence a 30s o devuelve 500 segun servidor./api/current-match/playersvence a 30s encomunidad-hispana-01./api/serverspuede hacer refresh RCON en request publica y tarda 4.3s.get_snapshotde snapshots historicos ejecutainitialize_postgres_display_storageen lectura.- Muchos snapshots historicos estan
missing, generandofallback_used=trueen 75+ probes. - Hay residuos de fallback
127.0.0.1/localhosten HTML/JS publico. stats.js,partida-actual.jsehistorico-partida.jsno tienen timeout HTTP propio.- Endpoints legacy historicos siguen expuestos con fallback dinamico aunque el frontend ya usa snapshots para lo principal.
Top 10 recomendaciones priorizadas
- Crear task backend para
/api/stats/players/searchy/api/stats/players/{player_id}: read-only estricto, sininitialize_*ni fallback runtime en GET publico. - Crear task backend para
/api/current-match/killsy/api/current-match/players: quitar init de AdminLog en lectura, revisar indices y devolver payload vacio rapido si no hay ventana actual. - Crear task backend para
/api/servers: no hacer refresh RCON/A2S desde GET publico; responder snapshot y dejar refresh a worker. - Crear task frontend para
stats.js: AbortController/requestId/timeout y estado de error rapido para search/profile. - Crear task frontend para
partida-actual.js: timeout/abort por request y backoff si kills/players fallan. - Crear task backend para
historical_snapshot_storage/postgres_display_storage.get_snapshot: conexion read-only sin DDL/init en lectura. - Crear task de generacion/validacion snapshots historicos faltantes: reducir
snapshot_status=missing. - Crear task de limpieza de fallbacks locales en frontend publico, manteniendo soporte dev explicito sin contaminar produccion.
- Crear task backend para hardening de
/api/historical/matches/detail: read-only estricto y fallback rapido aunque hoy responda OK. - Crear task de deprecacion/control de endpoints legacy
/api/historical/*no usados por frontend o exponerlos solo como legacy con limites claros.
Fixes propuestos como tasks pequenas
TASK-225-stats-player-read-model-public-fast-path:/api/stats/players/searchy/api/stats/players/{player_id}sin inicializacion ni fallback runtime en lectura publica.TASK-226-current-match-adminlog-public-fast-path:/api/current-match/killsy/api/current-match/playersread-only, indices y errores controlados.TASK-227-servers-public-snapshot-only:/api/serversno refresca RCON/A2S durante request publica.TASK-228-frontend-stats-request-timeouts: timeout/abort/requestId parastats.js.TASK-229-frontend-current-match-request-timeouts: timeout/backoff parapartida-actual.js.TASK-230-historical-snapshot-storage-read-only: quitarinitialize_postgres_display_storagedel path de lectura de snapshots.TASK-231-historical-snapshot-coverage-refresh: completar snapshots faltantes usados porhistorico.html.TASK-232-frontend-public-backend-url-hardening: eliminar fallbacks locales de HTML/JS publico de produccion.TASK-233-historical-match-detail-read-only-hardening: hardening de/api/historical/matches/detail.TASK-234-legacy-historical-endpoint-policy: inventario/limites/deprecacion de legacy endpoints publicos.
Comandos de auditoria
Desde host contra produccion:
python scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --output tmp\public_request_audit.json
Desde host contra backend local:
python scripts\audit_public_requests.py --base-url http://127.0.0.1:8000 --timeout 30 --output tmp\public_request_audit.json
Dentro del contenedor backend desde PowerShell, sin copiar archivos al contenedor:
Get-Content scripts\audit_public_requests.py | docker compose exec -T backend python - --base-url http://127.0.0.1:8000 --timeout 30 --output /app/data/public_request_audit.json
Equivalente shell:
cat scripts/audit_public_requests.py | docker compose exec -T backend python - --base-url http://127.0.0.1:8000 --timeout 30 --output /app/data/public_request_audit.json
Compilacion del script:
python -m py_compile scripts\audit_public_requests.py
Notas de alcance
- No se ejecuto
ai-platform run. - No se hizo commit.
- No se hizo push.
- No se aplicaron fixes funcionales.
- No se modifico logica productiva backend ni frontend.
- No se tocaron assets, SVGs, imagenes fisicas,
frontend/assets/img/weapons/,frontend/assets/img/clans/niai/system-metrics.md. - No se reactivo Elo/MMR.
- No se agrego ningun servidor nuevo.