UPDATE platform_user_vehicle SET valid_from = granted_at WHERE valid_from IS NULL; CREATE INDEX idx_platform_user_vehicle_active_time ON platform_user_vehicle(user_id, valid_from, valid_to, vin); CREATE TABLE IF NOT EXISTS platform_user_vehicle_grant_history ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id BIGINT UNSIGNED NOT NULL, vin VARCHAR(64) NOT NULL, valid_from DATETIME(3) NOT NULL, valid_to DATETIME(3) NULL, source_system VARCHAR(32) NOT NULL DEFAULT 'manual', external_ref VARCHAR(128) NOT NULL DEFAULT '', granted_by VARCHAR(96) NOT NULL, revoked_by VARCHAR(96) NOT NULL DEFAULT '', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), INDEX idx_platform_vehicle_grant_user_time (user_id, valid_from, valid_to), INDEX idx_platform_vehicle_grant_vin_time (vin, valid_from, valid_to), CONSTRAINT fk_platform_vehicle_grant_user FOREIGN KEY (user_id) REFERENCES platform_user(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO platform_user_vehicle_grant_history( user_id, vin, valid_from, valid_to, source_system, external_ref, granted_by, revoked_by ) SELECT current_grant.user_id, current_grant.vin, COALESCE(current_grant.valid_from, current_grant.granted_at), current_grant.valid_to, current_grant.source_system, current_grant.external_ref, current_grant.granted_by, CASE WHEN current_grant.valid_to IS NULL THEN '' ELSE 'migration' END FROM platform_user_vehicle current_grant WHERE NOT EXISTS ( SELECT 1 FROM platform_user_vehicle_grant_history history WHERE history.user_id = current_grant.user_id AND history.vin = current_grant.vin AND history.valid_from = COALESCE(current_grant.valid_from, current_grant.granted_at) );