import { eq, inArray, count, and, sql, asc, desc } from "drizzle-orm"; import { database } from "~/database/context"; import * as schema from "~/database/schema"; export type Participant = typeof schema.participants.$inferSelect; export type NewParticipant = typeof schema.participants.$inferInsert; export async function createParticipant(data: NewParticipant): Promise { const db = database(); const [participant] = await db .insert(schema.participants) .values(data) .returning(); return participant; } export async function createManyParticipants(data: NewParticipant[]): Promise { const db = database(); return await db .insert(schema.participants) .values(data) .returning(); } export async function findParticipantById(id: string): Promise { const db = database(); return await db.query.participants.findFirst({ where: eq(schema.participants.id, id), with: { sportsSeason: { with: { sport: true, }, }, }, }); } export async function findParticipantByName( sportsSeasonId: string, name: string ): Promise { const db = database(); const results = await db .select() .from(schema.participants) .where( and( eq(schema.participants.sportsSeasonId, sportsSeasonId), sql`lower(${schema.participants.name}) = lower(${name})` ) ) .limit(1); return results[0]; } export async function findParticipantsBySportsSeasonId(sportsSeasonId: string): Promise { const db = database(); return await db.query.participants.findMany({ where: eq(schema.participants.sportsSeasonId, sportsSeasonId), orderBy: (participants, { asc: orderAsc }) => [orderAsc(participants.name)], }); } export async function findParticipantsByExternalId( externalId: string ): Promise { const db = database(); return await db.query.participants.findMany({ where: eq(schema.participants.externalId, externalId), with: { sportsSeason: { with: { sport: true, }, }, }, }); } export async function updateParticipant( id: string, data: Partial ): Promise { const db = database(); const [participant] = await db .update(schema.participants) .set({ ...data, updatedAt: new Date() }) .where(eq(schema.participants.id, id)) .returning(); return participant; } export async function countAllParticipants(): Promise { const db = database(); const result = await db.select({ value: count() }).from(schema.participants); return result[0].value; } export async function deleteParticipant(id: string): Promise { const db = database(); await db.delete(schema.participants).where(eq(schema.participants.id, id)); } export async function copyParticipantsFromSeason( sourceSportsSeasonId: string, targetSportsSeasonId: string ): Promise { // Get all participants from source season const sourceParticipants = await findParticipantsBySportsSeasonId(sourceSportsSeasonId); // Insert them into the target season if (sourceParticipants.length === 0) { return []; } return await createManyParticipants( sourceParticipants.map((p) => ({ sportsSeasonId: targetSportsSeasonId, name: p.name, shortName: p.shortName, externalId: p.externalId, expectedValue: p.expectedValue, })) ); } /** * Get all participants for a season with sport information * Used for draft eligibility calculations */ export async function getParticipantsForSeasonWithSports(seasonId: string, providedDb?: ReturnType) { const db = providedDb || database(); // First get all sports seasons for this season const seasonSports = await db.query.seasonSports.findMany({ where: eq(schema.seasonSports.seasonId, seasonId), }); if (seasonSports.length === 0) { return []; } const sportsSeasonIds = seasonSports.map((ss) => ss.sportsSeasonId); // Get all participants for these sports seasons with sport info const participants = await db .select({ id: schema.participants.id, name: schema.participants.name, sport: { id: schema.sports.id, name: schema.sports.name, }, }) .from(schema.participants) .innerJoin( schema.sportsSeasons, eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id) ) .innerJoin( schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id) ) .where( sportsSeasonIds.length === 1 ? eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]) : inArray(schema.participants.sportsSeasonId, sportsSeasonIds) ); return participants; } export async function getDraftParticipants(seasonId: string) { const db = database(); const seasonSports = await db.query.seasonSports.findMany({ where: eq(schema.seasonSports.seasonId, seasonId), }); const sportsSeasonIds = seasonSports.map((ss) => ss.sportsSeasonId); if (sportsSeasonIds.length === 0) return []; return await db .select({ id: schema.participants.id, name: schema.participants.name, vorpValue: schema.participants.vorpValue, sport: schema.sports, }) .from(schema.participants) .innerJoin(schema.sportsSeasons, eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)) .innerJoin(schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id)) .where( sportsSeasonIds.length === 1 ? eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]) : inArray(schema.participants.sportsSeasonId, sportsSeasonIds) ) .orderBy(desc(schema.participants.vorpValue), asc(schema.participants.name)); }