Files
Jyotisha/frontend/supabase/migrations/20260723020000_mark_captured_conversational_messages.sql
T
2026-07-23 14:58:56 +08:00

153 lines
5.3 KiB
PL/PgSQL

-- Only render message history that was captured verbatim at answer time.
-- Evidence rows created before the history contract contain normalized event
-- summaries, not guaranteed user-authored chat text, so they must not be used
-- to reconstruct a conversation.
alter table public.birth_time_rectification_turns
add column if not exists user_message_captured boolean not null default false;
create or replace function public.load_conversational_rectification_case_with_history(
p_user_id uuid,
p_case_id uuid default null
)
returns jsonb
language plpgsql
stable
security definer
set search_path = ''
as $$
declare
v_loaded jsonb;
v_case_id uuid;
begin
v_loaded := public.load_conversational_rectification_case(p_user_id, p_case_id);
if v_loaded is null then
return null;
end if;
v_case_id := (v_loaded ->> 'case_id')::uuid;
return v_loaded || pg_catalog.jsonb_build_object(
'message_history', coalesce((
select pg_catalog.jsonb_agg(
pg_catalog.jsonb_build_object(
'turnVersion', turn_row.turn_version,
'userMessage', turn_row.user_message,
'narrative', turn_row.narrative
) order by turn_row.turn_version
)
from (
select history.turn_version, history.user_message, history.narrative
from public.birth_time_rectification_turns history
where history.case_id = v_case_id
and history.user_message_captured is true
order by history.turn_version desc
limit 200
) turn_row
), '[]'::jsonb)
);
end;
$$;
create or replace function public.save_conversational_rectification_turn_with_history(
p_user_id uuid,
p_case_id uuid,
p_expected_version bigint,
p_action_id uuid,
p_turn jsonb,
p_evidence jsonb,
p_validation_receipt jsonb,
p_private_candidate jsonb,
p_command_fingerprint text,
p_user_message text
)
returns jsonb
language plpgsql
security definer
set search_path = ''
as $$
declare
v_response jsonb;
v_saved_user_message text;
begin
if p_user_message is null
or public.conversational_rectification_text_utf16_length(p_user_message) not between 1 and 4000
or public.conversational_rectification_text_is_nonblank(p_user_message) is not true then
raise exception 'conversational_action_conflict' using errcode = 'P0001';
end if;
v_response := public.save_conversational_rectification_turn(
p_user_id, p_case_id, p_expected_version, p_action_id, p_turn, p_evidence,
p_validation_receipt, p_private_candidate, p_command_fingerprint
);
update public.birth_time_rectification_turns
set user_message = coalesce(user_message, p_user_message),
user_message_captured = true
where case_id = p_case_id
and turn_version = p_expected_version + 1
returning user_message into v_saved_user_message;
if not found or v_saved_user_message is distinct from p_user_message then
raise exception 'conversational_action_conflict' using errcode = 'P0001';
end if;
return v_response;
end;
$$;
create or replace function public.complete_conversational_rectification_with_range_and_history(
p_user_id uuid,
p_case_id uuid,
p_expected_version bigint,
p_action_id uuid,
p_turn jsonb,
p_evidence jsonb,
p_validation_receipt jsonb,
p_private_candidate jsonb,
p_command_fingerprint text,
p_user_message text
)
returns jsonb
language plpgsql
security definer
set search_path = ''
as $$
declare
v_response jsonb;
v_saved_user_message text;
begin
if p_user_message is null
or public.conversational_rectification_text_utf16_length(p_user_message) not between 1 and 4000
or public.conversational_rectification_text_is_nonblank(p_user_message) is not true then
raise exception 'conversational_action_conflict' using errcode = 'P0001';
end if;
v_response := public.complete_conversational_rectification_with_range(
p_user_id, p_case_id, p_expected_version, p_action_id, p_turn, p_evidence,
p_validation_receipt, p_private_candidate, p_command_fingerprint
);
update public.birth_time_rectification_turns
set user_message = coalesce(user_message, p_user_message),
user_message_captured = true
where case_id = p_case_id
and turn_version = p_expected_version + 1
returning user_message into v_saved_user_message;
if not found or v_saved_user_message is distinct from p_user_message then
raise exception 'conversational_action_conflict' using errcode = 'P0001';
end if;
return v_response;
end;
$$;
revoke all on function public.load_conversational_rectification_case_with_history(uuid, uuid)
from public, anon, authenticated;
revoke all on function public.save_conversational_rectification_turn_with_history(
uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) from public, anon, authenticated;
revoke all on function public.complete_conversational_rectification_with_range_and_history(
uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) from public, anon, authenticated;
grant execute on function public.load_conversational_rectification_case_with_history(uuid, uuid)
to service_role;
grant execute on function public.save_conversational_rectification_turn_with_history(
uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) to service_role;
grant execute on function public.complete_conversational_rectification_with_range_and_history(
uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) to service_role;