Follow-up to the QP scoring fix, from self-review:
- Cloned qualifying windows carry a bracketTemplateId (copied by
cloneSportsSeason) but no playoff matches, so they hit the bracket branch,
where processQualifyingBracketEvent derives zero states and writes no QP —
the canonical-tie-count fix never ran for them. processQualifyingEvent now
routes to the bracket writer only when the window actually has playoff
matches; otherwise it falls through to the placement/canonical path like any
no-template sibling.
- The canonical tournament_results tie span was queried once per window inside
the fan-out loop. syncTournamentResults already loads the canonical results,
so it now builds the tie-count map once (buildTieCountByPlacement) and passes
it to each processQualifyingEvent call; direct callers still query it lazily.
- syncTournamentResults no longer re-stamps completedAt on windows that are
already complete, so a backfill re-run doesn't churn timestamps.
Adds regression tests: a cloned window (template id, no matches) scores R16
losers at 1.5 via the canonical path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AUcHy9m7aF6axsY6Grpe4