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 <noreply@anthropic.com>
72 lines
3.9 KiB
SQL
72 lines
3.9 KiB
SQL
-- ============================================================
|
|
-- 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 ────────────────────────────────────
|
|
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 ────────────────────────────────────────
|
|
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 ───────────────────────────────────
|
|
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 ───────────────────────────
|
|
DROP TRIGGER IF EXISTS prevent_audit_log_update;
|
|
CREATE TRIGGER prevent_audit_log_update
|
|
BEFORE UPDATE ON audit_logs
|
|
FOR EACH ROW
|
|
BEGIN
|
|
SIGNAL SQLSTATE '45000'
|
|
SET MESSAGE_TEXT = 'audit_logs is append-only: UPDATE not permitted';
|
|
END;
|
|
|
|
DROP TRIGGER IF EXISTS prevent_audit_log_delete;
|
|
CREATE TRIGGER prevent_audit_log_delete
|
|
BEFORE DELETE ON audit_logs
|
|
FOR EACH ROW
|
|
BEGIN
|
|
SIGNAL SQLSTATE '45000'
|
|
SET MESSAGE_TEXT = 'audit_logs is append-only: DELETE not permitted';
|
|
END;
|
|
|
|
-- ── 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 policies
|
|
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
|
|
|
ALTER TABLE suppliers
|
|
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_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);
|
|
|
|
-- ── 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
|
|
STARTS CURRENT_TIMESTAMP
|
|
DO
|
|
DELETE FROM refresh_tokens WHERE expires_at < NOW() - INTERVAL 1 DAY;
|
|
|
|
-- ── 8. Verifica ───────────────────────────────────────────────────────────
|
|
SELECT 'Migration 006 completed successfully' AS status;
|
|
|
|
-- Nota: per abilitare event scheduler (richiede SUPER):
|
|
-- SET GLOBAL event_scheduler = ON;
|