CREATE TABLE IF NOT EXISTS public.user_groups ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), name text NOT NULL, created_by uuid REFERENCES public.users(id), created_at timestamptz NOT NULL DEFAULT now() ); ALTER TABLE public.user_groups ENABLE ROW LEVEL SECURITY; CREATE POLICY "read_groups" ON public.user_groups FOR SELECT USING (auth.uid() IS NOT NULL); CREATE POLICY "manage_groups" ON public.user_groups FOR ALL USING ( EXISTS (SELECT 1 FROM public.users WHERE id = auth.uid() AND platform_role = 'platform_admin') OR created_by = auth.uid() ); CREATE TABLE IF NOT EXISTS public.group_memberships ( user_id uuid NOT NULL REFERENCES public.users(id) ON DELETE CASCADE, group_id uuid NOT NULL REFERENCES public.user_groups(id) ON DELETE CASCADE, role text NOT NULL DEFAULT 'member' CHECK (role IN ('owner','member')), PRIMARY KEY (user_id, group_id) ); ALTER TABLE public.group_memberships ENABLE ROW LEVEL SECURITY; CREATE POLICY "read_memberships" ON public.group_memberships FOR SELECT USING (auth.uid() IS NOT NULL); CREATE POLICY "manage_memberships" ON public.group_memberships FOR ALL USING ( EXISTS (SELECT 1 FROM public.users WHERE id = auth.uid() AND platform_role = 'platform_admin') OR EXISTS ( SELECT 1 FROM public.user_groups WHERE id = group_memberships.group_id AND created_by = auth.uid() ) );