Auto-populate & auto-score tennis Grand Slam brackets from Wikipedia #112

Merged
chrisp merged 1 commit from feat/tennis-draw-sync into main 2026-06-27 04:55:29 +00:00
Owner

What

Adds a per-event Sync Draw for tennis majors: pulls the full 128-player draw from its Wikipedia article, auto-creates/links participants (and propagates them to every linked sibling season), builds the bracket, and runs the qualifying-points scorer. Re-running advances the bracket and scoring as matches complete.

Highlights

Core sync

  • WikipediaTennisAdapter + wikitext bracket parser, syncTennisDraw orchestrator, idempotent populateBracketFromDraw (keyed on externalMatchId)
  • scoring_events.externalSourceKey column for the article (migration 0123)
  • Admin "Sync Draw" card (accepts a URL or a title) + a cron pass

Scoring fix

  • deriveBracketQualifyingStates now only floors players who've reached the scoring stage. For deep brackets (tennis_128) early-round losers earn 0 QP instead of a phantom 9th-place floor. CS2/simple_8 behavior preserved (gated on rounds[0].isScoring). Re-sync reconciles stale QP rows inside a transaction.

Matching & parsing

  • accent-folding in normalizeTeamName; strips Wikipedia (tennis) disambiguators; treats Bye/TBD/Qualifier as TBD; extracts the wikilink before template-stripping so {{nowrap}}-wrapped players parse correctly

Admin UX

  • dry-run Preview (matched / will-create / possible duplicates / unfilled slots) with inline "rename existing" / "create as new" resolution via fetcher (no full reload)

Testing

  • Parser against a real 2025 Wimbledon fixture, draw mapping, tennis_128 scoring, accent/disambiguator/nowrap parsing, URL parsing
  • Full suite green (2533 tests), typecheck + lint clean

Notes

  • Run npm run db:migrate to apply the externalSourceKey migration.

🤖 Generated with Claude Code

## What Adds a per-event **Sync Draw** for tennis majors: pulls the full 128-player draw from its Wikipedia article, auto-creates/links participants (and propagates them to every linked sibling season), builds the bracket, and runs the qualifying-points scorer. Re-running advances the bracket and scoring as matches complete. ## Highlights **Core sync** - `WikipediaTennisAdapter` + wikitext bracket parser, `syncTennisDraw` orchestrator, idempotent `populateBracketFromDraw` (keyed on `externalMatchId`) - `scoring_events.externalSourceKey` column for the article (migration `0123`) - Admin "Sync Draw" card (accepts a URL or a title) + a cron pass **Scoring fix** - `deriveBracketQualifyingStates` now only floors players who've reached the scoring stage. For deep brackets (`tennis_128`) early-round losers earn **0 QP** instead of a phantom 9th-place floor. CS2/`simple_8` behavior preserved (gated on `rounds[0].isScoring`). Re-sync reconciles stale QP rows inside a transaction. **Matching & parsing** - accent-folding in `normalizeTeamName`; strips Wikipedia `(tennis)` disambiguators; treats Bye/TBD/Qualifier as TBD; extracts the wikilink before template-stripping so `{{nowrap}}`-wrapped players parse correctly **Admin UX** - dry-run **Preview** (matched / will-create / possible duplicates / unfilled slots) with inline "rename existing" / "create as new" resolution via fetcher (no full reload) ## Testing - Parser against a real 2025 Wimbledon fixture, draw mapping, `tennis_128` scoring, accent/disambiguator/`nowrap` parsing, URL parsing - Full suite green (2533 tests), typecheck + lint clean ## Notes - Run `npm run db:migrate` to apply the `externalSourceKey` migration. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chrisp added 1 commit 2026-06-27 04:48:19 +00:00
Auto-populate & auto-score tennis Grand Slam brackets from Wikipedia
All checks were successful
🚀 Deploy / 🧪 Test (pull_request) Successful in 3m13s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Successful in 1m23s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
81d063faa1
Add a per-event "Sync Draw" that pulls a tennis major's full 128-player
draw from its Wikipedia article, auto-creates/links participants (and
propagates them to every linked sibling season), builds the bracket, and
runs the qualifying-points scorer. Re-running advances the bracket and
scoring as matches complete.

Core
- match-sync: WikipediaTennisAdapter + wikitext bracket parser, DrawSync
  DTOs, syncTennisDraw orchestrator, pure draw->rows mapping
- playoff-match: populateBracketFromDraw (idempotent upsert on externalMatchId)
- scoring_events.externalSourceKey column (Wikipedia article; migration 0123)
- admin bracket "Sync Draw" card (accepts URL or title) + cron pass

Scoring fix
- deriveBracketQualifyingStates only floors players who have reached the
  scoring stage; for deep brackets (tennis_128) early-round losers earn 0 QP
  instead of a phantom 9th-place floor. CS2/simple_8 behavior preserved
  (gated on rounds[0].isScoring). Re-sync reconciles stale QP rows in a
  transaction.

Matching & parsing
- accent-folding in normalizeTeamName; strip Wikipedia "(tennis)"
  disambiguators; treat Bye/TBD/Qualifier as TBD; extract wikilink before
  template-stripping so {{nowrap}}-wrapped players parse

Admin UX
- dry-run preview (matched / will-create / possible duplicates / unfilled
  slots) with inline "rename existing" / "create as new" resolution via
  fetcher (no full reload)

Tests: parser vs real 2025 Wimbledon fixture, draw mapping, tennis_128
scoring, accent/disambiguator/nowrap parsing, URL parsing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chrisp merged commit dfbb25771d into main 2026-06-27 04:55:29 +00:00
chrisp deleted branch feat/tennis-draw-sync 2026-06-27 04:55:30 +00:00
Sign in to join this conversation.
No description provided.