create or replace function public.review_moderator_application(p_application uuid, p_decision text, p_reviewer text) returns text language plpgsql security invoker set search_path = '' as $$ declare application public.moderator_applications; account_role text; account_state text; begin if not exists (select 1 from public.moderator_bot_admin where discord_user_id = p_reviewer) then raise exception 'Admin permission required'; end if; if p_decision not in ('approved', 'declined') then raise exception 'Invalid decision'; end if; select * into application from public.moderator_applications where id = p_application for update; if not found or application.status <> 'pending' then raise exception 'Application is no longer pending'; end if; if p_decision = 'approved' then select role, account_status into account_role, account_state from public.profiles where id = application.profile_id for update; if not found or account_state <> 'active' or account_role <> 'contributor' then raise exception 'Account cannot be promoted'; end if; update public.profiles set role = 'moderator' where id = application.profile_id; end if; update public.moderator_applications set status = p_decision, reviewed_at = now(), reviewer_discord_id = p_reviewer where id = p_application; return p_decision; end; $$; revoke all on function public.review_moderator_application(uuid,text,text) from public, anon, authenticated; grant execute on function public.review_moderator_application(uuid,text,text) to service_role;