Files
comunidadhll/ai/tasks/done/TASK-109-fix-backend-startup-with-elo-paused.md
devRaGonSa 2271608836 fix: keep backend startup independent from paused elo
Avoid eager Elo/MMR imports during backend startup while the feature is paused. Add validation coverage for backend startup and health route resolution.
2026-05-19 09:09:20 +02:00

8.0 KiB

id, title, status, type, team, supporting_teams, roadmap_item, priority
id title status type team supporting_teams roadmap_item priority
TASK-109 Keep backend startup independent from paused Elo/MMR pending backend Backend Senior
Arquitecto Python
foundation high

TASK-109 - Keep backend startup independent from paused Elo/MMR

Goal

Fix backend startup so the default operational Compose profile can start backend and frontend while Elo/MMR and complex historical materialization remain paused.

The backend must expose /health and non-Elo routes even if Elo/MMR engine internals are unavailable or temporarily broken.

Context

HLL Vietnam has simplified its default operational mode. The normal Compose profile should start only backend and frontend; historical workers, Elo/MMR, complex historical materialization, and server #03 are paused operationally.

Current validation shows:

  • docker compose config --services returns only backend and frontend.
  • docker compose up -d --build starts the frontend successfully.
  • The frontend responds with HTTP 200.
  • The backend restarts continuously.
  • /health fails because backend startup imports Elo/MMR code.
  • Backend logs include: ImportError: cannot import name 'ELO_K_FACTOR' from 'app.elo_mmr_models'.
  • The startup import path is: app.main -> app.routes -> app.payloads -> app.elo_mmr_engine -> app.elo_mmr_models.
  • payloads.py imports Elo/MMR payload functions at module import time, so a paused or broken Elo implementation can break the whole backend, including /health.

This task is startup-focused. Preserve the existing HLL Vietnam product identity and repository discipline, and keep the fix narrow.

Steps

  1. Inspect the listed files before changing anything.
  2. Confirm the backend startup import path and where Elo/MMR is imported at module load time.
  3. Refactor only the startup boundary needed so /health and non-Elo routes do not depend on successful import of Elo/MMR engine internals.
  4. Prefer lazy importing Elo/MMR functions only inside Elo-specific payload builders or routes.
  5. If Elo/MMR is paused or unavailable, make Elo-specific endpoints return a controlled unavailable or fallback payload instead of crashing backend import.
  6. Preserve the public API shape as much as possible.
  7. Add or update tests if a backend test framework exists.
  8. Update lightweight validation if needed so future startup import regressions are caught.
  9. Document the paused Elo/MMR startup boundary if documentation needs adjustment.
  10. Run the required validation before committing.
  11. Move this task file to ai/tasks/done/ only after validation is complete and the outcome is documented.
  12. Stage only intended files, commit, and push the branch to origin.

Files to Read First

  • backend/app/main.py
  • backend/app/routes.py
  • backend/app/payloads.py
  • backend/app/elo_mmr_engine.py
  • backend/app/elo_mmr_models.py
  • backend/app/config.py
  • backend/tests/ if present
  • docker-compose.yml
  • scripts/run-integration-tests.ps1
  • README.md
  • docs/decisions.md

Expected Files to Modify

  • likely backend/app/payloads.py
  • possibly backend/app/routes.py
  • possibly backend/app/elo_mmr_engine.py
  • possibly backend/app/elo_mmr_models.py only if justified
  • possibly tests under backend/tests/
  • possibly scripts/run-integration-tests.ps1
  • this task file moved from ai/tasks/pending/ to ai/tasks/done/

If additional files become necessary, explain why in the task outcome and commit message.

