diff --git a/supabase/migrations/20260807002000_reporting_view_fixes.sql b/supabase/migrations/20260807002000_reporting_view_fixes.sql index 96109c5..f7bc0f8 100644 --- a/supabase/migrations/20260807002000_reporting_view_fixes.sql +++ b/supabase/migrations/20260807002000_reporting_view_fixes.sql @@ -19,6 +19,21 @@ -- disciplinary_history, custody_agreement and primary_physician, which they -- have no business reading. So the name is resolved on its own instead, and -- student row access is left exactly as it was. +-- True for callers that bypass RLS outright: the service role used by +-- server-side code, and a direct superuser psql session (role unset). +-- +-- This MUST read the `role` GUC rather than current_user. Inside a +-- SECURITY DEFINER function current_user is the function's owner, so +-- pg_has_role(current_user, 'service_role', ...) is true for every caller and +-- silently turns an entitlement check into a no-op. +CREATE OR REPLACE FUNCTION public.is_service_context() +RETURNS BOOLEAN +LANGUAGE sql STABLE AS $$ + SELECT COALESCE(current_setting('role', true), 'none') IN ('service_role', 'none'); +$$; + +GRANT EXECUTE ON FUNCTION public.is_service_context() TO authenticated; + CREATE OR REPLACE FUNCTION public.student_display_name(_student UUID) RETURNS TEXT LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$