[FEAT] A4 Fase 4.2 — Competenze (skill/requisiti ruolo/gap) + alert→azione NCR+CAPA
Secondo modulo del modello relazionale A4 (docs/DESIGN_A4_RELATIONAL.md). Backend: - Migration 042 (docs/sql/042_competences.sql) + runner aggiornato (scripts/migrate-a4.php). 4 tabelle additive/idempotenti: skills (org-owned o globali), role_skills (competenze richieste dal ruolo, UNIQUE role+skill), user_skills (possedute, UNIQUE org+user+skill), skill_course_map. APPLICATA su prod (nis2-db v8.0.45, TLSv1.3). - CompetenceController (route 'competences'): catalog, skills CRUD, roleSkills, userSkills, skillCourses (map/unmap), gapGrid (richiesto−posseduto per ruolo con titolare), openAction. Multi-tenancy + anti-IDOR + livelli 1-5; competenze globali in sola lettura per gli utenti org. - alert→azione: openAction RIUSA il workflow NCR/CAPA reale (la tabella azioni è capa_actions figlia di non_conformities, NON 'corrective_actions' che non esiste): crea NCR (source='management_review', source_entity_type='competence_gap', source_entity_id=role_skills.id) + capa_actions figlia. Anti-duplicato sul gap. Zero ALTER alle tabelle esistenti. Ancoraggio PR.AT-01/02, GV.RR-04, art.24 D.Lgs. Frontend: - competenze.html (4 schede: Catalogo, Requisiti per ruolo, Competenze persone, Gap & azioni) + js/competenze.js. Bootstrap Italia V2. CTA "Assegna corso" (riuso /training/assign) e "Apri non conformità". - Voce sidebar "Competenze" (common.js + common-bi.js + BI_PAGES) + nav.competences i18n IT/EN. api.js: metodi comp* + assignTraining. Help/KB/PWA: - help.js: guida contestuale 'competences' (schede, calcolo gap, PR.AT-01/02, GV.RR-04, art.24 D.Lgs., disclaimer no-parere-legale) + mappa pagina. - sw.js: nome cache nis2-shell-v1.17.0 (allineamento PWA). - Design doc corretto (rettifica capa_actions vs corrective_actions) + avanzamento 4.1/4.2. Cache-buster: ?v=20260618 dei 5 JS condivisi su 32 HTML. version.json 1.16.0 -> 1.17.0. Smoke E2E su prod (fpm reale): catalogo, requisito, competenza, gap=2, openAction (NCR+CAPA), anti-dup 409, mappatura corso — tutti verdi; dati di test ripuliti. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
47199f1e4e
commit
5368b0a61c
@@ -1,7 +1,11 @@
|
||||
# DESIGN — A4: Modello relazionale (organigramma RACI ↔ skill / formazione / inventario / procedure / rischi + scadenziario)
|
||||
|
||||
> Stato: **DESIGN (pre-implementazione)**. Contesto: segnalazioni Simon Fattori, punti **2, 3, 4, 5, 6, 7** (accolti in A4). Data: 2026-06-15.
|
||||
> 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** (migration `041_org_roles.sql`, `OrgRoleController`, `organigramma.html`) — LIVE. ✅ **4.2 Competenze** (migration `042_competences.sql`: `skills`/`role_skills`/`user_skills`/`skill_course_map`; `CompetenceController`; `competenze.html`) — LIVE. ⏳ 4.3 RACI · 4.4 scadenziario · 4.5 stakeholder.
|
||||
>
|
||||
> 🔴 **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).
|
||||
@@ -31,7 +35,7 @@ A4 trasforma i moduli oggi "a silos" in un **grafo relazionale** con al centro l
|
||||
- **`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.
|
||||
- **`actions`** (oppure riuso `corrective_actions`): azione generata da **alert** (gap competenza, scadenza, rischio) → `source_type, source_id, assigned_role_id, due_date, status`. *(Riuso consigliato di `corrective_actions` + un campo `source_type` per non duplicare il workflow CAPA.)*
|
||||
- **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):
|
||||
```
|
||||
@@ -41,11 +45,11 @@ 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──> actions(corrective_actions)
|
||||
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** (`corrective_actions`, `source_type='competence_gap'`) + voce nello **`review_schedule`**. Ancoraggio: **PR.AT-01** (tutti), **PR.AT-02** (solo essenziali), **GV.RR-04** (cyber nelle pratiche HR).
|
||||
**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.
|
||||
|
||||
Reference in New Issue
Block a user