Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
155 lines
12 KiB
Markdown
155 lines
12 KiB
Markdown
# 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.
|