8.6 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-223 | Optimize historical match detail payload | done | backend | Backend Senior |
|
foundation | high |
TASK-223 - Optimize historical match detail payload
Goal
Corregir la lentitud extrema de /api/historical/matches/detail para la partida historica RCON comunidad-hispana-01:1781023156:1781028555:purpleheartlanewarfare, que tarda alrededor de 55 segundos dentro del backend con 140 jugadores y provoca timeout/error publico.
Context
La evidencia indica que el payload no es grande: unos 150 KB para 140 jugadores. La lentitud se produce durante la construccion del detalle, probablemente por enriquecimiento costoso o patron N+1 de perfiles/jugadores.
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
Steps
- Perfilar
build_historical_match_detail_payload()oget_rcon_historical_match_detail()para la partida problematica antes de cambiar codigo. - Identificar funciones lentas y confirmar si
profile_summary, enlaces externos,top_weapons,most_killed,death_by, victims o nemesis generan trabajo por jugador. - Optimizar el detalle inicial para que sirva metadata, marcador y lista basica de jugadores sin enriquecimiento historico global pesado.
- Mantener en el payload inicial las estadisticas de la partida que ya vengan del read model: kills, deaths, teamkills, KD, armas, abatidos y muertes por rival si no requieren queries extra.
- Si
profile_summaryresulta costoso, quitarlo o hacerlo opcional en el detalle inicial y dejarlo para endpoint diferido futuro. - Confirmar que
historico-partida.jssigue funcionando sinprofile_summary. - Validar backend, frontend si se toca, endpoint interno y endpoint publico cuando sea posible.
Files to Read First
ai/architecture-index.mdai/repo-context.mdai/orchestrator/backend-senior.mdbackend/app/rcon_historical_read_model.pybackend/app/payloads.pyfrontend/assets/js/historico-partida.jsai/tasks/done/TASK-222-fix-historical-match-detail-backend-url-and-false-kpm.mddocs/PERFORMANCE_PUBLIC_QUERY_AUDIT.md
Expected Files to Modify
backend/app/rcon_historical_read_model.pybackend/tests/test_rcon_materialization_pipeline.pyai/tasks/done/TASK-223-optimize-historical-match-detail-payload.md
Constraints
- Keep the change minimal.
- Preserve HLL Vietnam project identity.
- Do not introduce unnecessary frameworks or dependencies.
- Do not run
ai-platform run. - Do not push.
- Do not touch weapon assets.
- Do not touch SVGs.
- Do not modify physical images.
- Do not touch
ai/system-metrics.md. - Do not reactivate Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Do not include unrelated previous changes.
- Do not introduce runtime RCON or scoreboard queries in the public request.
- Do not reintroduce false KPM.
Validation
Before completing the task ensure:
- Profiling output before and after the backend change is recorded in the outcome.
python -m compileall backend/appif backend is touched.- Relevant backend tests run, or a small focused test is added if coverage is missing.
node --check frontend/assets/js/historico-partida.jsif frontend is touched.- The problematic internal endpoint is measured and returns under 1 second if the local environment can reach the same data.
- The public endpoint is checked for 200/found=true if publicly reachable from the current environment.
- Visual validation confirms the detail page renders marcador, mapa and players and does not show KPM if a browser target is available.
git diff --name-onlymatches expected scope, except pre-existing unrelated changes.- Confirm excluded files/assets were not touched.
Outcome
Archivos modificados por esta task:
backend/app/rcon_historical_read_model.pybackend/tests/test_rcon_materialization_pipeline.pyai/tasks/done/TASK-223-optimize-historical-match-detail-payload.md
Causa encontrada:
- En el path RCON materializado,
_build_materialized_detail_item()cargaba siempreget_latest_rcon_player_profile_summaries()para todos los jugadores de la partida antes de devolver el detalle inicial. - Ese enriquecimiento no pertenece al detalle basico de partida: trae historico global de perfil por jugador (
sessions,matches_played,favorite_weapons,victims,nemesis,averages,sanctions) y parsea esos JSON para cada perfil devuelto. - No se encontro N+1 en Python para
top_weapons,most_killedodeath_by: salen de JSON ya materializado enrcon_match_player_statspara esa partida. external_profile_linkses barato: se deriva localmente desdeplayer_idconbuild_external_player_profile_fields(), sin consulta extra.- El patron lento confirmado por codigo queda en
profile_summary, no en el tamano del payload ni en la renderizacion frontend.
Profiling ejecutado:
- Comando de perfil solicitado contra
build_historical_match_detail_payload()paracomunidad-hispana-01:1781023156:1781028555:purpleheartlanewarfare. - En este entorno no estaba configurada la misma base PostgreSQL de produccion y Docker no estaba disponible (
docker compose psno pudo conectar con Docker Desktop), por lo que el perfil local cayo a fallback SQLite confound=false. - Antes del cambio, perfil local disponible:
seconds: 5.333found: falseplayers: 0source:historical-crcon-storagefallback_used: true- cuello local no representativo:
historical_storage.initialize_historical_storage()y normalizacion SQLite legacy.
- Despues del cambio, perfil local disponible:
seconds: 3.644found: falseplayers: 0source:historical-crcon-storagefallback_used: true- sigue sin ser medicion representativa de la partida RCON porque no alcanza el read model real.
- Evidencia inicial de produccion recibida para el caso real:
seconds: 55.137http: 200bytes: 150813players: 140source:rcon-historical-competitive-read-modelfallback_used: false
Solucion aplicada:
- El detalle inicial RCON ya no llama a
get_latest_rcon_player_profile_summaries(). _build_player_row()ahora devuelve solo datos propios de la partida:player_nameteamkillsdeathsteamkillskd_ratiotop_weaponsmost_killeddeath_byexternal_profile_linksderivados localmente
profile_summaryqueda diferido para una futura ruta lazy por jugador si se necesita mostrar historico global al expandir una fila.
Frontend:
- No se modifico
frontend/assets/js/historico-partida.js. - La UI ya no dependia de
profile_summary; renderiza tabla y panel expandible con datos de partida, enlaces externos y mensajesNo disponiblecuando faltan listas ampliadas. - No se reintrodujo KPM.
- La llamada relativa
/api/historical/matches/detailse mantiene intacta.
Validaciones ejecutadas:
python -m compileall backend/apppython -m unittest tests.test_rcon_materialization_pipeline.RconMaterializationPipelineTests.test_match_detail_omits_profile_summary_when_snapshot_existspython -m unittest tests.test_rcon_materialization_pipeline- Perfil local con
cProfileantes y despues, documentado arriba. Invoke-WebRequestcontrahttp://127.0.0.1:8000/api/historical/matches/detail?...fallo conNo es posible conectar con el servidor remoto; no habia backend local escuchando.docker compose psfallo porque Docker Desktop no estaba disponible en esta sesion.git diff --name-onlyrevisado.
Resultado de validaciones:
compileallpaso.- La suite
tests.test_rcon_materialization_pipelinepaso: 9 tests OK. - La suite emite
ResourceWarningde conexiones SQLite no cerradas ya existentes en esos tests, pero no falla. - No se pudo validar el endpoint publico real ni visualmente por falta de URL publica absoluta/backend activo en este entorno.
Confirmacion de exclusiones:
- No se ejecuto
ai-platform run. - No se hizo push.
- No se hizo commit.
- No se tocaron assets de armas.
- No se tocaron SVGs.
- No se modificaron imagenes fisicas.
- No se toco
ai/system-metrics.md. - No se reactivo Elo/MMR.
- No se reintrodujo Comunidad Hispana #03.
- No se toco backend de rankings/snapshots.
- No se incluyeron cambios previos no relacionados.
git statusmuestra cambios preexistentes enai/system-metrics.md, assets de armas/SVGs y otros archivos no relacionados; esta task los dejo intactos.
Change Budget
- Prefer fewer than 5 modified files.
- Prefer changes under 200 lines when feasible.
- Split the work into follow-up tasks if limits are exceeded.