Files
Jyotisha/frontend/supabase/migrations/20260816010000_admin_redemption_admin_access.sql
T
Jesse_Chen 945d61fa1c
Independent Staging Quality Gate / validate (push) Failing after 12m38s
Independent Staging Quality Gate / publish (push) Has been skipped
fix(admin): remove redundant confirmations and repair code access
2026-08-16 17:55:15 +08:00

107 lines
4.6 KiB
PL/PgSQL

-- Redemption-code management is an ordinary admin-console capability.
-- Keep actor verification, trusted request IDs and server-owned audit markers,
-- but do not reuse the narrower billing adjustment permission.
create or replace function public.require_admin_redemption_reason()
returns trigger
language plpgsql
set search_path = ''
as $$
declare
v_reason text := nullif(btrim(current_setting('app.admin_redemption_reason', true)), '');
begin
if new.action in ('redemption_code.create','redemption_code.update','redemption_code.revoke') then
if v_reason is null or char_length(v_reason) > 500 then
raise exception 'admin_reason_required' using errcode='22023';
end if;
new.permission_used := 'admin.access';
new.reason := v_reason;
end if;
return new;
end;
$$;
revoke all on function public.require_admin_redemption_reason()
from public, anon, authenticated, service_role;
create or replace function public.admin_create_redemption_codes(
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_codes jsonb,p_reason text
)
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
language plpgsql security definer set search_path = ''
as $$
begin
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
raise exception 'admin_permission_denied' using errcode='42501';
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;
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
return query select * from public.admin_create_redemption_codes(
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_codes
);
end;
$$;
create or replace function public.admin_update_redemption_code(
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_code_id uuid,
p_set_note boolean,p_note text,p_set_expires_at boolean,p_expires_at timestamptz,p_reason text
)
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
language plpgsql security definer set search_path = ''
as $$
begin
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
raise exception 'admin_permission_denied' using errcode='42501';
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;
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
return query select * from public.admin_update_redemption_code(
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_code_id,
p_set_note,p_note,p_set_expires_at,p_expires_at
);
end;
$$;
create or replace function public.admin_revoke_redemption_code(
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_code_id uuid,p_reason text
)
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
language plpgsql security definer set search_path = ''
as $$
begin
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
raise exception 'admin_permission_denied' using errcode='42501';
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;
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
return query select * from public.admin_revoke_redemption_code(
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_code_id
);
end;
$$;
revoke all on function public.admin_create_redemption_codes(uuid,text,text,text,jsonb,text),
public.admin_update_redemption_code(uuid,text,text,text,uuid,boolean,text,boolean,timestamptz,text),
public.admin_revoke_redemption_code(uuid,text,text,text,uuid,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_create_redemption_codes(uuid,text,text,text,jsonb,text),
public.admin_update_redemption_code(uuid,text,text,text,uuid,boolean,text,boolean,timestamptz,text),
public.admin_revoke_redemption_code(uuid,text,text,text,uuid,text)
to admin_runtime;
end if;
end
$$;