nis2-agile/docs/sql/036_acn_gap_assessment.sql
DevEnv nis2-agile ea2a291325 [FEAT] Gap Analysis ACN: assessment misure/requisiti Det. 164179/2025 (backend)
Assessment di SECONDO LIVELLO sulla Determinazione ACN 164179/2025 (non le 10
lettere generiche Art.21, gia coperte). Distingue soggetti importanti/essenziali:
- IMPORTANTI (All.1): 37 misure, 87 requisiti
- ESSENZIALI (All.2): 43 misure, 116 requisiti

- application/data/acn_measures.json: dataset canonico estratto dai testi
  UFFICIALI ACN (Allegati 1+2), testi requisiti INTEGRALI (no troncamenti),
  flag per-requisito importante/essenziale. Validato 37/87 + 43/116, zero
  discrepanze vs codici di riferimento.
- AcnAssessmentController: catalog/list/create/get/requirements/respond/complete/
  report/aiAnalyze. Pre-popola requisiti applicabili per entity_level, scoring
  per funzione FW (GOVERN/IDENTIFY/PROTECT/DETECT/RESPOND/RECOVER), grounding AI
  sui 203 requisiti ACN gia in KB. Anti-IDOR, snapshot testo immutabile.
- Migrazione 036: acn_assessments + acn_assessment_responses (APPLICATA su host).
- Router: acn-gap controllerMap + actionMap.

Origine: finding revisore (la Gap Analysis Art.21 non e l'autovalutazione ACN).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 08:02:59 +02:00

77 lines
4.1 KiB
SQL

-- ============================================================================
-- Migration 036 - Gap Analysis ACN (Determinazione 164179/2025, Allegati 1 e 2)
-- ----------------------------------------------------------------------------
-- Aggiunge l'assessment di conformita di SECONDO LIVELLO: non le 10 lettere
-- generiche dell'Art. 21 NIS2 (gia coperte da assessments/assessment_responses),
-- ma le MISURE e i REQUISITI puntuali della Determinazione ACN n. 164179/2025:
-- - soggetti IMPORTANTI (Allegato 1): 37 misure, 87 requisiti
-- - soggetti ESSENZIALI (Allegato 2): 43 misure, 116 requisiti (= 87 + 29)
--
-- La codifica dei requisiti e IDENTICA per importanti ed essenziali (stessi
-- codici GV/ID/PR/DE/RS/RC); agli essenziali si aggiungono misure e punti.
-- L'app filtra i requisiti applicabili in base a organizations.entity_type.
--
-- Fonte testi: application/data/acn_measures.json (estratto integrale dagli
-- Allegati ufficiali ACN). Nessuna tabella esistente modificata.
--
-- IDEMPOTENTE: CREATE TABLE IF NOT EXISTS. Applicare su host MySQL
-- (mysql -h localhost nis2_agile_db), NON docker exec nis2-db.
-- STATO: APPLICATA su host 2026-06-01 (entrambe le tabelle verificate).
-- ============================================================================
-- Intestazione assessment ACN (una riga per ciclo di valutazione).
CREATE TABLE IF NOT EXISTS acn_assessments (
id INT AUTO_INCREMENT PRIMARY KEY,
organization_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
-- livello soggetto al momento della creazione: determina il perimetro
-- dei requisiti applicabili (importante=87, essenziale=116).
entity_level ENUM('important','essential') NOT NULL,
status ENUM('draft','in_progress','completed') DEFAULT 'draft',
-- punteggio complessivo 0-100 (media pesata requisiti applicabili)
overall_score DECIMAL(5,2) NULL,
-- punteggi per funzione FW (GOVERN/IDENTIFY/PROTECT/DETECT/RESPOND/RECOVER) JSON
function_scores JSON NULL,
-- conteggi sintetici: applicabili / conformi / parziali / non conformi / n.a.
stats JSON NULL,
ai_summary TEXT NULL,
ai_recommendations JSON NULL,
completed_by INT NULL,
completed_at DATETIME NULL,
created_by INT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
FOREIGN KEY (completed_by) REFERENCES users(id) ON DELETE SET NULL,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_acn_org (organization_id),
INDEX idx_acn_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Risposta per singolo REQUISITO ACN (granularita: misura.punto).
CREATE TABLE IF NOT EXISTS acn_assessment_responses (
id INT AUTO_INCREMENT PRIMARY KEY,
assessment_id INT NOT NULL,
organization_id INT NOT NULL,
-- chiave requisito: codice misura + indice punto, es. "GV.RR-04#4"
requirement_key VARCHAR(40) NOT NULL,
measure_code VARCHAR(20) NOT NULL, -- es. GV.RR-04
requirement_index INT NOT NULL, -- es. 4
function_code VARCHAR(12) NOT NULL, -- GOVERN/IDENTIFY/PROTECT/DETECT/RESPOND/RECOVER
category_code VARCHAR(12) NOT NULL, -- es. GV.RR
-- snapshot del testo requisito al momento della compilazione (immutabilita)
requirement_text TEXT NULL,
response_value ENUM('not_implemented','partial','implemented','not_applicable') NULL,
evidence_description TEXT NULL,
notes TEXT NULL,
answered_by INT NULL,
answered_at DATETIME NULL,
FOREIGN KEY (assessment_id) REFERENCES acn_assessments(id) ON DELETE CASCADE,
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
FOREIGN KEY (answered_by) REFERENCES users(id) ON DELETE SET NULL,
UNIQUE KEY uk_acn_assessment_req (assessment_id, requirement_key),
INDEX idx_acn_resp_assessment (assessment_id),
INDEX idx_acn_resp_measure (measure_code),
INDEX idx_acn_resp_function (function_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;