- Remove unused filterNewResults import (events batch-add-results legacy path was removed in Phase 4 Task 4). - Replace import() type annotation in sync-tournament-results test with a top-level type import (consistent-type-imports rule). - Hoist tableName helper out of makeFakeDb closure so it's not recreated per call (consistent-function-scoping rule). - eqeqeq: replace `!= null` with explicit null/undefined checks in tournament-identity. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
/**
|
|
* Extracts the canonical tournament identity — `(name, year)` — from a scoring
|
|
* event. Used both by the Phase 2 backfill and by the admin create-event flow
|
|
* that auto-provisions a canonical tournament for new qualifying events.
|
|
*
|
|
* Rules:
|
|
* - If the event name ends with a 4-digit year, strip it; that year wins.
|
|
* - Otherwise, fall back to the year portion of eventDate (YYYY-MM-DD).
|
|
* - If neither produces a year, throw.
|
|
*/
|
|
|
|
export interface ScoringEventIdentityInput {
|
|
name: string;
|
|
eventDate: string | Date | null | undefined;
|
|
eventType: string;
|
|
}
|
|
|
|
export interface TournamentIdentity {
|
|
name: string;
|
|
year: number;
|
|
}
|
|
|
|
const YEAR_SUFFIX = /\s+(\d{4})\s*$/;
|
|
|
|
export function extractTournamentIdentity(ev: ScoringEventIdentityInput): TournamentIdentity {
|
|
const trimmed = ev.name.trim();
|
|
const yearMatch = trimmed.match(YEAR_SUFFIX);
|
|
let cleanName = trimmed;
|
|
let year: number | null = null;
|
|
|
|
if (yearMatch) {
|
|
year = parseInt(yearMatch[1], 10);
|
|
cleanName = trimmed.replace(YEAR_SUFFIX, "").trim();
|
|
}
|
|
|
|
if (year === null && ev.eventDate !== null && ev.eventDate !== undefined) {
|
|
const iso = ev.eventDate instanceof Date
|
|
? ev.eventDate.toISOString()
|
|
: String(ev.eventDate);
|
|
year = parseInt(iso.slice(0, 4), 10);
|
|
}
|
|
|
|
if (year === null || Number.isNaN(year)) {
|
|
throw new Error(
|
|
`cannot determine year for event "${ev.name}" — no year in name and eventDate is null`,
|
|
);
|
|
}
|
|
|
|
return { name: cleanName, year };
|
|
}
|