-- Map owners can invite other accounts to manage their maps together. Invites -- stay pending until the invitee accepts from their dashboard; accepted admins -- act through the owner, so map RPC checks keep working unchanged. create table public.map_admins ( id uuid primary key default gen_random_uuid(), dataset_id uuid not null references public.datasets(id) on delete cascade, user_id uuid not null references auth.users(id) on delete cascade, invited_by uuid not null references auth.users(id) on delete cascade, state text not null default 'pending' check(state in ('pending','accepted')), created_at timestamptz not null default now(), responded_at timestamptz, constraint map_admins_unique unique(dataset_id,user_id), constraint map_admins_no_self check(user_id<>invited_by), constraint map_admins_response check( (state='pending' and responded_at is null) or (state='accepted' and responded_at is not null) ) ); create index map_admins_user_state on public.map_admins(user_id,state); create index map_admins_dataset on public.map_admins(dataset_id); -- Service role only: invites and membership are managed through the API. alter table public.map_admins enable row level security;