[DOCS] Handoff C5 (Stakeholder) — testimone per nuovo prompt

Briefing auto-contenuto: spec verbatim Simon C5, fonte docs/simon/C5_EleStakeH.xlsx (30 tipi),
validazione normativa (Mendelow=best practice, refuso Q4=potere 0-2, GV.SC-02), esistente da
riusare (org_roles/policies/cfg_nis2_requisiti/NCR-CAPA/review_schedule/suppliers), fasi C5.1/C5.2,
convenzioni operative critiche (deploy host SSH, migration runner, common-bi.js sidebar+cache-buster,
multi-tenancy, smoke tester), flotta verifica finale + help/trad/KB, open items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-16 20:18:51 +02:00
co-authored by Claude Opus 4.8
parent 8df8a5d91d
commit 419162594d
+117
View File
@@ -0,0 +1,117 @@
# HANDOFF — Epic C / C5: Modulo Stakeholder (mappatura + Mendelow + attività)
> Documento di passaggio di consegne per un NUOVO prompt che implementerà **C5**, l'ultimo
> punto delle segnalazioni di Simon Fattori. C1–C4 sono GIÀ LIVE. Leggi questo file + la memoria
> `project-epic-c-simon` prima di iniziare. Aggiornato 2026-06-16.
---
## 0. Cosa è già fatto (Epic C)
| Punto | Stato | Riferimenti |
|---|---|---|
| C1 — Elenco Misure/Requisiti config-driven + valutazione per requisito + copia procedure | ✅ LIVE | mig.046/047/048, `FrameworkController`, `misure-requisiti.html`, `org_requisito_state`, `cfg_nis2_*` |
| C2 — «Determinazione» (non «Determina») | ✅ | decisione utente bloccata |
| C3 — rimosso modulo "Analisi GAP ACN" | ✅ LIVE | mig.049 (drop), RaciController ripuntato su `cfg_nis2_misure` |
| C4 — inventario a 2 voci + sottoclassi | ✅ LIVE | mig.050, `cfg_inventory_voci`/`inventory_subclassi`, `assets.voce_code/subclass_id` |
| **C5 — modulo Stakeholder** | ⏳ **DA FARE** | questo documento |
HEAD al passaggio: `8df8a5d`. **Prossima migrazione = `051`**. Versione corrente `1.18.4`.
---
## 1. La spec C5 (testo VERBATIM di Simon — da rispettare alla lettera)
> C5 - la mappatura e la gestione degli stakeholder deve essere organizzata così:
> 1. l'utente seleziona il tipo stakeholder, con descrizione, dall'elenco (`docs/simon/C5_EleStakeH.xlsx`); l'utente può modificare l'elenco aggiungendo voci e tu provvederai alla codifica proseguendo la numerazione dall'ultimo codice che è **Stak.30**.
> 2. l'utente inizia a inserire i suoi stakeholder tramite un'anagrafica semplificata che deve comunque comprendere un **collegamento all'organigramma** per stakeholder interni, un **collegamento alle procedure**, una griglia di due valutazioni con valori da **0 a 5**: «grado di **potere** sull'azienda» e «grado di **interesse** sull'azienda».
> 3. gli stakeholder così valutati saranno collocati su un **grafico a quattro quadranti**: asse **x = interesse**, asse **y = potere**.
> - **Q1 in alto a sinistra** (interesse 0-2, potere 3-5): *Stakeholder Istituzionali / Keep Satisfied* — Tenerli soddisfatti. Forte potere di blocco, scarso interesse quotidiano. Evitare scontenti improvvisi.
> - **Q2 in alto a destra** (interesse 3-5, potere 3-5): *Stakeholder Chiave / Gestisci Attivamente* — Gestione attiva e coinvolgimento costante. Decisori principali, supporto vitale.
> - **Q3 in basso a destra** (interesse 3-5, potere 0-2): *Stakeholder Operativi / Keep Informed* — Tenere informati. Molto coinvolti, scarso peso decisionale.
> - **Q4 in basso a sinistra** (interesse 0-2, potere 0-2 — vedi §4 nota refuso): *Stakeholder Marginali / Monitorare* — Monitoraggio costante col minimo sforzo. Comunicazioni periodiche non dispendiose.
> 4. il dashboard stakeholder deve prevedere **attività**:
> 4.1 le attività possono essere **azioni e/o questionari** da inviare, con collegamento all'elenco procedure;
> 4.2 il modulo azioni lo trattiamo più avanti *(NB: esiste già il workflow NCR/CAPA — vedi §5)*;
> 4.3 i **questionari** devono prevedere un **sotto-dashboard di ricezione feedback** (questionari compilati o la firma di avvenuta lettura, a seconda del tipo) + possibilità di **commentare** l'attività e **allegare file**;
> 4.4 l'utente deve poter assegnare un'attività a un **codice stakeholder** oppure selezionare **singolarmente** ogni stakeholder (anche di codice diverso);
> 4.5 devono esistere **questionari tipo** con collegamento sia all'elenco procedure sia all'elenco misure/requisiti in **rapporto molti-a-molti**;
> 4.6 ogni attività deve poter essere **pianificata con data e scadenza** e con collegamento a un **calendario del sistema NIS2**.
---
## 2. Fonte dati autoritativa (codifica NON variabile)
- **`docs/simon/C5_EleStakeH.xlsx`** → 30 tipi `Stak.01`–`Stak.30`. **Interni**: Stak.01–06 (Dipendenti, Management, Azionisti, Collaboratori, Sindacalisti, Volontari/Associati). **Esterni**: Stak.07–30 (Clienti finali/aziendali, Fornitori materie prime/servizi, Partner strategici, Rivenditori, Governo/autorità, Camera di commercio, Agenzie di regolamentazione, Comunità locale, ONG, Giornalisti/blogger, Sponsorizzati, Influencer, Banche, Assicurazioni, Sponsor, Investitori privati, Donatori, Associazioni di categoria, Competitor, Attivisti ambientali, Organizzazioni di consumatori, Rappresentanti sindacali).
- **GIÀ DISPONIBILI parsati** in `application/data/nis2_framework_seed.json` → chiave **`stakeholder_types`** (array di `{code,tipo,descr}`, 30 elementi). Riusa quelli o ri-parsa l'xlsx (parser stdlib in cronologia, zipfile+xml, no openpyxl). NON variare codici/descrizioni.
- Nuovi tipi aggiunti dall'utente → **proseguire da `Stak.31`** (codifica automatica).
---
## 3. Validazione normativa (già fatta con `nis2-expert`)
- **Estensione a fornitori/clienti/partner = ancorata a GV.SC-02** (testo verbatim "fornitori, clienti e partner"). OK.
- **La matrice Mendelow (potere/interesse) è BEST PRACTICE, NON un obbligo NIS2.** → etichettarla come tale in AI/help (regola "fonti certe" di `application/config/nis2_sources.php`). NON spacciarla per requisito.
- L'obbligo VERO è GV.SC-02: ruoli/responsabilità di sicurezza per fornitori/clienti/partner + personale terze parti nell'elenco GV.RR-02 p.2. Assicurarsi che il modulo produca QUESTI artefatti, non solo la "bella matrice".
- Ancoraggio comprensione stakeholder: **GV.OC** (contesto organizzativo).
---
## 4. Decisioni di design già prese
- **Config-driven** (direttiva utente, vale per tutto Epic C): tipi e quadranti in **tabelle di configurazione**, NON hardcoded.
- 🔧 **REFUSO confermato (expert + Mendelow + descrizione)**: il **quadrante Q4 (basso-sinistra, Marginali/Monitorare)** nel testo di Simon ha "potere 3-5" ma deve essere **potere 0-2** (basso potere + basso interesse). Implementare con **potere 0-2**. (Q1 alto-sx = potere 3-5/interesse 0-2.) Regola quadranti: potere≥3 = alto, interesse≥3 = alto.
- **Riusare** il modulo Supply Chain / A4 4.5 (`suppliers.stakeholder_type` ENUM supplier/customer/partner, `SupplyChainController::stakeholderMap`, `public/stakeholders.html`) — **estendere, non duplicare**.
---
## 5. Esistente da riusare (NON reinventare)
| Serve a C5 | Esiste già |
|---|---|
| Stakeholder base | `suppliers` (+ `stakeholder_type` ENUM, A4 4.5) · `SupplyChainController::stakeholderMap` · `public/stakeholders.html` |
| Link organigramma (interni) | **`org_roles`** (A4 4.1, `OrgRoleController`) |
| Link procedure | **`policies`** (`PolicyController`) |
| Link misure/requisiti (m2m questionari) | **`cfg_nis2_requisiti`** / `cfg_nis2_misure` (C1) |
| Azioni (4.2) | **`non_conformities` + `capa_actions`** (workflow NCR/CAPA, mig.004) — riusare, NON creare `corrective_actions` (non esiste) |
| Scadenze/calendario (4.6) | **`review_schedule`** (A4 4.4, `ReviewScheduleController`) — valutare se le attività stakeholder ci entrano o serve un calendario dedicato |
| Pattern matrice/valutazione | `org_requisito_state` + modale valutazione di `misure-requisiti.html` (C1) come riferimento UI |
⚠️ **Scelta dati da fare**: estendere `suppliers` con i campi C5 (stakeholder_code, potere, interesse, link org_role, link procedure) **oppure** una tabella compagna `stakeholder_profile(supplier_id, ...)`. Raccomandazione: tabella compagna additiva per non appesantire `suppliers` e tenere C5 isolato. **Decidere a inizio C5.**
---
## 6. Fasi consigliate
- **C5.1 (fondazione)**: `cfg_stakeholder_types` (seed 30 + org-added da Stak.31) + `cfg_stakeholder_quadrants` (4, con range corretti) + anagrafica estesa (tipo, potere/interesse 0-5, link organigramma per interni, link procedure) + **matrice Mendelow** (UI grafico 4 quadranti) + collocazione automatica. Endpoint + pagina (estendere `stakeholders.html`). Help/i18n/KB.
- **C5.2 (operativo)**: **attività** (azioni→NCR/CAPA, questionari) + **questionari tipo** con m2m a procedure e misure/requisiti + **sotto-dashboard feedback** (compilazione / firma lettura) + commenti + allegati + **pianificazione data/scadenza su calendario** (review_schedule o calendario dedicato). Help/i18n/KB.
---
## 7. Convenzioni operative CRITICHE (non sbagliare)
- **DB writes**: SOLO via host SSH → `docker exec nis2-app php ...`. Il devenv NON raggiunge il DB. Chiave host in **`.ssh-temp/`** (ruota ~14h: se scaduta, chiedere all'utente una chiave fresca). Pattern migrazione: scrivi `application/_migrate_051_tmp.php` self-contained (require config+database) → esegui via SSH → **rimuovilo**. Commit del solo `docs/sql/051_*.sql` (record) + eventuale `application/data/*seed*.json`.
- **Migration runner**: il runner fa `PDO::exec` con split su `;` → **MAI `DELIMITER`/stored-procedure**. Usa `CREATE TABLE IF NOT EXISTS` / `ALTER ... ADD` bare + try/catch su errno (1050 tabella esiste, 1060 colonna dup, 1061 indice dup, 1826 FK dup). **UNIQUE con `organization_id` NULL NON deduplica** (NULL≠NULL) → per i default di sistema usa un **check d'esistenza** prima dell'INSERT (vedi `_migrate_050`).
- **PHP hot-reload**: dopo OGNI edit `.php` → `docker exec nis2-app kill -USR2 1` (l'opcache non rilegge da sola).
- **Git push**: DIRETTO dal devenv (helper vault `git-credential-vault`). Commit-early.
- **Frontend / sidebar**: la sidebar V2 attiva è in **`common-bi.js`** (NON solo `common.js` — gotcha: in C3 la voce nuova era stata messa solo in common.js e non compariva). `common-bi.js` ha un **`?v=` PROPRIO** (diverso dagli altri JS) → bumparlo a parte. Cache-buster `?v=YYYYMMDD` su **tutte** le `public/*.html` quando cambi JS condivisi (`sed -i 's/?v=VECCHIA/?v=NUOVA/g'`), + bump `version.json` (MINOR per feature) + nome cache in `public/sw.js` (`nis2-shell-vX.Y.Z`).
- **Help/i18n/KB**: aggiornare `public/js/help.js` (sezione + page-mapping) + `public/js/i18n.js` (chiavi `nav.*`) + ingest KB (`POST /api/knowledgebase/ingest`, super_admin, scope SYSTEM) dopo ogni cambio funzionale.
- **DB API**: `Database::query/fetchAll/fetchOne/insert/update` — **`Database::execute` NON ESISTE**.
- **Multi-tenancy / auth**: ogni query filtra `organization_id`. `getCurrentOrgId()` è valorizzato SOLO dopo `requireOrgAccess()`/`requireOrgRole()`; con `requireAuth()` usa `resolveOrgId()` + verifica accesso a mano (vedi `FrameworkController::catalog` per il pattern anti-IDOR su letture org-opzionali). Scritture: `requireOrgRole(['org_admin','compliance_manager'])`. Il demo guard (isDemo) blocca le scritture sulle org demo.
- **Smoke test**: login tester `s.fattori@agile.software` / **`Tester2026!`** (super_admin) via `POST /api/auth/login` (curl, NON python urllib → Cloudflare 1010). Header `X-Organization-Id`. Org: **151** DataCore (importante), **152** MedClinic (essenziale), **996001/996002** sandbox (isDemo → niente seed/scritture lì). **NON inquinare i golden 151/152**: testa e poi fai cleanup (capture max id → delete > max).
- **Email**: disabilitate (kill-switch); per i questionari "da inviare" NON spedire davvero a go-live mancante — usare `send-raw` solo per test espliciti, altrimenti registrare lo stato senza invio reale.
---
## 8. Alla FINE di C5 (istruzione esplicita dell'utente)
1. **Flotta di agenti per verificare il lavoro** (Workflow multi-agente: sicurezza/correttezza/fedeltà-dato/normativa/UI → verifica avversariale → sintesi; poi correggere i finding). Vedi il workflow usato per C1 come modello.
2. **Help online + traduzioni + KB AI** (giro finale di allineamento).
---
## 9. Open items aperti (segnalare, non rimuovere)
- **92 vs 87 requisiti importanti**: il prodotto usa **92** (file di Simon, vincolante); l'`nis2-expert` contando l'Allegato 1 ufficiale trova **87**. Da riconciliare con Simon sul testo ufficiale. (Allineato a 92 in help.js + nis2_sources.php.)
- **Determinazione 333017/2025**: data esatta (mese senza giorno) in `application/config/nis2_sources.php:60` da verificare sul testo ufficiale.
- **E2E browser di C1–C4**: nuove UI (misure-requisiti, valutazione per requisito, inventario 2 voci) NON collaudate a video — far esercitare ai tester.