# Design + Stima — Moduli "Audit Interni" (9.2) e "Riesame di Direzione" (9.3) > Proposta progettuale (NON ancora implementata) · 2026-06-17 · obiettivo: chiudere i 2 gap gestionali > emersi dalla valutazione ISO 27001 (`docs/Agile 27000/VALUTAZIONE_COPERTURA_NIS2AGILE_vs_ISO27001.md`) > e rendere NIS2 Agile **audit-ready end-to-end sul lato SGSI** (clausole 4–10 complete). > Vale anche per NIS2: il riesame periodico e gli audit interni sono buona prassi di governance (GV.PO-02/DE). ## Perché questi due La valutazione ha mostrato che il software copre bene SoA, rischi, NC/CAPA, formazione, asset, evidenze e audit-trail, ma lascia scoperti due **output formali** che l'auditor chiede sempre: - **9.2 Audit interni** — manca il ciclo programma → checklist → report. - **9.3 Riesame di direzione** — il software pianifica la scadenza (`review_schedule`) ma non produce il **verbale** con input/output. Entrambi sono **gestionali** (non controlli tecnici), quindi pienamente realizzabili in-app. --- ## MODULO A — Audit Interni (ISO 27001 §9.2) ### Cosa deve produrre (richiesta auditor) Procedura audit interni (documento) + **programma** annuale + **checklist** di conduzione + **report** con esiti, il tutto come **registrazioni** tracciate. Le non conformità rilevate confluiscono nel modulo NC/CAPA esistente. ### Modello dati (mig.055, additivo, runner-safe) - **`internal_audits`**: id, organization_id, code (AUD-NNN), title, scope (TEXT), criteria (TEXT: es. "ISO 27001:2022 cl.4-10 + Annex A"), planned_date, executed_date, status ENUM('planned','in_progress','completed','cancelled'), lead_auditor_user_id NULL, lead_auditor_role_id NULL (org_roles), conclusion TEXT, created_by, ts. - **`internal_audit_items`** (checklist): id, audit_id FK CASCADE, ref_type ENUM('clause','annex_control','nis2_measure','custom'), ref_code VARCHAR (es. '9.2', 'A.8.13', 'ID.AM-01'), checkpoint TEXT, result ENUM('conforme','non_conforme','osservazione','opportunita','non_applicabile','da_verificare') DEFAULT 'da_verificare', note TEXT, ord INT. - Riuso: **evidenze** su `evidence_files` (entity_type='internal_audit'); **finding NC** → crea riga `non_conformities` con `source_entity_type='internal_audit_item'` + `source_entity_id` (polimorfico già esistente, `004`); **calendario** → riga `review_schedule` (estendo ENUM con `internal_audit`). ### Seed checklist (valore chiave: "checklist pronta") Al `create` di un audit con criteria ISO, **pre-popolare gli item** da: - clausole 4–10 (28 punti) — lista statica in config, - controlli Annex A applicabili dal **SoA dell'org** (`isms_soa` dove applicable=1) — riuso del dataset `038`. Così l'auditor interno parte con la checklist già compilabile, non da foglio bianco. ### Endpoint — `InternalAuditController` (slug `internal-audits`) - `GET list` · `GET {id}` (con item) · `POST create` (genera code + seed checklist) · `PUT {id}` · `DELETE {id}` - `GET {id}/items` · `PUT {id}/items/{subId}` (esito/note) · `POST {id}/items` (item custom) - `POST {id}/items/{subId}/raise-ncr` (finding → NC/CAPA) - `GET {id}/report` (report HTML stampabile via ReportService) - Ruoli scrittura: `org_admin`/`compliance_manager`/`auditor`. Anti-IDOR + audit log (hash-chain). ### Frontend — `internal-audits.html` Lista programma (con stato/scadenza dal calendario) + dettaglio audit: intestazione (scope/criteri/auditor), **checklist** raggruppata per area (clausole / Annex A / NIS2) con esito per riga, pulsante "apri NC" sui non-conformi, **export report**. Voce sidebar in `common-bi.js` + `common.js` (sezione Audit & Report o Gestione). Help/i18n/KB. --- ## MODULO B — Riesame di Direzione (ISO 27001 §9.3) ### Cosa deve produrre Il **verbale** del riesame, ad intervalli pianificati, con **INPUT** e **OUTPUT** previsti dalla norma. Punto di forza possibile: **aggregare automaticamente gli input** dai moduli esistenti (enorme risparmio + coerenza). ### Modello dati (mig.056, additivo) - **`management_reviews`**: id, organization_id, code (RD-AAAA-NN), review_date, period_label, chair_user_id, attendees (JSON), status ENUM('draft','approved'), approved_by NULL, approved_at NULL, snapshot (JSON: gli input aggregati congelati al momento del verbale), conclusions TEXT, created_by, ts. - **`management_review_decisions`**: id, review_id FK CASCADE, decision TEXT, owner_role_id NULL, due_date NULL, status ENUM('open','in_progress','done'), capa_id NULL (link a `capa_actions` se diventa azione), ord. - Riuso: decisioni con scadenza → riga `review_schedule` e/o `capa_actions`; export via **ReportService**; immutabilità via audit-log all'`approve`. ### Aggregazione automatica degli input (il valore vero) `GET /api/management-reviews/gather` raccoglie e propone (l'utente rivede/edita prima di congelare nello `snapshot`): 1. stato azioni dal riesame precedente (`management_review_decisions` + CAPA); 2. cambiamenti contesto/parti interessate (ISMS context + stakeholder); 3. **risultati audit interni** (Modulo A); 4. stato NC/azioni correttive (`non_conformities`/`capa_actions`); 5. risultati monitoraggio/KPI (dashboard score, SoA `implementation_pct`); 6. raggiungimento **obiettivi** SGSI (`isms_objectives`); 7. risultati valutazione rischi e stato trattamento (Risk + treatments); 8. feedback parti interessate (attività stakeholder/feedback); 9. aggiornamenti normativi e ACK (`normative_*`); 10. opportunità di miglioramento. **OUTPUT**: decisioni → diventano azioni (CAPA) e/o scadenze (calendario). ### Endpoint — `ManagementReviewController` (slug `management-reviews`) - `GET list` · `GET {id}` · `POST create` · `PUT {id}` · `GET gather` (input aggregati) · `POST {id}/decisions` · `PUT {id}/decisions/{subId}` · `POST {id}/approve` (congela snapshot + audit log) · `GET {id}/report` (verbale stampabile). - Ruoli: `org_admin`/`compliance_manager` (approve: `org_admin`). ### Frontend — `management-review.html` Form/wizard del verbale: sezioni INPUT pre-compilate da `gather` (editabili), tabella DECISIONI (con owner/scadenza→calendario), stato draft→approvato, **export verbale**. Sidebar + help/i18n/KB. --- ## Integrazione e principi - **Config-driven** dove sensato (checklist clausole 4–10 in config/JSON di sistema; controlli da SoA org). - Riuso massimo: NC/CAPA, review_schedule (ENUM += `internal_audit`, `management_review`), evidence_files, ReportService, AuditService (hash-chain), ISMS SoA/objectives, dashboard score. - Convenzioni note: migrazioni runner-safe (CREATE IF NOT EXISTS + FK inline), deploy via host SSH + **reload php-fpm host** (il prod gira su fpm host), cache-buster, version bump, smoke su org 151 con cleanup, giro help/i18n/KB. - Chiude i gap **#1 e #2** della valutazione; gli altri (#3 A.8 tecnici, #4 A.7 fisici, #5 KPI/6.3) restano per natura fuori software (resta lo slot SoA+evidenza). ## Fasi e stima (riferimento: C5.1/C5.2a già fatti, complessità simile) | Fase | Contenuto | Stima | |---|---|---| | **A1** | mig.055 + InternalAuditController + seed checklist + router/api | ~0,5 sessione | | **A2** | `internal-audits.html` (programma+checklist+report) + sidebar/help/i18n/KB + deploy+smoke | ~0,5 sessione | | **B1** | mig.056 + ManagementReviewController + `gather` (aggregazione input) + router/api | ~0,5–1 sessione (il `gather` è il pezzo ricco) | | **B2** | `management-review.html` (verbale + decisioni + export) + sidebar/help/i18n/KB + deploy+smoke | ~0,5 sessione | | **V** | verifica flotta multi-agente + correzioni + doc | ~0,5 sessione | | **Totale** | due moduli completi, deployati, collaudati | **~2,5–3 sessioni** | Ogni fase è committata+pushata e LIVE in autonomia (1 sola istanza L1). Prossima migrazione libera: **055**. ## Esito atteso Con questi due moduli l'auditor ISO troverebbe in-app: SoA, rischi, NC/CAPA, formazione, asset, evidenze, **programma+report audit interni** e **verbale del riesame** — cioè **tutte le registrazioni gestionali delle clausole 4–10**. Resterebbe solo da dimostrare i controlli tecnici A.7/A.8 sull'infrastruttura reale (non delegabili ad alcun software).