import { PrismaClient } from "@prisma/client"; import { subDays, subHours } from "date-fns"; import { hashPassword } from "../src/lib/password.js"; const prisma = new PrismaClient(); const now = new Date("2026-06-12T12:00:00Z"); const defaultPasswordHash = hashPassword("correct-password"); const twoFactorPasswordHash = hashPassword("2fa-password"); async function main() { console.log("Cleaning database..."); // Clear tables in reverse sequence to avoid constraint violations await prisma.auditEntry.deleteMany(); await prisma.notification.deleteMany(); await prisma.automation.deleteMany(); await prisma.backup.deleteMany(); await prisma.securityFinding.deleteMany(); await prisma.metricPoint.deleteMany(); await prisma.resourceUsage.deleteMany(); await prisma.mailbox.deleteMany(); await prisma.dnsRecord.deleteMany(); await prisma.domain.deleteMany(); await prisma.website.deleteMany(); await prisma.accountUser.deleteMany(); await prisma.userPermission.deleteMany(); await prisma.session.deleteMany(); await prisma.hostingAccount.deleteMany(); await prisma.user.deleteMany(); await prisma.server.deleteMany(); console.log("Seeding Servers..."); await prisma.server.createMany({ data: [ { id: "srv-dal-01", name: "Dallas Web 01", hostname: "srv-dal-01.coaxys.net", os: "AlmaLinux 9.6", panelVersion: "CoaxysPanel 2026.6", load1: 0.38, load5: 0.44, load15: 0.41, ipAddress: "198.51.100.24", status: "healthy", location: "Dallas, US", }, { id: "srv-nyc-02", name: "New York Apps 02", hostname: "srv-nyc-02.coaxys.net", os: "Ubuntu 24.04 LTS", panelVersion: "CoaxysPanel 2026.6", load1: 1.12, load5: 0.91, load15: 0.78, ipAddress: "203.0.113.22", status: "warning", location: "New York, US", }, ], }); console.log("Seeding Users..."); const adminUser = await prisma.user.create({ data: { id: "usr-1", name: "Account Owner", email: "owner@example.com", passwordHash: defaultPasswordHash, role: "owner", avatarInitials: "AO", twoFactorEnabled: true, lastLogin: subHours(now, 2), }, }); const twoFactorUser = await prisma.user.create({ data: { id: "usr-2fa", name: "Two Factor Owner", email: "owner-2fa@example.com", passwordHash: twoFactorPasswordHash, role: "owner", avatarInitials: "TO", twoFactorEnabled: true, lastLogin: subHours(now, 4), }, }); const developerUser = await prisma.user.create({ data: { id: "usr-dev", name: "Developer User", email: "developer@example.com", passwordHash: defaultPasswordHash, role: "developer", avatarInitials: "DU", lastLogin: subHours(now, 6), }, }); const auditorUser = await prisma.user.create({ data: { id: "usr-audit", name: "Auditor User", email: "auditor@example.com", passwordHash: defaultPasswordHash, role: "auditor", avatarInitials: "AU", lastLogin: subHours(now, 8), }, }); console.log("Seeding Permissions..."); const permissionsList = [ "dashboard_read", "tools_read", "websites_manage", "domains_manage", "files_manage", "databases_manage", "email_manage", "metrics_read", "security_manage", "software_manage", "advanced_manage", "servers_manage", "users_manage", "resellers_manage", "backups_manage", "automation_manage", "notifications_read", "audit_read", "support_manage", "settings_manage", ] as const; const developerPermissions = [ "dashboard_read", "tools_read", "websites_manage", "domains_manage", "files_manage", "databases_manage", "metrics_read", "advanced_manage", ] as const; const auditorPermissions = [ "dashboard_read", "tools_read", "metrics_read", "audit_read", ] as const; await prisma.userPermission.createMany({ data: [ ...permissionsList.map((perm) => ({ userId: adminUser.id, permission: perm })), ...permissionsList.map((perm) => ({ userId: twoFactorUser.id, permission: perm })), ...developerPermissions.map((perm) => ({ userId: developerUser.id, permission: perm })), ...auditorPermissions.map((perm) => ({ userId: auditorUser.id, permission: perm })), ], }); console.log("Seeding Hosting Accounts..."); await prisma.hostingAccount.createMany({ data: [ { id: "acct-main", username: "coaxys", primaryDomain: "example.com", homeDirectory: "/home/coaxys", sharedIp: "198.51.100.24", dedicatedIp: "203.0.113.15", theme: "light", }, { id: "acct-shop", username: "storeops", primaryDomain: "store.example.com", homeDirectory: "/home/storeops", sharedIp: "198.51.100.31", theme: "system", }, ], }); console.log("Seeding Account Users..."); await prisma.accountUser.createMany({ data: [ { userId: adminUser.id, accountId: "acct-main" }, { userId: adminUser.id, accountId: "acct-shop" }, { userId: twoFactorUser.id, accountId: "acct-main" }, { userId: developerUser.id, accountId: "acct-main" }, { userId: auditorUser.id, accountId: "acct-main" }, ], }); console.log("Seeding Websites..."); await prisma.website.createMany({ data: [ { id: "alpha-site", name: "Alpha Marketing", domain: "example.com", runtime: "PHP", status: "healthy", ssl: "healthy", repository: "git@example.com:alpha/marketing.git", environment: "production", cpuLimit: "2 vCPU", memoryLimit: "2 GB", lastDeployment: subHours(now, 5), accountId: "acct-main", }, { id: "docs-hub", name: "Docs Hub", domain: "docs.example.com", runtime: "Node_js", status: "healthy", ssl: "healthy", repository: "git@example.com:alpha/docs.git", environment: "production", cpuLimit: "1 vCPU", memoryLimit: "1 GB", lastDeployment: subDays(now, 1), accountId: "acct-main", }, { id: "preview-api", name: "Preview API", domain: "api.preview.example.com", runtime: "Docker", status: "warning", ssl: "warning", environment: "staging", cpuLimit: "1 vCPU", memoryLimit: "768 MB", lastDeployment: subHours(now, 9), accountId: "acct-main", }, ], }); console.log("Seeding Domains..."); await prisma.domain.createMany({ data: [ { id: "dom-1", name: "example.com", type: "primary", documentRoot: "/home/coaxys/public_html", sslStatus: "healthy", dnssec: true, propagation: 98, accountId: "acct-main", websiteId: "alpha-site", }, { id: "dom-2", name: "docs.example.com", type: "subdomain", documentRoot: "/home/coaxys/docs", sslStatus: "healthy", dnssec: false, propagation: 100, accountId: "acct-main", websiteId: "docs-hub", }, { id: "dom-3", name: "legacy-example.net", type: "alias", documentRoot: "/home/coaxys/public_html", sslStatus: "warning", dnssec: false, propagation: 73, accountId: "acct-main", websiteId: "alpha-site", }, ], }); console.log("Seeding DNS Records..."); await prisma.dnsRecord.createMany({ data: [ { id: "dns-1", name: "example.com.", ttl: 14400, type: "A", record: "198.51.100.24", domainId: "dom-1", }, { id: "dns-2", name: "www.example.com.", ttl: 14400, type: "CNAME", record: "example.com.", domainId: "dom-1", }, { id: "dns-3", name: "example.com.", ttl: 14400, type: "MX", record: "mail.example.com.", priority: 10, domainId: "dom-1", }, { id: "dns-4", name: "example.com.", ttl: 3600, type: "TXT", record: "v=spf1 mx include:_spf.coaxys.net ~all", domainId: "dom-1", }, { id: "dns-5", name: "_dmarc.example.com.", ttl: 3600, type: "TXT", record: "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", domainId: "dom-1", }, ], }); console.log("Seeding Mailboxes..."); await prisma.mailbox.createMany({ data: [ { id: "mail-1", address: "admin@example.com", used: 1200000000n, // BigInt suffix quota: 5000000000n, lastLogin: subHours(now, 1), forwarding: true, spamScore: 1.8, authStatus: "healthy", domainId: "dom-1", accountId: "acct-main", }, { id: "mail-2", address: "support@example.com", used: 4600000000n, quota: 5000000000n, lastLogin: subDays(now, 2), forwarding: false, spamScore: 4.1, authStatus: "warning", domainId: "dom-1", accountId: "acct-main", }, ], }); console.log("Seeding Resource Usage..."); await prisma.resourceUsage.createMany({ data: [ { id: "usage-disk", key: "disk", label: "Disk usage", used: 38.4, limit: 100, unit: "GB", status: "healthy", accountId: "acct-main", }, { id: "usage-bandwidth", key: "bandwidth", label: "Bandwidth", used: 412, limit: 1000, unit: "GB", status: "healthy", accountId: "acct-main", }, { id: "usage-cpu", key: "cpu", label: "CPU", used: 42, limit: 100, unit: "%", status: "healthy", accountId: "acct-main", }, { id: "usage-memory", key: "memory", label: "Memory", used: 6.8, limit: 16, unit: "GB", status: "warning", accountId: "acct-main", }, { id: "usage-inodes", key: "inodes", label: "Inodes", used: 182000, limit: 500000, unit: "files", status: "healthy", accountId: "acct-main", }, { id: "usage-databases", key: "database_storage", label: "Database storage", used: 8.6, limit: 25, unit: "GB", status: "healthy", accountId: "acct-main", }, ], }); console.log("Seeding Metrics..."); await prisma.metricPoint.createMany({ data: Array.from({ length: 48 }, (_, index) => { const phase = index / 5; return { id: `metric-${index + 1}`, timestamp: subHours(now, 47 - index), cpu: Math.round(32 + Math.sin(phase) * 10 + (index % 7)), memory: Math.round(48 + Math.cos(phase) * 8 + (index % 5)), disk: Math.round(37 + index * 0.08), bandwidth: Math.round(220 + Math.sin(phase) * 60 + index * 3), requests: Math.round(1200 + Math.cos(phase) * 240 + index * 16), accountId: "acct-main", }; }), }); console.log("Seeding Security Findings..."); await prisma.securityFinding.createMany({ data: [ { id: "sec-1", severity: "high", title: "Two certificates expire within 14 days", target: "legacy-example.net", status: "open", recommendation: "Renew or replace the certificate before expiration.", accountId: "acct-main", }, { id: "sec-2", severity: "medium", title: "SSH password authentication is enabled", target: "srv-dal-01", status: "acknowledged", recommendation: "Prefer key-only authentication for administrative access.", accountId: "acct-main", }, { id: "sec-3", severity: "low", title: "Directory listing is enabled on one path", target: "/home/coaxys/public_html/assets", status: "open", recommendation: "Disable index listing unless intentionally public.", accountId: "acct-main", }, ], }); console.log("Seeding Backups..."); await prisma.backup.createMany({ data: [ { id: "bak-1", name: "Full account nightly", scope: "full", destination: "Local storage", size: 42_800_000_000n, status: "healthy", encrypted: true, createdAt: subHours(now, 7), accountId: "acct-main", }, { id: "bak-2", name: "Database pre-deploy", scope: "database", destination: "S3-compatible storage", size: 8_200_000_000n, status: "healthy", encrypted: true, createdAt: subDays(now, 1), accountId: "acct-main", }, ], }); console.log("Seeding Automations..."); await prisma.automation.createMany({ data: [ { id: "auto-1", name: "Renew expiring SSL certificates", trigger: "Daily at 03:10 UTC", status: "healthy", lastRun: subHours(now, 9), successRate: 99, accountId: "acct-main", }, { id: "auto-2", name: "Deploy docs on Git push", trigger: "Git webhook", status: "healthy", lastRun: subHours(now, 5), successRate: 96, accountId: "acct-main", }, ], }); console.log("Seeding Notifications..."); await prisma.notification.createMany({ data: [ { id: "notif-1", title: "Nightly backup verified", category: "backup", read: false, createdAt: subHours(now, 2), body: "The full account backup completed and passed verification.", accountId: "acct-main", }, { id: "notif-2", title: "Certificate renewal recommended", category: "ssl", read: false, createdAt: subHours(now, 4), body: "legacy-example.net has a certificate entering the renewal window.", accountId: "acct-main", }, { id: "notif-3", title: "Memory usage is elevated", category: "resource", read: true, createdAt: subHours(now, 6), body: "Memory usage has remained above the warning threshold for 25 minutes.", accountId: "acct-main", }, ], }); console.log("Seeding Audit logs..."); await prisma.auditEntry.createMany({ data: [ { id: "aud-1", actor: "Account Owner", action: "created DNS record", target: "api.example.com A", ipAddress: "192.0.2.44", createdAt: subHours(now, 2), requestId: "req_8f172a", accountId: "acct-main", }, { id: "aud-2", actor: "Account Owner", action: "downloaded backup", target: "bak-2026-06-12", ipAddress: "192.0.2.44", createdAt: subHours(now, 3), requestId: "req_9b72cf", accountId: "acct-main", }, ], }); console.log("Database seeded successfully!"); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });