-- +goose Up -- Normalize legacy HEMS duty roster artifacts into neutral duty roster naming. -- 1) Rename legacy tables when old name exists and new name does not. SET @has_old_rosters := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_rosters' ); SET @has_new_rosters := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters' ); SET @sql_rename_rosters := IF(@has_old_rosters = 1 AND @has_new_rosters = 0, 'RENAME TABLE hems_duty_rosters TO duty_rosters', 'SELECT 1' ); PREPARE stmt_rename_rosters FROM @sql_rename_rosters; EXECUTE stmt_rename_rosters; DEALLOCATE PREPARE stmt_rename_rosters; SET @has_old_crews := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_roster_crews' ); SET @has_new_crews := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_roster_crews' ); SET @sql_rename_crews := IF(@has_old_crews = 1 AND @has_new_crews = 0, 'RENAME TABLE hems_duty_roster_crews TO duty_roster_crews', 'SELECT 1' ); PREPARE stmt_rename_crews FROM @sql_rename_crews; EXECUTE stmt_rename_crews; DEALLOCATE PREPARE stmt_rename_crews; -- 2) Rename legacy header column. SET @has_duty_rosters := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters' ); SET @has_hems_base_id := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters' AND COLUMN_NAME = 'hems_base_id' ); SET @has_base_id := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters' AND COLUMN_NAME = 'base_id' ); SET @sql_rename_base_col := IF(@has_duty_rosters = 1 AND @has_hems_base_id = 1 AND @has_base_id = 0, 'ALTER TABLE duty_rosters RENAME COLUMN hems_base_id TO base_id', 'SELECT 1' ); PREPARE stmt_rename_base_col FROM @sql_rename_base_col; EXECUTE stmt_rename_base_col; DEALLOCATE PREPARE stmt_rename_base_col; -- 3) Ensure confirm_at exists on normalized crews table. SET @has_confirm_at_new_crews := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_roster_crews' AND COLUMN_NAME = 'confirm_at' ); SET @sql_add_confirm_at_new_crews := IF(@has_new_crews = 1 AND @has_confirm_at_new_crews = 0, 'ALTER TABLE duty_roster_crews ADD COLUMN confirm_at DATETIME NULL AFTER email', 'SELECT 1' ); PREPARE stmt_add_confirm_at_new_crews FROM @sql_add_confirm_at_new_crews; EXECUTE stmt_add_confirm_at_new_crews; DEALLOCATE PREPARE stmt_add_confirm_at_new_crews; -- 4) If legacy crew table still exists, keep it compatible too. SET @has_confirm_at_old_crews := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_roster_crews' AND COLUMN_NAME = 'confirm_at' ); SET @sql_add_confirm_at_old_crews := IF(@has_old_crews = 1 AND @has_confirm_at_old_crews = 0, 'ALTER TABLE hems_duty_roster_crews ADD COLUMN confirm_at DATETIME NULL AFTER email', 'SELECT 1' ); PREPARE stmt_add_confirm_at_old_crews FROM @sql_add_confirm_at_old_crews; EXECUTE stmt_add_confirm_at_old_crews; DEALLOCATE PREPARE stmt_add_confirm_at_old_crews; -- 5) Normalize legacy FK references to duty_rosters where needed. SET @fk_roster_crews_ref := ( SELECT COALESCE(MAX(kcu.REFERENCED_TABLE_NAME), '') FROM information_schema.TABLE_CONSTRAINTS tc JOIN information_schema.KEY_COLUMN_USAGE kcu ON tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA AND tc.TABLE_NAME = kcu.TABLE_NAME AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME WHERE tc.CONSTRAINT_SCHEMA = DATABASE() AND tc.TABLE_NAME = 'roster_crews' AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY' AND tc.CONSTRAINT_NAME = 'fk_roster_crews_roster' ); SET @sql_rewire_roster_crews_fk := IF(@has_new_rosters = 1 AND @fk_roster_crews_ref = 'hems_duty_rosters', 'ALTER TABLE roster_crews DROP FOREIGN KEY fk_roster_crews_roster, ADD CONSTRAINT fk_roster_crews_roster FOREIGN KEY (roster_id) REFERENCES duty_rosters(id)', 'SELECT 1' ); PREPARE stmt_rewire_roster_crews_fk FROM @sql_rewire_roster_crews_fk; EXECUTE stmt_rewire_roster_crews_fk; DEALLOCATE PREPARE stmt_rewire_roster_crews_fk; SET @fk_other_persons_ref := ( SELECT COALESCE(MAX(kcu.REFERENCED_TABLE_NAME), '') FROM information_schema.TABLE_CONSTRAINTS tc JOIN information_schema.KEY_COLUMN_USAGE kcu ON tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA AND tc.TABLE_NAME = kcu.TABLE_NAME AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME WHERE tc.CONSTRAINT_SCHEMA = DATABASE() AND tc.TABLE_NAME = 'duty_roster_other_persons' AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY' AND tc.CONSTRAINT_NAME = 'fk_duty_roster_other_persons_roster' ); SET @sql_rewire_other_persons_fk := IF(@has_new_rosters = 1 AND @fk_other_persons_ref = 'hems_duty_rosters', 'ALTER TABLE duty_roster_other_persons DROP FOREIGN KEY fk_duty_roster_other_persons_roster, ADD CONSTRAINT fk_duty_roster_other_persons_roster FOREIGN KEY (roster_id) REFERENCES duty_rosters(id)', 'SELECT 1' ); PREPARE stmt_rewire_other_persons_fk FROM @sql_rewire_other_persons_fk; EXECUTE stmt_rewire_other_persons_fk; DEALLOCATE PREPARE stmt_rewire_other_persons_fk; -- +goose Down -- Intentionally no-op: legacy normalization is one-way to keep schema stable. SELECT 1;