refactor: remove legacy direct-write fallback in batch-add-results

Every qualifying scoring_event now has tournament_id (check constraint
enforces it), so the non-canonical fallback is dead. Replace with an
explicit error surface so any configuration regression becomes visible
instead of silently bypassing canonical.

Phase 4 Task 4.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Chris Parsons 2026-05-01 23:08:19 +00:00
parent 549b437466
commit e2a62bd05b
No known key found for this signature in database

View file

@ -384,8 +384,15 @@ export async function action({ request, params }: Route.ActionArgs) {
return { error: "Scoring event not found" }; return { error: "Scoring event not found" };
} }
if (scoringEvent.tournamentId) { // Qualifying events always have a canonical tournament link (check
// Canonical path: translate season_participant.id → canonical participant.id // constraint). Write results canonically and fan out.
if (!scoringEvent.tournamentId) {
return {
error:
"This scoring event has no canonical tournament link — cannot save batch results. Contact a developer.",
};
}
const spRows = allSeasonParticipants.filter((sp) => const spRows = allSeasonParticipants.filter((sp) =>
incoming.some((r) => r.participantId === sp.id), incoming.some((r) => r.participantId === sp.id),
); );
@ -411,26 +418,6 @@ export async function action({ request, params }: Route.ActionArgs) {
success: `${incoming.length} result${incoming.length === 1 ? "" : "s"} saved canonically. Synced to ${syncReport.windowsSynced} window${syncReport.windowsSynced === 1 ? "" : "s"}${syncReport.windowsFailed > 0 ? ` (${syncReport.windowsFailed} failed)` : ""}.`, success: `${incoming.length} result${incoming.length === 1 ? "" : "s"} saved canonically. Synced to ${syncReport.windowsSynced} window${syncReport.windowsSynced === 1 ? "" : "s"}${syncReport.windowsFailed > 0 ? ` (${syncReport.windowsFailed} failed)` : ""}.`,
syncReport, syncReport,
}; };
}
// Legacy direct-write path for non-canonical events (team sports, etc.).
const existingResults = await getEventResults(params.eventId);
const existingIds = new Set(existingResults.map((r) => r.seasonParticipantId));
const newResults = filterNewResults(incoming, existingIds);
if (newResults.length > 0) {
await createEventResultsBulk(
newResults.map((r) => ({
scoringEventId: params.eventId,
participantId: r.participantId,
placement: r.placement,
}))
);
}
return {
success: `${newResults.length} result${newResults.length === 1 ? "" : "s"} saved${incoming.length - newResults.length > 0 ? ` (${incoming.length - newResults.length} duplicate${incoming.length - newResults.length === 1 ? "" : "s"} skipped)` : ""}.`,
};
} catch (error) { } catch (error) {
logger.error("Error saving batch results:", error); logger.error("Error saving batch results:", error);
return { error: "Failed to save results" }; return { error: "Failed to save results" };