[FEAT] Epic C / C5.1 — Modulo Stakeholder: registro + matrice di Mendelow (mig.051)

Registro dedicato degli stakeholder (tabella `stakeholders`, NON una colonna su
suppliers: gli interni non sono fornitori; gli esterni si COLLEGANO opzionalmente
a un supplier esistente senza duplicare il dato).

- mig.051: cfg_stakeholder_types (30 di sistema Stak.01-30 + org-added da Stak.31),
  cfg_stakeholder_quadrants (4, range corretti: Q4 potere 0-2), stakeholders,
  stakeholder_procedures (m2m -> policies). Seeder idempotente seed_stakeholders.php.
- StakeholderController: list/create/update/delete + types/addType + quadrants + pickers.
  Quadrante CALCOLATO a read-time dai range config. Anti-IDOR su org_role/supplier/
  policy/tipo; coerenza kind (interni->organigramma, esterni->fornitore); punteggi 0-5.
- api.js: metodi stk*. stakeholders.html riscritta: registro + matrice di Mendelow
  in SVG dependency-free + modali (stakeholder, nuovo tipo). Voce sidebar V2 (common-bi.js).
- Help aggiornato; cache-buster ?v=20260626 su tutte le pagine; version 1.19.0; sw cache v1.19.0.

Ancoraggio GV.SC-02 (obbligo, art. 24 D.Lgs. 138/2024). La matrice di Mendelow e'
etichettata come BUONA PRASSI, non obbligo NIS2 (regola fonti-certe). Additivo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-16 20:54:57 +02:00
co-authored by Claude Opus 4.8
parent 419162594d
commit c782aa54fa
43 changed files with 1256 additions and 278 deletions
+14
View File
@@ -295,6 +295,20 @@ class NIS2API {
// ═══════════════════════════════════════════════════════════════════
stakeholderMap() { return this._acn(this.get('/supply-chain/stakeholder-map')); }
// ═══════════════════════════════════════════════════════════════════
// Registro Stakeholder + matrice di Mendelow (Epic C / C5). Tutti _acn.
// Tipo configurabile (Stak.01-30 + org-added), potere/interesse 0-5,
// link organigramma (interni) / procedure (m2m). Quadrante calcolato lato API.
// ═══════════════════════════════════════════════════════════════════
stkList() { return this._acn(this.get('/stakeholders/list')); }
stkTypes() { return this._acn(this.get('/stakeholders/types')); }
stkAddType(d) { return this._acn(this.post('/stakeholders/types', d || {})); }
stkQuadrants() { return this._acn(this.get('/stakeholders/quadrants')); }
stkPickers() { return this._acn(this.get('/stakeholders/pickers')); }
stkCreate(d) { return this._acn(this.post('/stakeholders/create', d || {})); }
stkUpdate(id, d) { return this._acn(this.put(`/stakeholders/${id}`, d || {})); }
stkDelete(id) { return this._acn(this.del(`/stakeholders/${id}`)); }
// ═══════════════════════════════════════════════════════════════════
// Dashboard
// ═══════════════════════════════════════════════════════════════════