From d7ab2c77ddacb280dbd2b4824aa30e77af84cfa6 Mon Sep 17 00:00:00 2001 From: Moshfegh Hamedani Date: Tue, 10 Feb 2026 12:13:22 -0800 Subject: [PATCH] Add seed script to populate the database with admin user --- server/prisma.config.ts | 1 + .../migration.sql | 2 + .../migration.sql | 7 +++ server/prisma/schema.prisma | 6 ++ server/prisma/seed.ts | 63 +++++++++++++++++++ server/src/lib/auth.ts | 11 ++++ 6 files changed, 90 insertions(+) create mode 100644 server/prisma/migrations/20260210200027_add_user_role/migration.sql create mode 100644 server/prisma/migrations/20260210200100_change_role_to_enum/migration.sql create mode 100644 server/prisma/seed.ts diff --git a/server/prisma.config.ts b/server/prisma.config.ts index 831a20f..1b3e010 100644 --- a/server/prisma.config.ts +++ b/server/prisma.config.ts @@ -7,6 +7,7 @@ export default defineConfig({ schema: "prisma/schema.prisma", migrations: { path: "prisma/migrations", + seed: "bun prisma/seed.ts", }, datasource: { url: process.env["DATABASE_URL"], diff --git a/server/prisma/migrations/20260210200027_add_user_role/migration.sql b/server/prisma/migrations/20260210200027_add_user_role/migration.sql new file mode 100644 index 0000000..8b31345 --- /dev/null +++ b/server/prisma/migrations/20260210200027_add_user_role/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "user" ADD COLUMN "role" TEXT NOT NULL DEFAULT 'agent'; diff --git a/server/prisma/migrations/20260210200100_change_role_to_enum/migration.sql b/server/prisma/migrations/20260210200100_change_role_to_enum/migration.sql new file mode 100644 index 0000000..b4fa166 --- /dev/null +++ b/server/prisma/migrations/20260210200100_change_role_to_enum/migration.sql @@ -0,0 +1,7 @@ +-- CreateEnum +CREATE TYPE "Role" AS ENUM ('admin', 'agent'); + +-- AlterTable (cast existing text values to the new enum) +ALTER TABLE "user" ALTER COLUMN "role" DROP DEFAULT, + ALTER COLUMN "role" TYPE "Role" USING "role"::"Role", + ALTER COLUMN "role" SET DEFAULT 'agent'; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index e651050..6191406 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -13,12 +13,18 @@ datasource db { provider = "postgresql" } +enum Role { + admin + agent +} + model User { id String @id name String email String @unique emailVerified Boolean image String? + role Role @default(agent) createdAt DateTime updatedAt DateTime sessions Session[] diff --git a/server/prisma/seed.ts b/server/prisma/seed.ts new file mode 100644 index 0000000..e0347bd --- /dev/null +++ b/server/prisma/seed.ts @@ -0,0 +1,63 @@ +import "dotenv/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { PrismaClient } from "../src/generated/prisma/client"; +import { Role } from "../src/generated/prisma/client"; +import { hashPassword } from "better-auth/crypto"; + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); +const prisma = new PrismaClient({ adapter }); + +async function main() { + const email = process.env.SEED_ADMIN_EMAIL; + const password = process.env.SEED_ADMIN_PASSWORD; + + if (!email || !password) { + throw new Error( + "SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD must be set in .env" + ); + } + + const existing = await prisma.user.findUnique({ where: { email } }); + if (existing) { + console.log(`Admin user ${email} already exists — skipping.`); + return; + } + + const hashedPassword = await hashPassword(password); + const userId = crypto.randomUUID(); + const now = new Date(); + + await prisma.$transaction([ + prisma.user.create({ + data: { + id: userId, + name: "Admin", + email, + emailVerified: false, + role: Role.admin, + createdAt: now, + updatedAt: now, + }, + }), + prisma.account.create({ + data: { + id: crypto.randomUUID(), + accountId: userId, + providerId: "credential", + userId, + password: hashedPassword, + createdAt: now, + updatedAt: now, + }, + }), + ]); + + console.log(`Admin user ${email} created successfully.`); +} + +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(() => prisma.$disconnect()); diff --git a/server/src/lib/auth.ts b/server/src/lib/auth.ts index 110e2b7..78e9c73 100644 --- a/server/src/lib/auth.ts +++ b/server/src/lib/auth.ts @@ -9,5 +9,16 @@ export const auth = betterAuth({ }), emailAndPassword: { enabled: true, + disableSignUp: true, + }, + user: { + additionalFields: { + role: { + type: "string", + required: false, + defaultValue: "agent", + input: false, + }, + }, }, });