/** * Production seed — Pelagia Marine Services * * Idempotent: safe to run multiple times (all operations are upsert). * Run with: pnpm db:seed:prod * * Seeds: * - Users (SSO, no password) * - Sites * - Vessels (assigned to sites) * - Accounting codes (full hierarchy from Rev. 01/251227) */ import { PrismaClient, Role } from "@prisma/client"; import { ACCOUNTING_CODES } from "./accounting-codes-data"; const db = new PrismaClient(); // ─── Users ──────────────────────────────────────────────────────────────────── const USERS: { employeeId: string; name: string; email: string; role: Role }[] = [ { employeeId: "PMS-001", name: "Akshata Teli", email: "akshata@pelagiamarine.com", role: Role.ACCOUNTS }, { employeeId: "PMS-002", name: "Chhagan Sarang", email: "chhagan.sarang@pelagiamarine.com", role: Role.MANAGER }, { employeeId: "PMS-003", name: "Dipali K", email: "dipali.k@pelagiamarine.com", role: Role.ACCOUNTS }, { employeeId: "PMS-004", name: "Eeshan Singh", email: "eeshan.singh@pelagiamarine.com", role: Role.TECHNICAL }, { employeeId: "PMS-005", name: "Kaushal Pal Singh", email: "kps@pelagiamarine.com", role: Role.MANAGER }, { employeeId: "PMS-006", name: "Manjuprasad B", email: "manjuprasad.b@pelagiamarine.com", role: Role.TECHNICAL }, { employeeId: "PMS-007", name: "Mayur Deore", email: "mayur@pelagiamarine.com", role: Role.MANNING }, { employeeId: "PMS-008", name: "Nikita Accounts", email: "nikita.m@pelagiamarine.com", role: Role.ACCOUNTS }, { employeeId: "PMS-009", name: "Rakesh Kumar Pandey", email: "rkp@pelagiamarine.com", role: Role.MANAGER }, { employeeId: "PMS-010", name: "Shailesh B", email: "shailesh.b@pelagiamarine.com", role: Role.ACCOUNTS }, { employeeId: "PMS-011", name: "Shrikant T", email: "shrikant.t@pelagiamarine.com", role: Role.TECHNICAL }, { employeeId: "PMS-012", name: "Sunil Gupta", email: "sunil.gupta@pelagiamarine.com", role: Role.MANNING }, { employeeId: "PMS-013", name: "Supriya Sutar", email: "supriya.s@pelagiamarine.com", role: Role.TECHNICAL }, { employeeId: "PMS-014", name: "Tajinder Kaur", email: "tajinder.kaur@pelagiamarine.com", role: Role.MANAGER }, ]; // ─── Sites ──────────────────────────────────────────────────────────────────── const SITES: { code: string; name: string }[] = [ { code: "HOFC", name: "Head Office" }, { code: "PMSK", name: "PMS Kochi" }, { code: "LACD", name: "Laccadives" }, { code: "HLDA", name: "Haldia" }, { code: "THKM", name: "Thilakkam" }, { code: "KVRT", name: "Kavaratti" }, { code: "THNK", name: "Thinnakara" }, ]; // ─── Vessels (code, name, site code) ───────────────────────────────────────── const VESSELS: { code: string; name: string; siteCode: string }[] = [ { code: "HNR1", name: "HNR 1", siteCode: "HLDA" }, { code: "HNR2", name: "HNR 2", siteCode: "LACD" }, { code: "HNR3", name: "HNR 3", siteCode: "THKM" }, { code: "HNR4", name: "HNR 4", siteCode: "THNK" }, { code: "CHAMPION", name: "Champion", siteCode: "PMSK" }, { code: "HANUNAM", name: "Hanunam", siteCode: "KVRT" }, { code: "SEJAL", name: "Sejal", siteCode: "HLDA" }, { code: "SEJAL2", name: "Sejal 2", siteCode: "LACD" }, { code: "GD3000", name: "GD 3000", siteCode: "THKM" }, { code: "THILAKKAM", name: "Thilakkam", siteCode: "THNK" }, ]; // ─── Main ───────────────────────────────────────────────────────────────────── async function main() { console.log("🌱 Pelagia production seed starting…\n"); // ── Users ────────────────────────────────────────────────────────────────── console.log("👤 Seeding users…"); for (const u of USERS) { await db.user.upsert({ where: { email: u.email }, update: { name: u.name, role: u.role }, create: { employeeId: u.employeeId, email: u.email, name: u.name, role: u.role, // No passwordHash — SSO-only login }, }); console.log(` ✓ ${u.name} <${u.email}> [${u.role}]`); } // ── Sites ────────────────────────────────────────────────────────────────── console.log("\n📍 Seeding sites…"); const siteIdMap = new Map(); for (const s of SITES) { const site = await db.site.upsert({ where: { code: s.code }, update: { name: s.name }, create: { code: s.code, name: s.name }, }); siteIdMap.set(s.code, site.id); console.log(` ✓ ${s.name} (${s.code})`); } // ── Vessels ──────────────────────────────────────────────────────────────── console.log("\n🚢 Seeding vessels…"); for (const v of VESSELS) { const siteId = siteIdMap.get(v.siteCode); if (!siteId) { console.warn(` ⚠ Unknown site code "${v.siteCode}" for vessel ${v.code} — skipping`); continue; } await db.vessel.upsert({ where: { code: v.code }, update: { name: v.name, siteId }, create: { code: v.code, name: v.name, siteId }, }); console.log(` ✓ ${v.name} (${v.code}) → ${v.siteCode}`); } // ── Accounting Codes ─────────────────────────────────────────────────────── console.log("\n📊 Seeding accounting codes…"); const codeIdMap = new Map(); // Pass 1 — upsert every entry without parent links for (const entry of ACCOUNTING_CODES) { const rec = await db.account.upsert({ where: { code: entry.code }, update: { name: entry.name }, create: { code: entry.code, name: entry.name }, }); codeIdMap.set(entry.code, rec.id); } // Pass 2 — wire up parent relationships for (const entry of ACCOUNTING_CODES) { if (entry.parentCode) { const parentId = codeIdMap.get(entry.parentCode); if (parentId) { await db.account.update({ where: { code: entry.code }, data: { parentId }, }); } } } const leafCount = ACCOUNTING_CODES.filter((e) => { return !ACCOUNTING_CODES.some((other) => other.parentCode === e.code); }).length; console.log(` ✓ ${ACCOUNTING_CODES.length} codes (${leafCount} selectable leaf items)`); console.log("\n✅ Production seed complete."); } main() .catch((e) => { console.error("❌ Seed failed:", e); process.exit(1); }) .finally(() => db.$disconnect());