[FIX] ServicesController: allineamento colonne DB reali (risk_level, contained_at, owner_name, company_name, category compliance_controls)
This commit is contained in:
parent
27ec63c28d
commit
159d783ed7
@ -855,13 +855,13 @@ class ServicesController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
// Risk summary
|
||||
// Risk summary (risk_level calcolato da inherent_risk_score: >=16 critical, >=9 high)
|
||||
$riskStats = Database::fetchOne(
|
||||
'SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN status = "open" THEN 1 ELSE 0 END) as open_count,
|
||||
SUM(CASE WHEN risk_level IN ("high","critical") AND status = "open" THEN 1 ELSE 0 END) as high_critical,
|
||||
SUM(CASE WHEN status = "mitigated" THEN 1 ELSE 0 END) as mitigated
|
||||
SUM(CASE WHEN status NOT IN ("closed") THEN 1 ELSE 0 END) as open_count,
|
||||
SUM(CASE WHEN inherent_risk_score >= 9 AND status NOT IN ("closed") THEN 1 ELSE 0 END) as high_critical,
|
||||
SUM(CASE WHEN status = "monitored" THEN 1 ELSE 0 END) as mitigated
|
||||
FROM risks WHERE organization_id = ?',
|
||||
[$orgId]
|
||||
);
|
||||
@ -870,9 +870,9 @@ class ServicesController extends BaseController
|
||||
$incidentStats = Database::fetchOne(
|
||||
'SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN status = "open" OR status = "investigating" THEN 1 ELSE 0 END) as open_count,
|
||||
SUM(CASE WHEN status NOT IN ("closed","post_mortem") THEN 1 ELSE 0 END) as open_count,
|
||||
SUM(CASE WHEN is_significant = 1 THEN 1 ELSE 0 END) as significant,
|
||||
SUM(CASE WHEN early_warning_sent = 1 THEN 1 ELSE 0 END) as notified_acn
|
||||
SUM(CASE WHEN early_warning_sent_at IS NOT NULL THEN 1 ELSE 0 END) as notified_acn
|
||||
FROM incidents WHERE organization_id = ?',
|
||||
[$orgId]
|
||||
);
|
||||
@ -944,10 +944,18 @@ class ServicesController extends BaseController
|
||||
$params = [$orgId];
|
||||
|
||||
if (!empty($_GET['level'])) {
|
||||
// risk_level è calcolato da inherent_risk_score
|
||||
$levelMap = ['critical' => 16, 'high' => 9, 'medium' => 4, 'low' => 0];
|
||||
$levels = array_filter(explode(',', $_GET['level']));
|
||||
$placeholders = implode(',', array_fill(0, count($levels), '?'));
|
||||
$where .= " AND r.risk_level IN ({$placeholders})";
|
||||
$params = array_merge($params, $levels);
|
||||
$conditions = [];
|
||||
foreach ($levels as $lv) {
|
||||
$lv = strtolower(trim($lv));
|
||||
if ($lv === 'critical') { $conditions[] = 'r.inherent_risk_score >= 16'; }
|
||||
elseif ($lv === 'high') { $conditions[] = '(r.inherent_risk_score >= 9 AND r.inherent_risk_score < 16)'; }
|
||||
elseif ($lv === 'medium') { $conditions[] = '(r.inherent_risk_score >= 4 AND r.inherent_risk_score < 9)'; }
|
||||
elseif ($lv === 'low') { $conditions[] = 'r.inherent_risk_score < 4'; }
|
||||
}
|
||||
if ($conditions) $where .= ' AND ('.implode(' OR ', $conditions).')';
|
||||
}
|
||||
|
||||
if (!empty($_GET['area'])) {
|
||||
@ -969,8 +977,12 @@ class ServicesController extends BaseController
|
||||
|
||||
$risks = Database::fetchAll(
|
||||
"SELECT r.id, r.title, r.description, r.category, r.likelihood,
|
||||
r.impact, r.inherent_risk_score, r.risk_level, r.status,
|
||||
r.treatment_plan, r.owner_name, r.residual_risk_score,
|
||||
r.impact, r.inherent_risk_score,
|
||||
CASE WHEN r.inherent_risk_score >= 16 THEN 'critical'
|
||||
WHEN r.inherent_risk_score >= 9 THEN 'high'
|
||||
WHEN r.inherent_risk_score >= 4 THEN 'medium'
|
||||
ELSE 'low' END as risk_level,
|
||||
r.status, r.treatment, r.residual_risk_score,
|
||||
r.created_at, r.updated_at
|
||||
FROM risks r
|
||||
WHERE {$where}
|
||||
@ -1035,12 +1047,10 @@ class ServicesController extends BaseController
|
||||
|
||||
$incidents = Database::fetchAll(
|
||||
"SELECT id, title, classification, severity, status, is_significant,
|
||||
detected_at, contained_at, resolved_at,
|
||||
early_warning_sent, early_warning_sent_at,
|
||||
notification_sent, notification_sent_at,
|
||||
final_report_sent, final_report_sent_at,
|
||||
notification_deadline, final_report_deadline,
|
||||
affected_systems, impact_description,
|
||||
detected_at, closed_at,
|
||||
early_warning_sent_at, notification_sent_at, final_report_sent_at,
|
||||
early_warning_due, notification_due, final_report_due,
|
||||
affected_services, root_cause,
|
||||
created_at, updated_at
|
||||
FROM incidents
|
||||
WHERE {$where}
|
||||
@ -1057,20 +1067,20 @@ class ServicesController extends BaseController
|
||||
'early_warning_24h' => [
|
||||
'required' => (bool)$inc['is_significant'],
|
||||
'deadline' => date('c', $detectedTs + 86400),
|
||||
'sent' => (bool)$inc['early_warning_sent'],
|
||||
'overdue' => !$inc['early_warning_sent'] && $now > $detectedTs + 86400,
|
||||
'sent' => $inc['early_warning_sent_at'] !== null,
|
||||
'overdue' => !$inc['early_warning_sent_at'] && $now > $detectedTs + 86400,
|
||||
],
|
||||
'notification_72h' => [
|
||||
'required' => (bool)$inc['is_significant'],
|
||||
'deadline' => date('c', $detectedTs + 259200),
|
||||
'sent' => (bool)$inc['notification_sent'],
|
||||
'overdue' => !$inc['notification_sent'] && $now > $detectedTs + 259200,
|
||||
'sent' => $inc['notification_sent_at'] !== null,
|
||||
'overdue' => !$inc['notification_sent_at'] && $now > $detectedTs + 259200,
|
||||
],
|
||||
'final_report_30d' => [
|
||||
'required' => (bool)$inc['is_significant'],
|
||||
'deadline' => date('c', $detectedTs + 2592000),
|
||||
'sent' => (bool)$inc['final_report_sent'],
|
||||
'overdue' => !$inc['final_report_sent'] && $now > $detectedTs + 2592000,
|
||||
'sent' => $inc['final_report_sent_at'] !== null,
|
||||
'overdue' => !$inc['final_report_sent_at'] && $now > $detectedTs + 2592000,
|
||||
],
|
||||
];
|
||||
}
|
||||
@ -1099,28 +1109,28 @@ class ServicesController extends BaseController
|
||||
$orgId = $this->currentOrgId;
|
||||
|
||||
$controls = Database::fetchAll(
|
||||
'SELECT id, control_code, title, category, status,
|
||||
implementation_notes, due_date, updated_at
|
||||
'SELECT id, control_code, title, framework, status,
|
||||
implementation_percentage, evidence_description, next_review_date, updated_at
|
||||
FROM compliance_controls
|
||||
WHERE organization_id = ?
|
||||
ORDER BY category, control_code',
|
||||
ORDER BY framework, control_code',
|
||||
[$orgId]
|
||||
);
|
||||
|
||||
// Raggruppa per categoria
|
||||
// Raggruppa per framework
|
||||
$byCategory = [];
|
||||
foreach ($controls as $ctrl) {
|
||||
$cat = $ctrl['category'] ?? 'uncategorized';
|
||||
$cat = $ctrl['framework'] ?? 'nis2';
|
||||
if (!isset($byCategory[$cat])) {
|
||||
$byCategory[$cat] = [
|
||||
'category' => $cat,
|
||||
'controls' => [],
|
||||
'stats' => ['total' => 0, 'implemented' => 0, 'partial' => 0, 'planned' => 0, 'not_applicable' => 0],
|
||||
'stats' => ['total' => 0, 'implemented' => 0, 'in_progress' => 0, 'not_started' => 0, 'verified' => 0],
|
||||
];
|
||||
}
|
||||
$byCategory[$cat]['controls'][] = $ctrl;
|
||||
$byCategory[$cat]['stats']['total']++;
|
||||
$s = $ctrl['status'] ?? 'not_applicable';
|
||||
$s = $ctrl['status'] ?? 'not_started';
|
||||
if (isset($byCategory[$cat]['stats'][$s])) {
|
||||
$byCategory[$cat]['stats'][$s]++;
|
||||
}
|
||||
@ -1129,25 +1139,26 @@ class ServicesController extends BaseController
|
||||
// Score per categoria
|
||||
foreach ($byCategory as &$cat) {
|
||||
$t = $cat['stats']['total'];
|
||||
$i = $cat['stats']['implemented'];
|
||||
$p = $cat['stats']['partial'];
|
||||
$i = $cat['stats']['implemented'] + ($cat['stats']['verified'] ?? 0);
|
||||
$p = $cat['stats']['in_progress'] ?? 0;
|
||||
$cat['score'] = $t > 0 ? round((($i + $p * 0.5) / $t) * 100) : 0;
|
||||
}
|
||||
unset($cat);
|
||||
|
||||
$totals = [
|
||||
'total' => count($controls),
|
||||
'implemented' => 0,
|
||||
'partial' => 0,
|
||||
'planned' => 0,
|
||||
'not_applicable' => 0,
|
||||
'total' => count($controls),
|
||||
'implemented' => 0,
|
||||
'verified' => 0,
|
||||
'in_progress' => 0,
|
||||
'not_started' => 0,
|
||||
];
|
||||
foreach ($controls as $ctrl) {
|
||||
$s = $ctrl['status'] ?? 'not_applicable';
|
||||
$s = $ctrl['status'] ?? 'not_started';
|
||||
if (isset($totals[$s])) $totals[$s]++;
|
||||
}
|
||||
$done = $totals['implemented'] + $totals['verified'];
|
||||
$totals['overall_score'] = $totals['total'] > 0
|
||||
? round((($totals['implemented'] + $totals['partial'] * 0.5) / $totals['total']) * 100)
|
||||
? round((($done + $totals['in_progress'] * 0.5) / $totals['total']) * 100)
|
||||
: 0;
|
||||
|
||||
$this->jsonSuccess([
|
||||
@ -1191,7 +1202,7 @@ class ServicesController extends BaseController
|
||||
|
||||
$assets = Database::fetchAll(
|
||||
"SELECT id, name, asset_type, criticality, status,
|
||||
owner_name, location, ip_address, description,
|
||||
owner_user_id, location, ip_address, description,
|
||||
dependencies, created_at
|
||||
FROM assets
|
||||
WHERE {$where}
|
||||
@ -1222,10 +1233,17 @@ class ServicesController extends BaseController
|
||||
$params = [$orgId];
|
||||
|
||||
if (!empty($_GET['risk_level'])) {
|
||||
// risk_score: 0-100, mappa high=>=60, critical=>=80
|
||||
$levels = array_filter(explode(',', $_GET['risk_level']));
|
||||
$ph = implode(',', array_fill(0, count($levels), '?'));
|
||||
$where .= " AND s.risk_level IN ({$ph})";
|
||||
$params = array_merge($params, $levels);
|
||||
$conditions = [];
|
||||
foreach ($levels as $lv) {
|
||||
$lv = strtolower(trim($lv));
|
||||
if ($lv === 'critical') { $conditions[] = 's.risk_score >= 80'; }
|
||||
elseif ($lv === 'high') { $conditions[] = '(s.risk_score >= 60 AND s.risk_score < 80)'; }
|
||||
elseif ($lv === 'medium') { $conditions[] = '(s.risk_score >= 30 AND s.risk_score < 60)'; }
|
||||
elseif ($lv === 'low') { $conditions[] = 's.risk_score < 30'; }
|
||||
}
|
||||
if ($conditions) $where .= ' AND ('.implode(' OR ', $conditions).')';
|
||||
}
|
||||
|
||||
if (!empty($_GET['status'])) {
|
||||
@ -1234,21 +1252,20 @@ class ServicesController extends BaseController
|
||||
}
|
||||
|
||||
$suppliers = Database::fetchAll(
|
||||
"SELECT s.id, s.company_name, s.category, s.risk_level, s.status,
|
||||
s.last_assessment_date, s.assessment_score, s.contact_email,
|
||||
s.services_provided, s.critical_dependency,
|
||||
"SELECT s.id, s.name, s.service_type, s.criticality, s.risk_score, s.status,
|
||||
s.last_assessment_date, s.contact_email,
|
||||
s.created_at, s.updated_at
|
||||
FROM suppliers s
|
||||
WHERE {$where}
|
||||
ORDER BY FIELD(s.risk_level,'critical','high','medium','low'), s.company_name",
|
||||
ORDER BY FIELD(s.criticality,'critical','high','medium','low'), s.risk_score DESC, s.name",
|
||||
$params
|
||||
);
|
||||
|
||||
$stats = Database::fetchOne(
|
||||
"SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN risk_level IN ('high','critical') AND deleted_at IS NULL THEN 1 ELSE 0 END) as high_risk,
|
||||
SUM(CASE WHEN critical_dependency = 1 AND deleted_at IS NULL THEN 1 ELSE 0 END) as critical_deps,
|
||||
SUM(CASE WHEN risk_score >= 60 AND deleted_at IS NULL THEN 1 ELSE 0 END) as high_risk,
|
||||
SUM(CASE WHEN criticality IN ('critical','high') AND deleted_at IS NULL THEN 1 ELSE 0 END) as critical_deps,
|
||||
SUM(CASE WHEN last_assessment_date IS NULL AND deleted_at IS NULL THEN 1 ELSE 0 END) as unassessed
|
||||
FROM suppliers WHERE organization_id = ?",
|
||||
[$orgId]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user