/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/import-project.js (11325B)
const fs = require("fs"); const path = require("path"); const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); function mapStatus(s) { if (!s) return "PENDING"; const m = { completed: "Completed", in_progress: "In Progress", planned: "Pending", active_pilot: "ACTIVE", active: "ACTIVE" }; return m[s.toLowerCase()] || s; } function mapRiskStatus(s) { if (!s) return "OPEN"; const m = { open: "OPEN", in_mitigation: "IN_MITIGATION", controlled: "ACCEPTED", closed: "CLOSED" }; return m[s.toLowerCase()] || "OPEN"; } function mapApprovalStatus(s) { if (!s) return "PENDING"; const m = { pending: "PENDING", pending_legal: "PENDING", pending_ethics: "PENDING", pending_security: "PENDING", approved: "APPROVED", accepted: "ACCEPTED", rejected: "REJECTED" }; return m[s.toLowerCase()] || "PENDING"; } function mapMitigationStatus(s) { if (!s) return "NOT_STARTED"; const m = { planned: "NOT_STARTED", in_progress: "IN_PROGRESS", completed: "DONE", rejected: "REJECTED" }; return m[s.toLowerCase()] || "NOT_STARTED"; } function mapGateStatus(s) { if (!s) return "READY"; const m = { passed: "READY", conditional_pass: "WARNING", blocked: "BLOCKED", warning: "WARNING" }; return m[s.toLowerCase()] || "READY"; } function scoreFromStatus(s) { const m = { "Completed": 100, "completed": 100, "In Progress": 50, "in_progress": 50, "Pending": 10, "planned": 10 }; return m[s] || 25; } async function importProject(jsonPath) { const raw = JSON.parse(fs.readFileSync(jsonPath, "utf8")); const data = raw.project ? raw : { project: raw }; const p = data.project; const ai = data.aiSystem || {}; const lifecycleStages = data.lifecycleStages || []; const risks = data.risks || []; const mitigations = data.mitigations || []; const metrics = data.metrics || []; const experiments = data.experiments || []; const gates = data.gates || []; const governance = data.governance || {}; // Use or create the demo organization let org = await prisma.organization.findUnique({ where: { slug: "cosmic-demo" } }); if (!org) { org = await prisma.organization.create({ data: { name: "COSMIC Demo Organization", slug: "cosmic-demo", status: "TRIAL", planCode: "pilot", manualBilling: true } }); } let workspace = await prisma.workspace.findFirst({ where: { organizationId: org.id } }); if (!workspace) { workspace = await prisma.workspace.create({ data: { organizationId: org.id, name: "AI Risk Governance", slug: "ai-risk-governance", type: "B2B_TEAM", status: "TRIAL" } }); } // Ensure platform users have access to this organization const ownerRole = await prisma.role.findUnique({ where: { code: "owner" } }); if (ownerRole) { for (const email of ["super-owner@cosmic.local", "super-admin@cosmic.local"]) { const u = await prisma.user.findUnique({ where: { email } }); if (u) { await prisma.membership.upsert({ where: { organizationId_userId: { organizationId: org.id, userId: u.id } }, update: { roleId: ownerRole.id, status: "ACTIVE" }, create: { organizationId: org.id, userId: u.id, roleId: ownerRole.id, status: "ACTIVE" } }).catch(() => {}); console.log(` Added ${email} as member of ${org.name}`); } } } // Create project const projectType = (p.projectTypology && p.projectTypology[0]) || "AI-Enabler"; const project = await prisma.project.upsert({ where: { id: `imported-${p.id || p.name}`.replace(/[^a-zA-Z0-9_-]/g, "_") }, update: { name: p.name, description: p.description || "", projectType, status: mapStatus(p.status) || "ACTIVE", currentLifecyclePhase: "", riskAppetite: 50, ownerDisplayName: p.managerRole || "", thresholds: { source: jsonPath, importedAt: new Date().toISOString(), governance: governance, aiSystem: ai }, reviews: {} }, create: { id: `imported-${p.id || p.name}`.replace(/[^a-zA-Z0-9_-]/g, "_"), workspaceId: workspace.id, name: p.name, description: p.description || "", projectType, status: mapStatus(p.status) || "ACTIVE", currentLifecyclePhase: "", riskAppetite: 50, ownerDisplayName: p.managerRole || "", thresholds: { source: jsonPath, importedAt: new Date().toISOString(), governance: governance, aiSystem: ai }, reviews: {} } }).catch(async () => { // Fallback — create without custom ID return prisma.project.create({ data: { workspaceId: workspace.id, name: p.name, description: p.description || "", projectType, status: mapStatus(p.status) || "ACTIVE", riskAppetite: 50, ownerDisplayName: p.managerRole || "", thresholds: { source: jsonPath, importedAt: new Date().toISOString(), governance: governance, aiSystem: ai }, reviews: {} } }); }); console.log(`Project: ${project.id} — ${project.name}`); // Map lifecycle stage IDs to names and create phases const lifecycleIdToName = {}; for (let i = 0; i < lifecycleStages.length; i++) { const ls = lifecycleStages[i]; const name = ls.name; lifecycleIdToName[ls.id] = name; await prisma.lifecyclePhase.upsert({ where: { projectId_name: { projectId: project.id, name } }, update: { status: mapStatus(ls.status), readinessScore: scoreFromStatus(ls.status), sequence: i + 1 }, create: { projectId: project.id, name, status: mapStatus(ls.status), readinessScore: scoreFromStatus(ls.status), sequence: i + 1 } }).catch(() => {}); } // Set current lifecycle phase if (p.currentLifecycleStageId && lifecycleIdToName[p.currentLifecycleStageId]) { await prisma.project.update({ where: { id: project.id }, data: { currentLifecyclePhase: lifecycleIdToName[p.currentLifecycleStageId] } }); } // Import indicators (metrics) const metricIdMap = {}; for (const m of metrics) { const indicator = await prisma.indicator.upsert({ where: { projectId_name: { projectId: project.id, name: m.name } }, update: { dimension: m.dimension || "Technical", measurand: m.measurand || "", unit: m.unit || "", target: m.target || "", interpretationRule: m.interpretationRule || "" }, create: { projectId: project.id, name: m.name, dimension: m.dimension || "Technical", measurand: m.measurand || "", unit: m.unit || "", target: m.target || "", interpretationRule: m.interpretationRule || "" } }).catch(() => null); if (indicator) metricIdMap[m.id] = indicator.id; } console.log(` Imported ${metrics.length} indicators`); // Import risks const riskIdMap = {}; for (const r of risks) { const lifecyclePhaseName = lifecycleIdToName[r.lifecycleStageId] || r.lifecycleStageId || ""; const created = await prisma.risk.create({ data: { projectId: project.id, title: r.title, description: r.interpretationRule || "", dimension: r.governanceDimension || "Technical", domain: r.category || "", lifecyclePhase: lifecyclePhaseName, probability: Math.round((r.likelihood || 3) * 20), impact: Math.round((r.impact || 3) * 20), detectability: Math.round((r.uncertainty || 3) * 20), status: mapRiskStatus(r.status), approvalStatus: mapApprovalStatus(r.approvalState), dueDate: r.dueDate ? new Date(r.dueDate) : null, ownerDisplayName: r.ownerRole || "", evidenceSummary: r.gateEffect ? `Gate effect: ${r.gateEffect}. Residual: ${r.residualScore}/100. Inherent: ${r.inherentScore}/100.` : "" } }).catch(e => { console.warn(` Skipped risk "${r.title}": ${e.message}`); return null; }); if (created) { riskIdMap[r.id] = created.id; } } console.log(` Imported ${Object.keys(riskIdMap).length}/${risks.length} risks`); // Import mitigations let mitigationCount = 0; for (const m of mitigations) { const dbRiskId = riskIdMap[m.riskId]; if (!dbRiskId) continue; await prisma.mitigation.create({ data: { riskId: dbRiskId, title: m.title, ownerDisplayName: m.ownerRole || "", status: mapMitigationStatus(m.status), progressPercent: m.completionPercent || 0, effectivenessPercent: m.completionPercent || 0, dueDate: m.dueDate ? new Date(m.dueDate) : null } }).catch(() => {}); mitigationCount++; } console.log(` Imported ${mitigationCount} mitigations`); // Import experiments for (const e of experiments) { const experiment = await prisma.experiment.upsert({ where: { projectId_name: { projectId: project.id, name: e.name } }, update: { modelName: e.modelVersion || "", selected: e.status === "completed" || e.status === "in_progress" }, create: { projectId: project.id, name: e.name, modelName: e.modelVersion || "", selected: e.status === "completed" || e.status === "in_progress" } }).catch(() => null); if (!experiment) continue; // Import experiment metrics if (e.metrics && typeof e.metrics === "object") { for (const [metricName, metricValue] of Object.entries(e.metrics)) { if (typeof metricValue === "number") { await prisma.modelMetric.create({ data: { experimentId: experiment.id, metricName, metricValue, thresholdValue: 0, status: "pass", measuredAt: new Date() } }).catch(() => {}); } } } } console.log(` Imported ${experiments.length} experiments`); // Import gates for (const g of gates) { const status = mapGateStatus(g.status); const decisionDate = g.decisionDate ? new Date(g.decisionDate) : null; const gate = await prisma.gateEvaluation.create({ data: { projectId: project.id, status, reviewStatus: g.status === "blocked" ? "Blocked" : g.status === "conditional_pass" ? "Conditional Pass" : "Approved", summary: `Gate: ${g.name}${g.conditions && g.conditions.length ? `. Conditions: ${g.conditions.join("; ")}` : ""}`, evaluatedAt: decisionDate || new Date(), reviewedAt: decisionDate } }).catch(() => null); if (!gate) continue; // Import gate criteria for (const c of g.criteria || []) { await prisma.gateCriterion.create({ data: { gateId: gate.id, name: c.name, actualValue: c.status || "", expectedRule: c.metricId || "", status: c.status === "pass" ? "Pass" : c.status === "fail" ? "Fail" : c.status === "watch" ? "Watch" : c.status === "pending" ? "Pending" : c.status || "", blocking: c.status === "fail", evidenceTitle: c.blockedRiskIds ? `Blocked by risks: ${c.blockedRiskIds.join(", ")}` : (c.metricId || "") } }).catch(() => {}); } } console.log(` Imported ${gates.length} gates`); console.log(`\nImport complete. Project: ${project.name} (${project.id})`); console.log(` Indicators: ${metrics.length}, Risks: ${Object.keys(riskIdMap).length}, Mitigations: ${mitigationCount}, Experiments: ${experiments.length}, Gates: ${gates.length}`); } const filePath = process.argv[2]; if (!filePath) { console.error("Usage: node prisma/import-project.js "); process.exit(1); } importProject(filePath) .catch(e => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());