Files
nis2-agile/docs/DESIGN_A4_RELATIONAL.md

82 lines
9.5 KiB
Markdown
Raw Permalink 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 — A4: Modello relazionale (organigramma RACI ↔ skill / formazione / inventario / procedure / rischi + scadenziario)
> Stato: **IN CORSO**. Contesto: segnalazioni Simon Fattori, punti **2, 3, 4, 5, 6, 7** (accolti in A4). Data: 2026-06-15.
> È l'epic più grande → da realizzare a **FASI**. Ancoraggio normativo verificato (Det. ACN 164179/2025 + D.Lgs. 138/2024). Vedi `reference-dlgs-articles`, `DESIGN_A2_ONBOARDING.md`.
>
> **AVANZAMENTO**: ✅ **4.1 Organigramma** (`041_org_roles.sql`, `OrgRoleController`, `organigramma.html`) — LIVE. ✅ **4.2 Competenze** (`042_competences.sql`: `skills`/`role_skills`/`user_skills`/`skill_course_map`; `CompetenceController`; `competenze.html`) — LIVE. ✅ **4.3 Matrice RACI** (`043_raci.sql`: `raci_assignments` + `procedure_inventory`/`procedure_risk`/`inventory_risk`/`risk_measure`; `RaciController`; `raci.html`+`raci.js`; object_id polimorfico anti-IDOR app-layer) — LIVE (commit `b4d47d5`). ✅ **4.4 Scadenziario** (`044_review_schedule.sql`; `ReviewScheduleController` list/complete/sync; `review-schedule.html`) — LIVE. ✅ **4.5 Stakeholder estesi** (`045_stakeholders.sql` suppliers.stakeholder_type; `SupplyChainController::stakeholderMap`; `stakeholders.html`) — LIVE (commit `c5b00cc`). **🎉 A4 COMPLETA (5/5).**
>
> 🔴 **RETTIFICA NOMI REALI (verificata sul codice)**: questo design parlava di una tabella **`corrective_actions`** che **NON ESISTE**. La tabella delle azioni reale è **`capa_actions`** (mig.004), **figlia obbligatoria** di **`non_conformities`** (NCR) via `ncr_id NOT NULL`, e **non ha** una colonna `source_type`. L'alert "gap → azione" (impl. in 4.2) quindi **NON** crea `corrective_actions`/`source_type`: crea una **`non_conformities`** ancorata al gap (`source='management_review'`, `source_entity_type='competence_gap'`, `source_entity_id=role_skills.id`) + una **`capa_actions`** figlia. Le menzioni di `corrective_actions`/`source_type` qui sotto vanno lette in questo senso.
## 0. Principio
A4 trasforma i moduli oggi "a silos" in un **grafo relazionale** con al centro l'**organigramma** (ruoli/responsabilità) e la **matrice RACI** come hub che lega i ruoli agli oggetti (inventario, procedure, rischi). Obiettivo: compliance *vissuta e dimostrabile in audit* (chi è responsabile di cosa, con quali competenze, con quali scadenze).
## 1. Stato attuale (da ESTENDERE)
| Ambito | Esiste? | Note |
|---|---|---|
| RACI ruoli | Parziale | `isms_roles` (mig.037): `role_name`, `user_id`, `responsibility`, `raci ENUM(R,A,C,I)` — ma **legato a un `isms_model`** (SGSI clausola 5.3), 1 valore RACI per ruolo, **non** matrice ruolo×oggetto |
| Organigramma org-wide | NO | nessuna gerarchia ruoli, nessun "nodo organo di gestione/board" |
| Skill / mansioni / competenze | NO | — |
| Gap competenze | NO | — |
| Formazione | SÌ | `training_courses` / `training_assignments` (`target_role` solo ENUM, non FK a ruolo) |
| Procedure | SÌ | `policies` (+ `policy_versions`, `next_review_date`) |
| Inventario | SÌ | `assets` (+ `relevance_score`/`is_nis2_relevant` GV.OC-04) |
| Rischi | SÌ | `risks` (+ `risk_treatments`, `kri`) |
| Fornitori/stakeholder | SÌ | `suppliers` (Supply Chain) |
| Azioni | SÌ | `non_conformities` / `corrective_actions` (mig.004) |
| Scadenziario centralizzato | NO | scadenze sparse (`policies.next_review_date`, `compliance_controls.next_review_date`, `*.due_date`) |
## 2. Modello entità + relazioni (il cuore)
**Nuove tabelle** (additive):
- **`org_roles`** — organigramma: `id, organization_id, role_name, parent_role_id NULL (gerarchia), holder_user_id NULL, is_governance_body TINYINT (nodo organi di amministrazione/direttivi, Art.23), description, created_at`. *(L'`isms_roles` SGSI può puntare a `org_roles` via `org_role_id` opzionale; non si duplica.)*
- **`skills`** — catalogo competenze: `id, organization_id NULL(=globali), name, area`.
- **`role_skills`** — competenze RICHIESTE da un ruolo: `role_id → org_roles, skill_id, required_level (1-5)`. (m2m ruolo↔skill)
- **`user_skills`** — competenze POSSEDUTE: `user_id, skill_id, level (1-5), acquired_via (course_id NULL → training), evidence`. (m2m utente↔skill, collegato al registro corsi)
- **`skill_course_map`** — skill ↔ corso che la eroga: `skill_id, training_course_id`. (collega competenze ↔ formazione)
- **`raci_assignments`** — **MATRICE RACI** (hub): `id, organization_id, role_id → org_roles, object_type ENUM('inventory','procedure','risk','supplier'), object_id, raci ENUM('R','A','C','I')`. → lega l'organigramma a inventario/procedure/rischi/fornitori (m2m via questa tabella).
- **link m2m diretti** (richiesti dalle segnalazioni 4/5/7): `procedure_inventory(procedure_id, asset_id)`, `procedure_risk(procedure_id, risk_id)`, `inventory_risk(asset_id, risk_id)`, `risk_measure(risk_id, measure_code)` (le misure ACN dell'assessment).
- **`review_schedule`** — **SCADENZIARIO centralizzato**: `id, organization_id, entity_type ENUM('role','skill','inventory','procedure','risk','supplier','measure'), entity_id, owner_role_id NULL, frequency_months, last_reviewed_at, next_review_date, status ENUM('ok','due','overdue'), notes`. Aggrega/sostituisce le scadenze sparse.
- **azione da alert** → **riuso `non_conformities` + `capa_actions`** (mig.004): l'alert (gap competenza, scadenza, rischio) crea una NCR ancorata via `source_entity_type`/`source_entity_id` (es. `'competence_gap'` + `role_skills.id`) e una `capa_actions` figlia. *(NON esiste `corrective_actions`/`source_type`: si riusa l'intero workflow CAPA senza alterarne lo schema.)*
**Relazioni chiave** (tutte m2m dove indicato dalle segnalazioni):
```
org_roles ──< raci_assignments >── (inventory | procedure | risk | supplier)
org_roles ──< role_skills >── skills ──< user_skills >── users
skills ──< skill_course_map >── training_courses
procedures ──< procedure_inventory >── inventory ──< inventory_risk >── risks
procedures ──< procedure_risk >── risks ──< risk_measure >── misure ACN (assessment)
(role|skill|inventory|procedure|risk|supplier) ──1:N── review_schedule
gap competenze / scadenze / rischi ──trigger──> non_conformities ──< capa_actions (workflow CAPA)
```
## 3. Gap competenze (segnalazione 3)
**Gap = `role_skills.required_level` (del ruolo che l'utente ricopre) − `user_skills.level`** per ciascuna skill richiesta. Vista `competence_gap` (calcolata): per ogni utente con `org_roles.holder_user_id`, confronto richiesto vs posseduto. **Alert** quando gap > 0 → apertura **azione** = NCR (`non_conformities`, `source_entity_type='competence_gap'`, `source_entity_id=role_skills.id`) + `capa_actions` figlia (+ in futuro voce nello **`review_schedule`**). Ancoraggio: **PR.AT-01** (tutti), **PR.AT-02** (solo essenziali), **GV.RR-04** (cyber nelle pratiche HR).
## 4. Ancoraggio normativo per entità (must-have)
- **Organigramma/ruoli** → **GV.RR-02** (ruoli, responsabilità e poteri stabiliti/comunicati) + **Art. 23 D.Lgs. 138/2024** (responsabilità organi di amministrazione e direttivi) → **`is_governance_body`** obbligatorio come nodo distinto con potere di approvazione.
- **Skill/formazione** → **PR.AT-01/02**, **GV.RR-04**.
- **Inventario** → **ID.AM-01/02** (+03 essenziali); collegare al **registro GV.OC-04** (`relevance_score`), non duplicarlo.
- **Procedure** → **GV.PO-01** (policy) + **GV.PO-02** (riesame/aggiornamento → scadenziario obbligatorio).
- **Rischi** → **Art. 24 D.Lgs.** + **GV.RM-03** + famiglia **ID.RA**; mappabili sulle misure (37 importanti / 43 essenziali, fino al livello requisito).
- **Stakeholder/fornitori** (segnalazione 6) → **GV.SC-02** include fornitori **+ clienti + partner** (non solo fornitori) + **GV.SC-04/05/07**; non duplicare il modulo Supply Chain esistente.
- **Scadenziario** → la revisione periodica è obbligo per **GV.PO-02**, **GV.SC-07**, **PR.AT**, **DE.CM** (periodicità puntuale come buona prassi dove non fissata).
## 5. Migration (additiva) — sketch
Nuova `041_relational_model.sql`: `org_roles`, `skills`, `role_skills`, `user_skills`, `skill_course_map`, `raci_assignments`, `procedure_inventory`, `procedure_risk`, `inventory_risk`, `risk_measure`, `review_schedule` (+ `corrective_actions.source_type`). Tutte con `organization_id` + FK + UNIQUE sulle coppie m2m. Idempotente (runner come 039/040).
## 6. UI (a fasi)
- **Organigramma**: vista ad albero (ruoli, holder, RACI badge), editor ruolo.
- **Matrice RACI**: griglia ruolo × oggetto con celle R/A/C/I.
- **Gap competenze**: dashboard per utente/ruolo (richiesto vs posseduto) + CTA "apri azione/assegna corso".
- **Scadenziario**: calendario/tabella unica delle revisioni (filtrabile per entità, owner, stato due/overdue).
- Link m2m editabili nelle pagine inventario/procedure/rischi.
## 7. Fasi consigliate (A4 è grande → spezzare)
- **4.1** `org_roles` (organigramma + nodo governance Art.23) + vista albero.
- **4.2** `skills`/`role_skills`/`user_skills`/`skill_course_map` + gap competenze (segn. 3) + alert→azione.
- **4.3** `raci_assignments` (matrice RACI) + link m2m procedure/inventario/rischi (segn. 4/5/7).
- **4.4** `review_schedule` centralizzato (segn. trasversale) + migrazione delle scadenze esistenti.
- **4.5** estensione stakeholder a clienti/partner (segn. 6, GV.SC-02) riusando Supply Chain.
## 8. Cosa NON cambia / riuso
Riuso `training_*`, `policies`, `assets` (+relevance GV.OC-04), `risks`, `suppliers`, `corrective_actions`. `isms_roles` resta per la SoA SGSI (può linkare `org_roles`). Nessuna modifica ai flussi auth/onboarding/incidenti. `entity_type`/schema esistente invariati.