import { and, eq, isNull, ne, sql } from "drizzle-orm"; import { database } from "~/database/context"; import * as schema from "~/database/schema"; export async function countSports(): Promise { const db = database(); const [{ count }] = await db .select({ count: sql`count(*)::int` }) .from(schema.sports); return count; } export type Sport = typeof schema.sports.$inferSelect; export type NewSport = typeof schema.sports.$inferInsert; export type SportType = "team" | "individual"; export type SportWithActiveSeasons = Sport & { activeSeasons: Array<{ id: string; name: string; year: number }>; }; export type PublicSportWithCurrentSeasons = Sport & { currentSeasons: Array<{ id: string; name: string; year: number; status: "active" | "upcoming"; scoringPattern: "playoff_bracket" | "season_standings" | "qualifying_points" | null; scoringType: "playoffs" | "regular_season" | "majors"; }>; }; export async function createSport(data: NewSport): Promise { const db = database(); const [sport] = await db .insert(schema.sports) .values(data) .returning(); return sport; } export async function findSportById(id: string): Promise { const db = database(); return await db.query.sports.findFirst({ where: eq(schema.sports.id, id), }); } export async function findSportBySlug(slug: string): Promise { const db = database(); return await db.query.sports.findFirst({ where: eq(schema.sports.slug, slug), }); } export async function findAllSports(): Promise { const db = database(); return await db.query.sports.findMany({ orderBy: (s, { asc }) => [asc(s.name)], }); } export async function isSportIconUrlUsed(iconUrl: string, excludeSportId?: string): Promise { const db = database(); const sport = await db.query.sports.findFirst({ where: excludeSportId ? and(eq(schema.sports.iconUrl, iconUrl), ne(schema.sports.id, excludeSportId)) : eq(schema.sports.iconUrl, iconUrl), columns: { id: true }, }); return Boolean(sport); } export async function findAllSportsWithActiveSeasons(): Promise { const db = database(); const sports = await db.query.sports.findMany({ orderBy: (s, { asc }) => [asc(s.name)], with: { sportsSeasons: { where: (ss, { or }) => or( eq(ss.status, "active"), eq(ss.status, "upcoming") ), orderBy: (ss, { desc }) => [desc(ss.year)], }, }, }); return sports.map((sport) => ({ ...sport, activeSeasons: sport.sportsSeasons.map((season) => ({ id: season.id, name: season.name, year: season.year, })), })); } export async function findPublicSportsWithCurrentSeasons(): Promise { const db = database(); const sports = await db.query.sports.findMany({ where: eq(schema.sports.excludeFromHomepage, false), orderBy: (s, { asc }) => [asc(s.name)], with: { sportsSeasons: { where: (ss, { and: relationAnd, or }) => relationAnd( isNull(ss.fantasySeasonId), or( eq(ss.status, "active"), eq(ss.status, "upcoming") ) ), orderBy: (ss, { desc, asc }) => [desc(ss.year), asc(ss.name)], }, }, }); return sports .filter((sport) => !sport.excludeFromHomepage && sport.slug !== "brackt" && sport.simulatorType !== "brackt" ) .map((sport) => ({ ...sport, currentSeasons: sport.sportsSeasons.map((season) => ({ id: season.id, name: season.name, year: season.year, status: season.status as "active" | "upcoming", scoringPattern: season.scoringPattern, scoringType: season.scoringType, })), })) .filter((sport) => sport.currentSeasons.length > 0); } export async function findSportsByType(type: SportType): Promise { const db = database(); return await db.query.sports.findMany({ where: eq(schema.sports.type, type), orderBy: (s, { asc }) => [asc(s.name)], }); } export async function updateSport( id: string, data: Partial ): Promise { const db = database(); const [sport] = await db .update(schema.sports) .set({ ...data, updatedAt: new Date() }) .where(eq(schema.sports.id, id)) .returning(); return sport; } export async function deleteSport(id: string): Promise { const db = database(); await db.delete(schema.sports).where(eq(schema.sports.id, id)); }