8.4 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-148 | Relink existing RCON matches to scoreboard candidates | done | backend | Backend Senior |
|
rcon-full-data | high |
TASK-148 - Relink existing RCON matches to scoreboard candidates
Goal
Add a deterministic relink flow that can update or resolve scoreboard URLs for already-materialized RCON matches after new scoreboard candidates are inserted.
Background
After manually inserting the Foy 1562115 candidate, the match detail page
showed the expected scoreboard button. Future backfills may insert candidates
after RCON matches already exist, so the system must relink existing RCON
matches with null or missing match_url dynamically or via materialization.
Known Foy regression target:
- RCON match key:
comunidad-hispana-02:1779310451:1779315851:foywarfare - candidate external match id:
1562115 - expected URL:
https://scoreboard.comunidadhll.es:5443/games/1562115
Constraints / DO NOT BREAK
- Do not relax trusted scoreboard URL allowlist.
- Do not link to unsafe origins.
- Do not choose ambiguous candidates silently.
- Do not break old Carentan match:
comunidad-hispana-02:1779178461:1779183861:carentanwarfare - Do not break Kharkov:
comunidad-hispana-02:1779315955:1779319098:kharkovwarfare - Do not re-add public scoreboard buttons to recent match cards.
- Do not expose correlation debug text in normal UI.
Allowed Changes
- Existing RCON materialization, historical read-model, and RCON storage modules needed for deterministic candidate relinking.
backend/app/scoreboard_candidate_backfill.pyonly when needed to trigger or document the relink sequence.- A focused backend relink command module or a narrowly scoped command option on existing materialization CLI.
- Focused backend scoreboard correlation tests and fixtures/mocks.
- This task file when it moves through the task workflow.
Implementation Requirements
- Inspect current correlation logic:
backend/app/rcon_admin_log_materialization.pybackend/app/rcon_historical_read_model.pybackend/app/postgres_rcon_storage.pybackend/app/scoreboard_candidate_backfill.py
- Add or improve a function that matches RCON materialized matches to
rcon_scoreboard_match_candidatesusing:- same server slug / external server id
- normalized map identity
- overlapping or close time window
- score allied/axis where present
- winner where present
- Tolerances:
- allow reasonable time drift between RCON and scoreboard, at least +/- 15 minutes, preferably configurable or centralized
- for matches with null
started_at/ended_atbutclosed_atplusduration_seconds, derive a correlation window
- When a best safe candidate is found, make
match_urlavailable in detail payload. - Prefer deterministic scoring:
- exact map match
- close end time
- score match
- same server
- reject ambiguous ties unless one candidate is clearly better
- Add a command or option to relink existing matches without needing new
ingestion:
- acceptable command module:
python -m app.rcon_scoreboard_relink - acceptable alternative: an option inside
app.rcon_admin_log_materialization
- acceptable command module:
- The relink command must print JSON summary:
matches_scannedcandidates_scannedmatches_linkedmatches_skipped_no_candidatematches_skipped_ambiguouserrors
- Ensure
scoreboard_candidate_backfillcan optionally trigger relink at the end, or document the command sequence. - Add regression coverage for the Foy case:
- RCON match key
comunidad-hispana-02:1779310451:1779315851:foywarfare - candidate external match id
1562115 - expected
match_urlhttps://scoreboard.comunidadhll.es:5443/games/1562115
- RCON match key
- Ensure the detail endpoint returns
match_urlafter relink.
Files to Read First
AGENTS.mdai/architecture-index.mdai/repo-context.mdai/orchestrator/backend-senior.mdbackend/app/rcon_admin_log_materialization.pybackend/app/rcon_historical_read_model.py
Expected Files to Modify
- Existing RCON correlation/materialization/storage code needed for relinking.
- One relink CLI entry point or one existing CLI option.
- Focused scoreboard correlation regression tests.
- This task file after moving it through the workflow.
Keep correlation diagnostics out of this task except the JSON relink summary required here. Use TASK-149 for detailed diagnostic output and docs.
Validation
python -m compileall backend/apppython -m unittest discover -s tests -p "*scoreboard*"powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1docker compose --profile advanced up -d --build backend frontend postgresdocker compose exec backend python -m app.scoreboard_candidate_backfill --server comunidad-hispana-02 --from 2026-05-20T00:00:00Z --to 2026-05-21T23:59:59Z --max-pages 5 --page-size 100- Run the new relink command.
- Use
Invoke-WebRequestfor the Foy detail payload and verifyfoundis true andmatch_urlis present. - Use
Invoke-WebRequestfor the Carentan detail payload and verify the existingmatch_urlis still present. - Review
git diff --name-onlyand confirm the changed files match this task.
Manual Verification
- Foy detail page shows
Ver en Scoreboard. - Scoreboard button opens the
1562115public URL. - Recent match cards still do not show public scoreboard links.
- No
Detalle no disponiblestate appears for the validated detail page. - Player filters and external profile links still work.
Commit Message
fix: relink rcon matches to scoreboard candidates
Outcome
Document correlation scoring choices, time-window derivation, ambiguity handling, relink command output, validation, and any follow-up task instead of expanding scope.
- Added
python -m app.rcon_scoreboard_relinkto scan already-materialized ended RCON matches against the same trusted candidate resolution used by the detail read model. The command reportsmatches_scanned,candidates_scanned,matches_linked,matches_skipped_no_candidate,matches_skipped_ambiguousanderrorsas JSON. - Kept URL availability dynamic in the read model instead of adding a second persisted URL column to RCON matches. The new correlation resolution summary preserves the existing deterministic map/time/duration/score scoring path, returns explicit low-confidence/no-candidate/ambiguous reasons, and exposes the selected external candidate only to command callers.
- Reused the existing materialized window derivation for closed-at plus server-time duration cases so relink and detail payloads evaluate the same effective correlation window.
- Added a Foy regression for materialized match key
comunidad-hispana-02:1779310451:1779315851:foywarfare: relink reports a safe link and detail returnshttps://scoreboard.comunidadhll.es:5443/games/1562115. - Validation:
python -m compileall backend/apppython -m unittest discover -s tests -p "*scoreboard*"frombackend/passed with existing SQLiteResourceWarningoutput in the scoreboard regression file.powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1passed; the script reports no product integration tests configured for its platform-only scope.docker compose --profile advanced up -d --build backend frontend postgres- Re-ran
app.scoreboard_candidate_backfillfor the requested May 20-21 window. Candidate refresh succeeded (list_candidates_updated: 11), while detail enrichment returned a partial status because SQLite reporteddatabase is lockedfor detail match1562104. docker compose exec backend python -m app.rcon_scoreboard_relink --server comunidad-hispana-02reported 19 scanned matches, 13 linked matches, 6 no-candidate skips, 0 ambiguous skips and no errors.- HTTP detail verification returned
found: trueand the expected Foy URL. Existing Carentan detail keycomunidad-hispana-02:1779178461:1779183861:carentanwarfarealso kept a trustedmatch_url.
- Scope review used
git diff --name-only; relink changes stay within the correlation/read-model command path, focused scoreboard tests and this task file.
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 grows.