/home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production
Edit: /home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production/8.pack (214363B)
wpc OE §webpack/lib/cache/PackFileCacheStrategyPackContentItems€¦ Compilation/modules|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain\risk-engine.js|rscœCompilation/assets|chunk6930MinifierWebpackPlugin|6930.js˜webpack/lib/NormalModule«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceê2 "use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
€
javascript/autoƒrscœ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain€…aliasŠmainFieldsŽconditionNamesŽfullySpecified`$Œserver-only$Œclient-only$Ÿnext/dist/compiled/server-only$Ÿnext/dist/compiled/client-only$« C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\head.js¬ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\image.js° C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\constants.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\router.js® C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dynamic.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\script.js« C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\link.js« C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\form.js± C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\navigation.js® C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\headers.js© C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\og.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\server.js¯ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\document.jsª C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\app.js†react$—react/compiler-runtime$–react/jsx-dev-runtime$’react/jsx-runtime$Šreact-dom$‘react-dom/client$‘react-dom/server$™react-dom/server.browser$–react-dom/server.edge$‘react-dom/static$™react-dom/static.browser$–react-dom/static.edge$ react-server-dom-webpack/client$ react-server-dom-webpack/server$¥react-server-dom-webpack/server.node$ react-server-dom-webpack/static$É@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.ts„next¤next/dist/compiled/server-only/empty¤next/dist/compiled/client-only/errorþÿ¥next/dist/client/components/noop-head“next/dist/api/image—next/dist/api/constants”next/dist/api/router™next/dist/api/app-dynamic”next/dist/api/scriptnext/dist/client/app-dir/linknext/dist/client/app-dir/form¥next/dist/api/navigation.react-server•next/dist/api/headersnext/dist/api/og”next/dist/api/server–next/dist/api/document‘next/dist/api/appºnext/dist/server/route-modules/app-page/vendored/rsc/reactËnext/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtimeÊnext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtimeÆnext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtime¾next/dist/server/route-modules/app-page/vendored/rsc/react-dom£next/dist/compiled/react-dom/client¨next/dist/compiled/react-dom/server.node«next/dist/compiled/react-dom/server.browser±next/dist/build/webpack/alias/react-dom-server.js¨next/dist/compiled/react-dom/static.node«next/dist/compiled/react-dom/static.browser¨next/dist/compiled/react-dom/static.edge·next/dist/compiled/react-server-dom-webpack/client.nodeÔnext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-serverÿÔnext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-static§next/dist/client/dev/noop-turbopack-hmr£ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next†module„mainŒreact-serverƒ...
¨`‰cacheable†parsedfileDependencies“contextDependencies“missingDependencies‘buildDependencies‘valueDependencies„hash†assetsŠassetsInfo¡†strict”topLevelDeclarationsˆsnapshot˜webpack/lib/util/LazySetÚ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.jsÑ C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js™webpack/DefinePlugin_hashˆb5546ded345f7990784ae20b„type‰actionIdsŠclientRefsclientEntryType‹isClientRef†server
€`…clampnormalizeStatus—normalizeApprovalStatusˆgetLevel‰scoreRisk‡average’selectedExperiment”riskMitigationRollup‘scoreProjectRisks•calculateOverallScoredimensionScoreslifecycleScores”mitigationCompletionŒevaluateGate’calculateDashboardŠDIMENSIONS†LEVELSšwebpack/lib/FileSystemInfoˆSnapshot ¶÷óyB« C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain\risk-engine.jsˆsafeTime‰timestampÔ! àóóóyB ÐóóóyB8edb17f240cfc0f6¨webpack/lib/dependencies/ConstDependency€ `
`
¸webpack/lib/dependencies/CommonJsSelfReferenceDependencyAL2 Z2 Žmodule.exports @ @ ` «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource r% «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€`«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceJ exports.id = 6930;
exports.ids = [6930];
exports.modules = {
/***/ 2488:
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource — «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$ /***/ ((module) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourcel "use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
`€€†buffer†source„size„maps„hash_
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourcel "use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
012undefined
/***/ })€†buffer†source„size„maps„hash /***/ ((module) => {
"use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
/***/ })€”{"finalSource":true}ƒmap‹bufferedMap ConcatSourceRawSource$ /***/ ((module) => {
"use strict";
ReplaceSourceRawSourcel "use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
012undefined RawSource
/***/ }) ,
/***/ 2773:
‹# «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource ¨ «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceÍ
"use strict";
const { prisma } = require("./prisma");
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = require("../domain/permissions");
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
d!')2C( . 0 F €“__webpack_require__„7964þ„5707€†buffer†source„size„maps„hash¿
const { prisma } = __webpack_require__(7964);
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = __webpack_require__(5707);
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceÍ
"use strict";
const { prisma } = require("./prisma");
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = require("../domain/permissions");
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
v 012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefined
/***/ })ì /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { prisma } = __webpack_require__(7964);
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = __webpack_require__(5707);
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
/***/ })íðñS /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
òÍ
"use strict";
const { prisma } = require("./prisma");
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = require("../domain/permissions");
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
v 012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefinedóô ,
/***/ 3421:
ÿ( «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource Û
«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource var __webpack_unused_export__;
«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourceù "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "sendResponse", {
enumerable: true,
get: function() {
return sendResponse;
}
});
const _helpers = require("./base-http/helpers");
const _pipereadable = require("./pipe-readable");
const _utils = require("./web/utils");
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.maph :NNQOÒ Ò æ ì î " $ 4 G M O [ 0 R €__webpack_unused_export__ = ()¥Object.defineProperty(exports, "I", (‚))“__webpack_require__„1237þ„5088ý„7679… true€†buffer†source„size„maps„hashÑ var __webpack_unused_export__;
__webpack_unused_export__ = ({
value: true
});
Object.defineProperty(exports, "I", ({
enumerable: true,
get: function() {
return sendResponse;
}
}));
const _helpers = __webpack_require__(1237);
const _pipereadable = __webpack_require__(5088);
const _utils = __webpack_require__(7679);
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
true && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map€”{"finalSource":true}ƒmap‹bufferedMap ConcatSourceRawSource var __webpack_unused_export__;
ReplaceSourceRawSourceù "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "sendResponse", {
enumerable: true,
get: function() {
return sendResponse;
}
});
const _helpers = require("./base-http/helpers");
const _pipereadable = require("./pipe-readable");
const _utils = require("./web/utils");
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map; 012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefined
/***/ })á. /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var __webpack_unused_export__;
__webpack_unused_export__ = ({
value: true
});
Object.defineProperty(exports, "I", ({
enumerable: true,
get: function() {
return sendResponse;
}
}));
const _helpers = __webpack_require__(1237);
const _pipereadable = __webpack_require__(5088);
const _utils = __webpack_require__(7679);
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
true && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map
/***/ })âå æS /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
å var __webpack_unused_export__;
æù "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "sendResponse", {
enumerable: true,
get: function() {
return sendResponse;
}
});
const _helpers = require("./base-http/helpers");
const _pipereadable = require("./pipe-readable");
const _utils = require("./web/utils");
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map; 012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefinedçè ,
/***/ 5400:
«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource " «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceP "use strict";
const { prisma } = require("./prisma");
const { hasPermission, canAccessWorkspace } = require("../domain/permissions");
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
g!')2djl@‚ €“__webpack_require__„7964þ„5707€†buffer†source„size„maps„hashB
const { prisma } = __webpack_require__(7964);
const { hasPermission, canAccessWorkspace } = __webpack_require__(5707);
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceP "use strict";
const { prisma } = require("./prisma");
const { hasPermission, canAccessWorkspace } = require("../domain/permissions");
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
r 012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefined
/***/ })ÕŸ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { prisma } = __webpack_require__(7964);
const { hasPermission, canAccessWorkspace } = __webpack_require__(5707);
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
/***/ })ÖÙÚéÜP "use strict";
const { prisma } = require("./prisma");
const { hasPermission, canAccessWorkspace } = require("../domain/permissions");
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
r 012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefinedÝÞ ,
/***/ 5567:
› «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$ /***/ ((module) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource Œ3 «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceê2 "use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
`€€†buffer†source„size„maps„hashÝ2
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceê2 "use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
012undefined
/***/ })Ë3 /***/ ((module) => {
"use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
/***/ })ÌÏÐÑÒê2 "use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
ÓÔÕ ,
/***/ 5707:
}, «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$ /***/ ((module) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource ° «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource "use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
`€€†buffer†source„size„maps„hash
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource "use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
012undefined
/***/ })Â/ /***/ ((module) => {
"use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
/***/ })ÃÆÇÈÉ "use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
ÊËÌ ,
/***/ 5736:
‚ «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource } «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceR "use strict";
if (process.env.NEXT_RUNTIME === 'edge') {
module.exports = require('next/dist/server/route-modules/app-route/module.js');
} else {
if (process.env.__NEXT_EXPERIMENTAL_REACT) {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js');
}
}
} else {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js');
}
}
}
}
//# sourceMappingURL=module.compiled.js.map
c47N ž Â Å Š Ÿ Ä Ç í — ° €…false‚{}þÿþÿþÿªmodule.exports = __webpack_require__(4870)€†buffer†source„size„maps„hashõ
if (false) {} else {
if (false) {} else {
if (false) {} else {
if (false) {} else {
module.exports = __webpack_require__(4870);
}
}
}
}
//# sourceMappingURL=module.compiled.js.map€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceR "use strict";
if (process.env.NEXT_RUNTIME === 'edge') {
module.exports = require('next/dist/server/route-modules/app-route/module.js');
} else {
if (process.env.__NEXT_EXPERIMENTAL_REACT) {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js');
}
}
} else {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js');
}
}
}
}
//# sourceMappingURL=module.compiled.js.mapÝ 012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefined
/***/ })¹R /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
if (false) {} else {
if (false) {} else {
if (false) {} else {
if (false) {} else {
module.exports = __webpack_require__(4870);
}
}
}
}
//# sourceMappingURL=module.compiled.js.map
/***/ })º½¾ÍÀR "use strict";
if (process.env.NEXT_RUNTIME === 'edge') {
module.exports = require('next/dist/server/route-modules/app-route/module.js');
} else {
if (process.env.__NEXT_EXPERIMENTAL_REACT) {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js');
}
}
} else {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js');
}
}
}
}
//# sourceMappingURL=module.compiled.js.mapÝ 012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefinedÁÂ ,
/***/ 6487:
4 «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource /***/ (() => {
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource €†buffer†source„size„maps„hash€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource ÿ
/***/ })¯ /***/ (() => {
/***/ })°³´ /***/ (() => {
µ ÿ·¸ ,
/***/ 7964:
- «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource ý «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource "use strict";
const { PrismaClient } = require("@prisma/client");
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if ("production" !== "production") {
globalForPrisma.__cosmicPrisma = prisma;
}
module.exports = {
prisma
};
d'-/>C¯ Ë Î ý €“__webpack_require__„6330…false‚{}€†buffer†source„size„maps„hashÍ
const { PrismaClient } = __webpack_require__(6330);
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if (false) {}
module.exports = {
prisma
};
€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource "use strict";
const { PrismaClient } = require("@prisma/client");
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if ("production" !== "production") {
globalForPrisma.__cosmicPrisma = prisma;
}
module.exports = {
prisma
};
b 012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefined
/***/ })¥* /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { PrismaClient } = __webpack_require__(6330);
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if (false) {}
module.exports = {
prisma
};
/***/ })¦©ª¹¬ "use strict";
const { PrismaClient } = require("@prisma/client");
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if ("production" !== "production") {
globalForPrisma.__cosmicPrisma = prisma;
}
module.exports = {
prisma
};
b 012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefined® ,
/***/ 8335:
4 «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource /***/ (() => {
«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource €†buffer†source„size„maps„hash€”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource ÿ
/***/ })›ì ¡í£î
};
;†buffer†source„size„mapsÀ7e exports.id = 6930;
exports.ids = [6930];
exports.modules = {
/***/ 2488:
/***/ ((module) => {
"use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
/***/ }),
/***/ 2773:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { prisma } = __webpack_require__(7964);
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = __webpack_require__(5707);
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
/***/ }),
/***/ 3421:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var __webpack_unused_export__;
__webpack_unused_export__ = ({
value: true
});
Object.defineProperty(exports, "I", ({
enumerable: true,
get: function() {
return sendResponse;
}
}));
const _helpers = __webpack_require__(1237);
const _pipereadable = __webpack_require__(5088);
const _utils = __webpack_require__(7679);
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
true && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map
/***/ }),
/***/ 5400:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { prisma } = __webpack_require__(7964);
const { hasPermission, canAccessWorkspace } = __webpack_require__(5707);
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
/***/ }),
/***/ 5567:
/***/ ((module) => {
"use strict";
const DIMENSIONS = [
"Organizational",
"Technical",
"Human"
];
const LEVELS = [
{
name: "Low",
min: 0,
max: 24
},
{
name: "Moderate",
min: 25,
max: 49
},
{
name: "High",
min: 50,
max: 74
},
{
name: "Critical",
min: 75,
max: 100
}
];
function clamp(value, min, max) {
return Math.max(min, Math.min(max, Number(value) || 0));
}
function normalizeStatus(status) {
return String(status || "OPEN").replace(/_/g, " ").toLowerCase();
}
function normalizeApprovalStatus(status) {
return String(status || "PENDING").replace(/_/g, " ").toLowerCase();
}
function getLevel(score) {
const bounded = clamp(score, 0, 100);
const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max);
return level ? level.name : "Unknown";
}
function scoreRisk(risk) {
const probability = clamp(risk.probability, 1, 5);
const impact = clamp(risk.impact, 1, 5);
const detectability = clamp(risk.detectability, 1, 5);
const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round(rawScore / 125 * 100);
const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100);
const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
probability,
impact,
detectability,
mitigationProgress,
mitigationEffectiveness,
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function average(values) {
const clean = values.filter((value)=>Number.isFinite(Number(value)));
if (!clean.length) return 0;
return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length);
}
function selectedExperiment(experiments) {
return experiments.find((item)=>item.selected) || experiments[0] || null;
}
function riskMitigationRollup(risk) {
const mitigations = risk.mitigations || [];
if (!mitigations.length) return {
mitigationProgress: 0,
mitigationEffectiveness: 0
};
return {
mitigationProgress: average(mitigations.map((item)=>item.progressPercent)),
mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent))
};
}
function scoreProjectRisks(risks) {
return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk))));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
if (!active.length) return 0;
const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8);
const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore));
const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore));
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4);
const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3);
return clamp(exposure + approvalPenalty, 0, 100);
}
function dimensionScores(scoredRisks) {
return DIMENSIONS.map((dimension)=>{
const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed");
return {
name: dimension,
score: average(risks.map((risk)=>risk.residualScore))
};
});
}
function lifecycleScores(lifecyclePhases, scoredRisks) {
return lifecyclePhases.map((phase)=>{
const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed");
const riskScore = average(phaseRisks.map((risk)=>risk.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return average(active.map((risk)=>risk.mitigationProgress));
}
function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) {
const thresholds = project.thresholds || {};
const reviews = project.reviews || {};
const selected = selectedExperiment(experiments || []);
const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![
"accepted",
"approved"
].includes(normalizeApprovalStatus(risk.approvalStatus))).length;
const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null;
const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null;
const criteria = [
{
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
blocking: overallScore > (thresholds.overallRiskMax ?? 50),
evidence: "Calculated from residual active risks and approval penalty."
},
{
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0),
evidence: "Critical risks must be closed, accepted, or approved."
},
{
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60),
evidence: "Average mitigation progress across active risks."
},
{
name: "Data readiness",
required: `>= ${thresholds.dataReadinessMin ?? 70}`,
actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing",
status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked",
blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)),
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selectedF1 ? selectedF1.metricValue : "Missing",
status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)),
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selectedStability ? selectedStability.metricValue : "Missing",
status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
blocking: false,
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
name: "Ethical review",
required: "Approved or Accepted",
actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing",
status: reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.ethicalReview && [
"Approved",
"Accepted"
].includes(reviews.ethicalReview.status)),
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
name: "Legal review",
required: "Approved or Accepted",
actual: reviews.legalReview ? reviews.legalReview.status : "Missing",
status: reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status) ? "Pass" : "Blocked",
blocking: !(reviews.legalReview && [
"Approved",
"Accepted"
].includes(reviews.legalReview.status)),
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
blocking: unapprovedHigh !== 0,
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter((item)=>item.status === "Blocked");
const warnings = criteria.filter((item)=>item.status === "Warning");
const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY";
return {
status,
criteria,
blockedCount: blocked.length,
warningCount: warnings.length,
message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready."
};
}
function calculateDashboard(project) {
const risks = scoreProjectRisks(project.risks || []);
const mitigationPct = mitigationCompletion(risks);
const overallScore = calculateOverallScore(risks);
const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct);
const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed");
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
status: project.status,
assessmentDate: project.assessmentDate
},
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: risks.length,
highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length,
criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length,
mitigationCompletion: mitigationPct
},
dimensions: dimensionScores(risks),
lifecycle: lifecycleScores(project.lifecyclePhases || [], risks),
gate,
scoredRisks: risks,
topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8),
mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, {
riskTitle: risk.title,
riskResidualScore: risk.residualScore
}))),
indicators: project.indicators || [],
experiments: project.experiments || []
};
}
module.exports = {
DIMENSIONS,
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate,
calculateOverallScore,
scoreProjectRisks
};
/***/ }),
/***/ 5707:
/***/ ((module) => {
"use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
/***/ }),
/***/ 5736:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
if (false) {} else {
if (false) {} else {
if (false) {} else {
if (false) {} else {
module.exports = __webpack_require__(4870);
}
}
}
}
//# sourceMappingURL=module.compiled.js.map
/***/ }),
/***/ 6487:
/***/ (() => {
/***/ }),
/***/ 7964:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
const { PrismaClient } = __webpack_require__(6330);
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if (false) {}
module.exports = {
prisma
};
/***/ }),
/***/ 8335:
/***/ (() => {
/***/ })
};
;‚{}ƒmap‹bufferedMap`^ ConcatSourceRawSourceJ exports.id = 6930;
exports.ids = [6930];
exports.modules = {
/***/ 2488:
þ$ /***/ ((module) => {
"use strict";
ReplaceSourceRawSourcel "use strict";
function jsonResponse(payload, status = 200, headers = {}) {
return Response.json(payload, {
status,
headers: Object.assign({
"Cache-Control": "no-store"
}, headers)
});
}
function errorResponse(error) {
return jsonResponse({
error: error.message || "Unexpected error",
details: error.details || undefined
}, error.status || 500);
}
async function parseJson(request) {
const text = await request.text();
if (!text) return {};
return JSON.parse(text);
}
module.exports = {
jsonResponse,
errorResponse,
parseJson
};
012undefined RawSource
/***/ })þ ,
/***/ 2773:
÷S /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
ùÍ
"use strict";
const { prisma } = require("./prisma");
async function getActorFromRequest(request) {
const cookie = request.headers.get("cookie") || "";
const sessionMatch = cookie.match(/cosmic_session=([^;]+)/);
if (sessionMatch) {
const session = await prisma.session.findUnique({
where: {
token: sessionMatch[1]
},
include: {
user: {
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
}
}
});
if (session && session.expiresAt > new Date()) {
return session.user;
}
if (session) {
await prisma.session.delete({
where: {
id: session.id
}
}).catch(()=>{});
}
}
const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local";
const user = await prisma.user.findUnique({
where: {
email
},
include: {
memberships: {
where: {
status: "ACTIVE"
},
include: {
role: true,
organization: true
}
}
}
});
if (!user) {
const error = new Error(`Unknown actor: ${email}`);
error.status = 401;
throw error;
}
return user;
}
function getMembership(actor, organizationId) {
return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE");
}
async function requireOrganizationActor(request, organizationId, permission = "project:read") {
const { hasPermission } = require("../domain/permissions");
const actor = await getActorFromRequest(request);
const membership = getMembership(actor, organizationId);
if (!membership) {
const error = new Error("Actor is not a member of this organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
return {
actor,
membership,
organization: membership.organization
};
}
module.exports = {
getActorFromRequest,
requireOrganizationActor
};
v 012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefinedúûú ,
/***/ 3421:
óS /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
ò var __webpack_unused_export__;
ôù "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "sendResponse", {
enumerable: true,
get: function() {
return sendResponse;
}
});
const _helpers = require("./base-http/helpers");
const _pipereadable = require("./pipe-readable");
const _utils = require("./web/utils");
async function sendResponse(req, res, response, waitUntil) {
if (// The type check here ensures that `req` is correctly typed, and the
// environment variable check provides dead code elimination.
process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) {
var // Copy over the response headers.
_response_headers;
// Copy over the response status.
res.statusCode = response.status;
res.statusMessage = response.statusText;
// TODO: this is not spec-compliant behavior and we should not restrict
// headers that are allowed to appear many times.
//
// See:
// https://github.com/vercel/next.js/pull/70127
const headersWithMultipleValuesAllowed = [
// can add more headers to this list if needed
'set-cookie',
'www-authenticate',
'proxy-authenticate',
'vary'
];
(_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{
// `x-middleware-set-cookie` is an internal header not needed for the response
if (name.toLowerCase() === 'x-middleware-set-cookie') {
return;
}
// The append handling is special cased for `set-cookie`.
if (name.toLowerCase() === 'set-cookie') {
// TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
for (const cookie of (0, _utils.splitCookiesString)(value)){
res.appendHeader(name, cookie);
}
} else {
// only append the header if it is either not present in the outbound response
// or if the header supports multiple values
const isHeaderPresent = typeof res.getHeader(name) !== 'undefined';
if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) {
res.appendHeader(name, value);
}
}
});
/**
* The response can't be directly piped to the underlying response. The
* following is duplicated from the edge runtime handler.
*
* See packages/next/server/next-server.ts
*/ const { originalResponse } = res;
// A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD
if (response.body && req.method !== 'HEAD') {
await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil);
} else {
originalResponse.end();
}
}
}
//# sourceMappingURL=send-response.js.map; 012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefinedõöõ ,
/***/ 5400:
î÷ñP "use strict";
const { prisma } = require("./prisma");
const { hasPermission, canAccessWorkspace } = require("../domain/permissions");
async function getProjectScope(projectId) {
const project = await prisma.project.findUnique({
where: {
id: projectId
},
include: {
workspace: {
include: {
organization: true
}
}
}
});
if (!project) {
const error = new Error(`Project not found: ${projectId}`);
error.status = 404;
throw error;
}
return project;
}
async function requireProjectAccess(actor, projectId, permission = "project:read") {
const project = await getProjectScope(projectId);
const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE");
if (!membership) {
const error = new Error("Actor cannot access this project's organization.");
error.status = 403;
throw error;
}
if (!hasPermission(membership.role.permissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
if (!canAccessWorkspace(membership, project.workspaceId)) {
const error = new Error("Actor cannot access this workspace.");
error.status = 403;
throw error;
}
return {
project,
membership,
organization: project.workspace.organization
};
}
module.exports = {
getProjectScope,
requireProjectAccess
};
r 012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefinedòóò ,
/***/ 5567:
ëíîBÿÿÿðñòñ ,
/***/ 5707:
êìí "use strict";
const PERMISSIONS = [
"organization:manage",
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"risk:delete",
"mitigation:write",
"gate:read",
"gate:evaluate",
"gate:review",
"report:export",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"billing:manage",
"audit:read"
];
const ROLE_PERMISSIONS = {
owner: [
"*"
],
admin: [
"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"
],
project_manager: [
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"report:export",
"integration:read",
"audit:read"
],
risk_owner: [
"project:read",
"risk:read",
"risk:write",
"mitigation:write",
"gate:read"
],
governance_reviewer: [
"project:read",
"risk:read",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
],
legal_ethics_reviewer: [
"project:read",
"risk:read",
"mitigation:write",
"gate:review",
"report:export",
"audit:read"
],
integration_admin: [
"project:read",
"integration:read",
"integration:manage",
"integration:sync",
"oauth:manage",
"audit:read"
],
viewer: [
"project:read",
"risk:read",
"gate:read",
"integration:read",
"report:export"
],
consultant: [
"workspace:manage",
"project:read",
"project:write",
"risk:read",
"risk:write",
"mitigation:write",
"gate:evaluate",
"gate:review",
"report:export",
"audit:read"
]
};
function unique(values) {
return Array.from(new Set(values.filter(Boolean)));
}
function resolvePermissions(roleCodeOrPermissions) {
if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions);
return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : [];
}
function hasPermission(roleCodeOrPermissions, permission) {
const permissions = resolvePermissions(roleCodeOrPermissions);
return permissions.includes("*") || permissions.includes(permission);
}
function assertPermission(roleCodeOrPermissions, permission) {
if (!hasPermission(roleCodeOrPermissions, permission)) {
const error = new Error(`Permission denied: ${permission}`);
error.status = 403;
throw error;
}
}
function canAccessWorkspace(membership, workspaceId) {
if (!membership || membership.status !== "ACTIVE") return false;
if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true;
return membership.workspaceScope.includes(workspaceId);
}
function canMutateRisk(membership) {
return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write");
}
module.exports = {
PERMISSIONS,
ROLE_PERMISSIONS,
resolvePermissions,
hasPermission,
assertPermission,
canAccessWorkspace,
canMutateRisk
};
îïðï ,
/***/ 5736:
èñëR "use strict";
if (process.env.NEXT_RUNTIME === 'edge') {
module.exports = require('next/dist/server/route-modules/app-route/module.js');
} else {
if (process.env.__NEXT_EXPERIMENTAL_REACT) {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js');
}
}
} else {
if (process.env.NODE_ENV === 'development') {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js');
}
} else {
if (process.env.TURBOPACK) {
module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js');
} else {
module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js');
}
}
}
}
//# sourceMappingURL=module.compiled.js.mapÝ 012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefinedìíì ,
/***/ 6487:
å /***/ (() => {
ç ÿéêé ,
/***/ 7964:
âëå "use strict";
const { PrismaClient } = require("@prisma/client");
const globalForPrisma = globalThis;
const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient();
if ("production" !== "production") {
globalForPrisma.__cosmicPrisma = prisma;
}
module.exports = {
prisma
};
b 012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefinedæçæ ,
/***/ 8335:
ßúâûûåæå
};
;Ð / exports.id=6930,exports.ids=[6930],exports.modules={2488:a=>{"use strict";function b(a,c=200,d={}){return Response.json(a,{status:c,headers:Object.assign({"Cache-Control":"no-store"},d)})}a.exports={jsonResponse:b,errorResponse:function(a){return b({error:a.message||"Unexpected error",details:a.details||void 0},a.status||500)},parseJson:async function(a){let b=await a.text();return b?JSON.parse(b):{}}}},2773:(a,b,c)=>{"use strict";let{prisma:d}=c(7964);async function e(a){let b=(a.headers.get("cookie")||"").match(/cosmic_session=([^;]+)/);if(b){let a=await d.session.findUnique({where:{token:b[1]},include:{user:{include:{memberships:{where:{status:"ACTIVE"},include:{role:!0,organization:!0}}}}}});if(a&&a.expiresAt>new Date)return a.user;a&&await d.session.delete({where:{id:a.id}}).catch(()=>{})}let c=a.headers.get("x-cosmic-user-email")||process.env.COSMIC_BOOTSTRAP_EMAIL||"owner@cosmic.local",e=await d.user.findUnique({where:{email:c},include:{memberships:{where:{status:"ACTIVE"},include:{role:!0,organization:!0}}}});if(!e){let a=Error(`Unknown actor: ${c}`);throw a.status=401,a}return e}async function f(a,b,d="project:read"){let{hasPermission:g}=c(5707),h=await e(a),i=h.memberships.find(a=>a.organizationId===b&&"ACTIVE"===a.status);if(!i){let a=Error("Actor is not a member of this organization.");throw a.status=403,a}if(!g(i.role.permissions,d)){let a=Error(`Permission denied: ${d}`);throw a.status=403,a}return{actor:h,membership:i,organization:i.organization}}a.exports={getActorFromRequest:e,requireOrganizationActor:f}},3421:(a,b,c)=>{"use strict";Object.defineProperty(b,"I",{enumerable:!0,get:function(){return g}});let d=c(1237),e=c(5088),f=c(7679);async function g(a,b,c,g){if((0,d.isNodeNextResponse)(b)){var h;b.statusCode=c.status,b.statusMessage=c.statusText;let d=["set-cookie","www-authenticate","proxy-authenticate","vary"];null==(h=c.headers)||h.forEach((a,c)=>{if("x-middleware-set-cookie"!==c.toLowerCase())if("set-cookie"===c.toLowerCase())for(let d of(0,f.splitCookiesString)(a))b.appendHeader(c,d);else{let e=void 0!==b.getHeader(c);(d.includes(c.toLowerCase())||!e)&&b.appendHeader(c,a)}});let{originalResponse:i}=b;c.body&&"HEAD"!==a.method?await (0,e.pipeToNodeResponse)(c.body,i,g):i.end()}}},5400:(a,b,c)=>{"use strict";let{prisma:d}=c(7964),{hasPermission:e,canAccessWorkspace:f}=c(5707);async function g(a){let b=await d.project.findUnique({where:{id:a},include:{workspace:{include:{organization:!0}}}});if(!b){let b=Error(`Project not found: ${a}`);throw b.status=404,b}return b}async function h(a,b,c="project:read"){let d=await g(b),i=a.memberships.find(a=>a.organizationId===d.workspace.organizationId&&"ACTIVE"===a.status);if(!i){let a=Error("Actor cannot access this project's organization.");throw a.status=403,a}if(!e(i.role.permissions,c)){let a=Error(`Permission denied: ${c}`);throw a.status=403,a}if(!f(i,d.workspaceId)){let a=Error("Actor cannot access this workspace.");throw a.status=403,a}return{project:d,membership:i,organization:d.workspace.organization}}a.exports={getProjectScope:g,requireProjectAccess:h}},5567:a=>{"use strict";let b=["Organizational","Technical","Human"],c=[{name:"Low",min:0,max:24},{name:"Moderate",min:25,max:49},{name:"High",min:50,max:74},{name:"Critical",min:75,max:100}];function d(a,b,c){return Math.max(b,Math.min(c,Number(a)||0))}function e(a){return String(a||"OPEN").replace(/_/g," ").toLowerCase()}function f(a){return String(a||"PENDING").replace(/_/g," ").toLowerCase()}function g(a){let b=d(a,0,100),e=c.find(a=>b>=a.min&&b<=a.max);return e?e.name:"Unknown"}function h(a){let b=d(a.probability,1,5),c=d(a.impact,1,5),f=d(a.detectability,1,5),h=d(a.mitigationProgress??a.mitigation_progress??a.progressPercent??0,0,100),i=d(a.mitigationEffectiveness??a.mitigation_effectiveness??a.effectivenessPercent??0,0,100),j=b*c*f,k=Math.round(j/125*100),l=h/100*(i/100),m="closed"===e(a.status)?Math.round(.1*k):Math.round(k*(1-l));return Object.assign({},a,{probability:b,impact:c,detectability:f,mitigationProgress:h,mitigationEffectiveness:i,rawScore:j,normalizedScore:k,residualScore:d(m,0,100),severity:g(k),residualSeverity:g(m)})}function i(a){let b=a.filter(a=>Number.isFinite(Number(a)));return b.length?Math.round(b.reduce((a,b)=>a+Number(b),0)/b.length):0}function j(a){return a.map(a=>h(Object.assign({},a,function(a){let b=a.mitigations||[];return b.length?{mitigationProgress:i(b.map(a=>a.progressPercent)),mitigationEffectiveness:i(b.map(a=>a.effectivenessPercent))}:{mitigationProgress:0,mitigationEffectiveness:0}}(a))))}function k(a){let b=a.filter(a=>"closed"!==e(a.status));if(!b.length)return 0;let c=b.slice().sort((a,b)=>b.normalizedScore-a.normalizedScore).slice(0,8),g=i(c.map(a=>a.normalizedScore)),h=i(c.map(a=>a.residualScore)),j=b.filter(a=>a.normalizedScore>=75&&!["accepted","approved"].includes(f(a.approvalStatus))).length;return d(Math.round(.7*g+.3*h)+(Math.min(12,2*b.filter(a=>a.normalizedScore>=50&&!["accepted","approved"].includes(f(a.approvalStatus))).length)+Math.min(15,4*j)),0,100)}function l(a,b,c,d,g){var h;let i=a.thresholds||{},j=a.reviews||{},k=(h=c||[]).find(a=>a.selected)||h[0]||null,l=b.filter(a=>"closed"!==e(a.status)),m=l.filter(a=>a.normalizedScore>=75&&!["accepted","approved"].includes(f(a.approvalStatus))).length,n=l.filter(a=>a.normalizedScore>=50&&!["accepted","approved"].includes(f(a.approvalStatus))).length,o=k&&k.metrics?k.metrics.find(a=>"f1"===a.metricName):null,p=k&&k.metrics?k.metrics.find(a=>"stability"===a.metricName):null,q=[{name:"Overall risk score",required:`<= ${i.overallRiskMax??50}`,actual:d,status:d<=(i.overallRiskMax??50)?"Pass":"Blocked",blocking:d>(i.overallRiskMax??50),evidence:"Calculated from residual active risks and approval penalty."},{name:"Open critical risks",required:`<= ${i.criticalOpenMax??0}`,actual:m,status:m<=(i.criticalOpenMax??0)?"Pass":"Blocked",blocking:m>(i.criticalOpenMax??0),evidence:"Critical risks must be closed, accepted, or approved."},{name:"Mitigation completeness",required:`>= ${i.mitigationCompletionMin??60}%`,actual:`${g}%`,status:g>=(i.mitigationCompletionMin??60)?"Pass":"Blocked",blocking:g<(i.mitigationCompletionMin??60),evidence:"Average mitigation progress across active risks."},{name:"Data readiness",required:`>= ${i.dataReadinessMin??70}`,actual:j.dataReadiness?j.dataReadiness.score:"Missing",status:j.dataReadiness&&j.dataReadiness.score>=(i.dataReadinessMin??70)?"Pass":"Blocked",blocking:!(j.dataReadiness&&j.dataReadiness.score>=(i.dataReadinessMin??70)),evidence:j.dataReadiness?j.dataReadiness.evidence:"Data readiness review missing."},{name:"Selected model performance",required:`F1 >= ${i.selectedModelF1Min??.8}`,actual:o?o.metricValue:"Missing",status:o&&o.metricValue>=(i.selectedModelF1Min??.8)?"Pass":"Blocked",blocking:!(o&&o.metricValue>=(i.selectedModelF1Min??.8)),evidence:k?`${k.name} selected for gate review.`:"No selected experiment."},{name:"Selected model stability",required:`>= ${i.selectedModelStabilityMin??75}`,actual:p?p.metricValue:"Missing",status:p&&p.metricValue>=(i.selectedModelStabilityMin??75)?"Pass":"Warning",blocking:!1,evidence:k?"Stability is based on repeated evaluation variation.":"No selected experiment."},{name:"Ethical review",required:"Approved or Accepted",actual:j.ethicalReview?j.ethicalReview.status:"Missing",status:j.ethicalReview&&["Approved","Accepted"].includes(j.ethicalReview.status)?"Pass":"Blocked",blocking:!(j.ethicalReview&&["Approved","Accepted"].includes(j.ethicalReview.status)),evidence:j.ethicalReview?j.ethicalReview.evidence:"Ethical review missing."},{name:"Legal review",required:"Approved or Accepted",actual:j.legalReview?j.legalReview.status:"Missing",status:j.legalReview&&["Approved","Accepted"].includes(j.legalReview.status)?"Pass":"Blocked",blocking:!(j.legalReview&&["Approved","Accepted"].includes(j.legalReview.status)),evidence:j.legalReview?j.legalReview.evidence:"Legal review missing."},{name:"High-risk approval state",required:"No unapproved high risks",actual:n,status:0===n?"Pass":"Blocked",blocking:0!==n,evidence:"High risks require owner approval, acceptance, closure, or documented treatment."}],r=q.filter(a=>"Blocked"===a.status),s=q.filter(a=>"Warning"===a.status),t=r.length?"BLOCKED":s.length||d>=(i.gateWarningScore??35)?"WARNING":"READY";return{status:t,criteria:q,blockedCount:r.length,warningCount:s.length,message:"BLOCKED"===t?`Deployment gate blocked by ${r.length} criterion or criteria.`:"WARNING"===t?"Deployment gate requires reviewer attention before release.":"Deployment gate is ready."}}a.exports={DIMENSIONS:b,scoreRisk:h,getLevel:g,calculateDashboard:function(a){var c;let d=j(a.risks||[]),f=i(d.filter(a=>"closed"!==e(a.status)).map(a=>a.mitigationProgress)),h=k(d),m=l(a,d,a.experiments||[],h,f),n=d.filter(a=>"closed"!==e(a.status));return{project:{id:a.id,name:a.name,subtitle:a.subtitle,status:a.status,assessmentDate:a.assessmentDate},summary:{overallScore:h,riskLevel:g(h),gateStatus:m.status,openRisks:n.length,totalRisks:d.length,highRisks:n.filter(a=>a.normalizedScore>=50&&a.normalizedScore<75).length,criticalRisks:n.filter(a=>a.normalizedScore>=75).length,mitigationCompletion:f},dimensions:b.map(a=>{let b=d.filter(b=>b.dimension===a&&"closed"!==e(b.status));return{name:a,score:i(b.map(a=>a.residualScore))}}),lifecycle:(c=a.lifecyclePhases||[],c.map(a=>{let b=d.filter(b=>b.lifecyclePhase===a.name&&"closed"!==e(b.status)),c=i(b.map(a=>a.residualScore));return Object.assign({},a,{openRisks:b.length,riskScore:c,riskLevel:g(c)})})),gate:m,scoredRisks:d,topRisks:n.slice().sort((a,b)=>b.residualScore-a.residualScore).slice(0,8),mitigations:d.flatMap(a=>(a.mitigations||[]).map(b=>Object.assign({},b,{riskTitle:a.title,riskResidualScore:a.residualScore}))),indicators:a.indicators||[],experiments:a.experiments||[]}},evaluateGate:l,calculateOverallScore:k,scoreProjectRisks:j}},5707:a=>{"use strict";let b={owner:["*"],admin:["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"],project_manager:["project:read","project:write","risk:read","risk:write","mitigation:write","gate:evaluate","report:export","integration:read","audit:read"],risk_owner:["project:read","risk:read","risk:write","mitigation:write","gate:read"],governance_reviewer:["project:read","risk:read","gate:evaluate","gate:review","report:export","audit:read"],legal_ethics_reviewer:["project:read","risk:read","mitigation:write","gate:review","report:export","audit:read"],integration_admin:["project:read","integration:read","integration:manage","integration:sync","oauth:manage","audit:read"],viewer:["project:read","risk:read","gate:read","integration:read","report:export"],consultant:["workspace:manage","project:read","project:write","risk:read","risk:write","mitigation:write","gate:evaluate","gate:review","report:export","audit:read"]};function c(a){return Array.isArray(a)?Array.from(new Set(a.filter(Boolean))):b[a]?b[a].slice():[]}function d(a,b){let d=c(a);return d.includes("*")||d.includes(b)}function e(a,b){return!!a&&"ACTIVE"===a.status&&(!a.workspaceScope||0===a.workspaceScope.length||a.workspaceScope.includes(b))}a.exports={PERMISSIONS:["organization:manage","workspace:manage","project:read","project:write","risk:read","risk:write","risk:delete","mitigation:write","gate:read","gate:evaluate","gate:review","report:export","integration:read","integration:manage","integration:sync","oauth:manage","billing:manage","audit:read"],ROLE_PERMISSIONS:b,resolvePermissions:c,hasPermission:d,assertPermission:function(a,b){if(!d(a,b)){let a=Error(`Permission denied: ${b}`);throw a.status=403,a}},canAccessWorkspace:e,canMutateRisk:function(a){return e(a,"workspace-a")&&d(a.permissions||a.role?.permissions,"risk:write")}}},5736:(a,b,c)=>{"use strict";a.exports=c(4870)},6487:()=>{},7964:(a,b,c)=>{"use strict";let{PrismaClient:d}=c(6330);a.exports={prisma:globalThis.__cosmicPrisma||new d}},8335:()=>{}};