import { integer, pgTable, varchar, uuid, timestamp, pgEnum, boolean, text, date, decimal } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; // Users table - synced from Clerk export const users = pgTable("users", { id: uuid("id").primaryKey().defaultRandom(), clerkId: varchar("clerk_id", { length: 255 }).notNull().unique(), email: varchar("email", { length: 255 }).notNull(), username: varchar("username", { length: 255 }), displayName: varchar("display_name", { length: 255 }), firstName: varchar("first_name", { length: 255 }), lastName: varchar("last_name", { length: 255 }), imageUrl: varchar("image_url", { length: 512 }), isAdmin: boolean("is_admin").notNull().default(false), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); // Fantasy League Tables export const seasonStatusEnum = pgEnum("season_status", [ "pre_draft", "draft", "active", "completed", ]); // Sports Tables - Enums export const sportTypeEnum = pgEnum("sport_type", ["team", "individual"]); export const sportsSeasonStatusEnum = pgEnum("sports_season_status", [ "upcoming", "active", "completed", ]); export const scoringTypeEnum = pgEnum("scoring_type", [ "playoffs", "regular_season", "majors", ]); export const leagues = pgTable("leagues", { id: uuid("id").primaryKey().defaultRandom(), name: varchar("name", { length: 255 }).notNull(), createdBy: varchar("created_by", { length: 255 }).notNull(), // Clerk user ID currentSeasonId: uuid("current_season_id"), // References the active season createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const seasonTemplates = pgTable("season_templates", { id: uuid("id").primaryKey().defaultRandom(), name: varchar("name", { length: 255 }).notNull(), description: text("description"), year: integer("year").notNull(), isActive: boolean("is_active").notNull().default(true), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const seasons = pgTable("seasons", { id: uuid("id").primaryKey().defaultRandom(), leagueId: uuid("league_id") .notNull() .references(() => leagues.id, { onDelete: "cascade" }), year: integer("year").notNull(), status: seasonStatusEnum("status").notNull().default("pre_draft"), templateId: uuid("template_id") .references(() => seasonTemplates.id, { onDelete: "set null" }), draftRounds: integer("draft_rounds").notNull().default(20), flexSpots: integer("flex_spots").notNull().default(0), inviteCode: varchar("invite_code", { length: 20 }).notNull().unique(), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const teams = pgTable("teams", { id: uuid("id").primaryKey().defaultRandom(), seasonId: uuid("season_id") .notNull() .references(() => seasons.id, { onDelete: "cascade" }), name: varchar("name", { length: 255 }).notNull(), logoUrl: varchar("logo_url", { length: 512 }), ownerId: varchar("owner_id", { length: 255 }), // Clerk user ID, nullable createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const draftSlots = pgTable("draft_slots", { id: uuid("id").primaryKey().defaultRandom(), seasonId: uuid("season_id") .notNull() .references(() => seasons.id, { onDelete: "cascade" }), teamId: uuid("team_id") .notNull() .references(() => teams.id, { onDelete: "cascade" }), draftOrder: integer("draft_order").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const commissioners = pgTable("commissioners", { id: uuid("id").primaryKey().defaultRandom(), leagueId: uuid("league_id") .notNull() .references(() => leagues.id, { onDelete: "cascade" }), userId: varchar("user_id", { length: 255 }).notNull(), // Clerk user ID createdAt: timestamp("created_at").defaultNow().notNull(), }); // Sports Tables export const sports = pgTable("sports", { id: uuid("id").primaryKey().defaultRandom(), name: varchar("name", { length: 255 }).notNull(), type: sportTypeEnum("type").notNull(), slug: varchar("slug", { length: 255 }).notNull().unique(), description: text("description"), iconUrl: varchar("icon_url", { length: 255 }), // Filename of icon in /public/sports-icons/ createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const sportsSeasons = pgTable("sports_seasons", { id: uuid("id").primaryKey().defaultRandom(), sportId: uuid("sport_id") .notNull() .references(() => sports.id, { onDelete: "cascade" }), name: varchar("name", { length: 255 }).notNull(), year: integer("year").notNull(), startDate: date("start_date"), endDate: date("end_date"), status: sportsSeasonStatusEnum("status").notNull().default("upcoming"), scoringType: scoringTypeEnum("scoring_type").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const participants = pgTable("participants", { id: uuid("id").primaryKey().defaultRandom(), sportsSeasonId: uuid("sports_season_id") .notNull() .references(() => sportsSeasons.id, { onDelete: "cascade" }), name: varchar("name", { length: 255 }).notNull(), shortName: varchar("short_name", { length: 100 }), externalId: varchar("external_id", { length: 255 }), expectedValue: integer("expected_value").notNull().default(0), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const seasonTemplateSports = pgTable("season_template_sports", { id: uuid("id").primaryKey().defaultRandom(), templateId: uuid("template_id") .notNull() .references(() => seasonTemplates.id, { onDelete: "cascade" }), sportsSeasonId: uuid("sports_season_id") .notNull() .references(() => sportsSeasons.id, { onDelete: "cascade" }), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const seasonSports = pgTable("season_sports", { id: uuid("id").primaryKey().defaultRandom(), seasonId: uuid("season_id") .notNull() .references(() => seasons.id, { onDelete: "cascade" }), sportsSeasonId: uuid("sports_season_id") .notNull() .references(() => sportsSeasons.id, { onDelete: "cascade" }), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const participantResults = pgTable("participant_results", { id: uuid("id").primaryKey().defaultRandom(), participantId: uuid("participant_id") .notNull() .references(() => participants.id, { onDelete: "cascade" }), sportsSeasonId: uuid("sports_season_id") .notNull() .references(() => sportsSeasons.id, { onDelete: "cascade" }), finalPosition: integer("final_position"), pointsAwarded: integer("points_awarded").notNull().default(0), qualifyingPoints: decimal("qualifying_points", { precision: 10, scale: 2 }), notes: text("notes"), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); // Relations export const sportsRelations = relations(sports, ({ many }) => ({ sportsSeasons: many(sportsSeasons), })); export const sportsSeasonsRelations = relations(sportsSeasons, ({ one, many }) => ({ sport: one(sports, { fields: [sportsSeasons.sportId], references: [sports.id], }), participants: many(participants), seasonTemplateSports: many(seasonTemplateSports), seasonSports: many(seasonSports), participantResults: many(participantResults), })); export const participantsRelations = relations(participants, ({ one, many }) => ({ sportsSeason: one(sportsSeasons, { fields: [participants.sportsSeasonId], references: [sportsSeasons.id], }), results: many(participantResults), })); export const seasonTemplatesRelations = relations(seasonTemplates, ({ many }) => ({ seasonTemplateSports: many(seasonTemplateSports), seasons: many(seasons), })); export const seasonTemplateSportsRelations = relations(seasonTemplateSports, ({ one }) => ({ template: one(seasonTemplates, { fields: [seasonTemplateSports.templateId], references: [seasonTemplates.id], }), sportsSeason: one(sportsSeasons, { fields: [seasonTemplateSports.sportsSeasonId], references: [sportsSeasons.id], }), })); export const seasonsRelations = relations(seasons, ({ one, many }) => ({ league: one(leagues, { fields: [seasons.leagueId], references: [leagues.id], }), template: one(seasonTemplates, { fields: [seasons.templateId], references: [seasonTemplates.id], }), teams: many(teams), seasonSports: many(seasonSports), })); export const seasonSportsRelations = relations(seasonSports, ({ one }) => ({ season: one(seasons, { fields: [seasonSports.seasonId], references: [seasons.id], }), sportsSeason: one(sportsSeasons, { fields: [seasonSports.sportsSeasonId], references: [sportsSeasons.id], }), })); export const participantResultsRelations = relations(participantResults, ({ one }) => ({ participant: one(participants, { fields: [participantResults.participantId], references: [participants.id], }), sportsSeason: one(sportsSeasons, { fields: [participantResults.sportsSeasonId], references: [sportsSeasons.id], }), })); export const teamsRelations = relations(teams, ({ one }) => ({ season: one(seasons, { fields: [teams.seasonId], references: [seasons.id], }), draftSlot: one(draftSlots, { fields: [teams.id], references: [draftSlots.teamId], }), })); export const draftSlotsRelations = relations(draftSlots, ({ one }) => ({ season: one(seasons, { fields: [draftSlots.seasonId], references: [seasons.id], }), team: one(teams, { fields: [draftSlots.teamId], references: [teams.id], }), }));