Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
598 lines
15 KiB
TypeScript
598 lines
15 KiB
TypeScript
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();
|
|
});
|