nis2-agile/docs/sql/030_policy_versions_unique.sql
DevEnv nis2-agile 5413730b00 [FIX] Policy: UNIQUE(policy_id,version) + diff LCS posizionale (findings review)
- Migrazione 030: UNIQUE uq_policy_version su policy_versions (de-dup prima, idempotente).
  approve() ora usa INSERT ... ON DUPLICATE KEY UPDATE -> riapprovare la stessa versione
  aggiorna lo snapshot invece di duplicarlo. Verificato E2E: 2x approve v1.0 -> 1 sola riga.
- diff(): sostituito il confronto set-based (falsi negativi su righe duplicate/riordino) con
  un vero diff LCS line-by-line con posizioni. Verificato E2E: bump v1->v2 -> added 2, removed 1 corretti.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:39:38 +02:00

37 lines
1.4 KiB
SQL

-- ============================================================================
-- Migration 030 - UNIQUE(policy_id, version) su policy_versions (P3 hardening)
-- ----------------------------------------------------------------------------
-- Evita snapshot duplicati della stessa versione di policy (riapprovazioni
-- ripetute con la stessa version creavano righe duplicate, confondendo il diff).
-- Idempotente: aggiunge l'indice solo se assente; de-duplica prima se necessario.
--
-- mysql -h localhost nis2_agile_db -e "source docs/sql/030_policy_versions_unique.sql"
-- ============================================================================
-- 1) Rimuovi eventuali duplicati pre-esistenti (mantieni il piu recente per id)
DELETE pv1 FROM policy_versions pv1
JOIN policy_versions pv2
ON pv1.policy_id = pv2.policy_id
AND pv1.version = pv2.version
AND pv1.id < pv2.id;
-- 2) Aggiungi UNIQUE solo se non esiste gia
DELIMITER //
DROP PROCEDURE IF EXISTS _mig030 //
CREATE PROCEDURE _mig030()
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'policy_versions'
AND INDEX_NAME = 'uq_policy_version'
) THEN
ALTER TABLE policy_versions ADD UNIQUE KEY uq_policy_version (policy_id, version);
END IF;
END //
DELIMITER ;
CALL _mig030();
DROP PROCEDURE IF EXISTS _mig030;
-- ROLLBACK:
-- ALTER TABLE policy_versions DROP INDEX uq_policy_version;