import { database } from "~/database/context"; import { eq } from "drizzle-orm"; import * as schema from "~/database/schema"; import { findSportsSeasonsByStatus } from "~/models/sports-season"; import { syncStandings } from "~/services/standings-sync"; import { runSportsSeasonSimulation } from "~/services/simulations/runner"; import { requireCronSecret } from "~/lib/cron-auth"; export async function action({ request }: { request: Request }) { requireCronSecret(request); const activeSeasons = await findSportsSeasonsByStatus("active"); const synced: string[] = []; const unchanged: string[] = []; const simulated: string[] = []; const syncErrors: { id: string; error: string }[] = []; const simErrors: { id: string; error: string }[] = []; for (const season of activeSeasons) { let changed = false; try { const result = await syncStandings(season.id); changed = result.changed; if (changed) { synced.push(season.id); } else { unchanged.push(season.id); } } catch (err) { // Sports without a sync adapter (F1, IndyCar, etc.) throw — skip gracefully syncErrors.push({ id: season.id, error: err instanceof Error ? err.message : String(err) }); continue; } if (!changed) continue; // Only simulate if standings changed since last simulation const current = await database() .select({ standingsLastChangedAt: schema.sportsSeasons.standingsLastChangedAt, lastSimulatedAt: schema.sportsSeasons.lastSimulatedAt }) .from(schema.sportsSeasons) .where(eq(schema.sportsSeasons.id, season.id)) .then((rows) => rows[0]); const needsSim = current?.standingsLastChangedAt && (!current.lastSimulatedAt || current.standingsLastChangedAt > current.lastSimulatedAt); if (!needsSim) continue; try { await runSportsSeasonSimulation(season.id); await database() .update(schema.sportsSeasons) .set({ lastSimulatedAt: new Date() }) .where(eq(schema.sportsSeasons.id, season.id)); simulated.push(season.id); } catch (err) { // Seasons without a simulator config or that fail readiness checks throw — skip gracefully simErrors.push({ id: season.id, error: err instanceof Error ? err.message : String(err) }); } } const hasErrors = syncErrors.length > 0 || simErrors.length > 0; const hasSuccess = synced.length > 0 || unchanged.length > 0; const status = hasErrors && !hasSuccess ? 500 : 200; return Response.json( { synced, unchanged, simulated, syncErrors, simErrors }, { status } ); }