import { defaultAdminPermissions, permissions, type PermissionKey } from "@mrp/shared"; import { env } from "../config/env.js"; import { prisma } from "./prisma.js"; import { hashPassword } from "./password.js"; import { ensureDataDirectories } from "./storage.js"; const permissionDescriptions: Record = { [permissions.adminManage]: "Full administrative access", [permissions.companyRead]: "View company settings", [permissions.companyWrite]: "Update company settings", [permissions.crmRead]: "View CRM records", [permissions.crmWrite]: "Manage CRM records", [permissions.inventoryRead]: "View inventory items and BOMs", [permissions.inventoryWrite]: "Manage inventory items and BOMs", [permissions.filesRead]: "View attached files", [permissions.filesWrite]: "Upload and manage attached files", [permissions.ganttRead]: "View gantt timelines", [permissions.salesRead]: "View sales data", [permissions.shippingRead]: "View shipping data", }; export async function bootstrapAppData() { await ensureDataDirectories(); for (const permissionKey of defaultAdminPermissions) { await prisma.permission.upsert({ where: { key: permissionKey }, update: {}, create: { key: permissionKey, description: permissionDescriptions[permissionKey], }, }); } const adminRole = await prisma.role.upsert({ where: { name: "Administrator" }, update: { description: "Full system access" }, create: { name: "Administrator", description: "Full system access", }, }); const allPermissions = await prisma.permission.findMany({ where: { key: { in: defaultAdminPermissions, }, }, }); for (const permission of allPermissions) { await prisma.rolePermission.upsert({ where: { roleId_permissionId: { roleId: adminRole.id, permissionId: permission.id, }, }, update: {}, create: { roleId: adminRole.id, permissionId: permission.id, }, }); } const adminUser = await prisma.user.upsert({ where: { email: env.ADMIN_EMAIL }, update: {}, create: { email: env.ADMIN_EMAIL, firstName: "System", lastName: "Administrator", passwordHash: await hashPassword(env.ADMIN_PASSWORD), }, }); await prisma.userRole.upsert({ where: { userId_roleId: { userId: adminUser.id, roleId: adminRole.id, }, }, update: {}, create: { userId: adminUser.id, roleId: adminRole.id, }, }); const existingProfile = await prisma.companyProfile.findFirst({ where: { isActive: true }, }); if (!existingProfile) { await prisma.companyProfile.create({ data: { companyName: "MRP Codex Manufacturing", legalName: "MRP Codex Manufacturing LLC", email: "operations@example.com", phone: "+1 (555) 010-2000", website: "https://example.com", taxId: "99-9999999", addressLine1: "100 Foundry Lane", addressLine2: "Suite 200", city: "Chicago", state: "IL", postalCode: "60601", country: "USA", }, }); } if ((await prisma.customer.count()) === 0) { await prisma.customer.createMany({ data: [ { name: "Acme Components", email: "buyer@acme.example", phone: "555-0101", addressLine1: "1 Industrial Road", addressLine2: "", city: "Detroit", state: "MI", postalCode: "48201", country: "USA", notes: "Priority account", }, { name: "Northwind Fabrication", email: "ops@northwind.example", phone: "555-0120", addressLine1: "42 Assembly Ave", addressLine2: "", city: "Milwaukee", state: "WI", postalCode: "53202", country: "USA", notes: "Requires ASN notice", }, ], }); } if ((await prisma.vendor.count()) === 0) { await prisma.vendor.create({ data: { name: "SteelSource Supply", email: "sales@steelsource.example", phone: "555-0142", addressLine1: "77 Mill Street", addressLine2: "", city: "Gary", state: "IN", postalCode: "46402", country: "USA", notes: "Lead time 5 business days", }, }); } if ((await prisma.inventoryItem.count()) === 0) { const plate = await prisma.inventoryItem.create({ data: { sku: "RM-PLATE-AL-125", name: "Aluminum Plate 1/8in", description: "Raw aluminum plate stock for fabricated assemblies.", type: "PURCHASED", status: "ACTIVE", unitOfMeasure: "EA", isSellable: false, isPurchasable: true, defaultCost: 42.5, notes: "Primary sheet stock for enclosure fabrication.", }, }); const fastener = await prisma.inventoryItem.create({ data: { sku: "HW-SCREW-832", name: "8-32 Socket Head Screw", description: "Standard socket head cap screw for enclosure assemblies.", type: "PURCHASED", status: "ACTIVE", unitOfMeasure: "EA", isSellable: false, isPurchasable: true, defaultCost: 0.18, notes: "Bulk hardware item.", }, }); const assembly = await prisma.inventoryItem.create({ data: { sku: "FG-CTRL-BASE", name: "Control Base Assembly", description: "Base enclosure assembly for standard control packages.", type: "ASSEMBLY", status: "ACTIVE", unitOfMeasure: "EA", isSellable: true, isPurchasable: false, defaultCost: 118, notes: "Starter BOM for the inventory foundation slice.", }, }); await prisma.inventoryBomLine.createMany({ data: [ { parentItemId: assembly.id, componentItemId: plate.id, quantity: 2, unitOfMeasure: "EA", notes: "Side panel blanks", position: 10, }, { parentItemId: assembly.id, componentItemId: fastener.id, quantity: 12, unitOfMeasure: "EA", notes: "General assembly hardware", position: 20, }, ], }); } if ((await prisma.warehouse.count()) === 0) { await prisma.warehouse.create({ data: { code: "MAIN", name: "Main Warehouse", notes: "Primary stocking location for finished goods and purchased materials.", locations: { create: [ { code: "RECV", name: "Receiving", notes: "Initial inbound inspection and receipt staging.", }, { code: "STOCK-A1", name: "Aisle A1", notes: "General rack storage for standard material.", }, { code: "FG-STAGE", name: "Finished Goods Staging", notes: "Outbound-ready finished assemblies.", }, ], }, }, }); } }