import { and, eq, isNotNull } from "drizzle-orm"; import { database } from "~/database/context"; import * as schema from "~/database/schema"; import { requireCronSecret } from "~/lib/cron-auth"; import { syncMatches, syncTennisDraw } from "~/services/match-sync"; export async function action({ request }: { request: Request }) { requireCronSecret(request); const db = database(); const seasons = await db.query.sportsSeasons.findMany({ where: and( isNotNull(schema.sportsSeasons.externalSeasonId), eq(schema.sportsSeasons.status, "active") ), with: { sport: true }, }); const synced: string[] = []; const errors: { id: string; name: string; error: string }[] = []; for (const season of seasons) { try { const result = await syncMatches(season.id); synced.push(season.id); if (result.errors.length > 0) { for (const e of result.errors) { errors.push({ id: season.id, name: season.name, error: e.error }); } } } catch (err) { errors.push({ id: season.id, name: season.name, error: err instanceof Error ? err.message : String(err), }); } } // Tennis Grand Slam draws: sync each active tennis major's primary window from // its configured Wikipedia article. (Tennis uses a per-event externalSourceKey, // not a per-season externalSeasonId, so it isn't covered by the loop above.) const tennisEvents = await db.query.scoringEvents.findMany({ where: and( isNotNull(schema.scoringEvents.externalSourceKey), eq(schema.scoringEvents.isQualifyingEvent, true), eq(schema.scoringEvents.isComplete, false), ), with: { sportsSeason: { with: { sport: true } } }, }); const drawSynced: string[] = []; for (const ev of tennisEvents) { if (ev.sportsSeason?.status !== "active") continue; if (ev.sportsSeason?.sport?.simulatorType !== "tennis_qualifying_points") continue; // Skip read-only siblings of a shared major — results fan out from the primary. if (ev.tournamentId && !ev.isPrimary) continue; try { await syncTennisDraw(ev.id); drawSynced.push(ev.id); } catch (err) { errors.push({ id: ev.id, name: ev.name ?? "(tennis draw)", error: err instanceof Error ? err.message : String(err), }); } } const okCount = synced.length + drawSynced.length; return Response.json( { synced, drawSynced, errors }, { status: errors.length > 0 && okCount === 0 ? 500 : 200 }, ); }