diff --git a/application/controllers/FrameworkController.php b/application/controllers/FrameworkController.php
new file mode 100644
index 0000000..efc1172
--- /dev/null
+++ b/application/controllers/FrameworkController.php
@@ -0,0 +1,104 @@
+requireAuth();
+
+ // Classe del soggetto (per evidenziare/spegnere le righe) — opzionale.
+ $orgClass = null;
+ $orgId = $this->getCurrentOrgId();
+ if ($orgId) {
+ $row = Database::fetchOne('SELECT entity_type FROM organizations WHERE id = ?', [$orgId]);
+ $orgClass = $row['entity_type'] ?? null; // essential | important | not_applicable
+ }
+
+ $ambiti = Database::fetchAll(
+ 'SELECT nist_code, nist_descr FROM cfg_nis2_ambiti ORDER BY nist_code ASC'
+ );
+
+ $misure = Database::fetchAll(
+ 'SELECT misura_code, nist_code, area_politica, misura_descr, ord,
+ applies_important, applies_essential
+ FROM cfg_nis2_misure
+ ORDER BY ord ASC'
+ );
+
+ $reqs = Database::fetchAll(
+ 'SELECT q.n, q.misura_code, q.requisito_code, q.requisito_descr,
+ q.proc_code, p.proc_descr, q.risk_code, r.risk_descr,
+ q.applies_important, q.applies_essential
+ FROM cfg_nis2_requisiti q
+ LEFT JOIN cfg_nis2_procedure p ON p.proc_code = q.proc_code
+ LEFT JOIN cfg_nis2_rischi r ON r.risk_code = q.risk_code
+ ORDER BY q.n ASC, q.id ASC'
+ );
+
+ $byMis = [];
+ foreach ($reqs as $q) {
+ $byMis[$q['misura_code']][] = [
+ 'n' => $q['n'] !== null ? (int) $q['n'] : null,
+ 'requisito_code' => $q['requisito_code'],
+ 'requisito_descr' => $q['requisito_descr'],
+ 'proc_code' => $q['proc_code'],
+ 'proc_descr' => $q['proc_descr'],
+ 'risk_code' => $q['risk_code'],
+ 'risk_descr' => $q['risk_descr'],
+ 'applies_important' => (int) $q['applies_important'],
+ 'applies_essential' => (int) $q['applies_essential'],
+ ];
+ }
+
+ $measures = [];
+ foreach ($misure as $m) {
+ $measures[] = [
+ 'misura_code' => $m['misura_code'],
+ 'nist_code' => $m['nist_code'],
+ 'area_politica' => $m['area_politica'],
+ 'misura_descr' => $m['misura_descr'],
+ 'ord' => (int) $m['ord'],
+ 'applies_important' => (int) $m['applies_important'],
+ 'applies_essential' => (int) $m['applies_essential'],
+ 'requisiti' => $byMis[$m['misura_code']] ?? [],
+ ];
+ }
+
+ $this->jsonSuccess([
+ 'org_class' => $orgClass,
+ 'ambiti' => $ambiti,
+ 'measures' => $measures,
+ 'totals' => ['misure' => count($measures), 'requisiti' => count($reqs)],
+ 'readonly' => true,
+ 'source' => 'Determinazione ACN n. 164179 del 14 aprile 2025',
+ ]);
+ }
+}
diff --git a/docs/simon/C1_Misure_Requisiti.xlsx b/docs/simon/C1_Misure_Requisiti.xlsx
new file mode 100644
index 0000000..7eb644b
Binary files /dev/null and b/docs/simon/C1_Misure_Requisiti.xlsx differ
diff --git a/docs/simon/C1_Vista_MisureRequisiti.xlsx b/docs/simon/C1_Vista_MisureRequisiti.xlsx
new file mode 100644
index 0000000..8c77b8f
Binary files /dev/null and b/docs/simon/C1_Vista_MisureRequisiti.xlsx differ
diff --git a/docs/simon/C5_EleStakeH.xlsx b/docs/simon/C5_EleStakeH.xlsx
new file mode 100644
index 0000000..a780e69
Binary files /dev/null and b/docs/simon/C5_EleStakeH.xlsx differ
diff --git a/public/_app-bi-demo.html b/public/_app-bi-demo.html
index 28ef554..1f847dc 100644
--- a/public/_app-bi-demo.html
+++ b/public/_app-bi-demo.html
@@ -70,8 +70,8 @@
-
-
+
+
-
+
+
@@ -164,8 +164,8 @@
}
-
-
+
+
-
-
-
+
+
+
+
-
+
+
@@ -166,8 +166,8 @@
}
-
-
+
+
-
+
+
@@ -378,8 +378,8 @@
}
-
-
+
+
-
+
+
-
-
+
+
-
+
+
-
-
+
+