-- ============================================================================ -- Phase V2-2: Storage 버킷 + 접근 정책 -- ============================================================================ -- 버킷 생성 ------------------------------------------------------------------ INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) VALUES ('audio', 'audio', false, 524288000, ARRAY['audio/wav', 'audio/webm', 'audio/mpeg', 'audio/mp4', 'audio/ogg']), ('exports', 'exports', false, 52428800, ARRAY['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/markdown', 'text/html']), ('avatars', 'avatars', true, 5242880, ARRAY['image/jpeg', 'image/png', 'image/webp']) ON CONFLICT (id) DO NOTHING; -- ============================================================================ -- audio 버킷: 본인 경로 ({user_id}/...) 에서만 읽기/쓰기 -- ============================================================================ CREATE POLICY "audio_read_own" ON storage.objects FOR SELECT USING ( bucket_id = 'audio' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "audio_insert_own" ON storage.objects FOR INSERT WITH CHECK ( bucket_id = 'audio' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "audio_update_own" ON storage.objects FOR UPDATE USING ( bucket_id = 'audio' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "audio_delete_own" ON storage.objects FOR DELETE USING ( bucket_id = 'audio' AND auth.uid()::text = (storage.foldername(name))[1] ); -- ============================================================================ -- exports 버킷: 동일 패턴 -- ============================================================================ CREATE POLICY "exports_read_own" ON storage.objects FOR SELECT USING ( bucket_id = 'exports' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "exports_insert_own" ON storage.objects FOR INSERT WITH CHECK ( bucket_id = 'exports' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "exports_delete_own" ON storage.objects FOR DELETE USING ( bucket_id = 'exports' AND auth.uid()::text = (storage.foldername(name))[1] ); -- ============================================================================ -- avatars 버킷: 공개 읽기, 본인만 쓰기 -- ============================================================================ CREATE POLICY "avatars_read_public" ON storage.objects FOR SELECT USING (bucket_id = 'avatars'); CREATE POLICY "avatars_insert_own" ON storage.objects FOR INSERT WITH CHECK ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "avatars_update_own" ON storage.objects FOR UPDATE USING ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] ); CREATE POLICY "avatars_delete_own" ON storage.objects FOR DELETE USING ( bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1] );