Initial commit
This commit is contained in:
136
supabase/migrations/20260321000000_assessment_shares.sql
Normal file
136
supabase/migrations/20260321000000_assessment_shares.sql
Normal file
@@ -0,0 +1,136 @@
|
||||
-- Token-based sharing for individual assessments
|
||||
create table if not exists public.assessment_shares (
|
||||
assessment_id uuid primary key references public.assessments(id) on delete cascade,
|
||||
user_id uuid not null references auth.users(id) on delete cascade,
|
||||
share_token text not null unique,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
drop trigger if exists trg_assessment_shares_updated_at on public.assessment_shares;
|
||||
create trigger trg_assessment_shares_updated_at
|
||||
before update on public.assessment_shares
|
||||
for each row execute function public.set_updated_at();
|
||||
|
||||
alter table public.assessment_shares enable row level security;
|
||||
|
||||
drop policy if exists "Allow users to insert own assessment shares" on public.assessment_shares;
|
||||
create policy "Allow users to insert own assessment shares"
|
||||
on public.assessment_shares
|
||||
for insert
|
||||
with check (
|
||||
auth.uid() = user_id
|
||||
and exists (
|
||||
select 1
|
||||
from public.assessments a
|
||||
where a.id = assessment_shares.assessment_id
|
||||
and a.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "Allow users to select own assessment shares" on public.assessment_shares;
|
||||
create policy "Allow users to select own assessment shares"
|
||||
on public.assessment_shares
|
||||
for select
|
||||
using (auth.uid() = user_id);
|
||||
|
||||
drop policy if exists "Allow users to update own assessment shares" on public.assessment_shares;
|
||||
create policy "Allow users to update own assessment shares"
|
||||
on public.assessment_shares
|
||||
for update
|
||||
using (auth.uid() = user_id)
|
||||
with check (
|
||||
auth.uid() = user_id
|
||||
and exists (
|
||||
select 1
|
||||
from public.assessments a
|
||||
where a.id = assessment_shares.assessment_id
|
||||
and a.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "Allow users to delete own assessment shares" on public.assessment_shares;
|
||||
create policy "Allow users to delete own assessment shares"
|
||||
on public.assessment_shares
|
||||
for delete
|
||||
using (auth.uid() = user_id);
|
||||
|
||||
create index if not exists idx_assessment_shares_user_id
|
||||
on public.assessment_shares(user_id);
|
||||
|
||||
create or replace function public.generate_share_token()
|
||||
returns text
|
||||
language sql
|
||||
as $$
|
||||
select replace(gen_random_uuid()::text, '-', '') || replace(gen_random_uuid()::text, '-', '');
|
||||
$$;
|
||||
|
||||
create or replace function public.create_or_get_assessment_share(p_assessment_id uuid)
|
||||
returns table (
|
||||
assessment_id uuid,
|
||||
share_token text
|
||||
)
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
declare
|
||||
v_user_id uuid;
|
||||
begin
|
||||
v_user_id := auth.uid();
|
||||
|
||||
if v_user_id is null then
|
||||
raise exception 'Not authenticated';
|
||||
end if;
|
||||
|
||||
if not exists (
|
||||
select 1
|
||||
from public.assessments a
|
||||
where a.id = p_assessment_id
|
||||
and a.user_id = v_user_id
|
||||
) then
|
||||
raise exception 'Assessment not found';
|
||||
end if;
|
||||
|
||||
insert into public.assessment_shares (assessment_id, user_id, share_token)
|
||||
values (p_assessment_id, v_user_id, public.generate_share_token())
|
||||
on conflict on constraint assessment_shares_pkey do nothing;
|
||||
|
||||
return query
|
||||
select s.assessment_id, s.share_token
|
||||
from public.assessment_shares s
|
||||
where s.assessment_id = p_assessment_id
|
||||
and s.user_id = v_user_id
|
||||
limit 1;
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function public.get_shared_assessment(p_share_token text)
|
||||
returns table (
|
||||
id uuid,
|
||||
pat_type text,
|
||||
datum date,
|
||||
name text,
|
||||
exercises jsonb
|
||||
)
|
||||
language sql
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
select
|
||||
a.id,
|
||||
a.pat_type,
|
||||
a.datum,
|
||||
a.name,
|
||||
a.exercises
|
||||
from public.assessment_shares s
|
||||
join public.assessments a on a.id = s.assessment_id
|
||||
where s.share_token = p_share_token
|
||||
limit 1;
|
||||
$$;
|
||||
|
||||
revoke all on function public.create_or_get_assessment_share(uuid) from public;
|
||||
grant execute on function public.create_or_get_assessment_share(uuid) to authenticated;
|
||||
|
||||
revoke all on function public.get_shared_assessment(text) from public;
|
||||
grant execute on function public.get_shared_assessment(text) to anon, authenticated;
|
||||
Reference in New Issue
Block a user