-- ============================================================
-- NIS2 Agile - Migration 006: Security & Performance Improvements
-- Data: 2026-02-20
-- Eseguire come: mysql -u root -p nis2_agile_db < 006_security_improvements.sql
-- ============================================================

-- ── 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);

-- ── 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);

-- ── 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);

-- ── 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
    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. Colonna deleted_at per soft delete su tabelle critiche ─────────────
-- Permette di "eliminare" record senza perdere traccia storica

-- Risks: soft delete
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);

-- ── 7. Pulizia automatica refresh token scaduti ───────────────────────────
-- Evento schedulato (richiede event scheduler abilitato)
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;

-- Abilita event scheduler (da eseguire manualmente se necessario):
-- SET GLOBAL event_scheduler = ON;
