/home/techb158/balavpn.abdallabala.com/prisma
NameSizeModeActions
add-membership.js9960644editdlrm
check-counts.js5250644editdlrm
check-org.js5430644editdlrm
check-project.js4010644editdlrm
cleanup-dups.js19130644editdlrm
import-project-1.js113250644editdlrm
import-project.js113250644editdlrm
list-projects.js2640644editdlrm
schema.prisma180360644editdlrm
seed-import.json1709830644editdlrm
seed.js177900644editdlrm
Edit: /home/techb158/balavpn.abdallabala.com/prisma/seed.js (17790B)
const fs = require("fs"); const path = require("path"); const bcrypt = require("bcryptjs"); const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); const CREATE_DEMO = process.env.COSMIC_CREATE_DEMO === "true"; const ROLE_TEMPLATES = [ { code: "owner", name: "Owner", permissions: ["*"] }, { code: "admin", name: "Admin", permissions: ["organization:view", "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read"] }, { code: "project_manager", name: "Project Manager", permissions: ["organization:view", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read"] }, { code: "risk_owner", name: "Risk Owner", permissions: ["project:read", "risk:read", "risk:write", "mitigation:write", "gate:read"] }, { code: "governance_reviewer", name: "Governance Reviewer", permissions: ["project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read"] }, { code: "legal_ethics_reviewer", name: "Legal / Ethics Reviewer", permissions: ["project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read"] }, { code: "integration_admin", name: "Integration Admin", permissions: ["project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read"] }, { code: "viewer", name: "Viewer", permissions: ["organization:view", "project:read", "risk:read", "gate:read", "integration:read", "report:export"] }, { code: "consultant", name: "Consultant", permissions: ["workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read"] } ]; function slug(value) { return String(value || "item") .toLowerCase() .replace(/[^a-z0-9]+/g, "-") .replace(/(^-|-$)/g, ""); } const defaultPassword = process.env.COSMIC_BOOTSTRAP_PASSWORD || "cosmic123"; async function upsertChild(model, projectId, item) { try { await prisma[model].upsert({ where: { projectId_name: { projectId, name: item.name } }, update: item, create: { projectId, ...item } }); } catch { // Fallback if the unique constraint isn't applied yet const existing = await prisma[model].findFirst({ where: { projectId, name: item.name } }); if (existing) await prisma[model].update({ where: { id: existing.id }, data: item }); else await prisma[model].create({ data: { projectId, ...item } }); } } async function upsertUser(email, displayName, password, platformRole, roleCode, organizationId) { const h = await bcrypt.hash(password || defaultPassword, 12); // Never downgrade a platform-level user (SUPER_OWNER/SUPER_ADMIN) to NONE const existing = await prisma.user.findUnique({ where: { email } }); const finalPlatformRole = (existing && existing.platformRole !== "NONE") ? existing.platformRole : (platformRole || "NONE"); const user = await prisma.user.upsert({ where: { email }, update: { displayName, passwordHash: h, platformRole: finalPlatformRole }, create: { email, displayName, passwordHash: h, platformRole: platformRole || "NONE", emailVerifiedAt: new Date() }, }); if (organizationId && roleCode) { const role = await prisma.role.findUnique({ where: { code: roleCode } }); if (role) { await prisma.membership.upsert({ where: { organizationId_userId: { organizationId, userId: user.id } }, update: { roleId: role.id, status: "ACTIVE" }, create: { organizationId, userId: user.id, roleId: role.id, status: "ACTIVE" }, }).catch(() => {}); } } return user; } async function main() { for (const role of ROLE_TEMPLATES) { await prisma.role.upsert({ where: { code: role.code }, update: { name: role.name, permissions: role.permissions }, create: role }); } // Bootstrap user from env var (e.g., COSMIC_BOOTSTRAP_EMAIL) const bootstrapEmail = process.env.COSMIC_BOOTSTRAP_EMAIL; if (bootstrapEmail) { await upsertUser( bootstrapEmail, process.env.COSMIC_BOOTSTRAP_NAME || "COSMIC Platform Owner", defaultPassword, "SUPER_OWNER", null, null ); } // Always create the standard demo platform users const superOwner = await upsertUser("super-owner@cosmic.local", "COSMIC Platform Owner", defaultPassword, "SUPER_OWNER", null, null); const superAdmin = await upsertUser("super-admin@cosmic.local", "Super Admin", "super123", "SUPER_ADMIN", null, null); // Cleanup: remove orphaned orgs from any previous seed runs await prisma.$executeRawUnsafe(`DELETE FROM "Organization" WHERE id NOT IN (SELECT "organizationId" FROM "Membership")`).catch(() => {}); if (CREATE_DEMO) { // Demo organization with org-level users const organization = await prisma.organization.upsert({ where: { slug: "cosmic-demo" }, update: {}, create: { name: "COSMIC Demo Organization", slug: "cosmic-demo", status: "TRIAL", planCode: "pilot", manualBilling: true } }); // Grant Super Admin access to this organization await prisma.organizationAccess.upsert({ where: { userId_organizationId: { userId: superAdmin.id, organizationId: organization.id } }, update: {}, create: { userId: superAdmin.id, organizationId: organization.id } }).catch(() => {}); await prisma.subscription.create({ data: { organizationId: organization.id, source: "MANUAL", status: "TRIALING", planCode: "pilot", userLimit: 10, projectLimit: 5, reportLimitMonthly: 100, integrationLimit: 4, adminOverride: true } }).catch(() => null); const workspace = await prisma.workspace.upsert({ where: { organizationId_slug: { organizationId: organization.id, slug: "ai-risk-governance" } }, update: {}, create: { organizationId: organization.id, name: "AI Risk Governance", slug: "ai-risk-governance", type: "B2B_TEAM", status: "TRIAL" } }); // Org-level users (members of the demo org) const orgOwner = await upsertUser("org-owner@cosmic.local", "Organization Owner", "orgowner123", "NONE", "owner", organization.id); // Only create org-level owner@ if it wasn't already created as SUPER_OWNER by bootstrap env var const ownerExisting = await prisma.user.findUnique({ where: { email: "owner@cosmic.local" } }); if (!ownerExisting || ownerExisting.platformRole === "NONE") { await upsertUser("owner@cosmic.local", "Owner", "owner123", "NONE", "owner", organization.id); } await upsertUser("admin@cosmic.local", "COSMIC Admin", "admin123", "NONE", "admin", organization.id); await upsertUser("pm@cosmic.local", "Project Manager", "pm123", "NONE", "project_manager", organization.id); await upsertUser("risk-owner@cosmic.local", "Risk Owner", "risk123", "NONE", "risk_owner", organization.id); await upsertUser("viewer@cosmic.local", "Read-Only Viewer", "view123", "NONE", "viewer", organization.id); // Seed project data const sourcePath = path.join(__dirname, "..", "..", "data", "database.json"); let sourceData = null; try { if (fs.existsSync(sourcePath)) { sourceData = JSON.parse(fs.readFileSync(sourcePath, "utf8")); } } catch (e) { console.warn(`Could not read seed data file: ${e.message}`); } let project = await prisma.project.findFirst({ where: { workspaceId: workspace.id } }); if (!project) { project = await prisma.project.create({ data: { workspaceId: workspace.id, name: "Demo Project", projectType: "GENERATIVE_AI", currentLifecyclePhase: "DEPLOYMENT", riskAppetite: 50, status: "ACTIVE", ownerDisplayName: "Organization Owner", description: "Demo project seeded on first startup", thresholds: {}, reviews: {} } }); console.log(`Created project: ${project.id}`); } else { console.log(`Project already exists: ${project.id}`); } const riskIdMap = new Map(); const mitigationIdMap = new Map(); await prisma.$executeRawUnsafe(`DELETE FROM "LifecyclePhase" lp USING "LifecyclePhase" lp2 WHERE lp.id > lp2.id AND lp."projectId" = lp2."projectId" AND lp.name = lp2.name`).catch(() => {}); for (const ph of [ { name: "Design", status: "Completed", readinessScore: 95, sequence: 1 }, { name: "Development", status: "Completed", readinessScore: 80, sequence: 2 }, { name: "Testing", status: "In Progress", readinessScore: 55, sequence: 3 }, { name: "Deployment", status: "Pending", readinessScore: 15, sequence: 4 }, ]) await upsertChild("lifecyclePhase", project.id, ph); const demoRisks = [ { title: "LLM hallucination in production outputs", dimension: "Technical", domain: "Reliability", lifecyclePhase: "Deployment", probability: 70, impact: 85, detectability: 30, status: "OPEN", approvalStatus: "PENDING" }, { title: "Insufficient human oversight on AI decisions", dimension: "Organizational", domain: "Accountability", lifecyclePhase: "Deployment", probability: 55, impact: 75, detectability: 45, status: "IN_MITIGATION", approvalStatus: "APPROVED" }, { title: "Training data copyright infringement", dimension: "Organizational", domain: "IP", lifecyclePhase: "Development", probability: 45, impact: 90, detectability: 50, status: "OPEN", approvalStatus: "PENDING" }, { title: "Bias amplification in user-facing outputs", dimension: "Human", domain: "Fairness", lifecyclePhase: "Testing", probability: 60, impact: 80, detectability: 35, status: "OPEN", approvalStatus: "PENDING" }, { title: "Model drift after deployment", dimension: "Technical", domain: "Monitoring", lifecyclePhase: "Deployment", probability: 65, impact: 70, detectability: 40, status: "OPEN", approvalStatus: "PENDING" }, ]; for (const r of demoRisks) { const risk = await prisma.risk.create({ data: { projectId: project.id, ownerDisplayName: "Organization Owner", description: `Sample risk: ${r.title}`, ...r, } }).catch(() => null); if (!risk) continue; riskIdMap.set(r.title, risk.id); const mits = [ { title: `Implement guardrails for "${r.title}"`, status: r.status === "IN_MITIGATION" ? "IN_PROGRESS" : "NOT_STARTED", progressPercent: r.status === "IN_MITIGATION" ? 50 : 0, effectivenessPercent: r.status === "IN_MITIGATION" ? 30 : 0 }, { title: `Document mitigation plan for "${r.title}"`, status: "NOT_STARTED", progressPercent: 0, effectivenessPercent: 0 }, ]; for (const m of mits) { const mit = await prisma.mitigation.create({ data: { riskId: risk.id, ownerDisplayName: "Organization Owner", ...m } }).catch(() => null); if (mit) mitigationIdMap.set(m.title, mit.id); } } const demoGate = await prisma.gateEvaluation.create({ data: { projectId: project.id, status: "WARNING", reviewStatus: "Pending review", summary: "Deployment gate review for AI Risk Governance demo project. Most criteria met, bias testing needs improvement.", evaluatedByUserId: orgOwner.id, evaluatedAt: new Date(), } }).catch(() => null); if (demoGate) { const criteria = [ { name: "Risk Assessment", actualValue: "90%", expectedRule: ">=80%", status: "Pass", blocking: false }, { name: "Bias & Fairness Testing", actualValue: "55%", expectedRule: ">=70%", status: "Fail", blocking: true, evidenceTitle: "Bias audit report v2" }, { name: "Documentation", actualValue: "85%", expectedRule: ">=80%", status: "Pass", blocking: false }, { name: "Human Oversight Plan", actualValue: "70%", expectedRule: ">=75%", status: "Fail", blocking: false, evidenceTitle: "Oversight plan draft" }, ]; for (const c of criteria) { await prisma.gateCriterion.create({ data: { gateId: demoGate.id, ...c } }).catch(() => {}); } } await prisma.$executeRawUnsafe(`DELETE FROM "Indicator" lp USING "Indicator" lp2 WHERE lp.id > lp2.id AND lp."projectId" = lp2."projectId" AND lp.name = lp2.name`).catch(() => {}); await prisma.$executeRawUnsafe(`DELETE FROM "Experiment" lp USING "Experiment" lp2 WHERE lp.id > lp2.id AND lp."projectId" = lp2."projectId" AND lp.name = lp2.name`).catch(() => {}); for (const ind of [ { name: "Fairness Score", dimension: "Technical", measurand: "Demographic parity ratio", unit: "ratio", target: ">=0.8", interpretationRule: "Higher is better" }, { name: "Model Accuracy", dimension: "Technical", measurand: "Accuracy rate", unit: "%", target: ">=90", interpretationRule: "Higher is better" }, { name: "Response Latency", dimension: "Operational", measurand: "P95 response time", unit: "ms", target: "<2000", interpretationRule: "Lower is better" }, ]) await upsertChild("indicator", project.id, ind); const demoExperiments = [ { name: "GPT-4 Baseline", modelName: "gpt-4", selected: true, metrics: [ { metricName: "Accuracy", metricValue: 92, thresholdValue: 85, status: "pass" }, { metricName: "Latency (ms)", metricValue: 480, thresholdValue: 500, status: "warn" }, { metricName: "Fairness Score", metricValue: 0.78, thresholdValue: 0.8, status: "warn" }, ]}, { name: "Claude 3 Comparison", modelName: "claude-3-opus", selected: false, metrics: [ { metricName: "Accuracy", metricValue: 94, thresholdValue: 85, status: "pass" }, { metricName: "Latency (ms)", metricValue: 620, thresholdValue: 500, status: "fail" }, { metricName: "Fairness Score", metricValue: 0.85, thresholdValue: 0.8, status: "pass" }, ]}, { name: "Fine-tuned LLaMA", modelName: "llama-3-70b", selected: false, metrics: [ { metricName: "Accuracy", metricValue: 88, thresholdValue: 85, status: "pass" }, { metricName: "Latency (ms)", metricValue: 350, thresholdValue: 500, status: "pass" }, ]}, ]; for (const exp of demoExperiments) { const existing = await prisma.experiment.findFirst({ where: { projectId: project.id, name: exp.name } }); const experiment = existing ? await prisma.experiment.update({ where: { id: existing.id }, data: { name: exp.name, modelName: exp.modelName, selected: exp.selected } }) : await prisma.experiment.create({ data: { projectId: project.id, name: exp.name, modelName: exp.modelName, selected: exp.selected } }); for (const m of exp.metrics) { const em = await prisma.modelMetric.findFirst({ where: { experimentId: experiment.id, metricName: m.metricName } }); if (em) await prisma.modelMetric.update({ where: { id: em.id }, data: { metricValue: m.metricValue, thresholdValue: m.thresholdValue, status: m.status } }); else await prisma.modelMetric.create({ data: { experimentId: experiment.id, ...m, measuredAt: new Date() } }); } } const existingReport = await prisma.reportExport.findFirst({ where: { projectId: project.id } }); if (!existingReport) { await prisma.reportExport.create({ data: { workspaceId: workspace.id, projectId: project.id, reportType: "executive.html", format: "html", status: "Generated", metadata: { note: "Seeded demo report" }, createdById: orgOwner.id } }).catch(() => {}); } await prisma.integration.create({ data: { workspaceId: workspace.id, provider: "TRELLO", workspaceName: "AI Risk Board", baseUrl: "https://trello.com", authMode: "API_KEY", connectionStatus: "NEEDS_CONFIGURATION", syncDirection: "COSMIC to PM", liveEnabled: false, } }).catch(() => {}); await prisma.auditEvent.create({ data: { organizationId: organization.id, workspaceId: workspace.id, projectId: project.id, actorUserId: orgOwner.id, entityType: "Seed", entityId: project.id, action: "seed-demo-workspace", afterJson: { risks: riskIdMap.size } } }); console.log(`Seeded ${organization.name} with workspace ${workspace.name} and ${riskIdMap.size} risks.`); console.log(""); console.log("=== Organization-level users (members of COSMIC Demo Org) ==="); console.log(" owner@cosmic.local / owner123 → Organization Owner"); console.log(" org-owner@cosmic.local / orgowner123 → Organization Owner"); console.log(" admin@cosmic.local / admin123 → Organization Admin"); console.log(" pm@cosmic.local / pm123 → Project Manager"); console.log(" risk-owner@cosmic.local / risk123 → Risk Owner"); console.log(" viewer@cosmic.local / view123 → Viewer"); } console.log("=== Platform-level users (no org membership) ==="); console.log(" super-owner@cosmic.local / cosmic123 → Super Owner"); console.log(" super-admin@cosmic.local / super123 → Super Admin"); if (!CREATE_DEMO) { console.log(""); console.log("=== No demo organization created ==="); console.log(" Set COSMIC_CREATE_DEMO=true to seed demo data."); console.log(" Log in as Super Owner to create your own organizations and projects."); } } main() .catch(error => { console.error(error); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });