/** * Create (or reset) the platform superadmin: admin@demo.test / Admin123! * Sets user.role = 'admin' so both our requireAdmin() gate and the Better Auth * admin plugin authorize it. Password is hashed (Better Auth node scrypt). * * Run: npx tsx scripts/seed-admin.ts */ import { config } from "dotenv" config({ path: ".env.local" }) process.env.DATABASE_SSL = process.env.DATABASE_SSL ?? "disable" import { randomUUID } from "node:crypto" const EMAIL = "admin@demo.test" const PASSWORD = "Admin123!" async function main() { const { db, pool } = await import("../lib/db") const s = await import("../lib/db/schema") const { eq } = await import("drizzle-orm") const { hashPassword } = await import("better-auth/crypto") await db.delete(s.user).where(eq(s.user.email, EMAIL)) const userId = randomUUID() const now = new Date() await db.insert(s.user).values({ id: userId, name: "Platform Admin", email: EMAIL, emailVerified: true, role: "admin", createdAt: now, updatedAt: now, }) await db.insert(s.account).values({ id: randomUUID(), accountId: userId, providerId: "credential", userId, password: await hashPassword(PASSWORD), createdAt: now, updatedAt: now, }) await db.insert(s.profiles).values({ id: userId, email: EMAIL, full_name: "Platform Admin", plan: "lifetime", onboarding_completed: true, }) console.log(`✓ Superadmin ready`) console.log(` email: ${EMAIL}`) console.log(` password: ${PASSWORD}`) console.log(` user id: ${userId}`) console.log(` role: admin`) await pool.end() } main().catch((e) => { console.error("seed-admin failed:", e) process.exit(1) })