From b9c43d0960728ecbfb3f73441112f86ad4587629 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 21 May 2026 02:07:31 +0000 Subject: [PATCH] Fix log_event alight by avoiding unassigned record field reference The previous fix gated v_pred field access on `v_src is null`, but PL/pgSQL still resolves v_pred's tuple structure when compiling the CASE expression, raising "record v_pred is not assigned yet" on alight events where v_pred is never assigned. Move the prediction JSON build inside the board branch where v_pred is guaranteed assigned, and return a pre-built jsonb variable from the outer return. https://claude.ai/code/session_01P38Yh6XMhrQupsB2xSS8no --- .../0004_fix_log_event_alight_record.sql | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 supabase/migrations/0004_fix_log_event_alight_record.sql diff --git a/supabase/migrations/0004_fix_log_event_alight_record.sql b/supabase/migrations/0004_fix_log_event_alight_record.sql new file mode 100644 index 0000000..15d4df2 --- /dev/null +++ b/supabase/migrations/0004_fix_log_event_alight_record.sql @@ -0,0 +1,78 @@ +create or replace function commute.log_event( + p_secret text, + p_direction text, + p_event text, + p_weather text default 'unknown', + p_temp_c numeric default null, + p_lat numeric default null, + p_lon numeric default null, + p_note text default null +) returns jsonb +language plpgsql security definer +set search_path = commute, public +as $$ +declare + v_now timestamptz := now(); + v_local timestamp := (v_now at time zone 'Asia/Taipei'); + v_weekday smallint := extract(isodow from v_local)::smallint; + v_date date := v_local::date; + v_time time := v_local::time; + v_id uuid; + v_pred record; + v_src text := null; + v_prediction jsonb := null; +begin + if not commute.check_secret(p_secret) then + raise exception 'unauthorized' using errcode = '42501'; + end if; + + if p_direction not in ('to_work','from_work') then + raise exception 'invalid direction' using errcode = '22023'; + end if; + if p_event not in ('board','alight') then + raise exception 'invalid event' using errcode = '22023'; + end if; + + insert into commute.events + (event_at, local_date, local_time, weekday, direction, event, weather, temp_c, lat, lon, note) + values + (v_now, v_date, v_time, v_weekday, + p_direction, p_event, p_weather, p_temp_c, p_lat, p_lon, p_note) + returning id into v_id; + + if p_event = 'board' then + select * into v_pred from commute.predictions + where direction = p_direction + and weekday = v_weekday + and weather = p_weather + and n >= 3; + if found then v_src := 'weather'; end if; + + if not found then + select * into v_pred from commute.predictions_weekday + where direction = p_direction + and weekday = v_weekday + and n >= 3; + if found then v_src := 'weekday'; end if; + end if; + + if v_src is not null then + v_prediction := jsonb_build_object( + 'median_min', v_pred.median_min, + 'p90_min', v_pred.p90_min, + 'n', v_pred.n, + 'source', v_src + ); + end if; + end if; + + return jsonb_build_object( + 'id', v_id, + 'logged_at', v_now, + 'local_date', v_date, + 'local_time', v_time, + 'weekday', v_weekday, + 'prediction', v_prediction + ); +end; +$$;