REVOKE EXECUTE ON FUNCTION public.notify_booking_change() FROM anon, authenticated;
REVOKE EXECUTE ON FUNCTION public.notify_report_published() FROM anon, authenticated;
REVOKE EXECUTE ON FUNCTION public.notify_review_approved() FROM anon, authenticated;
REVOKE EXECUTE ON FUNCTION public.notify_payment_change() FROM anon, authenticated;
REVOKE EXECUTE ON FUNCTION public.notify_admins(text,text) FROM PUBLIC;

CREATE OR REPLACE FUNCTION public.guard_payment_update()
RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$
BEGIN
  IF public.has_role(auth.uid(), 'admin') THEN
    RETURN NEW;
  END IF;
  IF NEW.amount IS DISTINCT FROM OLD.amount
     OR NEW.currency IS DISTINCT FROM OLD.currency
     OR NEW.reference IS DISTINCT FROM OLD.reference
     OR NEW.user_id IS DISTINCT FROM OLD.user_id
     OR NEW.reviewed_by IS DISTINCT FROM OLD.reviewed_by
     OR NEW.admin_note IS DISTINCT FROM OLD.admin_note THEN
    RAISE EXCEPTION 'Not allowed to modify this payment';
  END IF;
  IF NEW.status IS DISTINCT FROM OLD.status
     AND NOT (OLD.status IN ('awaiting_payment','rejected') AND NEW.status = 'proof_submitted') THEN
    RAISE EXCEPTION 'Only an administrator can change the payment status';
  END IF;
  RETURN NEW;
END; $$;
REVOKE EXECUTE ON FUNCTION public.guard_payment_update() FROM anon, authenticated;

CREATE TRIGGER payments_guard BEFORE UPDATE ON public.payments
  FOR EACH ROW EXECUTE FUNCTION public.guard_payment_update();