From bfa924e6e87c13af14820608c39cb357cfd3b93a Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Wed, 18 Mar 2026 23:49:20 -0700 Subject: [PATCH] feat: Supabase Storage bucket for screenshots Creates public 'screenshots' bucket with RLS policies that restrict uploads to team members (path: {team_id}/{slug}/{branch}/{filename}). Public read access enables embedding URLs in PR bodies without auth. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../migrations/008_screenshot_storage.sql | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 supabase/migrations/008_screenshot_storage.sql diff --git a/supabase/migrations/008_screenshot_storage.sql b/supabase/migrations/008_screenshot_storage.sql new file mode 100644 index 00000000..e2bfe3d7 --- /dev/null +++ b/supabase/migrations/008_screenshot_storage.sql @@ -0,0 +1,43 @@ +-- 008_screenshot_storage.sql — Supabase Storage bucket for QA/design screenshots. +-- +-- Creates a 'screenshots' bucket with RLS so team members can upload and +-- view screenshots scoped to their team. + +-- ─── Storage bucket ─────────────────────────────────────────── + +insert into storage.buckets (id, name, public) +values ('screenshots', 'screenshots', true) +on conflict (id) do nothing; + +-- ─── RLS policies ───────────────────────────────────────────── + +-- Team members can upload screenshots under their team's folder. +-- Path convention: {team_id}/{slug}/{branch}/{filename} +create policy "team_upload_screenshots" on storage.objects + for insert with check ( + bucket_id = 'screenshots' + and (storage.foldername(name))[1] in ( + select id::text from teams + where id in ( + select team_id from team_members + where user_id = auth.uid() + ) + ) + ); + +-- Team members can view their team's screenshots. +create policy "team_read_screenshots" on storage.objects + for select using ( + bucket_id = 'screenshots' + and (storage.foldername(name))[1] in ( + select id::text from teams + where id in ( + select team_id from team_members + where user_id = auth.uid() + ) + ) + ); + +-- Public bucket: anyone with the URL can view (for PR body embedding). +-- The RLS above controls who can *upload*; public access is for reading +-- via the CDN URL without auth.