claude/wimbledon-qp-scoring-bug-xevhlf #127

Merged
chrisp merged 3 commits from claude/wimbledon-qp-scoring-bug-xevhlf into main 2026-07-03 21:40:12 +00:00
Owner
No description provided.
chrisp added 2 commits 2026-07-03 21:26:24 +00:00
Four related bugs in the Qualifying Points subsystem surfaced on Wimbledon:

1. Some leagues stored 2 QP instead of 1.5 for Round-of-16 losers. Sibling/
   mirror windows scored via the placement-group path in processQualifyingEvent,
   which took the tie span from the players present on that window's roster
   (a draftable subset) instead of the full field. A window holding fewer than
   the 8 tied R16 losers split the 9-16 points too few ways and over-awarded.
   The tie span is now derived from the canonical tournament_results (the whole
   field) for tournament-linked events, falling back to the live count only for
   standalone events. Every league now scores identically.

2. Discord notifications rounded QP with Math.round, turning 1.5 into "2".
   Both the "Points Awarded" and "QP Standings" values now use a 2-decimal
   formatter mirroring the web UI's formatQP, so Discord and the site agree.

3. The Discord "QP Standings" block ranked players only among that event's
   scorers, showing two R16 losers as T1 instead of T9. Rank is now computed
   over the full season field and passed through to the notifier.

4. "N of M majors completed" reached "11 of 4": majorsCompleted was a stored
   counter incremented on every fan-out sync with a guard that misfired. It is
   now derived on read (getMajorsCompleted = count of completed qualifying
   events), which is self-correcting; the increment/decrement writes are removed
   along with the now-unused hasProcessedQualifyingPlacement helper.

Adds scripts/backfill-qp-resplit.ts to silently re-score existing majors so
already-corrupted seasons are corrected (2 -> 1.5), and threads a
skipNotifications option through processQualifyingEvent / syncTournamentResults
so the backfill does not re-ping every league.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AUcHy9m7aF6axsY6Grpe4
Address code review: route cloned windows correctly, dedupe canonical query
Some checks failed
🚀 Deploy / 🧪 Test (pull_request) Successful in 3m3s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Failing after 48s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
ad238e6bfb
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
chrisp added 1 commit 2026-07-03 21:33:48 +00:00
Fix lint errors from oxlint: array-sort and function-scoping
All checks were successful
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
🚀 Deploy / 🧪 Test (pull_request) Successful in 3m12s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Successful in 1m18s
83e41e9cf1
- Use Array#toSorted() instead of Array#sort() in the QP global-rank builder
  (qualifying-points-discord.server.ts) and the test's withRanks helper.
- Move the discord.test.ts withRanks helper to module scope — it captured
  nothing from the enclosing describe block, which oxlint's
  consistent-function-scoping rule flags as an error.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017AUcHy9m7aF6axsY6Grpe4
chrisp merged commit 58e656f15e into main 2026-07-03 21:40:12 +00:00
chrisp deleted branch claude/wimbledon-qp-scoring-bug-xevhlf 2026-07-03 21:40:12 +00:00
Sign in to join this conversation.
No description provided.