-- Update only the legacy Jetson bridge URL; preserve array order and all other settings. WITH replacement AS ( SELECT 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/slam-ros-bridge/jetson-orin/latest/slam-ros-bridge-jetson-orin.tar.zst'::text AS old_url, 'https://pub-ca72c40797144462bdb7d200c215d361.r2.dev/studio-artifacts/runtime-images/slam-ros-bridge/arm64/20260819-0659d4cf5578/slam-ros-bridge-jetson-orin.tar.zst'::text AS new_url ), updated_profiles AS ( SELECT profile.id, jsonb_agg( CASE WHEN artifact->>'image' = 'slam-ros-bridge:jetson_orin' AND split_part(artifact->>'url', '?', 1) = replacement.old_url THEN jsonb_set(artifact, '{url}', to_jsonb(replacement.new_url)) ELSE artifact END ORDER BY ordinal ) AS images FROM "course_environment_profiles" profile CROSS JOIN replacement CROSS JOIN LATERAL jsonb_array_elements( CASE WHEN jsonb_typeof(profile.config::jsonb->'runtimeImages') = 'array' THEN profile.config::jsonb->'runtimeImages' ELSE '[]'::jsonb END ) WITH ORDINALITY AS entries(artifact, ordinal) WHERE profile.config::jsonb->>'target' = 'remote-jetson' GROUP BY profile.id HAVING bool_or(artifact->>'image' = 'slam-ros-bridge:jetson_orin' AND split_part(artifact->>'url', '?', 1) = replacement.old_url) ) UPDATE "course_environment_profiles" profile SET config = jsonb_set(profile.config::jsonb, '{runtimeImages}', updated.images), updated_at = CURRENT_TIMESTAMP FROM updated_profiles updated WHERE profile.id = updated.id RETURNING profile.id, profile.config::jsonb->'runtimeImages' AS runtime_images;