-- 1. Create role enum CREATE TYPE public.app_role AS ENUM ('admin', 'moderator', 'user'); -- 2. Create user_roles table CREATE TABLE public.user_roles ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL, role app_role NOT NULL, UNIQUE (user_id, role) ); -- 3. Enable RLS ALTER TABLE public.user_roles ENABLE ROW LEVEL SECURITY; -- 4. Security definer function (created BEFORE policy that uses it) CREATE OR REPLACE FUNCTION public.has_role(_user_id UUID, _role app_role) RETURNS BOOLEAN LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$ SELECT EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = _user_id AND role = _role ) $$; -- 5. RLS policy using the function CREATE POLICY "Admins can view all roles" ON public.user_roles FOR SELECT TO authenticated USING (public.has_role(auth.uid(), 'admin'));