alter table public.badges add column if not exists metadata jsonb not null default '{}'::jsonb; alter table public.user_badges add column if not exists metadata jsonb not null default '{}'::jsonb; with ranked_badges as ( select id, row_number() over ( partition by tenant_id, user_id, badge_id order by granted_at asc nulls last, created_at asc, id asc ) as rn from public.user_badges where user_id is not null and badge_id is not null ) delete from public.user_badges ub using ranked_badges rb where ub.id = rb.id and rb.rn > 1; create unique index if not exists idx_user_badges_user_badge_unique on public.user_badges(tenant_id, user_id, badge_id); create index if not exists idx_badges_tenant_category_active on public.badges(tenant_id, category, is_active, sort_order); create index if not exists idx_user_badges_tenant_user_granted on public.user_badges(tenant_id, user_id, granted_at desc nulls last, created_at desc);