brackt/scripts/backfill/match-tournament.ts
Chris Parsons 85bca8bb77
scripts: add extractTournamentIdentity helper for backfill
Pure function that derives canonical (name, year) identity from a
scoring_events row, stripping trailing 4-digit years from the name or
falling back to eventDate. Used by the Phase 2 backfill to group
per-window events into canonical tournaments.
2026-05-01 20:47:23 +00:00

57 lines
1.6 KiB
TypeScript

/**
* Pure function(s) for extracting canonical tournament identity
* (name + year) from a `scoring_events` row.
*
* Used by the Phase 2 backfill to group per-window events into
* canonical `tournaments` rows.
*/
export interface ScoringEventInput {
name: string;
eventDate: string | null;
eventType: string;
}
export interface TournamentIdentity {
/** Tournament name with any trailing 4-digit year stripped. */
name: string;
year: number;
}
const TRAILING_YEAR_RE = / (\d{4})$/;
/**
* Extracts the canonical `(name, year)` identity for a tournament
* from a scoring event.
*
* Resolution order for year:
* 1. A trailing 4-digit year on the event name (e.g. "Wimbledon 2026").
* The year is stripped from the returned name.
* 2. The first 4 characters of `eventDate` (format `YYYY-MM-DD`).
*
* Throws if neither source supplies a year.
*/
export function extractTournamentIdentity(
ev: ScoringEventInput,
): TournamentIdentity {
const trimmedName = ev.name.trim();
const match = trimmedName.match(TRAILING_YEAR_RE);
if (match) {
const yearFromName = Number(match[1]);
const nameWithoutYear = trimmedName.slice(0, match.index).trim();
return { name: nameWithoutYear, year: yearFromName };
}
if (ev.eventDate) {
const yearStr = ev.eventDate.slice(0, 4);
const yearFromDate = Number(yearStr);
if (Number.isFinite(yearFromDate) && yearStr.length === 4) {
return { name: trimmedName, year: yearFromDate };
}
}
throw new Error(
`cannot determine year for scoring event "${ev.name}" (eventDate=${ev.eventDate ?? "null"})`,
);
}