import { sql } from "drizzle-orm"; import { pgTable, uuid, varchar, text, integer, timestamp, primaryKey, uniqueIndex, index, } from "drizzle-orm/pg-core"; export const users = pgTable( "users", { id: uuid("id").primaryKey().defaultRandom(), email: varchar("email", { length: 255 }).notNull().unique(), name: varchar("name", { length: 255 }), avatarUrl: text("avatar_url"), createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), }, (table) => ({ emailIdx: index("users_email_idx").on(table.email), // Belt-and-braces: existing column-level UNIQUE on `email` plus a // case-insensitive UNIQUE on `lower(email)`. The latter prevents // accidentally storing `Alice@x.com` and `alice@x.com` as two users // and makes the case-insensitive lookups in `apps/web/lib/auth.ts` // safe even if upstream rows were created mixed-case. emailLowerUnique: uniqueIndex("users_email_lower_unique").on(sql`lower(${table.email})`), }), ); export const accounts = pgTable( "accounts", { id: uuid("id").primaryKey().defaultRandom(), userId: uuid("user_id") .notNull() .references(() => users.id, { onDelete: "cascade" }), type: varchar("type", { length: 255 }).notNull(), provider: varchar("provider", { length: 255 }).notNull(), providerAccountId: varchar("provider_account_id", { length: 255 }).notNull(), refreshToken: text("refresh_token"), accessToken: text("access_token"), expiresAt: integer("expires_at"), tokenType: varchar("token_type", { length: 255 }), scope: varchar("scope", { length: 255 }), idToken: text("id_token"), sessionState: varchar("session_state", { length: 255 }), }, (table) => ({ providerAccountUnique: uniqueIndex("accounts_provider_provider_account_id_unique").on( table.provider, table.providerAccountId, ), userIdIdx: index("accounts_user_id_idx").on(table.userId), }), ); export const sessions = pgTable( "sessions", { id: uuid("id").primaryKey().defaultRandom(), sessionToken: varchar("session_token", { length: 255 }).notNull().unique(), userId: uuid("user_id") .notNull() .references(() => users.id, { onDelete: "cascade" }), expires: timestamp("expires", { withTimezone: true }).notNull(), }, (table) => ({ userIdIdx: index("sessions_user_id_idx").on(table.userId), }), ); export const verificationTokens = pgTable( "verification_tokens", { identifier: varchar("identifier", { length: 255 }).notNull(), token: varchar("token", { length: 255 }).notNull(), expires: timestamp("expires", { withTimezone: true }).notNull(), }, (table) => ({ pk: primaryKey({ columns: [table.identifier, table.token] }), }), );