alter table public.profiles
  add column description text not null default '' check (char_length(description) <= 500),
  add column avatar_path text check (avatar_path is null or avatar_path = id::text || '/avatar'),
  add column updated_at timestamptz not null default now();

-- Avatars are public profile media, but only the owning authenticated user may
-- create, replace, or remove the one deterministic object in their folder.
insert into storage.buckets(id, name, public, file_size_limit, allowed_mime_types)
values (
  'profile-avatars',
  'profile-avatars',
  true,
  2097152,
  array['image/jpeg', 'image/png', 'image/webp']
)
on conflict (id) do update
set public = excluded.public,
    file_size_limit = excluded.file_size_limit,
    allowed_mime_types = excluded.allowed_mime_types;

create policy dng_profile_avatar_insert
on storage.objects for insert to authenticated
with check (
  bucket_id = 'profile-avatars'
  and name = (select auth.uid())::text || '/avatar'
);

create policy dng_profile_avatar_select_own
on storage.objects for select to authenticated
using (
  bucket_id = 'profile-avatars'
  and name = (select auth.uid())::text || '/avatar'
);

create policy dng_profile_avatar_update
on storage.objects for update to authenticated
using (
  bucket_id = 'profile-avatars'
  and name = (select auth.uid())::text || '/avatar'
)
with check (
  bucket_id = 'profile-avatars'
  and name = (select auth.uid())::text || '/avatar'
);

create policy dng_profile_avatar_delete
on storage.objects for delete to authenticated
using (
  bucket_id = 'profile-avatars'
  and name = (select auth.uid())::text || '/avatar'
);

create or replace function public.dng_schema_version()
returns integer language sql stable security definer set search_path = '' as $$
  select 9;
$$;

revoke all on function public.dng_schema_version() from public, anon, authenticated;
grant execute on function public.dng_schema_version() to service_role;

notify pgrst, 'reload schema';
