fix: clean up derived data when deleting scoring events (#130)
- Bracket events (playoff_game): delete all participantResults for the sports season atomically with the event, then recalculate league standings - Qualifying events: capture affected participant IDs before cascade deletes eventResults, recalculate participantQualifyingTotals from remaining events, decrement majorsCompleted if QP had been processed, and recalculate league standings Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
50722531ca
commit
80bdbbc3bb
1 changed files with 61 additions and 2 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
import { eq, and, desc, asc, gte, lte } from "drizzle-orm";
|
||||
import { recalculateAffectedLeagues } from "./scoring-calculator";
|
||||
import { recalculateParticipantQP } from "./qualifying-points";
|
||||
|
||||
export type EventType = "playoff_game" | "major_tournament" | "final_standings" | "schedule_event";
|
||||
|
||||
|
|
@ -189,7 +191,10 @@ export async function completeScoringEvent(
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete a scoring event
|
||||
* Delete a scoring event.
|
||||
* For bracket events (playoff_game), also clears all participant results for the
|
||||
* sports season (placements are stored there with no FK back to the event) and
|
||||
* recalculates league standings.
|
||||
*/
|
||||
export async function deleteScoringEvent(
|
||||
eventId: string,
|
||||
|
|
@ -197,7 +202,61 @@ export async function deleteScoringEvent(
|
|||
) {
|
||||
const db = providedDb || database();
|
||||
|
||||
await db.delete(schema.scoringEvents).where(eq(schema.scoringEvents.id, eventId));
|
||||
const event = await db.query.scoringEvents.findFirst({
|
||||
where: eq(schema.scoringEvents.id, eventId),
|
||||
});
|
||||
|
||||
if (!event) return;
|
||||
|
||||
// For qualifying events: capture affected participant IDs before the cascade deletes
|
||||
// eventResults (which is how we know who had QP awarded from this event).
|
||||
let affectedParticipantIds: string[] = [];
|
||||
let wasQPProcessed = false;
|
||||
if (event.isQualifyingEvent) {
|
||||
const results = await db.query.eventResults.findMany({
|
||||
where: eq(schema.eventResults.scoringEventId, eventId),
|
||||
});
|
||||
affectedParticipantIds = results.map((r) => r.participantId);
|
||||
wasQPProcessed = results.some(
|
||||
(r) => r.qualifyingPointsAwarded && parseFloat(r.qualifyingPointsAwarded) > 0
|
||||
);
|
||||
}
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
if (event.eventType === "playoff_game") {
|
||||
await tx
|
||||
.delete(schema.participantResults)
|
||||
.where(eq(schema.participantResults.sportsSeasonId, event.sportsSeasonId));
|
||||
}
|
||||
// Cascades: playoffMatches, eventResults, tournamentGroups/Members
|
||||
await tx.delete(schema.scoringEvents).where(eq(schema.scoringEvents.id, eventId));
|
||||
});
|
||||
|
||||
if (event.eventType === "playoff_game") {
|
||||
await recalculateAffectedLeagues(event.sportsSeasonId, db);
|
||||
}
|
||||
|
||||
if (event.isQualifyingEvent && affectedParticipantIds.length > 0) {
|
||||
// eventResults have been cascade-deleted; recalculate QP totals from remaining events
|
||||
for (const participantId of affectedParticipantIds) {
|
||||
await recalculateParticipantQP(participantId, event.sportsSeasonId, db);
|
||||
}
|
||||
|
||||
// Decrement majorsCompleted if this event had already been processed
|
||||
if (wasQPProcessed) {
|
||||
const sportsSeason = await db.query.sportsSeasons.findFirst({
|
||||
where: eq(schema.sportsSeasons.id, event.sportsSeasonId),
|
||||
});
|
||||
if (sportsSeason && (sportsSeason.majorsCompleted ?? 0) > 0) {
|
||||
await db
|
||||
.update(schema.sportsSeasons)
|
||||
.set({ majorsCompleted: (sportsSeason.majorsCompleted ?? 1) - 1, updatedAt: new Date() })
|
||||
.where(eq(schema.sportsSeasons.id, event.sportsSeasonId));
|
||||
}
|
||||
}
|
||||
|
||||
await recalculateAffectedLeagues(event.sportsSeasonId, db);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue