supabase/volumes/db/68-cabinet-memberships.sql

74 lines
3.4 KiB
SQL

-- Cabinet memberships for sharing access
create table if not exists public.cabinet_memberships (
id uuid default uuid_generate_v4() primary key,
cabinet_id uuid not null references public.file_cabinets(id) on delete cascade,
profile_id uuid not null references public.profiles(id) on delete cascade,
role text not null check (role in ('owner','editor','viewer')),
created_at timestamp with time zone default timezone('utc'::text, now()),
updated_at timestamp with time zone default timezone('utc'::text, now()),
unique(cabinet_id, profile_id)
);
create index if not exists idx_cabinet_memberships_cabinet on public.cabinet_memberships(cabinet_id);
create index if not exists idx_cabinet_memberships_profile on public.cabinet_memberships(profile_id);
-- Updated at trigger
drop trigger if exists trg_cabinet_memberships_updated_at on public.cabinet_memberships;
create trigger trg_cabinet_memberships_updated_at
before update on public.cabinet_memberships
for each row execute function public.handle_updated_at();
-- RLS and policies
alter table if exists public.cabinet_memberships enable row level security;
-- Members can select their own memberships; cabinet owners can also see memberships
drop policy if exists cm_read_self_or_owner on public.cabinet_memberships;
create policy cm_read_self_or_owner on public.cabinet_memberships for select to authenticated
using (
profile_id = auth.uid() or exists (
select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
)
);
-- Cabinet owners can insert memberships
drop policy if exists cm_insert_by_owner on public.cabinet_memberships;
create policy cm_insert_by_owner on public.cabinet_memberships for insert to authenticated
with check (exists (
select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));
-- Cabinet owners can update memberships (e.g., role)
drop policy if exists cm_update_by_owner on public.cabinet_memberships;
create policy cm_update_by_owner on public.cabinet_memberships for update to authenticated
using (exists (
select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
))
with check (exists (
select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));
-- Cabinet owners can delete memberships
drop policy if exists cm_delete_by_owner on public.cabinet_memberships;
create policy cm_delete_by_owner on public.cabinet_memberships for delete to authenticated
using (exists (
select 1 from public.file_cabinets c where c.id = cabinet_memberships.cabinet_id and c.user_id = auth.uid()
));
-- Extend access to cabinets/files for members (after table exists)
drop policy if exists "User can access cabinets via membership" on public.file_cabinets;
create policy "User can access cabinets via membership" on public.file_cabinets for select to authenticated
using (exists (
select 1 from public.cabinet_memberships m
where m.cabinet_id = file_cabinets.id and m.profile_id = auth.uid()
));
drop policy if exists "User can access files via membership" on public.files;
create policy "User can access files via membership" on public.files for select to authenticated
using (exists (
select 1 from public.cabinet_memberships m
where m.cabinet_id = files.cabinet_id and m.profile_id = auth.uid()
));