/** * Seed deterministic, credential-capable TEST USERS into a database. * * Why this exists * --------------- * `pelagia_test` (the staging / autofix DB) is a daily mirror of production, so it * only contains real `@pelagiamarine.com` users — most are SSO-only (no password) * and none have a password we know. That makes it impossible to log into the * staging instance (port 3200) with the credentials provider to run end-to-end * feature tests. * * This script upserts one **known-password** user per `Role` (using the throwaway * `@pelagia.local` domain, which never exists in prod, so there is zero collision * with real accounts). Credentials intentionally mirror * `tests/e2e/helpers/login.ts` so the same Playwright specs run locally and against * staging unchanged. * * Safety * ------ * - Idempotent: upsert keyed on the (unique) email; re-running only refreshes the * password hash / role / isActive. * - `employeeId` uses a `TEST-*` prefix so it can never clash with a real * production employee id carried over by the mirror. * - Only ever creates the `@pelagia.local` users below — it touches no prod rows. * * Usage * ----- * DATABASE_URL="postgresql://.../pelagia_test" pnpm tsx prisma/seed-test-users.ts * * It is wired into `automation/refresh-test-db.sh` so these accounts are recreated * automatically after every daily refresh of `pelagia_test`. */ import { PrismaClient, Role } from "@prisma/client"; import bcrypt from "bcryptjs"; const prisma = new PrismaClient(); /** * One login per role/flow that the closed-issue feature tests exercise. * Passwords match tests/e2e/helpers/login.ts (do not change one without the other). */ const TEST_USERS: Array<{ employeeId: string; email: string; name: string; password: string; role: Role; }> = [ { employeeId: "TEST-TECH", email: "tech@pelagia.local", name: "Test Technical", password: "tech1234", role: Role.TECHNICAL }, { employeeId: "TEST-MANNING",email: "manning@pelagia.local", name: "Test Manning", password: "manning1234", role: Role.MANNING }, { employeeId: "TEST-ACCT", email: "accounts@pelagia.local", name: "Test Accounts", password: "accounts1234", role: Role.ACCOUNTS }, { employeeId: "TEST-MGR", email: "manager@pelagia.local", name: "Test Manager", password: "manager1234", role: Role.MANAGER }, { employeeId: "TEST-SUPER", email: "superuser@pelagia.local", name: "Test Superuser", password: "super1234", role: Role.SUPERUSER }, { employeeId: "TEST-AUDIT", email: "auditor@pelagia.local", name: "Test Auditor", password: "audit1234", role: Role.AUDITOR }, { employeeId: "TEST-ADMIN", email: "admin@pelagia.local", name: "Test Admin", password: "admin1234", role: Role.ADMIN }, { employeeId: "TEST-SITE", email: "site@pelagia.local", name: "Test Site Staff", password: "site1234", role: Role.SITE_STAFF}, ]; async function main() { console.log(`Seeding ${TEST_USERS.length} test users...`); for (const u of TEST_USERS) { const passwordHash = await bcrypt.hash(u.password, 12); await prisma.user.upsert({ where: { email: u.email }, // Keep an existing test account in sync (refresh the hash / role / active flag) // but never overwrite its employeeId once created. update: { name: u.name, passwordHash, role: u.role, isActive: true }, create: { employeeId: u.employeeId, email: u.email, name: u.name, passwordHash, role: u.role, isActive: true, }, }); console.log(` ✓ ${u.email.padEnd(28)} ${u.role}`); } console.log("Test users ready."); } main() .catch((e) => { console.error("seed-test-users failed:", e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });