-- Migration 004: Storage bucket for user avatars INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) VALUES ( 'avatars', 'avatars', false, -- private: access via signed URLs only 2097152, -- 2 MB per file ARRAY['image/webp', 'image/jpeg', 'image/png', 'image/gif'] ) ON CONFLICT (id) DO NOTHING; -- Storage RLS: a user can read/write only their own avatar folder ({user_id}/avatar.*) CREATE POLICY avatars_select ON storage.objects FOR SELECT USING ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = auth.uid()::text ); CREATE POLICY avatars_insert ON storage.objects FOR INSERT WITH CHECK ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = auth.uid()::text ); CREATE POLICY avatars_update ON storage.objects FOR UPDATE USING ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = auth.uid()::text ); CREATE POLICY avatars_delete ON storage.objects FOR DELETE USING ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = auth.uid()::text );