import { relations, sql } from "drizzle-orm"; import { pgTableCreator, index, primaryKey } from "drizzle-orm/pg-core"; import { type AdapterAccount } from "next-auth/adapters"; import { createId } from "@paralleldrive/cuid2"; /** * This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same * database instance for multiple projects. * * @see https://orm.drizzle.team/docs/goodies#multi-project-schema */ export const createTable = pgTableCreator((name) => `game-master_${name}`); const defaultTimeStamp = (name: string, d: any) => d .timestamp(name, { withTimezone: true }) .default(sql`CURRENT_TIMESTAMP`) .notNull(); export const lobbies = createTable("lobby", (d) => ({ id: d .varchar({ length: 255 }) .primaryKey() .notNull() .$defaultFn(() => createId()), name: d.varchar({ length: 255 }).notNull(), maxPlayers: d.integer().notNull().default(0), createdById: d .varchar({ length: 255 }) .notNull() .references(() => players.id, { onDelete: "cascade" }), createdAt: defaultTimeStamp("created_at", d), updatedAt: d .timestamp("updated_at", { withTimezone: true }) .$onUpdate(() => new Date()), })); export type Lobby = typeof lobbies.$inferSelect & { members?: LobbyMember[]; leader?: Player; }; export const lobbyRelations = relations(lobbies, ({ many, one }) => ({ leader: one(players, { fields: [lobbies.createdById], references: [players.id], }), members: many(lobbyMembers), })); export const lobbyMembers = createTable( "lobby_member", (d) => ({ playerId: d .varchar({ length: 255 }) .notNull() .references(() => players.id, { onDelete: "cascade" }), lobbyId: d .varchar({ length: 255 }) .notNull() .references(() => lobbies.id, { onDelete: "cascade" }), joinedAt: defaultTimeStamp("joined_at", d), role: d .varchar({ length: 255 }) .notNull() .$type() .default("player"), isReady: d.boolean().notNull(), }), (t) => [primaryKey({ columns: [t.playerId] })], ); export type LobbyMember = typeof lobbyMembers.$inferSelect & { player?: Player; }; export const lobbyMembersRelations = relations(lobbyMembers, ({ one }) => ({ lobby: one(lobbies, { fields: [lobbyMembers.lobbyId], references: [lobbies.id], }), player: one(players, { fields: [lobbyMembers.playerId], references: [players.id], }), })); export const players = createTable( "player", (d) => ({ id: d .varchar({ length: 255 }) .notNull() .references(() => users.id, { onDelete: "cascade" }), displayName: d.varchar({ length: 255 }), avatar: d.varchar({ length: 255 }), joinedAt: defaultTimeStamp("joined_at", d), }), (t) => [ primaryKey({ columns: [t.id], }), ], ); export type Player = typeof players.$inferSelect; export const users = createTable("user", (d) => ({ id: d .varchar({ length: 255 }) .notNull() .primaryKey() .$defaultFn(() => createId()), name: d.varchar({ length: 255 }), email: d.varchar({ length: 255 }).notNull(), emailVerified: d .timestamp("email_verified", { mode: "date", withTimezone: true, }) .default(sql`CURRENT_TIMESTAMP`), })); export const usersRelations = relations(users, ({ many }) => ({ accounts: many(accounts), sessions: many(sessions), })); export const accounts = createTable( "account", (d) => ({ userId: d .varchar({ length: 255 }) .notNull() .references(() => users.id, { onDelete: "cascade" }), type: d.varchar({ length: 255 }).$type().notNull(), provider: d.varchar({ length: 255 }).notNull(), providerAccountId: d.varchar({ length: 255 }).notNull(), refresh_token: d.text(), access_token: d.text(), expires_at: d.integer(), token_type: d.varchar({ length: 255 }), scope: d.varchar({ length: 255 }), id_token: d.text(), session_state: d.varchar({ length: 255 }), }), (t) => [ primaryKey({ columns: [t.provider, t.providerAccountId], }), index("account_user_id_idx").on(t.userId), ], ); export const accountsRelations = relations(accounts, ({ one }) => ({ user: one(users, { fields: [accounts.userId], references: [users.id] }), })); export const sessions = createTable( "session", (d) => ({ sessionToken: d.varchar({ length: 255 }).notNull().primaryKey(), userId: d .varchar({ length: 255 }) .notNull() .references(() => users.id, { onDelete: "cascade" }), expires: d.timestamp({ mode: "date" }).notNull(), }), (t) => [index("session_user_id_idx").on(t.userId)], ); export const sessionsRelations = relations(sessions, ({ one }) => ({ user: one(users, { fields: [sessions.userId], references: [users.id] }), })); export const verificationTokens = createTable( "verification_token", (d) => ({ identifier: d.varchar({ length: 255 }).notNull(), token: d.varchar({ length: 255 }).notNull(), expires: d.timestamp({ mode: "date" }).notNull(), }), (t) => [primaryKey({ columns: [t.identifier, t.token] })], );