[FEAT] A4 Fasi 4.4 + 4.5 (A4 COMPLETA 5/5): scadenziario centralizzato review_schedule (mig.044; ReviewScheduleController list/create/update/delete/complete/sync) + stakeholder estesi clienti/partner GV.SC-02 (mig.045 suppliers.stakeholder_type, SupplyChainController::stakeholderMap). Pagine review-schedule.html + stakeholders.html (Bootstrap Italia/AGID). Workflow build+review adversariale (3 major risolti: 045 da DELIMITER -> ALTER bare runner-safe). help GV.SC-04/05 allineati al titolo canonico ACN. Cache-buster ?v=20260620.
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
c7d36c910f
commit
c5b00ccd96
@@ -0,0 +1,50 @@
|
||||
-- ============================================================================
|
||||
-- Migration 044 — A4 Fase 4.4: Scadenziario centralizzato delle revisioni.
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 1 tabella ADDITIVA. Idempotente (CREATE TABLE IF NOT EXISTS). Applicare con la
|
||||
-- STESSA connessione PDO dell'app (container nis2-db via TCP+TLS), via runner
|
||||
-- scripts/migrate-a4.php. Runner-safe: solo CREATE TABLE, niente DELIMITER /
|
||||
-- stored procedure, nessun ';' dentro commenti o stringhe.
|
||||
--
|
||||
-- Cosa fa: raccoglie in un unico registro le scadenze di revisione periodica
|
||||
-- (ruoli, competenze, inventario, procedure, rischi, fornitori, misure, voci
|
||||
-- custom). Lo stato (ok/due/overdue) e' calcolato LIVE dal controller in base a
|
||||
-- next_review_date e NON ci si affida alla colonna persistita.
|
||||
--
|
||||
-- Ancoraggio normativo (docs/DESIGN_A4_RELATIONAL.md):
|
||||
-- - GV.PO-02 (NIST CSF 2.0): le policy/procedure sono riesaminate periodicamente
|
||||
-- - GV.SC-07 (NIST CSF 2.0): la sicurezza dei fornitori e' monitorata/rivista
|
||||
-- - PR.AT: formazione e sensibilizzazione ricorrenti
|
||||
-- - DE.CM: monitoraggio continuo
|
||||
-- - art. 24 D.Lgs. 138/2024: misure di gestione del rischio mantenute aggiornate
|
||||
-- Disclaimer: la periodicita' puntuale e' buona prassi dove non fissata da norma;
|
||||
-- e' uno strumento di supporto, non un parere legale.
|
||||
--
|
||||
-- Multi-tenancy: organization_id NOT NULL (FK organizations, ON DELETE CASCADE).
|
||||
-- owner_role_id -> org_roles (mig.041) ON DELETE SET NULL. created_by -> users
|
||||
-- ON DELETE SET NULL. UNIQUE (org, entity_type, entity_id) abilita l'upsert
|
||||
-- idempotente di sync() (le voci custom con entity_id NULL non collidono in MySQL).
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS review_schedule (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id INT NOT NULL,
|
||||
entity_type ENUM('role','skill','inventory','procedure','risk','supplier','measure','custom') NOT NULL,
|
||||
entity_id INT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
owner_role_id INT NULL,
|
||||
frequency_months INT NULL,
|
||||
last_reviewed_at DATE NULL,
|
||||
next_review_date DATE NOT NULL,
|
||||
status ENUM('ok','due','overdue') NOT NULL DEFAULT 'ok',
|
||||
notes TEXT NULL,
|
||||
created_by INT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (owner_role_id) REFERENCES org_roles(id) ON DELETE SET NULL,
|
||||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
|
||||
UNIQUE KEY uk_rs_entity (organization_id, entity_type, entity_id),
|
||||
INDEX idx_rs_org_next (organization_id, next_review_date),
|
||||
INDEX idx_rs_entity (organization_id, entity_type, entity_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,42 @@
|
||||
-- ============================================================================
|
||||
-- Migration 045 — A4 Fase 4.5: Stakeholder estesi (GV.SC-02)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- ADDITIVO: aggiunge la colonna suppliers.stakeholder_type per distinguere
|
||||
-- FORNITORI, CLIENTI e PARTNER. RIUSA la tabella suppliers esistente (NESSUNA
|
||||
-- nuova tabella, NESSUNA duplicazione del modulo Supply Chain): la pagina
|
||||
-- "Stakeholder" e' solo una vista di sintesi raggruppata per tipo.
|
||||
--
|
||||
-- Ancoraggio normativo (docs/DESIGN_A4_RELATIONAL.md):
|
||||
-- - GV.SC-02 (NIST CSF 2.0): ruoli e responsabilita per fornitori, CLIENTI e
|
||||
-- PARTNER stabiliti, comunicati e coordinati internamente ed esternamente.
|
||||
-- - GV.SC-04/05/07: catalogazione, requisiti contrattuali e revisione periodica
|
||||
-- degli stakeholder della supply chain.
|
||||
-- - Gli OBBLIGHI fanno capo al D.Lgs. 138/2024 (governance art. 23, rischio
|
||||
-- art. 24): NON alla Direttiva. La tassonomia degli stakeholder e' buona prassi.
|
||||
--
|
||||
-- Multi-tenancy: suppliers.organization_id resta il discriminante tenant. L'indice
|
||||
-- (organization_id, stakeholder_type) supporta la mappa raggruppata per tipo.
|
||||
--
|
||||
-- IDEMPOTENZA / RUNNER:
|
||||
-- MySQL 8 Ubuntu NON supporta "ADD COLUMN IF NOT EXISTS". Questo file contiene
|
||||
-- SOLO statement nudi (niente DELIMITER, niente stored procedure, nessun ';'
|
||||
-- dentro i commenti) ed e' percio' RUNNER-SAFE: scripts/migrate-a4.php esegue un
|
||||
-- pre-check su information_schema PRIMA di questa ALTER (stesso pattern di
|
||||
-- mig.040_onboarding_classification.sql) e la salta se colonna/indice esistono
|
||||
-- gia'. Eseguire SEMPRE tramite il runner:
|
||||
-- docker exec nis2-app php /var/www/nis2-agile/scripts/migrate-a4.php
|
||||
-- NB: NON applicare questo file con un client che fa "split su ';'" SENZA il
|
||||
-- pre-check del runner, altrimenti una seconda esecuzione fallirebbe (colonna
|
||||
-- duplicata). Il runner garantisce l'idempotenza.
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE suppliers
|
||||
ADD COLUMN stakeholder_type ENUM('supplier','customer','partner') NOT NULL DEFAULT 'supplier'
|
||||
COMMENT 'GV.SC-02: tipo di stakeholder (fornitore/cliente/partner)' AFTER name;
|
||||
|
||||
ALTER TABLE suppliers
|
||||
ADD INDEX idx_suppliers_stakeholder (organization_id, stakeholder_type);
|
||||
|
||||
-- ROLLBACK (manuale):
|
||||
-- ALTER TABLE suppliers DROP INDEX idx_suppliers_stakeholder
|
||||
-- ALTER TABLE suppliers DROP COLUMN stakeholder_type
|
||||
Reference in New Issue
Block a user