-- Add avatar_url to profiles (schema omotomo) ALTER TABLE omotomo.profiles ADD COLUMN IF NOT EXISTS avatar_url text; -- Storage bucket for avatars (public read; uploads scoped to user folder). -- If the INSERT fails (e.g. different storage schema), create the bucket in Supabase Dashboard: -- Storage → New bucket → name "avatars", Public bucket ON, File size limit 2MB, Allowed MIME types: image/jpeg, image/png, image/gif, image/webp INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) VALUES ( 'avatars', 'avatars', true, 2097152, ARRAY['image/jpeg', 'image/png', 'image/gif', 'image/webp'] ) ON CONFLICT (id) DO NOTHING; -- RLS: allow authenticated users to upload only to their own folder (avatars//...) -- Use auth.jwt()->>'sub' to match the folder name (JWT sub is the user id string). CREATE POLICY "Users can upload own avatar" ON storage.objects FOR INSERT TO authenticated WITH CHECK ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = (auth.jwt()->>'sub') ); CREATE POLICY "Users can update own avatar" ON storage.objects FOR UPDATE TO authenticated USING ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = (auth.jwt()->>'sub') ) WITH CHECK ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = (auth.jwt()->>'sub') ); CREATE POLICY "Users can delete own avatar" ON storage.objects FOR DELETE TO authenticated USING ( bucket_id = 'avatars' AND (storage.foldername(name))[1] = (auth.jwt()->>'sub') ); -- Public read for avatars (bucket is public) CREATE POLICY "Avatar images are publicly readable" ON storage.objects FOR SELECT TO public USING (bucket_id = 'avatars');