import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"; import { sql } from "drizzle-orm"; import { createInsertSchema } from "drizzle-zod"; import { z } from "zod/v4"; export const USER_ROLES = ["user", "admin"] as const; export const USER_STATUSES = ["pending", "active", "suspended"] as const; export type UserRole = (typeof USER_ROLES)[number]; export type UserStatus = (typeof USER_STATUSES)[number]; export const usersTable = sqliteTable("users", { id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()), email: text("email").notNull().unique(), passwordHash: text("password_hash"), displayName: text("display_name"), role: text("role", { enum: USER_ROLES }).notNull().default("user"), status: text("status", { enum: USER_STATUSES }).notNull().default("pending"), resetToken: text("reset_token"), resetTokenExpiresAt: integer("reset_token_expires_at", { mode: "timestamp_ms" }), lastLoginAt: integer("last_login_at", { mode: "timestamp_ms" }), createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull().default(sql`(unixepoch() * 1000)`), updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull().default(sql`(unixepoch() * 1000)`), }); export const refreshTokensTable = sqliteTable("refresh_tokens", { id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()), userId: text("user_id").notNull().references(() => usersTable.id, { onDelete: "cascade" }), token: text("token").notNull().unique(), expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(), createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull().default(sql`(unixepoch() * 1000)`), }); export const insertUserSchema = createInsertSchema(usersTable).omit({ id: true, createdAt: true, updatedAt: true }); export type InsertUser = z.infer; export type User = typeof usersTable.$inferSelect;