import { database } from "~/database/context"; import * as schema from "~/database/schema"; import { eq, and, desc } from "drizzle-orm"; export type EventType = "playoff_game" | "major_tournament" | "final_standings"; export interface CreateScoringEventData { sportsSeasonId: string; name: string; eventDate?: Date; eventType: EventType; isQualifyingEvent?: boolean; // Template system fields (Phase 2.6) bracketTemplateId?: string; scoringStartsAtRound?: string; } export interface UpdateScoringEventData { name?: string; eventDate?: Date; isComplete?: boolean; completedAt?: Date; bracketTemplateId?: string; scoringStartsAtRound?: string; } /** * Create a new scoring event */ export async function createScoringEvent( data: CreateScoringEventData, providedDb?: ReturnType ) { const db = providedDb || database(); const [event] = await db .insert(schema.scoringEvents) .values({ sportsSeasonId: data.sportsSeasonId, name: data.name, eventDate: data.eventDate ? data.eventDate.toISOString().split('T')[0] : undefined, eventType: data.eventType, isQualifyingEvent: data.isQualifyingEvent || false, bracketTemplateId: data.bracketTemplateId, scoringStartsAtRound: data.scoringStartsAtRound, isComplete: false, }) .returning(); return event; } /** * Get a scoring event by ID */ export async function getScoringEventById( eventId: string, providedDb?: ReturnType ) { const db = providedDb || database(); return await db.query.scoringEvents.findFirst({ where: eq(schema.scoringEvents.id, eventId), with: { sportsSeason: { with: { sport: true, }, }, }, }); } /** * Get all scoring events for a sports season */ export async function getScoringEventsForSportsSeason( sportsSeasonId: string, providedDb?: ReturnType ) { const db = providedDb || database(); return await db.query.scoringEvents.findMany({ where: eq(schema.scoringEvents.sportsSeasonId, sportsSeasonId), orderBy: [desc(schema.scoringEvents.eventDate), desc(schema.scoringEvents.createdAt)], with: { eventResults: { with: { participant: true, }, }, }, }); } /** * Get incomplete scoring events for a sports season */ export async function getIncompleteScoringEvents( sportsSeasonId: string, providedDb?: ReturnType ) { const db = providedDb || database(); return await db.query.scoringEvents.findMany({ where: and( eq(schema.scoringEvents.sportsSeasonId, sportsSeasonId), eq(schema.scoringEvents.isComplete, false) ), orderBy: [desc(schema.scoringEvents.eventDate), desc(schema.scoringEvents.createdAt)], }); } /** * Get qualifying events for a sports season */ export async function getQualifyingEvents( sportsSeasonId: string, providedDb?: ReturnType ) { const db = providedDb || database(); return await db.query.scoringEvents.findMany({ where: and( eq(schema.scoringEvents.sportsSeasonId, sportsSeasonId), eq(schema.scoringEvents.isQualifyingEvent, true) ), orderBy: [desc(schema.scoringEvents.eventDate), desc(schema.scoringEvents.createdAt)], }); } /** * Update a scoring event */ export async function updateScoringEvent( eventId: string, data: UpdateScoringEventData, providedDb?: ReturnType ) { const db = providedDb || database(); const updateData: any = { updatedAt: new Date() }; if (data.name !== undefined) updateData.name = data.name; if (data.eventDate !== undefined) { updateData.eventDate = data.eventDate.toISOString().split('T')[0]; } if (data.isComplete !== undefined) updateData.isComplete = data.isComplete; if (data.completedAt !== undefined) updateData.completedAt = data.completedAt; if (data.bracketTemplateId !== undefined) updateData.bracketTemplateId = data.bracketTemplateId; if (data.scoringStartsAtRound !== undefined) updateData.scoringStartsAtRound = data.scoringStartsAtRound; const [updated] = await db .update(schema.scoringEvents) .set(updateData) .where(eq(schema.scoringEvents.id, eventId)) .returning(); return updated; } /** * Mark a scoring event as complete */ export async function completeScoringEvent( eventId: string, providedDb?: ReturnType ) { const db = providedDb || database(); return await updateScoringEvent( eventId, { isComplete: true, completedAt: new Date(), }, db ); } /** * Delete a scoring event */ export async function deleteScoringEvent( eventId: string, providedDb?: ReturnType ) { const db = providedDb || database(); await db.delete(schema.scoringEvents).where(eq(schema.scoringEvents.id, eventId)); } /** * Check if all events for a sports season are complete */ export async function areAllEventsComplete( sportsSeasonId: string, providedDb?: ReturnType ): Promise { const db = providedDb || database(); const incompleteEvents = await getIncompleteScoringEvents(sportsSeasonId, db); return incompleteEvents.length === 0; }