-- ===================================================================== -- 057 — Controlli periodici (control monitoring con frequenza + esecuzioni + NC/AC) -- ===================================================================== -- Registro dei controlli RICORRENTI con frequenza, owner e metodo; ogni -- ESECUZIONE è registrata (data, esito, note, evidenze su evidence_files) = -- EVIDENZA del monitoraggio periodico (ISO 27001 §9.1 / A.8.16; buona prassi, -- non obbligo). Da un esito non conforme si genera una NC o un'azione correttiva -- (riuso non_conformities/capa_actions). Distinto da: compliance_controls -- (registro stato), review_schedule (cadenza generica), internal_audits (audit -- puntuale). Vedi docs/DESIGN_CONTROLLI_PERIODICI.md. -- -- Additivo, reversibile. Runner-safe: CREATE TABLE IF NOT EXISTS con FK inline; -- l'ALTER dell'ENUM non_conformities.source è applicata dal seeder idempotente -- (preservando i valori) — application/cli/seed_periodic_controls.php. -- ===================================================================== CREATE TABLE IF NOT EXISTS periodic_controls ( id INT NOT NULL AUTO_INCREMENT, organization_id INT NOT NULL, code VARCHAR(20) NULL, -- CTL-NNN per org title VARCHAR(255) NOT NULL, description TEXT NULL, category VARCHAR(100) NULL, control_ref VARCHAR(32) NULL, -- codice SoA/NIS2 collegato (es. A.8.13) owner_role_id INT NULL, -- responsabile (org_roles) frequency ENUM('giornaliero','settimanale','mensile','trimestrale','semestrale','annuale','custom') NOT NULL DEFAULT 'mensile', frequency_days INT NULL, -- usato se frequency='custom' method TEXT NULL, -- metodologia di verifica next_due_date DATE NULL, last_executed_at DATE NULL, status ENUM('active','suspended') NOT NULL DEFAULT 'active', created_by INT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_pctl_org (organization_id), KEY idx_pctl_due (organization_id, next_due_date), CONSTRAINT fk_pctl_org FOREIGN KEY (organization_id) REFERENCES organizations (id) ON DELETE CASCADE, CONSTRAINT fk_pctl_role FOREIGN KEY (owner_role_id) REFERENCES org_roles (id) ON DELETE SET NULL, CONSTRAINT fk_pctl_user FOREIGN KEY (created_by) REFERENCES users (id) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS periodic_control_executions ( id INT NOT NULL AUTO_INCREMENT, control_id INT NOT NULL, executed_at DATE NOT NULL, executed_by INT NULL, outcome ENUM('conforme','non_conforme','parziale','non_applicabile') NOT NULL DEFAULT 'conforme', notes TEXT NULL, ncr_id INT NULL, -- NC eventualmente generata created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_pcexec_control (control_id), CONSTRAINT fk_pcexec_control FOREIGN KEY (control_id) REFERENCES periodic_controls (id) ON DELETE CASCADE, CONSTRAINT fk_pcexec_user FOREIGN KEY (executed_by) REFERENCES users (id) ON DELETE SET NULL, CONSTRAINT fk_pcexec_ncr FOREIGN KEY (ncr_id) REFERENCES non_conformities (id) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ALTER non_conformities.source: aggiunge 'monitoring' (eseguita dal seeder, idempotente). -- ALTER TABLE non_conformities MODIFY COLUMN source ENUM('assessment','audit','incident','supplier_review','management_review','external_audit','monitoring','other') NOT NULL DEFAULT 'assessment'; -- ROLLBACK (manuale): -- DROP TABLE IF EXISTS periodic_control_executions -- DROP TABLE IF EXISTS periodic_controls -- (non_conformities.source: rimuovere 'monitoring' dall'ENUM dopo aver riclassificato le NC relative)