Expected Files Not to Modify

  • frontend/**
  • docker-compose.yml, unless validation proves a Compose-only issue also exists
  • database migrations
  • persisted data
  • unrelated backend modules
  • server #03 configuration

Constraints

  • Do not delete Elo/MMR code.
  • Do not delete historical ingestion code.
  • Do not remove database migrations or persisted data.
  • Do not change frontend behavior.
  • Do not reintroduce server #03.
  • Keep the fix narrow and startup-focused.
  • Do not implement a new Elo/MMR algorithm.
  • Do not reintroduce ELO_K_FACTOR as a blind compatibility patch unless you prove it is the smallest safe fix and still prevents startup coupling.
  • Keep /health available even if Elo/MMR import fails.
  • Preserve existing public API shape as much as possible.
  • Do not modify unrelated files.
  • Do not leave completed work only in local; commit and push after validation.

Validation

Before completing the task, run and document:

  • git status
  • powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1
  • docker compose down
  • docker compose up -d --build
  • docker compose ps
  • docker compose logs --tail=100 backend
  • Invoke-WebRequest http://localhost:8000/health | Select-Object -ExpandProperty Content
  • Invoke-WebRequest http://localhost:8080 | Select-Object -ExpandProperty StatusCode

Also confirm and document:

  • backend is not restarting
  • /health returns a valid payload
  • frontend still returns 200
  • no frontend files changed
  • no database migrations or persisted data changed
  • backend/runtime/ is not created or committed
  • git diff --name-only matches the expected scope

If integration tests are relevant and scripts/run-integration-tests.ps1 exists, use it. If no backend test framework exists for this scope, document that explicitly in the outcome.

Commit And Push Requirements

  • Run all validation before committing.
  • Run git status.
  • Stage only intended files.
  • Commit with a clear message, for example: fix: keep backend startup independent from paused elo.
  • Push the branch to origin.
  • Do not leave completed work only in local.

Outcome

  • Validation performed:
    • git status --short
    • python -c "import sys; sys.path.insert(0, 'backend'); import app.main; from app.routes import resolve_get_payload; print(resolve_get_payload('/health'))"
    • python -c "import sys; sys.path.insert(0, 'backend'); from app.routes import resolve_get_payload; print(resolve_get_payload('/api/historical/elo-mmr/leaderboard'))"
    • powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1
    • docker compose down
    • docker compose up -d --build
    • docker compose ps
    • docker compose logs --tail=100 backend
    • Invoke-WebRequest http://localhost:8000/health | Select-Object -ExpandProperty Content
    • Invoke-WebRequest http://localhost:8080 | Select-Object -ExpandProperty StatusCode
    • Invoke-WebRequest 'http://localhost:8000/api/historical/elo-mmr/leaderboard' | Select-Object -ExpandProperty Content
    • git diff --name-only
  • Startup coupling removed:
    • backend/app/payloads.py no longer imports app.elo_mmr_engine at module load time.
    • Elo/MMR engine imports now happen only inside Elo/MMR payload builders.
    • app.main -> app.routes -> app.payloads can load and serve /health without importing paused Elo/MMR internals.
  • Elo/MMR unavailable behavior:
    • If the Elo/MMR engine cannot be imported, Elo/MMR endpoints return the existing status + data envelope with source: "elo-mmr-paused", available: false, unavailable_reason: "elo-mmr-engine-import-unavailable", normal source policy metadata, and empty/null Elo data.
  • Tests and validation:
    • No backend test framework is configured for this scope.
    • scripts/run-integration-tests.ps1 now includes a lightweight backend startup import check and /health route resolution check.
  • Scope confirmation:
    • Backend was up and not restarting in docker compose ps.
    • /health returned a valid JSON payload with status: "ok".
    • Frontend returned HTTP 200.
    • No frontend files changed.
    • No database migrations, persisted data, or server #03 configuration changed.
    • backend/runtime/ was not created.
    • git diff --name-only matched the expected scope: backend/app/payloads.py and scripts/run-integration-tests.ps1.
  • Commit and push:
    • Commit hash and pushed branch are recorded in the final task execution response.

Change Budget

  • Prefer fewer than 5 modified files.
  • Prefer changes under 200 lines when feasible.
  • Split follow-up work into a new task if the scope expands beyond startup independence.