import { PrismaClient, AccountType, RoleType, FiscalPeriodStatus, InvoiceStatus } from "@prisma/client"; import bcrypt from "bcryptjs"; const prisma = new PrismaClient(); async function main() { console.log("๐ŸŒฑ Starting database seed..."); // Create Organization console.log("๐Ÿ“Š Creating organization..."); const organization = await prisma.organization.create({ data: { name: "Acme Holdings", legalName: "Acme Holdings Inc.", fiscalYearStartMonth: 1, fiscalYearStartDay: 1, defaultCurrency: "USD", timezone: "America/New_York", }, }); console.log(`โœ“ Organization created: ${organization.name}`); // Create Entities console.log("๐Ÿข Creating entities..."); const acmeSoftware = await prisma.entity.create({ data: { organizationId: organization.id, name: "Acme Software Inc", code: "ACM-US", type: "SUBSIDIARY", defaultCurrency: "USD", status: "ACTIVE", }, }); const acmeCloud = await prisma.entity.create({ data: { organizationId: organization.id, name: "Acme Cloud Services Ltd", code: "ACM-UK", type: "SUBSIDIARY", defaultCurrency: "GBP", status: "ACTIVE", }, }); const acmeEurope = await prisma.entity.create({ data: { organizationId: organization.id, name: "Acme Europe GmbH", code: "ACM-DE", type: "SUBSIDIARY", defaultCurrency: "EUR", status: "ACTIVE", }, }); const acmePacific = await prisma.entity.create({ data: { organizationId: organization.id, name: "Acme Pacific Pty Ltd", code: "ACM-AU", type: "SUBSIDIARY", defaultCurrency: "AUD", status: "ACTIVE", }, }); const entities = [acmeSoftware, acmeCloud, acmeEurope, acmePacific]; console.log(`โœ“ Created ${entities.length} entities`); // Create Roles console.log("๐Ÿ‘ฅ Creating roles..."); const roleConfigs: { name: string; roleType: RoleType }[] = [ { name: "CEO", roleType: "CEO" }, { name: "CFO", roleType: "CFO" }, { name: "Controller", roleType: "CONTROLLER" }, { name: "Manager", roleType: "MANAGER" }, { name: "Analyst", roleType: "ANALYST" }, { name: "Clerk", roleType: "CLERK" }, ]; const roles = []; for (const rc of roleConfigs) { const role = await prisma.role.create({ data: { organizationId: organization.id, name: rc.name, roleType: rc.roleType, description: `${rc.name} role`, isSystem: true, }, }); roles.push(role); } console.log(`โœ“ Created ${roles.length} roles`); // Create Admin User console.log("๐Ÿ‘ค Creating admin user..."); const hashedPassword = await bcrypt.hash("demo123", 10); const user = await prisma.user.create({ data: { organizationId: organization.id, email: "ryan@acme.com", passwordHash: hashedPassword, name: "Ryan Francis", firstName: "Ryan", lastName: "Francis", status: "ACTIVE", }, }); // Assign CEO role await prisma.userRole.create({ data: { userId: user.id, roleId: roles[0].id, }, }); console.log(`โœ“ Admin user created: ${user.email}`); // Create Chart of Accounts console.log("๐Ÿ“ˆ Creating chart of accounts..."); const accountsData: { code: string; name: string; type: AccountType; parent: string | null }[] = [ { code: "1000", name: "Cash and Cash Equivalents", type: "ASSET", parent: null }, { code: "1010", name: "Operating Account", type: "ASSET", parent: "1000" }, { code: "1020", name: "Payroll Account", type: "ASSET", parent: "1000" }, { code: "1100", name: "Accounts Receivable", type: "ASSET", parent: null }, { code: "1200", name: "Prepaid Expenses", type: "ASSET", parent: null }, { code: "1500", name: "Fixed Assets", type: "ASSET", parent: null }, { code: "1550", name: "Accumulated Depreciation", type: "ASSET", parent: null }, { code: "2000", name: "Accounts Payable", type: "LIABILITY", parent: null }, { code: "2100", name: "Deferred Revenue", type: "LIABILITY", parent: null }, { code: "2200", name: "Accrued Liabilities", type: "LIABILITY", parent: null }, { code: "2500", name: "Long-Term Debt", type: "LIABILITY", parent: null }, { code: "3000", name: "Common Stock", type: "EQUITY", parent: null }, { code: "3100", name: "Additional Paid-In Capital", type: "EQUITY", parent: null }, { code: "3200", name: "Retained Earnings", type: "EQUITY", parent: null }, { code: "4000", name: "Software Revenue", type: "REVENUE", parent: null }, { code: "4100", name: "Services Revenue", type: "REVENUE", parent: null }, { code: "4500", name: "Interest Income", type: "REVENUE", parent: null }, { code: "5000", name: "Cost of Goods Sold", type: "EXPENSE", parent: null }, { code: "6000", name: "Operating Expenses", type: "EXPENSE", parent: null }, { code: "6100", name: "Sales & Marketing", type: "EXPENSE", parent: "6000" }, { code: "6200", name: "Engineering", type: "EXPENSE", parent: "6000" }, { code: "6300", name: "General & Administrative", type: "EXPENSE", parent: "6000" }, { code: "6400", name: "IT & Infrastructure", type: "EXPENSE", parent: "6000" }, { code: "7000", name: "Interest Expense", type: "EXPENSE", parent: null }, ]; // First pass: create all accounts without parents const accounts: Record = {}; for (const a of accountsData) { const account = await prisma.chartOfAccount.create({ data: { organizationId: organization.id, accountCode: a.code, accountName: a.name, accountType: a.type, status: "ACTIVE", level: a.parent ? 2 : 1, hierarchy: a.parent ? `${a.parent}/${a.code}` : a.code, }, }); accounts[a.code] = account; } // Second pass: set parent relationships for (const a of accountsData) { if (a.parent && accounts[a.parent]) { await prisma.chartOfAccount.update({ where: { id: accounts[a.code].id }, data: { parentAccountId: accounts[a.parent].id }, }); } } console.log(`โœ“ Created ${accountsData.length} accounts`); // ======================================== // Create Fiscal Periods for FY2024, FY2025, FY2026 // ======================================== console.log("๐Ÿ“… Creating fiscal periods..."); const months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; const allPeriods: Record = {}; // FY2024 โ€” all CLOSED for (let i = 0; i < 12; i++) { const startDate = new Date(2024, i, 1); const endDate = new Date(2024, i + 1, 0); const period = await prisma.fiscalPeriod.create({ data: { organizationId: organization.id, fiscalYear: 2024, periodNumber: i + 1, periodName: `${months[i]} 2024`, startDate, endDate, status: "CLOSED" as FiscalPeriodStatus, }, }); allPeriods[`2024-${i + 1}`] = period; } // FY2025 โ€” all CLOSED (year is complete) for (let i = 0; i < 12; i++) { const startDate = new Date(2025, i, 1); const endDate = new Date(2025, i + 1, 0); const period = await prisma.fiscalPeriod.create({ data: { organizationId: organization.id, fiscalYear: 2025, periodNumber: i + 1, periodName: `${months[i]} 2025`, startDate, endDate, status: "CLOSED" as FiscalPeriodStatus, }, }); allPeriods[`2025-${i + 1}`] = period; } // FY2026 โ€” Janโ€“Mar CLOSED, Aprโ€“Dec OPEN (current date: April 5, 2026) for (let i = 0; i < 12; i++) { const startDate = new Date(2026, i, 1); const endDate = new Date(2026, i + 1, 0); const status: FiscalPeriodStatus = i < 3 ? "CLOSED" : "OPEN"; const period = await prisma.fiscalPeriod.create({ data: { organizationId: organization.id, fiscalYear: 2026, periodNumber: i + 1, periodName: `${months[i]} 2026`, startDate, endDate, status, }, }); allPeriods[`2026-${i + 1}`] = period; } console.log(`โœ“ Created 36 fiscal periods (FY2024-FY2026)`); // ======================================== // COMPREHENSIVE JOURNAL ENTRIES // Spanning Jan 2025 โ€“ March 2026 across all account types // ======================================== console.log("๐Ÿ“ Creating comprehensive journal entries..."); let jeCounter = 0; async function createJE(opts: { periodKey: string; date: string; description: string; sourceModule: string; status: "POSTED" | "DRAFT" | "PENDING_APPROVAL"; entityRef: any; lines: { accountCode: string; debit: number; credit: number; desc: string }[]; }) { jeCounter++; const entryNumber = `JE-${opts.date.slice(0, 4)}-${String(jeCounter).padStart(4, "0")}`; const totalDebits = opts.lines.reduce((s, l) => s + l.debit, 0); const totalCredits = opts.lines.reduce((s, l) => s + l.credit, 0); const isPosted = opts.status === "POSTED"; const entryDate = new Date(opts.date); return prisma.journalEntry.create({ data: { organizationId: organization.id, fiscalPeriodId: allPeriods[opts.periodKey].id, entryNumber, entryDate, description: opts.description, sourceModule: opts.sourceModule, status: opts.status, totalDebits, totalCredits, isBalanced: totalDebits === totalCredits, postedAt: isPosted ? entryDate : null, postedBy: isPosted ? user.id : null, createdBy: user.name, journalEntryLines: { create: opts.lines.map((l, idx) => ({ organizationId: organization.id, entityId: opts.entityRef.id, accountId: accounts[l.accountCode].id, debitAmount: l.debit, creditAmount: l.credit, lineNumber: idx + 1, description: l.desc, })), }, }, }); } // ---- FY2025 MONTHLY JOURNAL ENTRIES ---- // We'll create recurring monthly entries + some one-off transactions for (let month = 1; month <= 12; month++) { const mm = String(month).padStart(2, "0"); const periodKey = `2025-${month}`; const monthName = months[month - 1]; // 1) Monthly Software Revenue (ACM-US) โ€” DR AR, CR Revenue await createJE({ periodKey, date: `2025-${mm}-05`, description: `${monthName} 2025 software license revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1100", debit: 185000, credit: 0, desc: `AR - software licenses ${monthName}` }, { accountCode: "4000", debit: 0, credit: 185000, desc: `Software revenue ${monthName}` }, ], }); // 2) Monthly Services Revenue (ACM-US) โ€” DR AR, CR Services Revenue await createJE({ periodKey, date: `2025-${mm}-08`, description: `${monthName} 2025 consulting & services revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1100", debit: 92000, credit: 0, desc: `AR - consulting services ${monthName}` }, { accountCode: "4100", debit: 0, credit: 92000, desc: `Services revenue ${monthName}` }, ], }); // 3) Monthly Cash Collection (ACM-US) โ€” DR Cash, CR AR await createJE({ periodKey, date: `2025-${mm}-20`, description: `${monthName} 2025 customer payments received`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 245000, credit: 0, desc: `Cash received from customers ${monthName}` }, { accountCode: "1100", debit: 0, credit: 245000, desc: `AR collections ${monthName}` }, ], }); // 4) Monthly COGS (ACM-US) โ€” DR COGS, CR Cash await createJE({ periodKey, date: `2025-${mm}-10`, description: `${monthName} 2025 cost of goods sold`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "5000", debit: 55000, credit: 0, desc: `COGS - hosting & delivery ${monthName}` }, { accountCode: "1010", debit: 0, credit: 55000, desc: `Payment for COGS ${monthName}` }, ], }); // 5) Monthly Engineering Payroll (ACM-US) โ€” DR Engineering, CR Payroll Account await createJE({ periodKey, date: `2025-${mm}-25`, description: `${monthName} 2025 engineering payroll`, sourceModule: "PAYROLL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6200", debit: 210000, credit: 0, desc: `Engineering salaries ${monthName}` }, { accountCode: "1020", debit: 0, credit: 210000, desc: `Payroll disbursement ${monthName}` }, ], }); // 6) Monthly S&M Expenses โ€” DR S&M, CR AP await createJE({ periodKey, date: `2025-${mm}-12`, description: `${monthName} 2025 sales & marketing expenses`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6100", debit: 45000, credit: 0, desc: `Marketing campaigns & sales ops ${monthName}` }, { accountCode: "2000", debit: 0, credit: 45000, desc: `AP - marketing vendors ${monthName}` }, ], }); // 7) Monthly G&A Expenses โ€” DR G&A, CR AP await createJE({ periodKey, date: `2025-${mm}-15`, description: `${monthName} 2025 general & administrative`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6300", debit: 38000, credit: 0, desc: `Office rent, insurance, admin ${monthName}` }, { accountCode: "2000", debit: 0, credit: 38000, desc: `AP - G&A vendors ${monthName}` }, ], }); // 8) Monthly IT & Infrastructure โ€” DR IT, CR AP await createJE({ periodKey, date: `2025-${mm}-14`, description: `${monthName} 2025 IT & infrastructure`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6400", debit: 22000, credit: 0, desc: `Cloud hosting, SaaS tools ${monthName}` }, { accountCode: "2000", debit: 0, credit: 22000, desc: `AP - IT vendors ${monthName}` }, ], }); // 9) Monthly AP Payments โ€” DR AP, CR Cash (pay last month's bills) await createJE({ periodKey, date: `2025-${mm}-18`, description: `${monthName} 2025 vendor payments`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "2000", debit: 95000, credit: 0, desc: `AP payments to vendors ${monthName}` }, { accountCode: "1010", debit: 0, credit: 95000, desc: `Cash disbursed ${monthName}` }, ], }); // 10) Monthly Depreciation โ€” DR Depreciation Expense (G&A), CR Accumulated Depreciation await createJE({ periodKey, date: `2025-${mm}-28`, description: `${monthName} 2025 depreciation expense`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6300", debit: 8500, credit: 0, desc: `Monthly depreciation ${monthName}` }, { accountCode: "1550", debit: 0, credit: 8500, desc: `Accumulated depreciation ${monthName}` }, ], }); // 11) Monthly Interest on Long-Term Debt โ€” DR Interest Expense, CR Accrued Liabilities await createJE({ periodKey, date: `2025-${mm}-28`, description: `${monthName} 2025 interest expense on long-term debt`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "7000", debit: 4200, credit: 0, desc: `Interest on term loan ${monthName}` }, { accountCode: "2200", debit: 0, credit: 4200, desc: `Accrued interest ${monthName}` }, ], }); // 12) Monthly Interest Income โ€” DR Cash, CR Interest Income (small) await createJE({ periodKey, date: `2025-${mm}-28`, description: `${monthName} 2025 interest income earned`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 1800, credit: 0, desc: `Interest earned on deposits ${monthName}` }, { accountCode: "4500", debit: 0, credit: 1800, desc: `Interest income ${monthName}` }, ], }); // UK Entity Revenue (quarterly โ€” Q1, Q2, Q3, Q4) if (month % 3 === 0) { await createJE({ periodKey, date: `2025-${mm}-15`, description: `Q${month / 3} 2025 Acme Cloud UK revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeCloud, lines: [ { accountCode: "1100", debit: 125000, credit: 0, desc: `AR - UK cloud services Q${month / 3}` }, { accountCode: "4000", debit: 0, credit: 125000, desc: `UK cloud revenue Q${month / 3}` }, ], }); } // Europe Entity Revenue (quarterly) if (month % 3 === 0) { await createJE({ periodKey, date: `2025-${mm}-16`, description: `Q${month / 3} 2025 Acme Europe revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeEurope, lines: [ { accountCode: "1100", debit: 95000, credit: 0, desc: `AR - Europe consulting Q${month / 3}` }, { accountCode: "4100", debit: 0, credit: 95000, desc: `Europe services revenue Q${month / 3}` }, ], }); } // Pacific Entity Revenue (quarterly) if (month % 3 === 0) { await createJE({ periodKey, date: `2025-${mm}-17`, description: `Q${month / 3} 2025 Acme Pacific revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmePacific, lines: [ { accountCode: "1100", debit: 68000, credit: 0, desc: `AR - Pacific software Q${month / 3}` }, { accountCode: "4000", debit: 0, credit: 68000, desc: `Pacific software revenue Q${month / 3}` }, ], }); } } // ---- ONE-OFF FY2025 ENTRIES ---- // Fixed Asset Purchase (Q1 2025) โ€” DR Fixed Assets, CR Cash await createJE({ periodKey: "2025-2", date: "2025-02-15", description: "Server hardware and office equipment purchase", sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1500", debit: 350000, credit: 0, desc: "Server hardware, networking gear" }, { accountCode: "1010", debit: 0, credit: 350000, desc: "Cash payment for fixed assets" }, ], }); // Additional Fixed Asset Purchase (Q3 2025) await createJE({ periodKey: "2025-8", date: "2025-08-10", description: "Office furniture and developer workstations", sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1500", debit: 125000, credit: 0, desc: "Office furniture & workstations" }, { accountCode: "1010", debit: 0, credit: 125000, desc: "Cash payment for equipment" }, ], }); // Prepaid Expenses โ€” annual insurance (Jan 2025) await createJE({ periodKey: "2025-1", date: "2025-01-05", description: "Annual business insurance premium prepayment", sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1200", debit: 96000, credit: 0, desc: "Prepaid D&O and E&O insurance" }, { accountCode: "1010", debit: 0, credit: 96000, desc: "Cash payment for insurance" }, ], }); // Deferred Revenue Recognition (Q2 2025) โ€” large annual license prepaid await createJE({ periodKey: "2025-4", date: "2025-04-01", description: "Received annual license prepayment from Global Partners", sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 480000, credit: 0, desc: "Cash received - annual prepayment" }, { accountCode: "2100", debit: 0, credit: 480000, desc: "Deferred revenue - Global Partners" }, ], }); // Deferred Revenue Recognition monthly (Q2-Q4, 9 months of $53,333) for (let m = 4; m <= 12; m++) { const mm = String(m).padStart(2, "0"); await createJE({ periodKey: `2025-${m}`, date: `2025-${mm}-28`, description: `${months[m - 1]} 2025 deferred revenue recognition`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "2100", debit: 53333, credit: 0, desc: `Deferred rev recognition ${months[m - 1]}` }, { accountCode: "4000", debit: 0, credit: 53333, desc: `Revenue recognized ${months[m - 1]}` }, ], }); } // Long-term Debt Drawdown (Mar 2025) โ€” DR Cash, CR Long-Term Debt await createJE({ periodKey: "2025-3", date: "2025-03-01", description: "Term loan drawdown - growth capital", sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 2000000, credit: 0, desc: "Loan proceeds received" }, { accountCode: "2500", debit: 0, credit: 2000000, desc: "Term loan - 5yr facility" }, ], }); // Equity Contribution (Jan 2025) โ€” Series B round await createJE({ periodKey: "2025-1", date: "2025-01-15", description: "Series B equity investment received", sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 5000000, credit: 0, desc: "Series B investment proceeds" }, { accountCode: "3000", debit: 0, credit: 500000, desc: "Common stock par value" }, { accountCode: "3100", debit: 0, credit: 4500000, desc: "Additional paid-in capital" }, ], }); // Quarterly debt principal repayment for (const q of [6, 9, 12]) { const mm = String(q).padStart(2, "0"); await createJE({ periodKey: `2025-${q}`, date: `2025-${mm}-30`, description: `Q${q / 3} 2025 loan principal repayment`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "2500", debit: 100000, credit: 0, desc: `Term loan principal Q${q / 3}` }, { accountCode: "1010", debit: 0, credit: 100000, desc: `Cash - loan repayment Q${q / 3}` }, ], }); } // Payroll Account Funding (monthly โ€” DR Payroll, CR Operating) for (let month = 1; month <= 12; month++) { const mm = String(month).padStart(2, "0"); await createJE({ periodKey: `2025-${month}`, date: `2025-${mm}-22`, description: `${months[month - 1]} 2025 payroll account funding`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1020", debit: 210000, credit: 0, desc: `Payroll funding ${months[month - 1]}` }, { accountCode: "1010", debit: 0, credit: 210000, desc: `Transfer to payroll ${months[month - 1]}` }, ], }); } // ---- FY2026 Q1 JOURNAL ENTRIES (Janโ€“Mar 2026) ---- for (let month = 1; month <= 3; month++) { const mm = String(month).padStart(2, "0"); const periodKey = `2026-${month}`; const monthName = months[month - 1]; // Revenue entries (growing 10% over FY2025) await createJE({ periodKey, date: `2026-${mm}-05`, description: `${monthName} 2026 software license revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1100", debit: 203500, credit: 0, desc: `AR - software licenses ${monthName}` }, { accountCode: "4000", debit: 0, credit: 203500, desc: `Software revenue ${monthName}` }, ], }); await createJE({ periodKey, date: `2026-${mm}-08`, description: `${monthName} 2026 services revenue`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1100", debit: 101200, credit: 0, desc: `AR - consulting services ${monthName}` }, { accountCode: "4100", debit: 0, credit: 101200, desc: `Services revenue ${monthName}` }, ], }); // Cash collections await createJE({ periodKey, date: `2026-${mm}-20`, description: `${monthName} 2026 customer payments received`, sourceModule: "AR", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 270000, credit: 0, desc: `Cash received ${monthName}` }, { accountCode: "1100", debit: 0, credit: 270000, desc: `AR collections ${monthName}` }, ], }); // COGS await createJE({ periodKey, date: `2026-${mm}-10`, description: `${monthName} 2026 cost of goods sold`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "5000", debit: 60500, credit: 0, desc: `COGS ${monthName}` }, { accountCode: "1010", debit: 0, credit: 60500, desc: `COGS payment ${monthName}` }, ], }); // Engineering Payroll await createJE({ periodKey, date: `2026-${mm}-25`, description: `${monthName} 2026 engineering payroll`, sourceModule: "PAYROLL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6200", debit: 225000, credit: 0, desc: `Engineering salaries ${monthName}` }, { accountCode: "1020", debit: 0, credit: 225000, desc: `Payroll disbursement ${monthName}` }, ], }); // S&M await createJE({ periodKey, date: `2026-${mm}-12`, description: `${monthName} 2026 sales & marketing`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6100", debit: 49500, credit: 0, desc: `Marketing ${monthName}` }, { accountCode: "2000", debit: 0, credit: 49500, desc: `AP - marketing ${monthName}` }, ], }); // G&A await createJE({ periodKey, date: `2026-${mm}-15`, description: `${monthName} 2026 G&A expenses`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6300", debit: 41800, credit: 0, desc: `G&A expenses ${monthName}` }, { accountCode: "2000", debit: 0, credit: 41800, desc: `AP - G&A ${monthName}` }, ], }); // IT await createJE({ periodKey, date: `2026-${mm}-14`, description: `${monthName} 2026 IT & infrastructure`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6400", debit: 24200, credit: 0, desc: `IT costs ${monthName}` }, { accountCode: "2000", debit: 0, credit: 24200, desc: `AP - IT ${monthName}` }, ], }); // AP Payments await createJE({ periodKey, date: `2026-${mm}-18`, description: `${monthName} 2026 vendor payments`, sourceModule: "AP", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "2000", debit: 105000, credit: 0, desc: `AP payments ${monthName}` }, { accountCode: "1010", debit: 0, credit: 105000, desc: `Cash disbursed ${monthName}` }, ], }); // Depreciation await createJE({ periodKey, date: `2026-${mm}-28`, description: `${monthName} 2026 depreciation`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "6300", debit: 9900, credit: 0, desc: `Depreciation ${monthName}` }, { accountCode: "1550", debit: 0, credit: 9900, desc: `Accum depreciation ${monthName}` }, ], }); // Interest Expense await createJE({ periodKey, date: `2026-${mm}-28`, description: `${monthName} 2026 interest expense`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "7000", debit: 3500, credit: 0, desc: `Interest on debt ${monthName}` }, { accountCode: "2200", debit: 0, credit: 3500, desc: `Accrued interest ${monthName}` }, ], }); // Interest Income await createJE({ periodKey, date: `2026-${mm}-28`, description: `${monthName} 2026 interest income`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1010", debit: 2100, credit: 0, desc: `Interest earned ${monthName}` }, { accountCode: "4500", debit: 0, credit: 2100, desc: `Interest income ${monthName}` }, ], }); // Payroll funding await createJE({ periodKey, date: `2026-${mm}-22`, description: `${monthName} 2026 payroll account funding`, sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "1020", debit: 225000, credit: 0, desc: `Payroll funding ${monthName}` }, { accountCode: "1010", debit: 0, credit: 225000, desc: `Transfer to payroll ${monthName}` }, ], }); } // Q1 2026 subsidiary revenues await createJE({ periodKey: "2026-3", date: "2026-03-15", description: "Q1 2026 Acme Cloud UK revenue", sourceModule: "AR", status: "POSTED", entityRef: acmeCloud, lines: [ { accountCode: "1100", debit: 142000, credit: 0, desc: "AR - UK cloud services Q1 2026" }, { accountCode: "4000", debit: 0, credit: 142000, desc: "UK cloud revenue Q1 2026" }, ], }); await createJE({ periodKey: "2026-3", date: "2026-03-16", description: "Q1 2026 Acme Europe revenue", sourceModule: "AR", status: "POSTED", entityRef: acmeEurope, lines: [ { accountCode: "1100", debit: 108000, credit: 0, desc: "AR - Europe consulting Q1 2026" }, { accountCode: "4100", debit: 0, credit: 108000, desc: "Europe services revenue Q1 2026" }, ], }); await createJE({ periodKey: "2026-3", date: "2026-03-17", description: "Q1 2026 Acme Pacific revenue", sourceModule: "AR", status: "POSTED", entityRef: acmePacific, lines: [ { accountCode: "1100", debit: 78000, credit: 0, desc: "AR - Pacific software Q1 2026" }, { accountCode: "4000", debit: 0, credit: 78000, desc: "Pacific revenue Q1 2026" }, ], }); // FY2026 Opening retained earnings entry (close FY2025 net income) // FY2025 Net Income calc: Revenue (185k*12+92k*12+125k*4+95k*4+68k*4+53.3k*9+1.8k*12) - Expenses // Approx: Revenue ~$4.87M, Expenses ~$4.61M โ†’ Net income ~$260k โ†’ round to closing entry await createJE({ periodKey: "2026-1", date: "2026-01-01", description: "FY2025 year-end close - retained earnings", sourceModule: "GL", status: "POSTED", entityRef: acmeSoftware, lines: [ { accountCode: "3200", debit: 0, credit: 258400, desc: "FY2025 net income to retained earnings" }, { accountCode: "1010", debit: 258400, credit: 0, desc: "Opening balance adjustment" }, ], }); // A couple DRAFT entries in April 2026 (current month) await createJE({ periodKey: "2026-4", date: "2026-04-03", description: "April 2026 software revenue accrual (draft)", sourceModule: "AR", status: "DRAFT", entityRef: acmeSoftware, lines: [ { accountCode: "1100", debit: 203500, credit: 0, desc: "AR - April software" }, { accountCode: "4000", debit: 0, credit: 203500, desc: "April software revenue" }, ], }); await createJE({ periodKey: "2026-4", date: "2026-04-04", description: "April 2026 payroll accrual (pending approval)", sourceModule: "PAYROLL", status: "PENDING_APPROVAL", entityRef: acmeSoftware, lines: [ { accountCode: "6200", debit: 225000, credit: 0, desc: "April engineering payroll" }, { accountCode: "2200", debit: 0, credit: 225000, desc: "Accrued payroll" }, ], }); console.log(`โœ“ Created ${jeCounter} journal entries`); // ======================================== // VENDORS // ======================================== console.log("๐Ÿช Creating vendors..."); const vendors = []; const vendorData = [ { code: "V001", name: "Amazon Web Services", termDays: 30, type: "Cloud Services", email: "billing@aws.amazon.com", phone: "206-555-0100" }, { code: "V002", name: "Salesforce Inc", termDays: 45, type: "Software", email: "invoices@salesforce.com", phone: "415-555-0200" }, { code: "V003", name: "WeWork", termDays: 30, type: "Real Estate", email: "accounts@wework.com", phone: "212-555-0300" }, { code: "V004", name: "ADP Inc", termDays: 15, type: "HR Services", email: "billing@adp.com", phone: "973-555-0400" }, { code: "V005", name: "Dell Technologies", termDays: 60, type: "Hardware", email: "orders@dell.com", phone: "512-555-0500" }, { code: "V006", name: "Google Cloud Platform", termDays: 30, type: "Cloud Services", email: "billing@google.com", phone: "650-555-0600" }, { code: "V007", name: "Datadog Inc", termDays: 30, type: "Software", email: "billing@datadoghq.com", phone: "646-555-0700" }, { code: "V008", name: "Marsh McLennan", termDays: 45, type: "Insurance", email: "accounts@marsh.com", phone: "212-555-0800" }, ]; for (const v of vendorData) { const vendor = await prisma.vendor.create({ data: { organizationId: organization.id, vendorCode: v.code, vendorName: v.name, vendorType: v.type, paymentTermDays: v.termDays, email: v.email, phone: v.phone, status: "ACTIVE", }, }); vendors.push(vendor); } console.log(`โœ“ Created ${vendors.length} vendors`); // ======================================== // PURCHASE ORDERS // ======================================== console.log("๐Ÿ“ฆ Creating purchase orders..."); const purchaseOrders = []; const poData = [ { poNumber: "PO-2026-001", vendor: vendors[0], orderDate: new Date("2026-01-15"), expectedDate: new Date("2026-02-01"), status: "RECEIVED", subtotal: 22000, tax: 1980, lines: [{ lineNumber: 1, description: "AWS Reserved Instances - Q1 2026", quantity: 1, unitPrice: 22000 }], }, { poNumber: "PO-2026-002", vendor: vendors[1], orderDate: new Date("2026-01-20"), expectedDate: new Date("2026-02-15"), status: "RECEIVED", subtotal: 48000, tax: 4320, lines: [{ lineNumber: 1, description: "Salesforce Enterprise - Annual Renewal", quantity: 1, unitPrice: 48000 }], }, { poNumber: "PO-2026-003", vendor: vendors[2], orderDate: new Date("2026-02-01"), expectedDate: new Date("2026-03-01"), status: "APPROVED", subtotal: 30000, tax: 2700, lines: [ { lineNumber: 1, description: "Office lease - Q2 2026", quantity: 3, unitPrice: 8000 }, { lineNumber: 2, description: "Common area + utilities", quantity: 1, unitPrice: 6000 }, ], }, { poNumber: "PO-2026-004", vendor: vendors[4], orderDate: new Date("2026-02-10"), expectedDate: new Date("2026-03-10"), status: "PARTIALLY_RECEIVED", subtotal: 75000, tax: 6750, lines: [{ lineNumber: 1, description: "Developer workstations - new hires", quantity: 15, unitPrice: 5000 }], }, { poNumber: "PO-2026-005", vendor: vendors[5], orderDate: new Date("2026-03-01"), expectedDate: new Date("2026-03-15"), status: "SENT", subtotal: 18000, tax: 1620, lines: [{ lineNumber: 1, description: "GCP BigQuery & Vertex AI credits", quantity: 1, unitPrice: 18000 }], }, { poNumber: "PO-2026-006", vendor: vendors[6], orderDate: new Date("2026-03-05"), expectedDate: new Date("2026-03-20"), status: "APPROVED", subtotal: 9600, tax: 864, lines: [{ lineNumber: 1, description: "Datadog Pro - Annual", quantity: 1, unitPrice: 9600 }], }, { poNumber: "PO-2026-007", vendor: vendors[3], orderDate: new Date("2026-03-15"), expectedDate: new Date("2026-04-01"), status: "SENT", subtotal: 12000, tax: 1080, lines: [{ lineNumber: 1, description: "ADP Workforce Now - Q2 processing", quantity: 1, unitPrice: 12000 }], }, { poNumber: "PO-2026-008", vendor: vendors[7], orderDate: new Date("2026-01-10"), expectedDate: new Date("2026-01-31"), status: "RECEIVED", subtotal: 96000, tax: 8640, lines: [{ lineNumber: 1, description: "Annual D&O and E&O insurance premium", quantity: 1, unitPrice: 96000 }], }, ]; for (const po of poData) { const subtotal = po.lines.reduce((sum, line) => sum + (line.quantity * line.unitPrice), 0); const totalAmount = subtotal + po.tax; const purchaseOrder = await prisma.purchaseOrder.create({ data: { organizationId: organization.id, poNumber: po.poNumber, vendorId: po.vendor.id, orderDate: po.orderDate, expectedDate: po.expectedDate, status: po.status, subtotal: subtotal.toString(), taxAmount: po.tax.toString(), totalAmount: totalAmount.toString(), notes: null, createdBy: user.id, lines: { create: po.lines.map(line => ({ lineNumber: line.lineNumber, description: line.description, quantity: line.quantity, unitPrice: line.unitPrice, lineAmount: (line.quantity * line.unitPrice).toString(), glAccountCode: null, })), }, }, include: { vendor: true, lines: true }, }); purchaseOrders.push(purchaseOrder); } console.log(`โœ“ Created ${purchaseOrders.length} purchase orders`); // ======================================== // CUSTOMERS // ======================================== console.log("๐Ÿ‘ฅ Creating customers..."); const customers = []; const customerData = [ { code: "C001", name: "ABC Corporation", termDays: 30, type: "Enterprise", email: "ap@abccorp.com", phone: "212-555-1001" }, { code: "C002", name: "TechVenture Inc", termDays: 30, type: "SaaS", email: "billing@techventure.io", phone: "415-555-1002" }, { code: "C003", name: "Global Partners Ltd", termDays: 45, type: "Consulting", email: "finance@globalpartners.com", phone: "44-20-555-1003" }, { code: "C004", name: "Premier Solutions Group", termDays: 30, type: "Enterprise", email: "accounts@premiersolutions.com", phone: "312-555-1004" }, { code: "C005", name: "StartUp Ventures", termDays: 15, type: "Startup", email: "cfo@startupventures.co", phone: "650-555-1005" }, { code: "C006", name: "Northern Health Systems", termDays: 45, type: "Enterprise", email: "procurement@northernhealth.org", phone: "617-555-1006" }, { code: "C007", name: "Pacific Retail Group", termDays: 30, type: "Enterprise", email: "finance@pacificretail.com", phone: "503-555-1007" }, { code: "C008", name: "Atlas Financial Corp", termDays: 30, type: "Financial Services", email: "vendor-mgmt@atlasfinancial.com", phone: "704-555-1008" }, ]; for (const c of customerData) { const customer = await prisma.customer.create({ data: { organizationId: organization.id, customerCode: c.code, customerName: c.name, customerType: c.type, paymentTermDays: c.termDays, email: c.email, phone: c.phone, status: "ACTIVE", }, }); customers.push(customer); } console.log(`โœ“ Created ${customers.length} customers`); // ======================================== // AP INVOICES (FY2026 Q1) // ======================================== console.log("๐Ÿ“„ Creating AP invoices..."); const apInvoices = []; const apInvoiceData = [ { number: "INV-AP-2026-0001", vendor: vendors[0], amount: 22000, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-01-10"), dueDate: new Date("2026-02-15"), paidAmount: 22000, lines: [{ accountCode: "6400", description: "AWS Reserved Instances - Jan", amount: 22000 }] }, { number: "INV-AP-2026-0002", vendor: vendors[1], amount: 48000, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-01-20"), dueDate: new Date("2026-03-05"), paidAmount: 48000, lines: [{ accountCode: "6100", description: "Salesforce Enterprise - Annual", amount: 48000 }] }, { number: "INV-AP-2026-0003", vendor: vendors[2], amount: 30000, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-02-01"), dueDate: new Date("2026-04-01"), lines: [{ accountCode: "6300", description: "Office lease - Q2", amount: 24000 }, { accountCode: "6300", description: "Utilities Q2", amount: 6000 }] }, { number: "INV-AP-2026-0004", vendor: vendors[3], amount: 12000, status: "PENDING_APPROVAL" as InvoiceStatus, issueDate: new Date("2026-03-15"), dueDate: new Date("2026-04-15"), lines: [{ accountCode: "6300", description: "ADP Payroll Processing Q2", amount: 12000 }] }, { number: "INV-AP-2026-0005", vendor: vendors[4], amount: 75000, status: "PARTIALLY_PAID" as InvoiceStatus, issueDate: new Date("2026-02-10"), dueDate: new Date("2026-04-10"), paidAmount: 37500, lines: [{ accountCode: "6400", description: "Developer workstations", amount: 75000 }] }, { number: "INV-AP-2026-0006", vendor: vendors[0], amount: 24200, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-02-28"), dueDate: new Date("2026-03-30"), lines: [{ accountCode: "6400", description: "AWS usage - February", amount: 24200 }] }, { number: "INV-AP-2026-0007", vendor: vendors[5], amount: 18000, status: "DRAFT" as InvoiceStatus, issueDate: new Date("2026-03-25"), dueDate: new Date("2026-04-30"), lines: [{ accountCode: "6400", description: "GCP BigQuery & AI credits", amount: 18000 }] }, { number: "INV-AP-2026-0008", vendor: vendors[6], amount: 9600, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-03-05"), dueDate: new Date("2026-04-05"), lines: [{ accountCode: "6400", description: "Datadog Pro Annual", amount: 9600 }] }, { number: "INV-AP-2026-0009", vendor: vendors[7], amount: 96000, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-01-08"), dueDate: new Date("2026-02-10"), paidAmount: 96000, lines: [{ accountCode: "1200", description: "Annual D&O + E&O insurance", amount: 96000 }] }, { number: "INV-AP-2026-0010", vendor: vendors[2], amount: 8000, status: "OVERDUE" as InvoiceStatus, issueDate: new Date("2026-01-25"), dueDate: new Date("2026-03-01"), daysOverdue: 35, lines: [{ accountCode: "6300", description: "Conference room rental Feb", amount: 8000 }] }, { number: "INV-AP-2026-0011", vendor: vendors[0], amount: 24200, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-03-28"), dueDate: new Date("2026-04-30"), lines: [{ accountCode: "6400", description: "AWS usage - March", amount: 24200 }] }, { number: "INV-AP-2026-0012", vendor: vendors[4], amount: 15000, status: "DRAFT" as InvoiceStatus, issueDate: new Date("2026-04-01"), dueDate: new Date("2026-05-10"), lines: [{ accountCode: "1500", description: "Additional server hardware", amount: 15000 }] }, ]; for (const apData of apInvoiceData) { const invoiceLines = apData.lines.map((line, index) => ({ description: line.description, quantity: 1, unitPrice: line.amount, lineAmount: line.amount, lineNumber: index + 1, glAccountCode: line.accountCode, })); const totalAmount = apData.lines.reduce((sum, line) => sum + line.amount, 0); const paidAmount = apData.paidAmount ?? (apData.status === "PAID" ? totalAmount : 0); const invoice = await prisma.invoice.create({ data: { organizationId: organization.id, entityId: acmeSoftware.id, vendorId: apData.vendor.id, invoiceNumber: apData.number, invoiceDate: apData.issueDate, dueDate: apData.dueDate, invoiceType: "ACCOUNTS_PAYABLE", status: apData.status, subtotalAmount: totalAmount, totalAmount, paidAmount, balanceDue: totalAmount - paidAmount, daysOverdue: apData.daysOverdue ?? null, invoiceLines: { create: invoiceLines }, }, }); apInvoices.push(invoice); } console.log(`โœ“ Created ${apInvoices.length} AP invoices`); // ======================================== // AR INVOICES (FY2026 Q1) // ======================================== console.log("๐Ÿ“„ Creating AR invoices..."); const arInvoices = []; const arInvoiceData = [ { number: "INV-AR-2026-0001", customer: customers[0], amount: 185000, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-01-05"), dueDate: new Date("2026-02-14"), paidAmount: 185000, lines: [{ accountCode: "4000", description: "Enterprise platform license - Jan", amount: 185000 }] }, { number: "INV-AR-2026-0002", customer: customers[1], amount: 45000, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-01-08"), dueDate: new Date("2026-02-14"), paidAmount: 45000, lines: [{ accountCode: "4100", description: "SaaS subscription Q1", amount: 45000 }] }, { number: "INV-AR-2026-0003", customer: customers[2], amount: 92000, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-02-10"), dueDate: new Date("2026-03-30"), lines: [{ accountCode: "4100", description: "Consulting engagement - Feb/Mar", amount: 92000 }] }, { number: "INV-AR-2026-0004", customer: customers[3], amount: 203500, status: "PAID" as InvoiceStatus, issueDate: new Date("2026-02-01"), dueDate: new Date("2026-03-14"), paidAmount: 203500, lines: [{ accountCode: "4000", description: "Enterprise license renewal", amount: 203500 }] }, { number: "INV-AR-2026-0005", customer: customers[4], amount: 24000, status: "OVERDUE" as InvoiceStatus, issueDate: new Date("2026-01-15"), dueDate: new Date("2026-02-20"), daysOverdue: 44, lines: [{ accountCode: "4100", description: "Startup plan - 12 months", amount: 24000 }] }, { number: "INV-AR-2026-0006", customer: customers[0], amount: 101200, status: "PARTIALLY_PAID" as InvoiceStatus, issueDate: new Date("2026-03-01"), dueDate: new Date("2026-04-14"), paidAmount: 50000, lines: [{ accountCode: "4000", description: "Implementation services", amount: 101200 }] }, { number: "INV-AR-2026-0007", customer: customers[5], amount: 156000, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-03-10"), dueDate: new Date("2026-04-30"), lines: [{ accountCode: "4000", description: "Healthcare platform license", amount: 156000 }] }, { number: "INV-AR-2026-0008", customer: customers[6], amount: 78000, status: "DRAFT" as InvoiceStatus, issueDate: new Date("2026-03-20"), dueDate: new Date("2026-05-15"), lines: [{ accountCode: "4000", description: "Retail analytics module", amount: 78000 }] }, { number: "INV-AR-2026-0009", customer: customers[7], amount: 210000, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-03-15"), dueDate: new Date("2026-04-20"), lines: [{ accountCode: "4000", description: "Financial compliance suite", amount: 135000 }, { accountCode: "4100", description: "Integration services", amount: 75000 }] }, { number: "INV-AR-2026-0010", customer: customers[1], amount: 15000, status: "APPROVED" as InvoiceStatus, issueDate: new Date("2026-03-28"), dueDate: new Date("2026-04-14"), lines: [{ accountCode: "4100", description: "SaaS subscription Q2", amount: 15000 }] }, ]; for (const arData of arInvoiceData) { const invoiceLines = arData.lines.map((line, index) => ({ description: line.description, quantity: 1, unitPrice: line.amount, lineAmount: line.amount, lineNumber: index + 1, glAccountCode: line.accountCode, })); const totalAmount = arData.lines.reduce((sum, line) => sum + line.amount, 0); const paidAmount = arData.paidAmount ?? (arData.status === "PAID" ? totalAmount : 0); const invoice = await prisma.invoice.create({ data: { organizationId: organization.id, entityId: acmeSoftware.id, customerId: arData.customer.id, invoiceNumber: arData.number, invoiceDate: arData.issueDate, dueDate: arData.dueDate, invoiceType: "ACCOUNTS_RECEIVABLE", status: arData.status, subtotalAmount: totalAmount, totalAmount, paidAmount, balanceDue: totalAmount - paidAmount, daysOverdue: arData.daysOverdue ?? null, invoiceLines: { create: invoiceLines }, }, }); arInvoices.push(invoice); } console.log(`โœ“ Created ${arInvoices.length} AR invoices`); // ======================================== // PAYMENTS // ======================================== console.log("๐Ÿ’ณ Creating payments..."); const payments = []; const paymentConfigs = [ { vendorId: vendors[0].id, invoiceIdx: 0, number: "PAY-2026-0001", date: "2026-02-10", method: "BANK_TRANSFER" as const, amount: 22000 }, { vendorId: vendors[1].id, invoiceIdx: 1, number: "PAY-2026-0002", date: "2026-02-28", method: "BANK_TRANSFER" as const, amount: 48000 }, { vendorId: vendors[7].id, invoiceIdx: 8, number: "PAY-2026-0003", date: "2026-02-05", method: "WIRE" as const, amount: 96000 }, { vendorId: vendors[4].id, invoiceIdx: 4, number: "PAY-2026-0004", date: "2026-03-20", method: "BANK_TRANSFER" as const, amount: 37500 }, { customerId: customers[0].id, invoiceIdx: 0, isAR: true, number: "PAY-2026-0005", date: "2026-02-12", method: "BANK_TRANSFER" as const, amount: 185000 }, { customerId: customers[1].id, invoiceIdx: 1, isAR: true, number: "PAY-2026-0006", date: "2026-02-10", method: "ACH" as const, amount: 45000 }, { customerId: customers[3].id, invoiceIdx: 3, isAR: true, number: "PAY-2026-0007", date: "2026-03-10", method: "WIRE" as const, amount: 203500 }, { customerId: customers[0].id, invoiceIdx: 5, isAR: true, number: "PAY-2026-0008", date: "2026-04-01", method: "CHECK" as const, amount: 50000 }, ]; for (const pc of paymentConfigs) { const invoiceRef = pc.isAR ? arInvoices[pc.invoiceIdx] : apInvoices[pc.invoiceIdx]; const payment = await prisma.payment.create({ data: { organizationId: organization.id, vendorId: pc.vendorId || null, customerId: pc.customerId || null, invoiceId: invoiceRef.id, paymentNumber: pc.number, paymentDate: new Date(pc.date), paymentMethod: pc.method, status: "COMPLETED", paymentAmount: pc.amount, totalPaymentAmount: pc.amount, paymentAllocations: { create: [{ organizationId: organization.id, invoiceId: invoiceRef.id, allocatedAmount: pc.amount }], }, }, }); payments.push(payment); } console.log(`โœ“ Created ${payments.length} payments`); // ======================================== // BANK ACCOUNTS // ======================================== console.log("๐Ÿฆ Creating bank accounts..."); const bankAccounts = []; const bankAccountsData = [ { name: "Chase Business Checking", bank: "Chase Bank", number: "****2847", type: "Checking", balance: 2845600.75, entity: acmeSoftware }, { name: "Bank of America Payroll", bank: "Bank of America", number: "****5923", type: "Checking", balance: 485340.50, entity: acmeSoftware }, { name: "Silicon Valley Bank", bank: "Silicon Valley Bank", number: "****7412", type: "Checking", balance: 1524850.00, entity: acmeSoftware }, { name: "Mercury Bank", bank: "Mercury", number: "****3156", type: "Savings", balance: 289750.25, entity: acmeSoftware }, { name: "Wells Fargo Business Savings", bank: "Wells Fargo", number: "****9284", type: "Savings", balance: 756200.00, entity: acmeSoftware }, { name: "Barclays UK Account", bank: "Barclays", number: "****6201", type: "Checking", balance: 342000.00, entity: acmeCloud }, { name: "Deutsche Bank EUR", bank: "Deutsche Bank", number: "****8834", type: "Checking", balance: 215000.00, entity: acmeEurope }, { name: "ANZ Business", bank: "ANZ", number: "****4477", type: "Checking", balance: 178500.00, entity: acmePacific }, ]; for (const accData of bankAccountsData) { const account = await prisma.bankAccount.create({ data: { organizationId: organization.id, entityId: accData.entity.id, accountName: accData.name, bankName: accData.bank, accountNumber: accData.number, accountNumberMasked: accData.number, accountType: accData.type, currencyCode: accData.entity === acmeCloud ? "GBP" : accData.entity === acmeEurope ? "EUR" : accData.entity === acmePacific ? "AUD" : "USD", currentBalance: accData.balance, availableBalance: accData.balance, lastBalanceUpdate: new Date("2026-04-03"), status: "ACTIVE", }, }); bankAccounts.push(account); } console.log(`โœ“ Created ${bankAccounts.length} bank accounts`); // ======================================== // BANK TRANSACTIONS (recent 30 days) // ======================================== console.log("๐Ÿ“Š Creating bank transactions..."); const bankTransactions = []; const transactionData = [ { account: bankAccounts[0], date: "2026-03-05", type: "CREDIT", amount: 185000, description: "Customer payment - ABC Corp", reconciled: true }, { account: bankAccounts[0], date: "2026-03-10", type: "CREDIT", amount: 203500, description: "Customer payment - Premier Solutions", reconciled: true }, { account: bankAccounts[0], date: "2026-03-12", type: "DEBIT", amount: 48000, description: "Salesforce annual renewal", reconciled: true }, { account: bankAccounts[0], date: "2026-03-15", type: "DEBIT", amount: 22000, description: "AWS cloud hosting", reconciled: true }, { account: bankAccounts[0], date: "2026-03-20", type: "DEBIT", amount: 37500, description: "Dell workstations partial", reconciled: true }, { account: bankAccounts[0], date: "2026-03-25", type: "CREDIT", amount: 45000, description: "Customer payment - TechVenture", reconciled: true }, { account: bankAccounts[0], date: "2026-04-01", type: "CREDIT", amount: 50000, description: "Customer payment - ABC Corp partial", reconciled: false }, { account: bankAccounts[0], date: "2026-04-03", type: "DEBIT", amount: 24200, description: "AWS usage - March billing", reconciled: false }, { account: bankAccounts[1], date: "2026-03-25", type: "DEBIT", amount: 225000, description: "March payroll - engineering", reconciled: true }, { account: bankAccounts[1], date: "2026-03-25", type: "DEBIT", amount: 49500, description: "March payroll - S&M team", reconciled: true }, { account: bankAccounts[1], date: "2026-03-25", type: "DEBIT", amount: 41800, description: "March payroll - G&A staff", reconciled: true }, { account: bankAccounts[1], date: "2026-03-22", type: "CREDIT", amount: 225000, description: "Payroll account funding - Mar", reconciled: true }, { account: bankAccounts[2], date: "2026-03-01", type: "DEBIT", amount: 96000, description: "Insurance premium - annual", reconciled: true }, { account: bankAccounts[2], date: "2026-03-15", type: "CREDIT", amount: 92000, description: "Customer payment - Global Partners", reconciled: true }, { account: bankAccounts[2], date: "2026-04-02", type: "DEBIT", amount: 105000, description: "Vendor payments batch", reconciled: false }, { account: bankAccounts[3], date: "2026-03-31", type: "CREDIT", amount: 2100, description: "Interest earned Q1", reconciled: true }, { account: bankAccounts[3], date: "2026-04-01", type: "DEBIT", amount: 150, description: "Monthly maintenance fee", reconciled: true }, { account: bankAccounts[4], date: "2026-03-30", type: "DEBIT", amount: 100000, description: "Loan principal payment Q1", reconciled: true }, { account: bankAccounts[4], date: "2026-03-30", type: "DEBIT", amount: 3500, description: "Interest payment Q1", reconciled: true }, { account: bankAccounts[5], date: "2026-03-15", type: "CREDIT", amount: 142000, description: "UK customer payments Q1", reconciled: true }, { account: bankAccounts[5], date: "2026-03-28", type: "DEBIT", amount: 45000, description: "UK operating expenses", reconciled: false }, { account: bankAccounts[6], date: "2026-03-16", type: "CREDIT", amount: 108000, description: "Europe customer payments Q1", reconciled: true }, { account: bankAccounts[6], date: "2026-03-30", type: "DEBIT", amount: 38000, description: "Europe operating expenses", reconciled: false }, { account: bankAccounts[7], date: "2026-03-17", type: "CREDIT", amount: 78000, description: "Pacific customer payments Q1", reconciled: true }, { account: bankAccounts[7], date: "2026-03-30", type: "DEBIT", amount: 28000, description: "Pacific operating expenses", reconciled: false }, ]; for (const txData of transactionData) { const txDate = new Date(txData.date); const transaction = await prisma.bankTransaction.create({ data: { organizationId: organization.id, bankAccountId: txData.account.id, transactionDate: txDate, postDate: txDate, transactionType: txData.type as "DEBIT" | "CREDIT" | "REVERSAL" | "ADJUSTMENT", amount: txData.amount, description: txData.description, reconciled: txData.reconciled, reconciledAt: txData.reconciled ? txDate : null, status: "PENDING", }, }); bankTransactions.push(transaction); } console.log(`โœ“ Created ${bankTransactions.length} bank transactions`); // ======================================== // CASH POSITION SNAPSHOTS // ======================================== console.log("๐Ÿ’ฐ Creating cash position snapshots..."); const cashSnapshots = [ { date: "2025-12-31", total: 5250000, byEntity: { "Acme Software Inc": 4450000, "Acme Cloud Services Ltd": 380000, "Acme Europe GmbH": 240000, "Acme Pacific Pty Ltd": 180000 } }, { date: "2026-01-31", total: 5680000, byEntity: { "Acme Software Inc": 4820000, "Acme Cloud Services Ltd": 395000, "Acme Europe GmbH": 268000, "Acme Pacific Pty Ltd": 197000 } }, { date: "2026-02-28", total: 5920000, byEntity: { "Acme Software Inc": 5010000, "Acme Cloud Services Ltd": 415000, "Acme Europe GmbH": 285000, "Acme Pacific Pty Ltd": 210000 } }, { date: "2026-03-31", total: 6137241.50, byEntity: { "Acme Software Inc": 5201741.50, "Acme Cloud Services Ltd": 439000, "Acme Europe GmbH": 310000, "Acme Pacific Pty Ltd": 186500 } }, { date: "2026-04-03", total: 6037241.50, byEntity: { "Acme Software Inc": 5101741.50, "Acme Cloud Services Ltd": 439000, "Acme Europe GmbH": 310000, "Acme Pacific Pty Ltd": 186500 } }, ]; for (const snap of cashSnapshots) { await prisma.cashPosition.create({ data: { organizationId: organization.id, snapshotDate: new Date(snap.date), totalCash: snap.total, totalAvailable: snap.total, cashByEntity: snap.byEntity, cashByCurrency: { USD: snap.byEntity["Acme Software Inc"], GBP: snap.byEntity["Acme Cloud Services Ltd"], EUR: snap.byEntity["Acme Europe GmbH"], AUD: snap.byEntity["Acme Pacific Pty Ltd"] }, }, }); } console.log(`โœ“ Created ${cashSnapshots.length} cash position snapshots`); // ======================================== // BUDGET LINES (FY2026) // ======================================== console.log("๐Ÿ“Š Creating budget lines..."); const budgetData = [ { accountCode: "4000", annual: 2640000, monthly: [200000, 210000, 215000, 220000, 225000, 225000, 220000, 215000, 220000, 230000, 230000, 230000] }, { accountCode: "4100", annual: 1200000, monthly: [95000, 98000, 100000, 102000, 100000, 100000, 100000, 102000, 103000, 100000, 100000, 100000] }, { accountCode: "4500", annual: 25200, monthly: [2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100] }, { accountCode: "5000", annual: 726000, monthly: [60500, 60500, 60500, 60500, 60500, 60500, 60500, 60500, 60500, 60500, 60500, 60500] }, { accountCode: "6100", annual: 594000, monthly: [49500, 49500, 49500, 49500, 49500, 49500, 49500, 49500, 49500, 49500, 49500, 49500] }, { accountCode: "6200", annual: 2700000, monthly: [225000, 225000, 225000, 225000, 225000, 225000, 225000, 225000, 225000, 225000, 225000, 225000] }, { accountCode: "6300", annual: 620400, monthly: [51700, 51700, 51700, 51700, 51700, 51700, 51700, 51700, 51700, 51700, 51700, 51700] }, { accountCode: "6400", annual: 290400, monthly: [24200, 24200, 24200, 24200, 24200, 24200, 24200, 24200, 24200, 24200, 24200, 24200] }, { accountCode: "7000", annual: 42000, monthly: [3500, 3500, 3500, 3500, 3500, 3500, 3500, 3500, 3500, 3500, 3500, 3500] }, ]; for (const bd of budgetData) { await prisma.budgetLine.create({ data: { organizationId: organization.id, accountId: accounts[bd.accountCode].id, fiscalYear: 2026, monthlyAmounts: bd.monthly, annualBudget: bd.annual, notes: `FY2026 budget for ${accounts[bd.accountCode].accountName}`, }, }); } console.log(`โœ“ Created ${budgetData.length} budget lines`); // Also create FY2025 budgets (for YoY comparison) const fy2025BudgetData = [ { accountCode: "4000", annual: 2400000, monthly: [185000, 190000, 195000, 200000, 205000, 205000, 200000, 200000, 205000, 210000, 200000, 205000] }, { accountCode: "4100", annual: 1104000, monthly: [92000, 92000, 92000, 92000, 92000, 92000, 92000, 92000, 92000, 92000, 92000, 92000] }, { accountCode: "5000", annual: 660000, monthly: [55000, 55000, 55000, 55000, 55000, 55000, 55000, 55000, 55000, 55000, 55000, 55000] }, { accountCode: "6200", annual: 2520000, monthly: [210000, 210000, 210000, 210000, 210000, 210000, 210000, 210000, 210000, 210000, 210000, 210000] }, { accountCode: "6100", annual: 540000, monthly: [45000, 45000, 45000, 45000, 45000, 45000, 45000, 45000, 45000, 45000, 45000, 45000] }, { accountCode: "6300", annual: 558000, monthly: [46500, 46500, 46500, 46500, 46500, 46500, 46500, 46500, 46500, 46500, 46500, 46500] }, { accountCode: "6400", annual: 264000, monthly: [22000, 22000, 22000, 22000, 22000, 22000, 22000, 22000, 22000, 22000, 22000, 22000] }, ]; for (const bd of fy2025BudgetData) { await prisma.budgetLine.create({ data: { organizationId: organization.id, accountId: accounts[bd.accountCode].id, fiscalYear: 2025, monthlyAmounts: bd.monthly, annualBudget: bd.annual, notes: `FY2025 budget for ${accounts[bd.accountCode].accountName}`, }, }); } console.log(`โœ“ Created ${fy2025BudgetData.length} FY2025 budget lines`); // ======================================== // LEASES (ASC 842) // ======================================== console.log("๐Ÿข Creating leases..."); const leases = [ { description: "NYC Office Space - 5th Avenue", type: "Operating", startDate: new Date("2024-01-01"), endDate: new Date("2028-12-31"), monthlyPayment: 24000, totalCommitment: 1440000, discountRate: 4.5, rouAsset: 1296000, leaseLiability: 1310400, currentPortion: 276480, nonCurrentPortion: 1033920, status: "Active", }, { description: "London Office - Canary Wharf", type: "Operating", startDate: new Date("2024-06-01"), endDate: new Date("2027-05-31"), monthlyPayment: 15000, totalCommitment: 540000, discountRate: 5.0, rouAsset: 486000, leaseLiability: 495000, currentPortion: 175500, nonCurrentPortion: 319500, status: "Active", }, { description: "Server Co-location - Equinix NY5", type: "Finance", startDate: new Date("2025-03-01"), endDate: new Date("2030-02-28"), monthlyPayment: 35000, totalCommitment: 2100000, discountRate: 3.8, rouAsset: 1890000, leaseLiability: 1932000, currentPortion: 396000, nonCurrentPortion: 1536000, status: "Active", }, { description: "Company Vehicles Fleet (12 units)", type: "Operating", startDate: new Date("2025-01-01"), endDate: new Date("2027-12-31"), monthlyPayment: 6000, totalCommitment: 216000, discountRate: 4.0, rouAsset: 194400, leaseLiability: 198000, currentPortion: 70200, nonCurrentPortion: 127800, status: "Active", }, { description: "Berlin Office - Alexanderplatz", type: "Operating", startDate: new Date("2025-06-01"), endDate: new Date("2028-05-31"), monthlyPayment: 8500, totalCommitment: 306000, discountRate: 4.2, rouAsset: 275400, leaseLiability: 280800, currentPortion: 99000, nonCurrentPortion: 181800, status: "Active", }, { description: "Old SF Office (terminated early)", type: "Operating", startDate: new Date("2022-01-01"), endDate: new Date("2025-06-30"), monthlyPayment: 18000, totalCommitment: 756000, discountRate: 3.5, rouAsset: 0, leaseLiability: 0, currentPortion: 0, nonCurrentPortion: 0, status: "Expired", }, ]; for (const l of leases) { await prisma.lease.create({ data: { organizationId: organization.id, description: l.description, type: l.type, startDate: l.startDate, endDate: l.endDate, monthlyPayment: l.monthlyPayment, totalCommitment: l.totalCommitment, discountRate: l.discountRate, rouAsset: l.rouAsset, leaseLiability: l.leaseLiability, currentPortion: l.currentPortion, nonCurrentPortion: l.nonCurrentPortion, status: l.status, }, }); } console.log(`โœ“ Created ${leases.length} leases`); // ======================================== // SHAREHOLDERS / CAP TABLE // ======================================== console.log("๐Ÿ“‹ Creating shareholders..."); const shareholders = [ { name: "Ryan Francis", type: "founder", sharesOwned: 4000000, shareClass: "Common", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 87.50, grantDate: new Date("2020-01-01"), exercisePrice: 0.01, status: "ACTIVE" }, { name: "Sarah Chen", type: "founder", sharesOwned: 3000000, shareClass: "Common", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 87.50, grantDate: new Date("2020-01-01"), exercisePrice: 0.01, status: "ACTIVE" }, { name: "Velocity Partners Fund III", type: "investor", sharesOwned: 2500000, shareClass: "Series A", vestingCliffMonths: 0, vestingTotalMonths: 0, vestedPercent: 100.00, grantDate: new Date("2022-06-15"), exercisePrice: 1.20, status: "ACTIVE" }, { name: "Summit Capital Growth", type: "investor", sharesOwned: 3500000, shareClass: "Series B", vestingCliffMonths: 0, vestingTotalMonths: 0, vestedPercent: 100.00, grantDate: new Date("2025-01-15"), exercisePrice: 2.85, status: "ACTIVE" }, { name: "Emily Rodriguez", type: "employee", sharesOwned: 500000, shareClass: "Options", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 62.50, grantDate: new Date("2021-06-01"), exercisePrice: 0.50, status: "ACTIVE" }, { name: "James Park", type: "employee", sharesOwned: 400000, shareClass: "Options", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 50.00, grantDate: new Date("2022-01-15"), exercisePrice: 0.80, status: "ACTIVE" }, { name: "Aisha Patel", type: "employee", sharesOwned: 350000, shareClass: "Options", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 37.50, grantDate: new Date("2023-01-01"), exercisePrice: 1.50, status: "ACTIVE" }, { name: "David Kim", type: "advisor", sharesOwned: 150000, shareClass: "Options", vestingCliffMonths: 6, vestingTotalMonths: 24, vestedPercent: 100.00, grantDate: new Date("2022-01-01"), exercisePrice: 0.80, status: "ACTIVE" }, { name: "Maria Santos", type: "employee", sharesOwned: 250000, shareClass: "Options", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 18.75, grantDate: new Date("2024-04-01"), exercisePrice: 2.00, status: "ACTIVE" }, { name: "Alex Thompson (departed)", type: "employee", sharesOwned: 200000, shareClass: "Options", vestingCliffMonths: 12, vestingTotalMonths: 48, vestedPercent: 25.00, grantDate: new Date("2023-01-01"), exercisePrice: 1.50, status: "TERMINATED" }, ]; for (const sh of shareholders) { await prisma.shareholder.create({ data: { organizationId: organization.id, name: sh.name, type: sh.type, sharesOwned: sh.sharesOwned, shareClass: sh.shareClass, vestingCliffMonths: sh.vestingCliffMonths, vestingTotalMonths: sh.vestingTotalMonths, vestedPercent: sh.vestedPercent, grantDate: sh.grantDate, exercisePrice: sh.exercisePrice, status: sh.status, }, }); } console.log(`โœ“ Created ${shareholders.length} shareholders`); // ======================================== // SUBSCRIPTIONS (customer recurring revenue) // ======================================== console.log("๐Ÿ”„ Creating subscriptions..."); const subscriptions = [ { customer: customers[0], plan: "Enterprise Platform", cycle: "ANNUAL", amount: 2220000, start: "2025-01-01", next: "2026-01-01", status: "ACTIVE" }, { customer: customers[1], plan: "SaaS Professional", cycle: "MONTHLY", amount: 15000, start: "2025-03-01", next: "2026-05-01", status: "ACTIVE" }, { customer: customers[2], plan: "Consulting Retainer", cycle: "QUARTERLY", amount: 92000, start: "2025-01-01", next: "2026-07-01", status: "ACTIVE" }, { customer: customers[3], plan: "Enterprise License", cycle: "ANNUAL", amount: 2442000, start: "2026-01-01", next: "2027-01-01", status: "ACTIVE" }, { customer: customers[4], plan: "Startup Plan", cycle: "ANNUAL", amount: 24000, start: "2025-06-01", next: "2026-06-01", status: "ACTIVE" }, { customer: customers[5], plan: "Healthcare Suite", cycle: "ANNUAL", amount: 1872000, start: "2026-01-01", next: "2027-01-01", status: "ACTIVE" }, { customer: customers[6], plan: "Retail Analytics", cycle: "MONTHLY", amount: 6500, start: "2025-09-01", next: "2026-05-01", status: "ACTIVE" }, { customer: customers[7], plan: "Financial Compliance", cycle: "ANNUAL", amount: 2520000, start: "2026-02-01", next: "2027-02-01", status: "ACTIVE" }, { customer: customers[1], plan: "SaaS Basic (old)", cycle: "MONTHLY", amount: 8000, start: "2024-01-01", end: "2025-02-28", status: "CANCELLED" }, ]; for (const sub of subscriptions) { await prisma.subscription.create({ data: { organizationId: organization.id, customerId: sub.customer.id, planName: sub.plan, billingCycle: sub.cycle, amount: sub.amount, startDate: new Date(sub.start), endDate: sub.end ? new Date(sub.end) : null, nextBillingDate: sub.next ? new Date(sub.next) : null, cancelledAt: sub.status === "CANCELLED" ? new Date(sub.end!) : null, status: sub.status, }, }); } console.log(`โœ“ Created ${subscriptions.length} subscriptions`); // ======================================== // FORECASTS // ======================================== console.log("๐Ÿ”ฎ Creating forecasts..."); const forecasts = [ { name: "FY2026 Base Case Forecast", description: "Conservative growth scenario based on current pipeline and retention rates", scenarioType: "BASE", startDate: new Date("2026-01-01"), endDate: new Date("2026-12-31"), status: "ACTIVE", assumptions: { revenueGrowth: 0.10, expenseGrowth: 0.08, churnRate: 0.05, newCustomers: 12 }, projections: { months: months.map((m, i) => ({ month: `${m} 2026`, revenue: 304700 + (i * 3000), expenses: 350400 + (i * 1500), netIncome: -45700 + (i * 1500), cashBalance: 6037241 + (i * 45000), })), }, }, { name: "FY2026 Optimistic Scenario", description: "Aggressive growth with accelerated enterprise sales and expansion revenue", scenarioType: "OPTIMISTIC", startDate: new Date("2026-01-01"), endDate: new Date("2026-12-31"), status: "ACTIVE", assumptions: { revenueGrowth: 0.25, expenseGrowth: 0.15, churnRate: 0.03, newCustomers: 24 }, projections: { months: months.map((m, i) => ({ month: `${m} 2026`, revenue: 345000 + (i * 8000), expenses: 365000 + (i * 3000), netIncome: -20000 + (i * 5000), cashBalance: 6037241 + (i * 85000), })), }, }, { name: "FY2026 Pessimistic Scenario", description: "Downturn scenario with reduced pipeline and higher churn", scenarioType: "PESSIMISTIC", startDate: new Date("2026-01-01"), endDate: new Date("2026-12-31"), status: "ACTIVE", assumptions: { revenueGrowth: -0.05, expenseGrowth: 0.03, churnRate: 0.12, newCustomers: 4 }, projections: { months: months.map((m, i) => ({ month: `${m} 2026`, revenue: 270000 - (i * 2000), expenses: 345000 + (i * 500), netIncome: -75000 - (i * 2500), cashBalance: 6037241 - (i * 35000), })), }, }, ]; for (const f of forecasts) { await prisma.forecast.create({ data: { organizationId: organization.id, name: f.name, description: f.description, scenarioType: f.scenarioType, startDate: f.startDate, endDate: f.endDate, status: f.status, assumptions: f.assumptions, projections: f.projections, createdBy: user.name, }, }); } console.log(`โœ“ Created ${forecasts.length} forecasts`); // ======================================== // DOCUMENTS // ======================================== console.log("๐Ÿ“ Creating documents..."); const documents = [ { name: "FY2025 Annual Report.pdf", category: "report", mimeType: "application/pdf", fileSize: 2450000, storagePath: "/documents/reports/fy2025-annual.pdf", tags: ["annual", "FY2025", "financial"] }, { name: "Series B Term Sheet.pdf", category: "legal", mimeType: "application/pdf", fileSize: 185000, storagePath: "/documents/legal/series-b-term-sheet.pdf", tags: ["legal", "fundraising", "Series B"] }, { name: "AWS MSA.pdf", category: "contract", mimeType: "application/pdf", fileSize: 420000, storagePath: "/documents/contracts/aws-msa.pdf", tags: ["contract", "vendor", "AWS"] }, { name: "Q1 2026 Board Deck.pptx", category: "report", mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation", fileSize: 5200000, storagePath: "/documents/reports/q1-2026-board-deck.pptx", tags: ["board", "Q1", "2026"] }, { name: "Office Lease Agreement - NYC.pdf", category: "contract", mimeType: "application/pdf", fileSize: 890000, storagePath: "/documents/contracts/nyc-office-lease.pdf", tags: ["lease", "real estate", "NYC"] }, { name: "D&O Insurance Policy.pdf", category: "legal", mimeType: "application/pdf", fileSize: 340000, storagePath: "/documents/legal/do-insurance-2026.pdf", tags: ["insurance", "D&O", "2026"] }, { name: "Employee Stock Option Plan.pdf", category: "legal", mimeType: "application/pdf", fileSize: 275000, storagePath: "/documents/legal/esop-plan.pdf", tags: ["ESOP", "equity", "options"] }, { name: "SOC 2 Type II Report.pdf", category: "report", mimeType: "application/pdf", fileSize: 1800000, storagePath: "/documents/compliance/soc2-type2-2025.pdf", tags: ["compliance", "SOC2", "audit"] }, { name: "Revenue Recognition Policy.docx", category: "report", mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileSize: 125000, storagePath: "/documents/policies/rev-rec-policy.docx", tags: ["policy", "ASC 606", "revenue"] }, { name: "ABC Corp Master Agreement.pdf", category: "contract", mimeType: "application/pdf", fileSize: 560000, storagePath: "/documents/contracts/abc-corp-msa.pdf", tags: ["contract", "customer", "ABC Corp"] }, ]; for (const doc of documents) { await prisma.document.create({ data: { organizationId: organization.id, name: doc.name, category: doc.category, mimeType: doc.mimeType, fileSize: doc.fileSize, storagePath: doc.storagePath, status: "ACTIVE", tags: doc.tags, uploadedBy: user.name, }, }); } console.log(`โœ“ Created ${documents.length} documents`); // ======================================== // AUDIT LOG // ======================================== console.log("๐Ÿ“œ Creating audit log entries..."); const auditEntries = [ { action: "LOGIN", module: "auth", entityType: "User", description: "User logged in", date: "2026-04-05T08:30:00Z" }, { action: "CREATE", module: "general-ledger", entityType: "JournalEntry", description: "Created JE-2026-0001 - January software revenue", date: "2026-01-06T09:15:00Z" }, { action: "POST", module: "general-ledger", entityType: "JournalEntry", description: "Posted JE-2026-0001", date: "2026-01-06T09:20:00Z" }, { action: "APPROVE", module: "ap", entityType: "Invoice", description: "Approved INV-AP-2026-0003 - WeWork office lease", date: "2026-02-15T14:00:00Z" }, { action: "CREATE", module: "ap", entityType: "Payment", description: "Created payment PAY-2026-0001 for AWS", date: "2026-02-10T10:30:00Z" }, { action: "APPROVE", module: "ar", entityType: "Invoice", description: "Approved INV-AR-2026-0007 - Northern Health Systems", date: "2026-03-20T11:00:00Z" }, { action: "EXPORT", module: "reports", entityType: "Report", description: "Exported Q1 2026 Trial Balance to CSV", date: "2026-04-02T16:45:00Z" }, { action: "UPDATE", module: "treasury", entityType: "BankAccount", description: "Updated Chase Business Checking balance", date: "2026-04-03T09:00:00Z" }, { action: "CREATE", module: "general-ledger", entityType: "JournalEntry", description: "Created April 2026 revenue accrual (draft)", date: "2026-04-03T10:00:00Z" }, { action: "CREATE", module: "ar", entityType: "Invoice", description: "Created INV-AR-2026-0008 - Pacific Retail Group", date: "2026-04-01T13:30:00Z" }, { action: "LOGIN", module: "auth", entityType: "User", description: "User logged in from new device", date: "2026-04-04T07:45:00Z" }, { action: "UPDATE", module: "planning", entityType: "BudgetLine", description: "Updated FY2026 engineering budget", date: "2026-03-15T15:20:00Z" }, ]; for (const entry of auditEntries) { await prisma.auditLog.create({ data: { organizationId: organization.id, userId: user.id, userName: user.name, action: entry.action, module: entry.module, entityType: entry.entityType, description: entry.description, createdAt: new Date(entry.date), }, }); } console.log(`โœ“ Created ${auditEntries.length} audit log entries`); // ======================================== // SUMMARY // ======================================== console.log("\nโœ… Database seed completed successfully!"); console.log(` Organization: ${organization.name} Entities: ${entities.length} Users: 1 (${user.email}) Accounts: ${accountsData.length} Fiscal Periods: 36 (FY2024-FY2026) Journal Entries: ${jeCounter} (spanning Jan 2025 - Apr 2026) Vendors: ${vendors.length} Purchase Orders: ${purchaseOrders.length} Customers: ${customers.length} AP Invoices: ${apInvoices.length} AR Invoices: ${arInvoices.length} Payments: ${payments.length} Bank Accounts: ${bankAccounts.length} Bank Transactions: ${bankTransactions.length} Cash Position Snapshots: ${cashSnapshots.length} Budget Lines: ${budgetData.length + fy2025BudgetData.length} (FY2025 + FY2026) Leases: ${leases.length} Shareholders: ${shareholders.length} Subscriptions: ${subscriptions.length} Forecasts: ${forecasts.length} Documents: ${documents.length} Audit Log Entries: ${auditEntries.length} `); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error("โŒ Seed error:", e); await prisma.$disconnect(); process.exit(1); });