diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index 43a0065..f6151a2 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -1746,27 +1746,42 @@ export type Database = { } profiles: { Row: { + avatar_url: string | null + bio: string | null created_at: string email: string full_name: string hourly_rate: number | null id: string + phone: string | null + timezone: string | null + title: string | null updated_at: string } Insert: { + avatar_url?: string | null + bio?: string | null created_at?: string email?: string full_name?: string hourly_rate?: number | null id: string + phone?: string | null + timezone?: string | null + title?: string | null updated_at?: string } Update: { + avatar_url?: string | null + bio?: string | null created_at?: string email?: string full_name?: string hourly_rate?: number | null id?: string + phone?: string | null + timezone?: string | null + title?: string | null updated_at?: string } Relationships: [] diff --git a/supabase/migrations/20260417025757_5ea91682-9bbe-4c65-b5a6-76e9ecd8b59b.sql b/supabase/migrations/20260417025757_5ea91682-9bbe-4c65-b5a6-76e9ecd8b59b.sql new file mode 100644 index 0000000..e28d7e4 --- /dev/null +++ b/supabase/migrations/20260417025757_5ea91682-9bbe-4c65-b5a6-76e9ecd8b59b.sql @@ -0,0 +1,52 @@ +-- Profile fields +ALTER TABLE public.profiles + ADD COLUMN IF NOT EXISTS avatar_url text, + ADD COLUMN IF NOT EXISTS title text, + ADD COLUMN IF NOT EXISTS phone text, + ADD COLUMN IF NOT EXISTS bio text, + ADD COLUMN IF NOT EXISTS timezone text; + +-- Ensure RLS on profiles +ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY; + +-- Recreate policies idempotently +DROP POLICY IF EXISTS profiles_select_auth ON public.profiles; +DROP POLICY IF EXISTS profiles_update_self_or_admin ON public.profiles; +DROP POLICY IF EXISTS profiles_insert_self ON public.profiles; + +CREATE POLICY profiles_select_auth ON public.profiles + FOR SELECT TO authenticated USING (true); + +CREATE POLICY profiles_update_self_or_admin ON public.profiles + FOR UPDATE TO authenticated + USING (id = auth.uid() OR public.is_admin(auth.uid())); + +CREATE POLICY profiles_insert_self ON public.profiles + FOR INSERT TO authenticated + WITH CHECK (id = auth.uid() OR public.is_admin(auth.uid())); + +-- Avatars bucket (public) +INSERT INTO storage.buckets (id, name, public) +VALUES ('avatars', 'avatars', true) +ON CONFLICT (id) DO UPDATE SET public = true; + +-- Storage policies for avatars +DROP POLICY IF EXISTS "avatars_public_read" ON storage.objects; +DROP POLICY IF EXISTS "avatars_user_insert" ON storage.objects; +DROP POLICY IF EXISTS "avatars_user_update" ON storage.objects; +DROP POLICY IF EXISTS "avatars_user_delete" ON storage.objects; + +CREATE POLICY "avatars_public_read" ON storage.objects + FOR SELECT USING (bucket_id = 'avatars'); + +CREATE POLICY "avatars_user_insert" ON storage.objects + FOR INSERT TO authenticated + WITH CHECK (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]); + +CREATE POLICY "avatars_user_update" ON storage.objects + FOR UPDATE TO authenticated + USING (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]); + +CREATE POLICY "avatars_user_delete" ON storage.objects + FOR DELETE TO authenticated + USING (bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]); \ No newline at end of file