-- ============================================================================ -- 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;