/home/techb158/cosmic.abdallabala.com/src/domain
Edit: /home/techb158/cosmic.abdallabala.com/src/domain/dataMapper.js (6745B)
const { list, findById } = require("../storage/jsonDatabase.js");
function average(values) {
const nums = values.map(Number).filter(Number.isFinite);
if (!nums.length) return 0;
return Math.round(nums.reduce((sum, value) => sum + value, 0) / nums.length);
}
function metricStatus(value, threshold, higherIsBetter = true) {
if (threshold === null || threshold === undefined) return "Pass";
if (higherIsBetter) {
if (value >= threshold) return "Pass";
if (value >= threshold * 0.9) return "Warning";
return "Fail";
}
if (value <= threshold) return "Pass";
if (value <= threshold * 1.1) return "Warning";
return "Fail";
}
function toExperimentView(database, experiment) {
const metrics = list(database, "model_metrics", metric => metric.experiment_id === experiment.id);
const metricValue = name => {
const metric = metrics.find(item => item.metric_name === name);
return metric ? metric.metric_value : null;
};
return {
id: experiment.id,
name: experiment.name,
model: experiment.model_name,
dataset: experiment.dataset_version,
accuracy: metricValue("accuracy"),
f1: metricValue("f1"),
precision: metricValue("precision"),
recall: metricValue("recall"),
auc: metricValue("auc"),
biasStatus: experiment.bias_status || "Pending",
stability: metricValue("stability") || experiment.stability_score || 0,
reproducibility: experiment.reproducibility_status,
selected: Boolean(experiment.selected),
metrics
};
}
function toMitigationView(database, mitigation) {
const risk = findById(database, "risks", mitigation.risk_id);
const evidence = list(database, "evidence_artifacts", artifact => {
return artifact.mitigation_id === mitigation.id || artifact.risk_id === mitigation.risk_id;
}).filter((artifact, index, artifacts) => {
return artifacts.findIndex(item => item.id === artifact.id) === index;
});
return {
id: mitigation.id,
riskId: mitigation.risk_id,
riskTitle: risk ? risk.title : "Unknown risk",
riskDimension: risk ? risk.dimension : "Unknown",
riskLifecyclePhase: risk ? risk.lifecycle_phase : "Unknown",
riskOwner: risk ? (risk.owner_display_name || risk.owner_user_id || "Unassigned") : "Unassigned",
owner: mitigation.owner_display_name || mitigation.owner_user_id || "Unassigned",
title: mitigation.title,
description: mitigation.description || "",
status: mitigation.status,
progress_percent: Number(mitigation.progress_percent || 0),
effectiveness_percent: Number(mitigation.effectiveness_percent || 0),
dueDate: mitigation.due_date || null,
sequence: mitigation.sequence || null,
evidenceArtifacts: evidence,
evidenceCount: evidence.length,
createdAt: mitigation.created_at || null,
updatedAt: mitigation.updated_at || null
};
}
function toRiskView(database, risk) {
const mitigations = list(database, "mitigation_actions", mitigation => mitigation.risk_id === risk.id);
const evidence = list(database, "evidence_artifacts", artifact => artifact.risk_id === risk.id);
const latestScore = list(database, "risk_scores", score => score.risk_id === risk.id)
.sort((a, b) => String(b.calculated_at).localeCompare(String(a.calculated_at)))[0];
return {
id: risk.id,
title: risk.title,
description: risk.description || "",
dimension: risk.dimension,
domain: risk.domain,
lifecyclePhase: risk.lifecycle_phase,
probability: risk.probability,
impact: risk.impact,
detectability: risk.detectability,
mitigationProgress: average(mitigations.map(item => item.progress_percent)),
mitigationEffectiveness: average(mitigations.map(item => item.effectiveness_percent)),
status: risk.status,
approvalStatus: risk.approval_status,
owner: risk.owner_display_name || risk.owner_user_id || "Unassigned",
dueDate: risk.due_date,
evidence: risk.evidence_summary || (evidence[0] ? evidence[0].title : ""),
mitigations: mitigations.map(item => item.title),
mitigationActions: mitigations.map(item => toMitigationView(database, item)),
evidenceArtifacts: evidence,
latestScore: latestScore || null
};
}
function databaseToProjectAggregate(database, projectId) {
const project = findById(database, "projects", projectId);
if (!project) return null;
const lifecycle = list(database, "lifecycle_phases", item => item.project_id === projectId)
.sort((a, b) => (a.sequence || 0) - (b.sequence || 0))
.map(item => ({
id: item.id,
name: item.name,
status: item.status,
readiness: item.readiness_score
}));
const indicators = list(database, "indicators", item => item.project_id === projectId)
.map(item => ({
id: item.id,
name: item.name,
measurand: item.measurand,
unit: item.unit,
interpretation: item.interpretation_rule,
thresholdMin: item.threshold_min,
thresholdMax: item.threshold_max,
dimension: item.dimension
}));
const risks = list(database, "risks", item => item.project_id === projectId).map(item => toRiskView(database, item));
const experiments = list(database, "experiments", item => item.project_id === projectId).map(item => toExperimentView(database, item));
const mitigations = list(database, "mitigation_actions", item => {
const risk = findById(database, "risks", item.risk_id);
return risk && risk.project_id === projectId;
}).map(item => toMitigationView(database, item));
const reviews = (database.project_reviews && database.project_reviews[projectId]) || project.reviews || {};
return {
project: {
id: project.id,
name: project.name,
subtitle: project.subtitle,
projectType: project.project_type,
lifecyclePhase: project.current_lifecycle_phase,
assessmentDate: project.assessment_date,
owner: project.owner_display_name || "AI Risk Governance Team",
riskAppetite: project.risk_appetite,
description: project.description || ""
},
sourceBasis: database.sourceBasis || {},
indicators,
lifecycle,
reviews,
experiments,
mitigations,
thresholds: project.thresholds || database.thresholds || {},
risks
};
}
function scoredRiskToScoreRecord(riskId, scoredRisk) {
return {
risk_id: riskId,
raw_score: scoredRisk.rawScore,
normalized_score: scoredRisk.normalizedScore,
residual_score: scoredRisk.residualScore,
risk_level: scoredRisk.residualSeverity === "Moderate" ? "Medium" : scoredRisk.residualSeverity,
calculated_at: new Date().toISOString()
};
}
module.exports = {
databaseToProjectAggregate,
toRiskView,
toMitigationView,
toExperimentView,
scoredRiskToScoreRecord,
metricStatus
};