/home/techb158/cosmic.abdallabala.com/src/repositories
Edit: /home/techb158/cosmic.abdallabala.com/src/repositories/riskRepository.js (8994B)
const {
list,
findById,
insert,
update,
remove,
audit
} = require("../storage/jsonDatabase.js");
const {
validateRiskInput,
validateRiskPatch,
validateMitigationInput,
validateMitigationPatch
} = require("../domain/validation.js");
const { toRiskView, toMitigationView } = require("../domain/dataMapper.js");
class RiskRepository {
constructor(database) {
this.database = database;
}
listRisks(projectId) {
const db = this.database.read();
return list(db, "risks", risk => risk.project_id === projectId).map(risk => toRiskView(db, risk));
}
getRisk(riskId) {
const db = this.database.read();
const risk = findById(db, "risks", riskId);
return risk ? toRiskView(db, risk) : null;
}
createRisk(projectId, payload, actorUserId = "system") {
const input = validateRiskInput(payload);
return this.database.transaction(db => {
if (!findById(db, "projects", projectId)) throw new Error(`Project not found: ${projectId}`);
const risk = insert(db, "risks", Object.assign({}, input, {
project_id: projectId,
owner_user_id: payload.owner_user_id || null
}), "RISK");
const mitigationItems = Array.isArray(payload.mitigations) ? payload.mitigations : [];
mitigationItems.forEach((item, index) => {
const title = typeof item === "string" ? item : item.title;
if (!title) return;
insert(db, "mitigation_actions", {
risk_id: risk.id,
owner_user_id: null,
owner_display_name: input.owner_display_name,
title,
description: typeof item === "object" ? item.description || "" : "",
status: typeof item === "object" ? item.status || "Not started" : "Not started",
progress_percent: typeof item === "object" && item.progress_percent !== undefined ? Number(item.progress_percent) : Number(payload.mitigationProgress || 0),
effectiveness_percent: typeof item === "object" && item.effectiveness_percent !== undefined ? Number(item.effectiveness_percent) : Number(payload.mitigationEffectiveness || 0),
due_date: typeof item === "object" ? item.due_date || null : null,
sequence: index + 1
}, "MIT");
});
if (input.evidence_summary) {
insert(db, "evidence_artifacts", {
project_id: projectId,
risk_id: risk.id,
mitigation_id: null,
type: "Review",
title: input.evidence_summary,
uri: payload.evidence_uri || null,
created_by_user_id: actorUserId
}, "EVD");
}
audit(db, {
project_id: projectId,
actor_user_id: actorUserId,
entity_type: "Risk",
entity_id: risk.id,
action: "create",
after_json: risk
});
return toRiskView(db, risk);
});
}
updateRisk(riskId, payload, actorUserId = "system") {
const patch = validateRiskPatch(payload);
return this.database.transaction(db => {
const before = findById(db, "risks", riskId);
if (!before) return null;
const risk = update(db, "risks", riskId, patch);
if (payload.evidence_uri || payload.evidence_title) {
insert(db, "evidence_artifacts", {
project_id: risk.project_id,
risk_id: risk.id,
mitigation_id: null,
type: payload.evidence_type || "Review",
title: payload.evidence_title || payload.evidence_uri,
uri: payload.evidence_uri || null,
created_by_user_id: actorUserId
}, "EVD");
}
audit(db, {
project_id: risk.project_id,
actor_user_id: actorUserId,
entity_type: "Risk",
entity_id: riskId,
action: "update",
before_json: before,
after_json: risk
});
return toRiskView(db, risk);
});
}
deleteRisk(riskId, actorUserId = "system") {
return this.database.transaction(db => {
const before = findById(db, "risks", riskId);
if (!before) return false;
["risk_scores", "mitigation_actions", "evidence_artifacts", "trello_mappings"].forEach(table => {
const rows = list(db, table, row => row.risk_id === riskId || row.local_entity_id === riskId);
rows.forEach(row => remove(db, table, row.id));
});
remove(db, "risks", riskId);
audit(db, {
project_id: before.project_id,
actor_user_id: actorUserId,
entity_type: "Risk",
entity_id: riskId,
action: "delete",
before_json: before
});
return true;
});
}
listMitigations(projectId) {
const db = this.database.read();
const riskIds = new Set(list(db, "risks", risk => risk.project_id === projectId).map(risk => risk.id));
return list(db, "mitigation_actions", mitigation => riskIds.has(mitigation.risk_id))
.map(mitigation => toMitigationView(db, mitigation));
}
getMitigation(mitigationId) {
const db = this.database.read();
const mitigation = findById(db, "mitigation_actions", mitigationId);
return mitigation ? toMitigationView(db, mitigation) : null;
}
createMitigation(riskId, payload, actorUserId = "system") {
const input = validateMitigationInput(payload);
return this.database.transaction(db => {
const risk = findById(db, "risks", riskId);
if (!risk) throw new Error(`Risk not found: ${riskId}`);
const mitigation = insert(db, "mitigation_actions", Object.assign({}, input, {
risk_id: riskId,
owner_user_id: payload.owner_user_id || null
}), "MIT");
this.createEvidenceRecord(db, risk.project_id, riskId, mitigation.id, payload, actorUserId);
audit(db, {
project_id: risk.project_id,
actor_user_id: actorUserId,
entity_type: "MitigationAction",
entity_id: mitigation.id,
action: "create",
after_json: mitigation
});
return toMitigationView(db, mitigation);
});
}
updateMitigation(mitigationId, payload, actorUserId = "system") {
const patch = validateMitigationPatch(payload);
return this.database.transaction(db => {
const before = findById(db, "mitigation_actions", mitigationId);
if (!before) return null;
const mitigation = update(db, "mitigation_actions", mitigationId, patch);
const risk = findById(db, "risks", mitigation.risk_id);
if (risk) {
this.createEvidenceRecord(db, risk.project_id, mitigation.risk_id, mitigation.id, payload, actorUserId);
}
audit(db, {
project_id: risk ? risk.project_id : "unknown",
actor_user_id: actorUserId,
entity_type: "MitigationAction",
entity_id: mitigationId,
action: "update",
before_json: before,
after_json: mitigation
});
return toMitigationView(db, mitigation);
});
}
deleteMitigation(mitigationId, actorUserId = "system") {
return this.database.transaction(db => {
const before = findById(db, "mitigation_actions", mitigationId);
if (!before) return false;
const risk = findById(db, "risks", before.risk_id);
const evidenceRows = list(db, "evidence_artifacts", row => row.mitigation_id === mitigationId);
evidenceRows.forEach(row => remove(db, "evidence_artifacts", row.id));
remove(db, "mitigation_actions", mitigationId);
audit(db, {
project_id: risk ? risk.project_id : "unknown",
actor_user_id: actorUserId,
entity_type: "MitigationAction",
entity_id: mitigationId,
action: "delete",
before_json: before
});
return true;
});
}
addEvidenceToMitigation(mitigationId, payload, actorUserId = "system") {
return this.database.transaction(db => {
const mitigation = findById(db, "mitigation_actions", mitigationId);
if (!mitigation) return null;
const risk = findById(db, "risks", mitigation.risk_id);
if (!risk) return null;
const evidence = this.createEvidenceRecord(db, risk.project_id, risk.id, mitigation.id, payload, actorUserId);
audit(db, {
project_id: risk.project_id,
actor_user_id: actorUserId,
entity_type: "EvidenceArtifact",
entity_id: evidence ? evidence.id : "unknown",
action: "create",
after_json: evidence
});
return evidence;
});
}
createEvidenceRecord(db, projectId, riskId, mitigationId, payload, actorUserId) {
const title = payload.evidence_title || payload.evidenceTitle || "";
const uri = payload.evidence_uri || payload.evidenceUri || "";
const type = payload.evidence_type || payload.evidenceType || "Review";
if (!title && !uri) return null;
return insert(db, "evidence_artifacts", {
project_id: projectId,
risk_id: riskId,
mitigation_id: mitigationId || null,
type,
title: title || uri,
uri: uri || null,
created_by_user_id: actorUserId
}, "EVD");
}
}
module.exports = { RiskRepository };