From 929e30c58c4e3cfdd09b1f71bcd6094a9114da64 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Jul 2026 21:51:23 +0000 Subject: [PATCH] Add --name/--sport filters to the QP backfill script The reported bug was scoped to Wimbledon, and men's/women's majors share the same tournament name ("Wimbledon") with gender only distinguished by the sport, so a name-only filter can't isolate one gender. Add --sport (matched against the sport's name, e.g. "Tennis - Men") alongside --name, and log the sport name per tournament in --dry output so the target is easy to verify before running for real. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017AUcHy9m7aF6axsY6Grpe4 --- scripts/backfill-qp-resplit.ts | 40 +++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/scripts/backfill-qp-resplit.ts b/scripts/backfill-qp-resplit.ts index 8185f55..2f1ada7 100644 --- a/scripts/backfill-qp-resplit.ts +++ b/scripts/backfill-qp-resplit.ts @@ -16,8 +16,18 @@ * * Safe to re-run. Validate on a DB snapshot first. Reads DATABASE_URL. * - * npx tsx scripts/backfill-qp-resplit.ts # apply - * npx tsx scripts/backfill-qp-resplit.ts --dry # report only + * npx tsx scripts/backfill-qp-resplit.ts # apply, all tournaments + * npx tsx scripts/backfill-qp-resplit.ts --dry # report only + * npx tsx scripts/backfill-qp-resplit.ts --name Wimbledon # scope to matching event names + * npx tsx scripts/backfill-qp-resplit.ts --name Wimbledon --sport Men # + scope to a sport (e.g. gender) + * npx tsx scripts/backfill-qp-resplit.ts --name Wimbledon --sport Men --dry + * + * --name matches case-insensitively against each linked scoring event's name; + * matches ALL tournaments with a matching event (e.g. both years of "Wimbledon"), + * since the reported bug spans seasons. Tournament names don't encode gender (both + * men's and women's majors are just "Wimbledon") — use --sport to scope further, + * matched case-insensitively against the sport's name (e.g. "Tennis - Men"). + * Both filters apply to a tournament if ANY of its linked events match. */ import { drizzle } from "drizzle-orm/postgres-js"; @@ -32,6 +42,12 @@ import { } from "../app/services/sync-tournament-results.js"; const DRY = process.argv.includes("--dry"); +function argValue(flag: string): string | null { + const idx = process.argv.indexOf(flag); + return idx !== -1 && process.argv[idx + 1] ? process.argv[idx + 1].toLowerCase() : null; +} +const NAME_FILTER = argValue("--name"); +const SPORT_FILTER = argValue("--sport"); const log = (...a: unknown[]) => console.log(...a); async function run() { @@ -50,6 +66,23 @@ async function run() { byTournament.set(ev.tournamentId, arr); } + if (NAME_FILTER) { + for (const [tournamentId, evs] of byTournament) { + const matches = evs.some((e) => e.name?.toLowerCase().includes(NAME_FILTER)); + if (!matches) byTournament.delete(tournamentId); + } + log(`Filtering to tournaments matching --name "${NAME_FILTER}"`); + } + if (SPORT_FILTER) { + for (const [tournamentId, evs] of byTournament) { + const matches = evs.some((e) => + e.sportsSeason?.sport?.name?.toLowerCase().includes(SPORT_FILTER) + ); + if (!matches) byTournament.delete(tournamentId); + } + log(`Filtering to tournaments matching --sport "${SPORT_FILTER}"`); + } + log(`Tournaments with linked qualifying events: ${byTournament.size}`); let ok = 0; let failed = 0; @@ -57,7 +90,8 @@ async function run() { for (const [tournamentId, evs] of byTournament) { const simulatorType = evs[0]?.sportsSeason?.sport?.simulatorType ?? null; const bracketMajor = isBracketMajor(simulatorType); - const name = evs[0]?.name ?? tournamentId; + const sportName = evs[0]?.sportsSeason?.sport?.name ?? "unknown sport"; + const name = `${evs[0]?.name ?? tournamentId} [${sportName}]`; // Only re-score fully-scored majors so we don't mark in-progress ones complete. const anyComplete = evs.some((e) => e.isComplete);