Files
comunidadhll/ai/tasks/done/TASK-220-schedule-public-snapshot-refreshes.md

6.5 KiB

id, title, status, type, team, supporting_teams, roadmap_item, priority
id title status type team supporting_teams roadmap_item priority
TASK-220 Schedule public snapshot refreshes done backend Backend Senior
Arquitecto Python
foundation high

TASK-220 - Schedule public snapshot refreshes

Goal

Configure automatic regeneration of public snapshots and read models at appropriate times, so public pages do not depend on heavy runtime calculations.

Context

Public historical, ranking and stats pages should read precomputed data. Heavy regeneration should happen inside the internal runner during low-load windows, while weekly/monthly ranking and recent matches stay fresh at shorter intervals.

Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.

Steps

  1. Inspect the listed files first.
  2. Document how the current refresh paths work.
  3. Add environment-driven scheduling for daily full refresh, frequent ranking refresh and recent match snapshot refresh.
  4. Keep refreshes idempotent and non-overlapping.
  5. Document Portainer configuration and manual emergency commands.
  6. Validate Python compilation and scheduler helpers.

Files to Read First

  • AGENTS.md
  • ai/repo-context.md
  • ai/architecture-index.md
  • ai/orchestrator/backend-senior.md
  • ai/orchestrator/python-architect.md
  • backend/app/historical_runner.py
  • backend/app/rcon_historical_leaderboards.py
  • backend/app/rcon_annual_rankings.py
  • backend/app/rcon_historical_player_stats.py
  • backend/app/historical_snapshot_storage.py
  • backend/app/historical_snapshots.py
  • backend/app/payloads.py
  • backend/app/config.py
  • backend/app/main.py
  • docker-compose.yml
  • README.md
  • docs/PERFORMANCE_PUBLIC_QUERY_AUDIT.md

Expected Files to Modify

  • backend/app/config.py
  • backend/app/historical_runner.py
  • backend/app/historical_snapshots.py
  • backend/app/routes.py
  • backend/tests/test_historical_snapshot_refresh.py
  • docker-compose.yml
  • docs/public-snapshot-refresh-schedule.md
  • ai/tasks/in-progress/TASK-220-schedule-public-snapshot-refreshes.md

Constraints

  • Do not execute ai-platform run.
  • Do not push or commit.
  • Do not touch frontend except documentation if unavoidable.
  • Do not touch weapon assets, SVGs or physical images.
  • Do not touch ai/system-metrics.md.
  • Do not reactivate Elo/MMR.
  • Do not reintroduce Comunidad Hispana #03.
  • Keep public requests on read models/snapshots for rankings.
  • Prefer the internal runner over host cron.

Validation

Before completing the task ensure:

  • Run python -m compileall for modified backend modules.
  • Run relevant existing backend tests if applicable.
  • Validate scheduler helper behavior for the next 06:00 Europe/Madrid.
  • Confirm public route modules still compile.
  • Review git diff --name-only.
  • Confirm no frontend, weapon assets, SVGs, physical images or ai/system-metrics.md were modified by this task.

Outcome

Completed.

Current-state analysis:

  • ranking_snapshots weekly/monthly were generated by refresh_ranking_snapshots() and invoked from historical_runner once per historical runner cycle. Compose forced --hourly, so public rankings could wait up to an hour despite the code recommending 5-15 minute freshness.
  • Annual ranking snapshots existed through generate_annual_ranking_snapshot() but were only manual/CLI-driven, not part of the runner schedule.
  • player_search_index and player_period_stats were refreshed from historical_runner once per runner cycle.
  • Recent matches were included in full/priority historical snapshots, but there was no dedicated short-cadence refresh. RCON capture exposed materialized_matches_inserted, which can be used as a finished-match hook.
  • historical_runner already existed and is the right place for internal scheduling; no host cron is required.
  • Public historical snapshot leaderboard routes in RCON mode were using a runtime materialized fast path despite being snapshot endpoints.

Implemented strategy:

  • Added public refresh env configuration with safe defaults.
  • Kept the internal runner as scheduler and removed the Compose --hourly override so the runner can tick at the shortest public interval while still throttling the heavier historical cycle separately.
  • Added daily public full refresh logic, due once per local day after 06:00 Europe/Madrid.
  • Added frequent weekly/monthly ranking snapshot refresh at HLL_PUBLIC_RANKING_REFRESH_INTERVAL_SECONDS.
  • Added recent-match-only snapshot generation and scheduled it at HLL_PUBLIC_RECENT_MATCHES_REFRESH_INTERVAL_SECONDS.
  • Added immediate recent-match refresh when RCON capture reports newly materialized finished matches.
  • Added structured start/end logs, durations and per-step results. Per-step failures are captured without stopping neighboring refreshes or the runner.
  • Added in-process non-overlap guards for public refresh classes.
  • Changed public historical leaderboard snapshot routes to read persisted snapshots instead of the RCON runtime fast path.
  • Documented Portainer configuration and emergency commands in docs/public-snapshot-refresh-schedule.md.

Validation:

  • python -m compileall backend/app/config.py backend/app/historical_runner.py backend/app/historical_snapshots.py backend/app/routes.py
  • python -m compileall backend/app backend/tests
  • $env:PYTHONPATH='backend'; python -m unittest backend.tests.test_historical_snapshot_refresh
  • $env:PYTHONPATH='backend'; python -m unittest backend.tests.test_annual_ranking_payload
  • Dry-run scheduler helper check:
    • 2026-06-10T03:30:00Z -> next refresh 2026-06-10T04:00:00Z (06:00 Europe/Madrid)
    • 2026-06-10T05:00:00Z -> next refresh 2026-06-11T04:00:00Z
  • Route dry-run with patched builder confirmed /api/historical/snapshots/leaderboard resolves through build_leaderboard_snapshot_payload.
  • git diff --name-only reviewed.

Exclusions:

  • Did not execute ai-platform run.
  • Did not push or commit.
  • Did not modify frontend files as part of this task.
  • Did not modify physical images, weapon assets, SVGs or ai/system-metrics.md.
  • Did not reactivate Elo/MMR.
  • Did not reintroduce Comunidad Hispana #03.

Note: the worktree still contains pre-existing unrelated changes in ai/system-metrics.md, frontend/assets/css/styles.css, clan image files and weapon/SVG assets. They were not touched by this task.

Change Budget

  • Prefer fewer than 5 modified files when feasible.
  • Prefer changes under 200 lines when feasible.
  • Split follow-up tasks if scope grows.