-- Run in Supabase SQL Editor. -- 1) Allow viewer role alter table public.collection_members drop constraint if exists collection_members_role_check; alter table public.collection_members add constraint collection_members_role_check check (role in ('owner', 'member', 'viewer')); -- 2) Ensure owners can delete members from their collections -- (and users can still remove themselves for leave flow). drop policy if exists "Owner can remove members" on public.collection_members; create policy "Owner can remove members" on public.collection_members for delete to authenticated using ( collection_id in ( select c.id from public.collections c where c.owner_id = auth.uid() ) or user_id = auth.uid() ); -- 3) Stable, policy-safe removal RPC for app use create or replace function public.remove_collection_member( p_collection_id uuid, p_member_user_id uuid ) returns void language plpgsql security definer set search_path = public as $$ declare v_owner_id uuid; begin select c.owner_id into v_owner_id from public.collections c where c.id = p_collection_id; if v_owner_id is null then raise exception 'Collection not found.'; end if; if v_owner_id <> auth.uid() then raise exception 'Only the collection owner can remove members.'; end if; if p_member_user_id = v_owner_id then raise exception 'Collection owner cannot be removed.'; end if; delete from public.collection_members cm where cm.collection_id = p_collection_id and cm.user_id = p_member_user_id and cm.role <> 'owner'; end; $$; grant execute on function public.remove_collection_member(uuid, uuid) to authenticated;