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