228 lines
9.8 KiB
PL/PgSQL
228 lines
9.8 KiB
PL/PgSQL
begin;
|
|
|
|
create or replace function public.admin_reset_customer_account(
|
|
p_actor_user_id uuid,
|
|
p_target_user_id uuid,
|
|
p_reason text,
|
|
p_request_id text
|
|
)
|
|
returns table (
|
|
user_id uuid,
|
|
email text,
|
|
credits integer,
|
|
chat_sessions_deleted integer,
|
|
chart_profiles_deleted integer,
|
|
synastry_reports_deleted integer
|
|
)
|
|
language plpgsql
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_actor_email text;
|
|
v_target_email text;
|
|
v_profile_email text;
|
|
v_credits integer;
|
|
v_identity_accounts bigint;
|
|
v_identity_sessions bigint;
|
|
v_admin_user_roles bigint;
|
|
v_credit_transactions bigint;
|
|
v_credit_cancellations bigint;
|
|
v_consultation_requests bigint;
|
|
v_rectification_billing bigint;
|
|
v_action_receipts bigint;
|
|
v_redeemed_codes bigint;
|
|
v_admin_audit_logs bigint;
|
|
v_chat_sessions_deleted integer;
|
|
v_chart_profiles_deleted integer;
|
|
v_synastry_reports_deleted integer;
|
|
begin
|
|
if not public.admin_has_permission(p_actor_user_id, 'admin.users.manage_roles') then
|
|
raise exception 'admin_permission_denied' using errcode = '42501';
|
|
end if;
|
|
if p_target_user_id is null then
|
|
raise exception 'admin_customer_scope_invalid' using errcode = '22023';
|
|
end if;
|
|
if char_length(btrim(coalesce(p_reason, ''))) not between 1 and 500 then
|
|
raise exception 'admin_reason_required' using errcode = '22023';
|
|
end if;
|
|
if char_length(btrim(coalesce(p_request_id, ''))) not between 1 and 200 then
|
|
raise exception 'admin_request_id_invalid' using errcode = '22023';
|
|
end if;
|
|
|
|
select lower(btrim(value.email))
|
|
into v_actor_email
|
|
from identity.users value
|
|
where value.id = p_actor_user_id;
|
|
if v_actor_email is null then
|
|
raise exception 'admin_user_not_found' using errcode = '22023';
|
|
end if;
|
|
|
|
select
|
|
identity_user.email,
|
|
profile.email,
|
|
profile.credits,
|
|
(select count(*) from identity.accounts value where value.user_id = identity_user.id),
|
|
(select count(*) from identity.sessions value where value.user_id = identity_user.id),
|
|
(select count(*) from public.admin_user_roles value where value.admin_user_id = identity_user.id),
|
|
(select count(*) from public.credit_transactions value where value.user_id = identity_user.id),
|
|
(select count(*) from public.credit_request_cancellations value where value.user_id = identity_user.id),
|
|
(select count(*) from public.consultation_requests value where value.user_id = identity_user.id),
|
|
(select count(*) from public.birth_time_rectification_billing value where value.user_id = identity_user.id),
|
|
(select count(*) from public.birth_time_rectification_action_receipts value where value.user_id = identity_user.id),
|
|
(select count(*) from public.redemption_codes value where value.redeemed_by = identity_user.id),
|
|
(select count(*) from audit.admin_audit_logs value where value.actor_user_id = identity_user.id)
|
|
into
|
|
v_target_email,
|
|
v_profile_email,
|
|
v_credits,
|
|
v_identity_accounts,
|
|
v_identity_sessions,
|
|
v_admin_user_roles,
|
|
v_credit_transactions,
|
|
v_credit_cancellations,
|
|
v_consultation_requests,
|
|
v_rectification_billing,
|
|
v_action_receipts,
|
|
v_redeemed_codes,
|
|
v_admin_audit_logs
|
|
from identity.users identity_user
|
|
join auth.users auth_user on auth_user.id = identity_user.id
|
|
join public.profiles profile on profile.id = identity_user.id
|
|
where identity_user.id = p_target_user_id
|
|
and lower(btrim(auth_user.email)) = lower(btrim(identity_user.email))
|
|
for update of identity_user, auth_user, profile;
|
|
|
|
if not found then
|
|
raise exception 'admin_customer_not_found_or_identity_bridge_mismatch' using errcode = 'P0002';
|
|
end if;
|
|
|
|
update public.profiles
|
|
set name = null,
|
|
birth_date = null,
|
|
birth_time = null,
|
|
country_code = null,
|
|
province_code = null,
|
|
city_code = null,
|
|
district_code = null,
|
|
onboarding_payload = null,
|
|
onboarding_version = null,
|
|
onboarding_generated_at = null,
|
|
latitude = null,
|
|
longitude = null,
|
|
timezone_offset = null,
|
|
reported_birth_time = null,
|
|
active_birth_time = null,
|
|
birth_time_source = null,
|
|
birth_time_period = null,
|
|
birth_time_clue = null,
|
|
uncertainty_before_minutes = null,
|
|
uncertainty_after_minutes = null,
|
|
birth_time_status = null,
|
|
rectification_confidence = null,
|
|
rectification_case_id = null,
|
|
birth_place_label = null,
|
|
birth_place_type = null,
|
|
birth_place_provider = null,
|
|
birth_place_provider_id = null,
|
|
timezone_id = null,
|
|
timezone_source = null,
|
|
updated_at = pg_catalog.now()
|
|
where id = p_target_user_id;
|
|
|
|
delete from public.chat_sessions value where value.user_id = p_target_user_id;
|
|
get diagnostics v_chat_sessions_deleted = row_count;
|
|
delete from public.chart_profiles value where value.user_id = p_target_user_id;
|
|
get diagnostics v_chart_profiles_deleted = row_count;
|
|
delete from public.synastry_reports value where value.user_id = p_target_user_id;
|
|
get diagnostics v_synastry_reports_deleted = row_count;
|
|
|
|
if exists (
|
|
select 1
|
|
from identity.users identity_user
|
|
join auth.users auth_user on auth_user.id = identity_user.id
|
|
join public.profiles profile on profile.id = identity_user.id
|
|
where identity_user.id = p_target_user_id
|
|
and (
|
|
identity_user.email is distinct from v_target_email
|
|
or auth_user.email is distinct from v_target_email
|
|
or profile.email is distinct from v_profile_email
|
|
or profile.credits is distinct from v_credits
|
|
or (select count(*) from identity.accounts value where value.user_id = identity_user.id) <> v_identity_accounts
|
|
or (select count(*) from identity.sessions value where value.user_id = identity_user.id) <> v_identity_sessions
|
|
or (select count(*) from public.admin_user_roles value where value.admin_user_id = identity_user.id) <> v_admin_user_roles
|
|
or (select count(*) from public.credit_transactions value where value.user_id = identity_user.id) <> v_credit_transactions
|
|
or (select count(*) from public.credit_request_cancellations value where value.user_id = identity_user.id) <> v_credit_cancellations
|
|
or (select count(*) from public.consultation_requests value where value.user_id = identity_user.id) <> v_consultation_requests
|
|
or (select count(*) from public.birth_time_rectification_billing value where value.user_id = identity_user.id) <> v_rectification_billing
|
|
or (select count(*) from public.birth_time_rectification_action_receipts value where value.user_id = identity_user.id) <> v_action_receipts
|
|
or (select count(*) from public.redemption_codes value where value.redeemed_by = identity_user.id) <> v_redeemed_codes
|
|
or (select count(*) from audit.admin_audit_logs value where value.actor_user_id = identity_user.id) <> v_admin_audit_logs
|
|
)
|
|
) then
|
|
raise exception 'admin_customer_preserved_state_changed' using errcode = 'P0001';
|
|
end if;
|
|
|
|
if exists (select 1 from public.chat_sessions value where value.user_id = p_target_user_id)
|
|
or exists (select 1 from public.chart_profiles value where value.user_id = p_target_user_id)
|
|
or exists (select 1 from public.synastry_reports value where value.user_id = p_target_user_id)
|
|
or exists (
|
|
select 1
|
|
from public.profiles profile
|
|
where profile.id = p_target_user_id
|
|
and (
|
|
profile.name is not null or profile.birth_date is not null or profile.birth_time is not null
|
|
or profile.country_code is not null or profile.province_code is not null or profile.city_code is not null or profile.district_code is not null
|
|
or profile.onboarding_payload is not null or profile.onboarding_version is not null or profile.onboarding_generated_at is not null
|
|
or profile.latitude is not null or profile.longitude is not null or profile.timezone_offset is not null
|
|
or profile.reported_birth_time is not null or profile.active_birth_time is not null or profile.birth_time_source is not null
|
|
or profile.birth_time_period is not null or profile.birth_time_clue is not null
|
|
or profile.uncertainty_before_minutes is not null or profile.uncertainty_after_minutes is not null
|
|
or profile.birth_time_status is not null or profile.rectification_confidence is not null or profile.rectification_case_id is not null
|
|
or profile.birth_place_label is not null or profile.birth_place_type is not null or profile.birth_place_provider is not null
|
|
or profile.birth_place_provider_id is not null or profile.timezone_id is not null or profile.timezone_source is not null
|
|
)
|
|
) then
|
|
raise exception 'admin_customer_reset_state_not_empty' using errcode = 'P0001';
|
|
end if;
|
|
|
|
insert into audit.admin_audit_logs (
|
|
actor_user_id, actor_email, actor_role, action, target_type, target_id,
|
|
after_value, request_id, permission_used, reason
|
|
) values (
|
|
p_actor_user_id, v_actor_email, 'admin', 'admin.customer.account.reset',
|
|
'customer', p_target_user_id,
|
|
jsonb_build_object(
|
|
'email', lower(btrim(v_target_email)),
|
|
'creditsPreserved', v_credits,
|
|
'chatSessionsDeleted', v_chat_sessions_deleted,
|
|
'chartProfilesDeleted', v_chart_profiles_deleted,
|
|
'synastryReportsDeleted', v_synastry_reports_deleted
|
|
),
|
|
btrim(p_request_id), 'admin.users.manage_roles', btrim(p_reason)
|
|
) on conflict do nothing;
|
|
|
|
return query select
|
|
p_target_user_id,
|
|
lower(btrim(v_target_email)),
|
|
v_credits,
|
|
v_chat_sessions_deleted,
|
|
v_chart_profiles_deleted,
|
|
v_synastry_reports_deleted;
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.admin_reset_customer_account(uuid, uuid, text, text)
|
|
from public, anon, authenticated, service_role;
|
|
|
|
do $$
|
|
begin
|
|
if exists (select 1 from pg_roles where rolname = 'admin_runtime') then
|
|
grant execute on function public.admin_reset_customer_account(uuid, uuid, text, text)
|
|
to admin_runtime;
|
|
end if;
|
|
end;
|
|
$$;
|
|
|
|
commit;
|