From 18dec353809e1653ed4cdac82f3123c99dfd362f Mon Sep 17 00:00:00 2001 From: DevEnv nis2-agile Date: Fri, 20 Feb 2026 12:04:16 +0100 Subject: [PATCH] [FIX] Migration 006: fix sintassi CREATE INDEX per MySQL 8.0 Sostituito ALTER TABLE ADD INDEX IF NOT EXISTS con CREATE INDEX IF NOT EXISTS per compatibilita' MySQL 8.0.x Co-Authored-By: Claude Sonnet 4.6 --- docs/sql/006_security_improvements.sql | 54 ++++++++++---------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/docs/sql/006_security_improvements.sql b/docs/sql/006_security_improvements.sql index f8cea2a..63a78d2 100644 --- a/docs/sql/006_security_improvements.sql +++ b/docs/sql/006_security_improvements.sql @@ -2,30 +2,25 @@ -- NIS2 Agile - Migration 006: Security & Performance Improvements -- Data: 2026-02-20 -- Eseguire come: mysql -u root -p nis2_agile_db < 006_security_improvements.sql +-- Compatibile: MySQL 8.0+ -- ============================================================ -- ── 1. Indici performance su incidents ──────────────────────────────────── --- Per query filtrate per org + scadenze NIS2 -ALTER TABLE incidents - ADD INDEX IF NOT EXISTS idx_inc_org_status (organization_id, status), - ADD INDEX IF NOT EXISTS idx_inc_org_significant (organization_id, is_significant), - ADD INDEX IF NOT EXISTS idx_inc_early_warning_due (organization_id, early_warning_due), - ADD INDEX IF NOT EXISTS idx_inc_notification_due (organization_id, notification_due), - ADD INDEX IF NOT EXISTS idx_inc_final_report_due (organization_id, final_report_due); +CREATE INDEX IF NOT EXISTS idx_inc_org_status ON incidents (organization_id, status); +CREATE INDEX IF NOT EXISTS idx_inc_org_significant ON incidents (organization_id, is_significant); +CREATE INDEX IF NOT EXISTS idx_inc_early_warning_due ON incidents (organization_id, early_warning_due); +CREATE INDEX IF NOT EXISTS idx_inc_notification_due ON incidents (organization_id, notification_due); +CREATE INDEX IF NOT EXISTS idx_inc_final_report_due ON incidents (organization_id, final_report_due); -- ── 2. Indici performance su risks ──────────────────────────────────────── -ALTER TABLE risks - ADD INDEX IF NOT EXISTS idx_risks_org_status (organization_id, status), - ADD INDEX IF NOT EXISTS idx_risks_score (organization_id, inherent_risk_score DESC); +CREATE INDEX IF NOT EXISTS idx_risks_org_status ON risks (organization_id, status); +CREATE INDEX IF NOT EXISTS idx_risks_score ON risks (organization_id, inherent_risk_score); --- ── 3. Indici performance su audit_logs (immutabilità) ──────────────────── --- L'audit log deve essere append-only e ricercabile rapidamente -ALTER TABLE audit_logs - ADD INDEX IF NOT EXISTS idx_audit_org_created (organization_id, created_at DESC), - ADD INDEX IF NOT EXISTS idx_audit_entity (entity_type, entity_id); +-- ── 3. Indici performance su audit_logs ─────────────────────────────────── +CREATE INDEX IF NOT EXISTS idx_audit_org_created ON audit_logs (organization_id, created_at); +CREATE INDEX IF NOT EXISTS idx_audit_entity ON audit_logs (entity_type, entity_id); -- ── 4. Trigger per rendere audit_log immutabile ─────────────────────────── --- Blocca UPDATE e DELETE sull'audit log (solo INSERT consentito) DROP TRIGGER IF EXISTS prevent_audit_log_update; CREATE TRIGGER prevent_audit_log_update BEFORE UPDATE ON audit_logs @@ -44,33 +39,24 @@ BEGIN SET MESSAGE_TEXT = 'audit_logs is append-only: DELETE not permitted'; END; --- ── 5. Colonna deleted_at per soft delete su tabelle critiche ───────────── --- Permette di "eliminare" record senza perdere traccia storica - --- Risks: soft delete +-- ── 5. Soft delete su tabelle critiche ──────────────────────────────────── ALTER TABLE risks ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at; -ALTER TABLE risks - ADD INDEX IF NOT EXISTS idx_risks_deleted (organization_id, deleted_at); - --- Policies: soft delete ALTER TABLE policies ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at; -ALTER TABLE policies - ADD INDEX IF NOT EXISTS idx_policies_deleted (organization_id, deleted_at); - --- Suppliers: soft delete ALTER TABLE suppliers ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at; --- ── 6. Indice su refresh_tokens per performance ─────────────────────────── -ALTER TABLE refresh_tokens - ADD INDEX IF NOT EXISTS idx_refresh_user_expires (user_id, expires_at); +-- Indici per soft delete (escludono record eliminati nelle query standard) +CREATE INDEX IF NOT EXISTS idx_risks_deleted ON risks (organization_id, deleted_at); +CREATE INDEX IF NOT EXISTS idx_policies_deleted ON policies (organization_id, deleted_at); --- ── 7. Pulizia automatica refresh token scaduti ─────────────────────────── --- Evento schedulato (richiede event scheduler abilitato) +-- ── 6. Indice su refresh_tokens ─────────────────────────────────────────── +CREATE INDEX IF NOT EXISTS idx_refresh_user_expires ON refresh_tokens (user_id, expires_at); + +-- ── 7. Evento pulizia refresh token scaduti ─────────────────────────────── DROP EVENT IF EXISTS cleanup_expired_refresh_tokens; CREATE EVENT IF NOT EXISTS cleanup_expired_refresh_tokens ON SCHEDULE EVERY 6 HOUR @@ -81,5 +67,5 @@ CREATE EVENT IF NOT EXISTS cleanup_expired_refresh_tokens -- ── 8. Verifica ─────────────────────────────────────────────────────────── SELECT 'Migration 006 completed successfully' AS status; --- Abilita event scheduler (da eseguire manualmente se necessario): +-- Nota: per abilitare event scheduler (richiede SUPER): -- SET GLOBAL event_scheduler = ON;