Files
nis2-agile/docs/DESIGN_AUDIT_INTERNI_RIESAME_DIREZIONE.md
T

155 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).
---
# MODULO C — Calendario unico delle scadenze (richiesta utente 2026-06-17)
## Obiettivo
Una **vista calendario unica** che raccoglie **ogni scadenza** del sistema in un solo posto (griglia mensile + lista + filtri), con stato (in ritardo / in scadenza / futura) e link diretto all'elemento. Oggi le scadenze sono sparse in molti moduli e aggregate solo in parte (dashboard "prossime scadenze" a 30 gg + Scadenziario revisioni periodiche): manca la vista d'insieme completa.
## Analisi — sorgenti di scadenza già presenti (verificate nel codice/DB)
| Sorgente | Campo data | Modulo |
|---|---|---|
| Incidenti Art.23 | `early_warning_due` / `notification_due` / `final_report_due` (calcolati) | incidents |
| Revisione policy/procedure | `policies.next_review_date` | Policy |
| Trattamenti rischio | `risk_treatments.due_date` | Rischi |
| Revisione controlli | `compliance_controls.next_review_date` | Audit/Controlli |
| Non conformità / azioni | `non_conformities.target_close_date`, `capa_actions.due_date` | NCR/CAPA |
| Formazione | `training_assignments.due_date` | Formazione |
| Attività stakeholder | `stk_activities.due_date` / `planned_date` | Stakeholder (C5) |
| Scadenziario revisioni | `review_schedule.next_review_date` (ricorrenti) | Scadenziario (A4 4.4) |
| **Audit interni** (nuovo) | `internal_audits.planned_date` | Modulo A |
| **Decisioni riesame** (nuovo) | `management_review_decisions.due_date` | Modulo B |
Esistente da riusare: `DashboardController::deadlines` (union incidenti/policy/trattamenti/formazione a 30 gg) — ne generalizzo il pattern. `review_schedule` resta per le revisioni **ricorrenti** (ha `frequency_months`); il calendario lo **include** come una delle sorgenti.
## Decisione architetturale — aggregatore READ-ONLY (nessuna tabella nuova)
Le scadenze **vivono già** nei moduli sorgente, ciascuna col proprio ciclo di vita: duplicarle in una tabella calendario creerebbe disallineamenti. Quindi: **endpoint aggregatore in sola lettura** che fa UNION live di tutte le sorgenti e normalizza gli eventi. **Niente migrazione** per il calendario (mig. solo per A/B). Vantaggi: sempre coerente, additivo, zero rischio dato.
### Endpoint — `CalendarController` (slug `calendar`)
- `GET /api/calendar/events?from=YYYY-MM-DD&to=YYYY-MM-DD&types=...` → lista eventi normalizzati:
`{ source, type, title, date, status (overdue|due_soon|upcoming|done), severity, entity_type, entity_id, link }`.
org-scoped, anti-IDOR (filtro `organization_id` su ogni sorgente), stato calcolato live (come `review_schedule`).
- `GET /api/calendar/summary` → conteggi per stato/tipo (per badge dashboard).
- Riusa/centralizza la logica di `DashboardController::deadlines` (che può poi delegare a questo).
- Sola lettura → `requireOrgAccess()`.
### Frontend — `calendario.html`
- **Griglia mensile** (HTML/CSS puro, dependency-free) con pallini colorati per tipo + navigazione mese prec./succ.; **vista lista** alternativa (ordinata per data, in ritardo in cima); **filtri** per tipo (incidenti, policy, rischi, formazione, NC/CAPA, stakeholder, audit, riesame, revisioni) e per stato.
- Click su evento → deep-link al modulo sorgente (es. incidente, policy, audit…).
- Legenda + badge "in ritardo / in scadenza". Voce sidebar ("Calendario") in `common-bi.js`+`common.js`; help/i18n/KB.
- La dashboard mostra già "prossime scadenze": aggiungere un link "Apri calendario".
## Ancoraggio
Strumento operativo trasversale; supporta direttamente la **buona prassi** di monitoraggio scadenze e revisioni periodiche (ISO 9.1/9.3, NIS2 GV.PO-02/GV.SC-07/DE.CM). Non è un obbligo specifico: è gestione.
## Stima Modulo C
| Fase | Contenuto | Stima |
|---|---|---|
| **C1** | `CalendarController` (aggregatore union tutte le sorgenti + summary) + router/api | ~0,5 sessione |
| **C2** | `calendario.html` (griglia mensile + lista + filtri + deep-link) + sidebar/help/i18n/KB + deploy+smoke | ~0,5–1 sessione |
**Nessuna migrazione** per C (solo lettura). Le scadenze di A e B vi confluiscono automaticamente.
## Stima complessiva aggiornata (A + B + C)
- Modulo A (Audit interni): ~1 sessione · Modulo B (Riesame): ~1–1,5 · Modulo C (Calendario): ~1 · Verifica flotta finale: ~0,5.
- **Totale ~3,5–4 sessioni**, tutto additivo/runner-safe, committato e LIVE a fasi.
## Ordine consigliato
**A → B → C**: il calendario (C) per ultimo così ingloba subito anche le scadenze di Audit interni e Riesame. In alternativa C si può fare per primo come quick-win trasversale (aggrega già tutto l'esistente) e poi A/B vi si agganciano.