fix: remove legacy knowledge card tables and compatibility code
This commit is contained in:
127
migrations/20260819_drop_sop_versions.sql
Normal file
127
migrations/20260819_drop_sop_versions.sql
Normal file
@@ -0,0 +1,127 @@
|
||||
-- Destructive cleanup for the SOP single-version migration.
|
||||
-- Run only after the backfill script completed and all sop_id values are set.
|
||||
-- The statements discover constraint/index names because deployments may use
|
||||
-- different GORM naming conventions.
|
||||
|
||||
-- The application does not use database foreign keys. Remove every existing
|
||||
-- foreign key in the database first so no historical constraint remains and
|
||||
-- no constraint blocks the old SOP column cleanup.
|
||||
DROP PROCEDURE IF EXISTS drop_all_iqudo_foreign_keys;
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE drop_all_iqudo_foreign_keys()
|
||||
BEGIN
|
||||
DECLARE finished INT DEFAULT 0;
|
||||
DECLARE table_name_value VARCHAR(64);
|
||||
DECLARE constraint_name_value VARCHAR(64);
|
||||
DECLARE foreign_keys CURSOR FOR
|
||||
SELECT TABLE_NAME, CONSTRAINT_NAME
|
||||
FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_TYPE = 'FOREIGN KEY';
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
|
||||
|
||||
OPEN foreign_keys;
|
||||
drop_loop: LOOP
|
||||
FETCH foreign_keys INTO table_name_value, constraint_name_value;
|
||||
IF finished = 1 THEN
|
||||
LEAVE drop_loop;
|
||||
END IF;
|
||||
SET @sql = CONCAT('ALTER TABLE `', table_name_value, '` DROP FOREIGN KEY `', constraint_name_value, '`');
|
||||
PREPARE stmt_all_fk FROM @sql;
|
||||
EXECUTE stmt_all_fk;
|
||||
DEALLOCATE PREPARE stmt_all_fk;
|
||||
END LOOP;
|
||||
CLOSE foreign_keys;
|
||||
END//
|
||||
DELIMITER ;
|
||||
CALL drop_all_iqudo_foreign_keys();
|
||||
DROP PROCEDURE drop_all_iqudo_foreign_keys;
|
||||
|
||||
-- The following blocks are retained as idempotent guards for databases where
|
||||
-- a concurrent/manual migration changed the schema between the procedure and
|
||||
-- the SOP cleanup statements.
|
||||
-- Remove foreign keys on the old sop_version_id columns, if present.
|
||||
SET @fk = (
|
||||
SELECT kcu.CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE kcu
|
||||
WHERE kcu.CONSTRAINT_SCHEMA = DATABASE() AND kcu.TABLE_NAME = 'sop_nodes'
|
||||
AND kcu.COLUMN_NAME = 'sop_version_id' AND kcu.REFERENCED_TABLE_NAME = 'sop_versions' LIMIT 1
|
||||
);
|
||||
SET @sql = IF(@fk IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_nodes DROP FOREIGN KEY `', @fk, '`'));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @fk = (
|
||||
SELECT kcu.CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE kcu
|
||||
WHERE kcu.CONSTRAINT_SCHEMA = DATABASE() AND kcu.TABLE_NAME = 'sop_edges'
|
||||
AND kcu.COLUMN_NAME = 'sop_version_id' AND kcu.REFERENCED_TABLE_NAME = 'sop_versions' LIMIT 1
|
||||
);
|
||||
SET @sql = IF(@fk IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_edges DROP FOREIGN KEY `', @fk, '`'));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @fk = (
|
||||
SELECT kcu.CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE kcu
|
||||
WHERE kcu.CONSTRAINT_SCHEMA = DATABASE() AND kcu.TABLE_NAME = 'sop_runs'
|
||||
AND kcu.COLUMN_NAME = 'sop_version_id' AND kcu.REFERENCED_TABLE_NAME = 'sop_versions' LIMIT 1
|
||||
);
|
||||
SET @sql = IF(@fk IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_runs DROP FOREIGN KEY `', @fk, '`'));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Drop indexes containing the old column, regardless of their names.
|
||||
SET @indexes = (
|
||||
SELECT GROUP_CONCAT(DISTINCT CONCAT('DROP INDEX `', INDEX_NAME, '`') SEPARATOR ', ')
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_nodes'
|
||||
AND COLUMN_NAME = 'sop_version_id' AND INDEX_NAME <> 'PRIMARY'
|
||||
);
|
||||
SET @sql = IF(@indexes IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_nodes ', @indexes));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @indexes = (
|
||||
SELECT GROUP_CONCAT(DISTINCT CONCAT('DROP INDEX `', INDEX_NAME, '`') SEPARATOR ', ')
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_edges'
|
||||
AND COLUMN_NAME = 'sop_version_id' AND INDEX_NAME <> 'PRIMARY'
|
||||
);
|
||||
SET @sql = IF(@indexes IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_edges ', @indexes));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @indexes = (
|
||||
SELECT GROUP_CONCAT(DISTINCT CONCAT('DROP INDEX `', INDEX_NAME, '`') SEPARATOR ', ')
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_runs'
|
||||
AND COLUMN_NAME = 'sop_version_id' AND INDEX_NAME <> 'PRIMARY'
|
||||
);
|
||||
SET @sql = IF(@indexes IS NULL, 'SELECT 1', CONCAT('ALTER TABLE sop_runs ', @indexes));
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Add replacement indexes once.
|
||||
SET @sql = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_nodes' AND INDEX_NAME = 'uk_sop_nodes_key'),
|
||||
'SELECT 1', 'ALTER TABLE sop_nodes ADD UNIQUE KEY uk_sop_nodes_key (sop_id, node_key)'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_edges' AND INDEX_NAME = 'idx_sop_edges_source'),
|
||||
'SELECT 1', 'ALTER TABLE sop_edges ADD INDEX idx_sop_edges_source (sop_id, source_node_key, priority)'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Drop old columns only when they still exist.
|
||||
SET @sql = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_nodes' AND COLUMN_NAME = 'sop_version_id'),
|
||||
'ALTER TABLE sop_nodes DROP COLUMN sop_version_id', 'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_edges' AND COLUMN_NAME = 'sop_version_id'),
|
||||
'ALTER TABLE sop_edges DROP COLUMN sop_version_id', 'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = IF(
|
||||
EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sop_runs' AND COLUMN_NAME = 'sop_version_id'),
|
||||
'ALTER TABLE sop_runs DROP COLUMN sop_version_id', 'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
DROP TABLE IF EXISTS sop_versions;
|
||||
134
migrations/20260819_remove_sop_versions.sql
Normal file
134
migrations/20260819_remove_sop_versions.sql
Normal file
@@ -0,0 +1,134 @@
|
||||
-- Run this once on an existing MySQL database before deploying the
|
||||
-- single-version SOP application. It is intentionally explicit: the Go
|
||||
-- service only performs the data-preserving backfill and does not drop data.
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sops ADD COLUMN start_node_key VARCHAR(64) NOT NULL DEFAULT ''start''',
|
||||
'SELECT 1')
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sops' AND column_name = 'start_node_key'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
UPDATE sops s
|
||||
JOIN (
|
||||
SELECT sop_id, MAX(id) AS version_id
|
||||
FROM sop_versions
|
||||
WHERE status = 'published'
|
||||
GROUP BY sop_id
|
||||
) current ON current.sop_id = s.id
|
||||
JOIN sop_versions sv ON sv.id = current.version_id
|
||||
SET s.start_node_key = COALESCE(NULLIF(sv.start_node_key, ''), NULLIF(s.start_node_key, ''), 'start');
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_nodes ADD COLUMN sop_id BIGINT UNSIGNED NULL',
|
||||
'SELECT 1')
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_nodes' AND column_name = 'sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_edges ADD COLUMN sop_id BIGINT UNSIGNED NULL',
|
||||
'SELECT 1')
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_edges' AND column_name = 'sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_runs ADD COLUMN sop_id BIGINT UNSIGNED NULL',
|
||||
'SELECT 1')
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_runs' AND column_name = 'sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
UPDATE sop_nodes n JOIN sop_versions sv ON sv.id = n.sop_version_id
|
||||
SET n.sop_id = sv.sop_id WHERE n.sop_id IS NULL;
|
||||
UPDATE sop_edges e JOIN sop_versions sv ON sv.id = e.sop_version_id
|
||||
SET e.sop_id = sv.sop_id WHERE e.sop_id IS NULL;
|
||||
UPDATE sop_runs r JOIN sop_versions sv ON sv.id = r.sop_version_id
|
||||
SET r.sop_id = sv.sop_id WHERE r.sop_id IS NULL;
|
||||
|
||||
-- A single-version SOP can only have one graph. Keep the latest published
|
||||
-- version's nodes and edges; remove historical graph rows after the backup.
|
||||
DELETE n
|
||||
FROM sop_nodes n
|
||||
JOIN sop_versions sv ON sv.id = n.sop_version_id
|
||||
JOIN (
|
||||
SELECT sop_id, MAX(id) AS version_id
|
||||
FROM sop_versions
|
||||
WHERE status = 'published'
|
||||
GROUP BY sop_id
|
||||
) current ON current.sop_id = sv.sop_id
|
||||
WHERE sv.id <> current.version_id;
|
||||
|
||||
DELETE e
|
||||
FROM sop_edges e
|
||||
JOIN sop_versions sv ON sv.id = e.sop_version_id
|
||||
JOIN (
|
||||
SELECT sop_id, MAX(id) AS version_id
|
||||
FROM sop_versions
|
||||
WHERE status = 'published'
|
||||
GROUP BY sop_id
|
||||
) current ON current.sop_id = sv.sop_id
|
||||
WHERE sv.id <> current.version_id;
|
||||
|
||||
ALTER TABLE sop_nodes MODIFY COLUMN sop_id BIGINT UNSIGNED NOT NULL;
|
||||
ALTER TABLE sop_edges MODIFY COLUMN sop_id BIGINT UNSIGNED NOT NULL;
|
||||
ALTER TABLE sop_runs MODIFY COLUMN sop_id BIGINT UNSIGNED NOT NULL;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_nodes ADD INDEX idx_sop_nodes_sop_id (sop_id)',
|
||||
'SELECT 1')
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_nodes' AND index_name = 'idx_sop_nodes_sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_edges ADD INDEX idx_sop_edges_sop_id (sop_id)',
|
||||
'SELECT 1')
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_edges' AND index_name = 'idx_sop_edges_sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(COUNT(*) = 0,
|
||||
'ALTER TABLE sop_runs ADD INDEX idx_sop_runs_sop_id (sop_id)',
|
||||
'SELECT 1')
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE() AND table_name = 'sop_runs' AND index_name = 'idx_sop_runs_sop_id'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Verify the backfill before the destructive cleanup below.
|
||||
SELECT COUNT(*) AS nodes_without_sop FROM sop_nodes WHERE sop_id IS NULL;
|
||||
SELECT COUNT(*) AS edges_without_sop FROM sop_edges WHERE sop_id IS NULL;
|
||||
SELECT COUNT(*) AS runs_without_sop FROM sop_runs WHERE sop_id IS NULL;
|
||||
|
||||
-- After the three counts above are all zero, remove the old version fields.
|
||||
-- The old columns/table are intentionally retained by this backfill step.
|
||||
-- Run 20260819_drop_sop_versions.sql only after all three counts above are 0.
|
||||
4
migrations/20260820_drop_legacy_knowledge_cards.sql
Normal file
4
migrations/20260820_drop_legacy_knowledge_cards.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
-- The scenario knowledge graph uses knowledge_items and knowledge_relations.
|
||||
-- These legacy knowledge-card tables are no longer used by the application.
|
||||
DROP TABLE IF EXISTS knowledge_card_versions;
|
||||
DROP TABLE IF EXISTS knowledge_cards;
|
||||
Reference in New Issue
Block a user