-- +goose Up -- Apply legacy ICAO staging data into `icaos`. -- Expected flow before this migration: -- 1) Run previous migration that creates `icao_old_import`. -- 2) Import old dump rows into `icao_old_import`. -- This migration maps old integer IDs into BINARY(16) UUID-style IDs, -- then upserts into `icaos` with `is_active` forced to 1. START TRANSACTION; INSERT INTO icao_old_id_map (old_id, new_id) SELECT s.id AS old_id, UNHEX(REPLACE( LOWER(CONCAT( LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'), '-', LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'), '-', '7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'), '-', LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'), '-', LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0') )), '-', '' )) AS new_id FROM icao_old_import s LEFT JOIN icao_old_id_map m ON m.old_id = s.id WHERE m.old_id IS NULL; INSERT INTO icaos ( id, icao_code, address, landline_number, mobile_number, email, is_active, created_at, updated_at ) SELECT m.new_id, LEFT(COALESCE(NULLIF(TRIM(s.code), ''), CONCAT('ICAO-', s.id)), 16) AS icao_code, LEFT(TRIM(COALESCE(s.address, '')), 256) AS address, LEFT(TRIM(COALESCE(s.phone, '')), 20) AS landline_number, LEFT(TRIM(COALESCE(s.mobile, '')), 20) AS mobile_number, LEFT(TRIM(COALESCE(s.email, '')), 128) AS email, 1 AS is_active, UTC_TIMESTAMP() AS created_at, UTC_TIMESTAMP() AS updated_at FROM icao_old_import s JOIN icao_old_id_map m ON m.old_id = s.id ON DUPLICATE KEY UPDATE icao_code = VALUES(icao_code), address = VALUES(address), landline_number = VALUES(landline_number), mobile_number = VALUES(mobile_number), email = VALUES(email), is_active = 1, updated_at = UTC_TIMESTAMP(); COMMIT; -- +goose Down -- Data migration is intentionally non-reversible. -- Keep imported data and ID mapping as audit trail. SELECT 1;