137 lines
5.0 KiB
PL/PgSQL
137 lines
5.0 KiB
PL/PgSQL
begin;
|
|
|
|
create or replace function public.save_guided_birth_time_candidate(
|
|
p_user_id uuid,
|
|
p_case_id uuid,
|
|
p_result_id uuid,
|
|
p_action_id uuid,
|
|
p_expected_version integer,
|
|
p_turn_state jsonb
|
|
)
|
|
returns void
|
|
language plpgsql
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
current_version integer;
|
|
receipts uuid[];
|
|
begin
|
|
select turn_version, processed_action_ids
|
|
into current_version, receipts
|
|
from public.birth_time_rectification_cases
|
|
where id = p_case_id and user_id = p_user_id
|
|
for update;
|
|
|
|
if not found then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
if p_action_id = any(receipts) then return; end if;
|
|
if current_version <> p_expected_version then raise exception 'stale_guided_candidate_turn'; end if;
|
|
if (p_turn_state ->> 'turnVersion')::integer <> p_expected_version + 1
|
|
or p_turn_state #>> '{nextAction,kind}' <> 'candidate_saved'
|
|
or p_turn_state #>> '{nextAction,resultId}' <> p_result_id::text
|
|
then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
|
|
update public.birth_time_rectification_cases
|
|
set candidate_saved_at = now(),
|
|
turn_version = p_expected_version + 1,
|
|
turn_state = p_turn_state,
|
|
processed_action_ids = (array_append(processed_action_ids, p_action_id))[
|
|
greatest(cardinality(processed_action_ids) + 2 - 100, 1):cardinality(processed_action_ids) + 1
|
|
],
|
|
updated_at = now()
|
|
where id = p_case_id
|
|
and user_id = p_user_id
|
|
and turn_version = p_expected_version
|
|
and candidate_result_id = p_result_id
|
|
and status = 'candidate'
|
|
and candidate_result ->> 'confidence' = 'medium'
|
|
and (
|
|
(
|
|
turn_state #>> '{nextAction,kind}' = 'present_medium_result'
|
|
and turn_state #>> '{nextAction,resultId}' = p_result_id::text
|
|
)
|
|
or turn_state is null
|
|
or turn_state = '{}'::jsonb
|
|
);
|
|
if not found then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
end;
|
|
$$;
|
|
|
|
create or replace function public.confirm_guided_birth_time_candidate(
|
|
p_user_id uuid,
|
|
p_case_id uuid,
|
|
p_result_id uuid,
|
|
p_time time without time zone,
|
|
p_action_id uuid,
|
|
p_expected_version integer,
|
|
p_snapshot jsonb,
|
|
p_turn_state jsonb
|
|
)
|
|
returns void
|
|
language plpgsql
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
current_version integer;
|
|
receipts uuid[];
|
|
begin
|
|
select turn_version, processed_action_ids
|
|
into current_version, receipts
|
|
from public.birth_time_rectification_cases
|
|
where id = p_case_id and user_id = p_user_id
|
|
for update;
|
|
|
|
if not found then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
if p_action_id = any(receipts) then return; end if;
|
|
if current_version <> p_expected_version then raise exception 'stale_guided_candidate_turn'; end if;
|
|
if (p_turn_state ->> 'turnVersion')::integer <> p_expected_version + 1
|
|
or p_turn_state #>> '{nextAction,kind}' <> 'ready'
|
|
or p_turn_state #>> '{nextAction,activeTime}' <> to_char(p_time, 'HH24:MI')
|
|
or p_snapshot ->> 'activeTime' <> to_char(p_time, 'HH24:MI')
|
|
then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
|
|
update public.birth_time_rectification_cases
|
|
set status = 'confirmed', journey_snapshot = p_snapshot,
|
|
confirmed_time = p_time, confirmed_at = now(),
|
|
turn_version = p_expected_version + 1, turn_state = p_turn_state,
|
|
processed_action_ids = (array_append(processed_action_ids, p_action_id))[
|
|
greatest(cardinality(processed_action_ids) + 2 - 100, 1):cardinality(processed_action_ids) + 1
|
|
],
|
|
updated_at = now()
|
|
where id = p_case_id
|
|
and user_id = p_user_id
|
|
and turn_version = p_expected_version
|
|
and candidate_result_id = p_result_id
|
|
and status = 'confirming'
|
|
and candidate_result ->> 'confidence' = 'high'
|
|
and (candidate_result ->> 'canApply')::boolean is true
|
|
and candidate_result #>> '{winningSegment,representativeTime}' = to_char(p_time, 'HH24:MI')
|
|
and (
|
|
(
|
|
turn_state #>> '{nextAction,kind}' = 'request_candidate_confirmation'
|
|
and turn_state #>> '{nextAction,resultId}' = p_result_id::text
|
|
)
|
|
or turn_state is null
|
|
or turn_state = '{}'::jsonb
|
|
);
|
|
if not found then raise exception 'invalid_guided_candidate_turn'; end if;
|
|
|
|
update public.profiles
|
|
set active_birth_time = p_time, birth_time = p_time, birth_time_status = 'confirmed'
|
|
where id = p_user_id and rectification_case_id = p_case_id;
|
|
if not found then raise exception 'birth_time_profile_not_found'; end if;
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.save_guided_birth_time_candidate(uuid, uuid, uuid, uuid, integer, jsonb)
|
|
from public, anon, authenticated;
|
|
grant execute on function public.save_guided_birth_time_candidate(uuid, uuid, uuid, uuid, integer, jsonb)
|
|
to service_role;
|
|
revoke all on function public.confirm_guided_birth_time_candidate(uuid, uuid, uuid, time without time zone, uuid, integer, jsonb, jsonb)
|
|
from public, anon, authenticated;
|
|
grant execute on function public.confirm_guided_birth_time_candidate(uuid, uuid, uuid, time without time zone, uuid, integer, jsonb, jsonb)
|
|
to service_role;
|
|
|
|
commit;
|