fix(rectification): restore message actions and retry receipts
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
-- Regenerate the latest completed Assistant reply in place.
|
||||
-- This is a free, read-only Agent pass followed by one narrowly scoped turn
|
||||
-- text update. It never appends a turn or changes evidence, results, profiles,
|
||||
-- cases, candidate state, or billing records.
|
||||
|
||||
begin;
|
||||
|
||||
create table if not exists public.agentic_rectification_turn_regenerations (
|
||||
request_id uuid primary key,
|
||||
user_id uuid not null,
|
||||
case_id uuid not null references public.agentic_rectification_cases(id) on delete cascade,
|
||||
turn_id uuid not null references public.agentic_rectification_turns(id) on delete cascade,
|
||||
assistant_message text not null check (length(btrim(assistant_message)) > 0),
|
||||
created_at timestamptz not null default pg_catalog.now()
|
||||
);
|
||||
|
||||
create index if not exists agentic_rectification_turn_regenerations_case_idx
|
||||
on public.agentic_rectification_turn_regenerations (case_id, created_at desc);
|
||||
|
||||
alter table public.agentic_rectification_turn_regenerations enable row level security;
|
||||
revoke all on table public.agentic_rectification_turn_regenerations from public, anon, authenticated;
|
||||
grant all on table public.agentic_rectification_turn_regenerations to service_role;
|
||||
|
||||
create or replace function public.get_agentic_rectification_turn_regeneration(
|
||||
p_user_id uuid,
|
||||
p_case_id uuid,
|
||||
p_turn_id uuid,
|
||||
p_request_id uuid
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_row public.agentic_rectification_turn_regenerations%rowtype;
|
||||
begin
|
||||
if p_user_id is null or p_case_id is null or p_turn_id is null or p_request_id is null then
|
||||
raise exception 'agentic_rectification_regeneration_invalid_input' using errcode = 'P0001';
|
||||
end if;
|
||||
select * into v_row
|
||||
from public.agentic_rectification_turn_regenerations
|
||||
where request_id = p_request_id
|
||||
and user_id = p_user_id
|
||||
and case_id = p_case_id
|
||||
and turn_id = p_turn_id;
|
||||
if not found then return null; end if;
|
||||
return jsonb_build_object(
|
||||
'ok', true,
|
||||
'turn_id', v_row.turn_id,
|
||||
'assistant_message', v_row.assistant_message,
|
||||
'idempotent', true
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.get_agentic_rectification_turn_regeneration(uuid, uuid, uuid, uuid)
|
||||
from public, anon, authenticated;
|
||||
grant execute on function public.get_agentic_rectification_turn_regeneration(uuid, uuid, uuid, uuid)
|
||||
to service_role;
|
||||
|
||||
create or replace function public.regenerate_agentic_rectification_turn(
|
||||
p_user_id uuid,
|
||||
p_case_id uuid,
|
||||
p_session_id uuid,
|
||||
p_turn_id uuid,
|
||||
p_request_id uuid,
|
||||
p_assistant_message text
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_case public.agentic_rectification_cases%rowtype;
|
||||
v_turn public.agentic_rectification_turns%rowtype;
|
||||
v_latest_turn_id uuid;
|
||||
v_existing public.agentic_rectification_turn_regenerations%rowtype;
|
||||
v_message text;
|
||||
begin
|
||||
if p_user_id is null
|
||||
or p_case_id is null
|
||||
or p_session_id is null
|
||||
or p_turn_id is null
|
||||
or p_request_id is null
|
||||
or p_assistant_message is null
|
||||
or length(btrim(p_assistant_message)) = 0
|
||||
then
|
||||
raise exception 'agentic_rectification_regeneration_invalid_input' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
perform pg_catalog.pg_advisory_xact_lock(
|
||||
pg_catalog.hashtextextended('agentic-rectification-regenerate:' || p_case_id::text, 0)
|
||||
);
|
||||
|
||||
select * into v_case
|
||||
from public.agentic_rectification_cases
|
||||
where id = p_case_id and user_id = p_user_id;
|
||||
if not found then
|
||||
raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
|
||||
end if;
|
||||
if v_case.session_id <> p_session_id then
|
||||
raise exception 'agentic_rectification_case_session_mismatch' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
select * into v_existing
|
||||
from public.agentic_rectification_turn_regenerations
|
||||
where request_id = p_request_id;
|
||||
if found then
|
||||
if v_existing.user_id <> p_user_id
|
||||
or v_existing.case_id <> p_case_id
|
||||
or v_existing.turn_id <> p_turn_id
|
||||
then
|
||||
raise exception 'agentic_rectification_regeneration_request_conflict' using errcode = 'P0001';
|
||||
end if;
|
||||
return jsonb_build_object(
|
||||
'ok', true,
|
||||
'turn_id', v_existing.turn_id,
|
||||
'assistant_message', v_existing.assistant_message,
|
||||
'idempotent', true
|
||||
);
|
||||
end if;
|
||||
|
||||
if v_case.status in ('confirmed', 'closed', 'abandoned', 'superseded') then
|
||||
raise exception 'agentic_rectification_case_terminal' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
select * into v_turn
|
||||
from public.agentic_rectification_turns
|
||||
where id = p_turn_id and case_id = p_case_id;
|
||||
if not found then
|
||||
raise exception 'agentic_rectification_turn_not_found' using errcode = 'P0001';
|
||||
end if;
|
||||
if v_turn.status <> 'completed'
|
||||
or v_turn.assistant_message is null
|
||||
or length(btrim(v_turn.assistant_message)) = 0
|
||||
then
|
||||
raise exception 'agentic_rectification_turn_not_completed' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
select id into v_latest_turn_id
|
||||
from public.agentic_rectification_turns
|
||||
where case_id = p_case_id
|
||||
and status = 'completed'
|
||||
and assistant_message is not null
|
||||
and length(btrim(assistant_message)) > 0
|
||||
order by created_at desc, id desc
|
||||
limit 1;
|
||||
if v_latest_turn_id is distinct from p_turn_id then
|
||||
raise exception 'agentic_rectification_turn_not_latest' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
v_message := btrim(p_assistant_message);
|
||||
update public.agentic_rectification_turns
|
||||
set assistant_message = v_message,
|
||||
updated_at = pg_catalog.now()
|
||||
where id = p_turn_id and case_id = p_case_id;
|
||||
|
||||
insert into public.agentic_rectification_turn_regenerations (
|
||||
request_id, user_id, case_id, turn_id, assistant_message
|
||||
) values (
|
||||
p_request_id, p_user_id, p_case_id, p_turn_id, v_message
|
||||
);
|
||||
|
||||
return jsonb_build_object(
|
||||
'ok', true,
|
||||
'turn_id', p_turn_id,
|
||||
'assistant_message', v_message,
|
||||
'idempotent', false
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.regenerate_agentic_rectification_turn(uuid, uuid, uuid, uuid, uuid, text)
|
||||
from public, anon, authenticated;
|
||||
grant execute on function public.regenerate_agentic_rectification_turn(uuid, uuid, uuid, uuid, uuid, text)
|
||||
to service_role;
|
||||
|
||||
commit;
|
||||
Reference in New Issue
Block a user