merge: sync latest staging into rectification v9
# Conflicts: # docs/BUG_HISTORY.md
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user