fix(rectification): reset fresh cases to reported time
This commit is contained in:
+235
@@ -0,0 +1,235 @@
|
||||
-- Rectification focus RPC and persisted activity receipt consistency.
|
||||
-- Created 2026-08-15. Forward-only repair for the deployed V10 contract.
|
||||
|
||||
begin;
|
||||
|
||||
create or replace function public.set_agentic_rectification_conversation_focus(
|
||||
p_user_id uuid,
|
||||
p_case_id uuid,
|
||||
p_question_id text,
|
||||
p_intent text,
|
||||
p_target_evidence_id uuid,
|
||||
p_target_domain text,
|
||||
p_target_kind text,
|
||||
p_expected_answer_schema jsonb
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_case public.agentic_rectification_cases%rowtype;
|
||||
v_focus public.agentic_rectification_conversation_focuses%rowtype;
|
||||
begin
|
||||
if p_user_id is null or p_case_id is null
|
||||
or length(btrim(coalesce(p_question_id, ''))) = 0
|
||||
or length(btrim(coalesce(p_intent, ''))) = 0
|
||||
or p_expected_answer_schema is null
|
||||
or jsonb_typeof(p_expected_answer_schema) <> 'object' then
|
||||
raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
select * into v_case
|
||||
from public.agentic_rectification_cases
|
||||
where id = p_case_id and user_id = p_user_id
|
||||
for update;
|
||||
if not found then
|
||||
raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
|
||||
end if;
|
||||
if v_case.status in ('confirmed', 'closed', 'abandoned', 'superseded') then
|
||||
raise exception 'agentic_rectification_case_terminal' using errcode = 'P0001';
|
||||
end if;
|
||||
if p_target_evidence_id is not null and not exists (
|
||||
select 1 from public.agentic_rectification_evidence
|
||||
where id = p_target_evidence_id and case_id = p_case_id
|
||||
) then
|
||||
raise exception 'agentic_rectification_evidence_not_found' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
select * into v_focus
|
||||
from public.agentic_rectification_conversation_focuses
|
||||
where case_id = p_case_id and question_id = p_question_id;
|
||||
if found then
|
||||
if v_focus.status = 'active'
|
||||
and v_focus.intent = p_intent
|
||||
and v_focus.target_evidence_id is not distinct from p_target_evidence_id
|
||||
and v_focus.target_domain is not distinct from p_target_domain
|
||||
and v_focus.target_kind is not distinct from p_target_kind
|
||||
and v_focus.expected_answer_schema = p_expected_answer_schema then
|
||||
return jsonb_build_object(
|
||||
'focus', to_jsonb(v_focus),
|
||||
'idempotent', true
|
||||
);
|
||||
end if;
|
||||
raise exception 'agentic_rectification_focus_idempotency_conflict' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
update public.agentic_rectification_conversation_focuses
|
||||
set status = 'superseded',
|
||||
resolved_at = pg_catalog.now(),
|
||||
updated_at = pg_catalog.now()
|
||||
where case_id = p_case_id and status = 'active';
|
||||
|
||||
insert into public.agentic_rectification_conversation_focuses (
|
||||
case_id, question_id, intent, target_evidence_id, target_domain, target_kind,
|
||||
expected_answer_schema, status, asked_at
|
||||
) values (
|
||||
p_case_id, p_question_id, p_intent, p_target_evidence_id, p_target_domain, p_target_kind,
|
||||
p_expected_answer_schema, 'active', pg_catalog.now()
|
||||
) returning * into v_focus;
|
||||
|
||||
return jsonb_build_object(
|
||||
'focus', to_jsonb(v_focus),
|
||||
'idempotent', false
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.set_agentic_rectification_conversation_focus(
|
||||
uuid, uuid, text, text, uuid, text, text, jsonb
|
||||
) from public, anon, authenticated;
|
||||
grant execute on function public.set_agentic_rectification_conversation_focus(
|
||||
uuid, uuid, text, text, uuid, text, text, jsonb
|
||||
) to service_role;
|
||||
|
||||
create or replace function public.get_agentic_rectification_turn_receipt(
|
||||
p_user_id uuid,
|
||||
p_case_id uuid,
|
||||
p_turn_id uuid
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_turn public.agentic_rectification_turns%rowtype;
|
||||
v_case public.agentic_rectification_cases%rowtype;
|
||||
v_attempt_id uuid;
|
||||
v_phases jsonb;
|
||||
v_tool_activities jsonb;
|
||||
v_tools jsonb;
|
||||
v_methods jsonb;
|
||||
v_engine_version text;
|
||||
begin
|
||||
if p_user_id is null or p_case_id is null or p_turn_id is null then
|
||||
raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
|
||||
end if;
|
||||
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;
|
||||
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;
|
||||
|
||||
v_attempt_id := v_turn.successful_attempt_id;
|
||||
if v_attempt_id is null then
|
||||
select id into v_attempt_id
|
||||
from public.agentic_rectification_run_attempts
|
||||
where turn_id = p_turn_id
|
||||
order by attempt_number desc
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
select coalesce(jsonb_agg(
|
||||
jsonb_build_object('phase', rp.phase, 'tool', rp.tool_name)
|
||||
order by rp.sequence, rp.created_at, rp.id
|
||||
), '[]'::jsonb) into v_phases
|
||||
from public.agentic_rectification_run_phases rp
|
||||
where rp.turn_id = p_turn_id
|
||||
and (
|
||||
(v_attempt_id is not null and rp.attempt_id = v_attempt_id)
|
||||
or (v_attempt_id is null and rp.attempt_id is null)
|
||||
);
|
||||
|
||||
with latest_terminal as materialized (
|
||||
select distinct on (tr.tool_name)
|
||||
tr.id,
|
||||
tr.tool_name,
|
||||
tr.status,
|
||||
tr.executed_methods,
|
||||
tr.started_at
|
||||
from public.agentic_rectification_tool_receipts tr
|
||||
where tr.turn_id = p_turn_id
|
||||
and tr.status in ('completed', 'failed')
|
||||
and (
|
||||
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
||||
or (v_attempt_id is null and tr.attempt_id is null)
|
||||
)
|
||||
order by tr.tool_name, tr.started_at desc, tr.id desc
|
||||
)
|
||||
select
|
||||
coalesce(jsonb_agg(
|
||||
jsonb_build_object(
|
||||
'tool', terminal.tool_name,
|
||||
'status', terminal.status,
|
||||
'methods', case
|
||||
when terminal.status = 'completed' then terminal.executed_methods
|
||||
else '[]'::jsonb
|
||||
end
|
||||
) order by terminal.started_at, terminal.id
|
||||
), '[]'::jsonb),
|
||||
coalesce(jsonb_agg(terminal.tool_name order by terminal.started_at, terminal.id)
|
||||
filter (where terminal.status = 'completed'), '[]'::jsonb)
|
||||
into v_tool_activities, v_tools
|
||||
from latest_terminal terminal;
|
||||
|
||||
with latest_terminal as materialized (
|
||||
select distinct on (tr.tool_name)
|
||||
tr.tool_name,
|
||||
tr.status,
|
||||
tr.executed_methods
|
||||
from public.agentic_rectification_tool_receipts tr
|
||||
where tr.turn_id = p_turn_id
|
||||
and tr.status in ('completed', 'failed')
|
||||
and (
|
||||
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
||||
or (v_attempt_id is null and tr.attempt_id is null)
|
||||
)
|
||||
order by tr.tool_name, tr.started_at desc, tr.id desc
|
||||
)
|
||||
select coalesce(jsonb_agg(method order by method), '[]'::jsonb) into v_methods
|
||||
from (
|
||||
select distinct jsonb_array_elements_text(terminal.executed_methods) as method
|
||||
from latest_terminal terminal
|
||||
where terminal.status = 'completed'
|
||||
) methods;
|
||||
|
||||
select max(tr.engine_version) into v_engine_version
|
||||
from public.agentic_rectification_tool_receipts tr
|
||||
where tr.turn_id = p_turn_id and tr.engine_version is not null
|
||||
and (
|
||||
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
||||
or (v_attempt_id is null and tr.attempt_id is null)
|
||||
);
|
||||
|
||||
return jsonb_build_object(
|
||||
'turn_id', v_turn.id,
|
||||
'attempt_id', v_attempt_id,
|
||||
'status', v_turn.status,
|
||||
'skill_name', v_case.skill_name,
|
||||
'skill_version', v_case.skill_version,
|
||||
'engine_version', v_engine_version,
|
||||
'phases', v_phases,
|
||||
'tool_activities', v_tool_activities,
|
||||
'tools', v_tools,
|
||||
'methods', v_methods,
|
||||
'started_at', v_turn.created_at,
|
||||
'completed_at', v_turn.completed_at
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.get_agentic_rectification_turn_receipt(uuid, uuid, uuid)
|
||||
from public, anon, authenticated;
|
||||
grant execute on function public.get_agentic_rectification_turn_receipt(uuid, uuid, uuid)
|
||||
to service_role;
|
||||
|
||||
commit;
|
||||
Reference in New Issue
Block a user