fix(cliproxy): prefer live entitlement tier in account badges

This commit is contained in:
Tam Nhu Tran
2026-04-10 13:24:00 -04:00
parent f9c61e0fac
commit 7330fdbf28
2 changed files with 70 additions and 7 deletions
@@ -59,6 +59,19 @@ function getCompactAudienceBadgeLabel(audience: 'business' | 'personal' | 'unkno
return '?';
}
function resolveEffectiveTier(
tier: AccountTier | undefined,
quota: UnifiedQuotaResult | undefined
): AccountTier | undefined {
if (quota && 'entitlement' in quota) {
const entitlementTier = quota.entitlement?.normalizedTier;
if (entitlementTier && entitlementTier !== 'unknown') {
return entitlementTier;
}
}
return tier;
}
export function AccountSurfaceCard({
mode,
provider,
@@ -85,13 +98,14 @@ export function AccountSurfaceCard({
const identity = getAccountIdentityPresentation(accountId, email, tokenFile);
const title = displayEmail || identity.email || accountId;
const normalizedProvider = provider.toLowerCase();
const effectiveTier = resolveEffectiveTier(tier, quota);
const showTierBadge =
(normalizedProvider === 'agy' ||
normalizedProvider === 'antigravity' ||
normalizedProvider === 'gemini') &&
tier &&
tier !== 'unknown' &&
tier !== 'free';
effectiveTier &&
effectiveTier !== 'unknown' &&
effectiveTier !== 'free';
const isCompact = mode === 'compact';
const defaultCompactMetaBadges = (
<>
@@ -99,10 +113,10 @@ export function AccountSurfaceCard({
<span
className={cn(
'text-[8px] font-semibold px-1.5 py-0.5 rounded-md shrink-0',
getTierBadgeClass(tier)
getTierBadgeClass(effectiveTier)
)}
>
{tier}
{effectiveTier}
</span>
)}
{identity.audienceLabel && (
@@ -145,12 +159,12 @@ export function AccountSurfaceCard({
<span
className={cn(
'absolute -bottom-0.5 -right-0.5 text-[7px] font-bold uppercase px-1 py-px rounded ring-1 ring-background',
tier === 'ultra'
effectiveTier === 'ultra'
? 'bg-violet-500/20 text-violet-600 dark:bg-violet-500/30 dark:text-violet-300'
: 'bg-yellow-500/20 text-yellow-700 dark:bg-yellow-500/25 dark:text-yellow-400'
)}
>
{tier === 'ultra' ? 'U' : 'P'}
{effectiveTier === 'ultra' ? 'U' : 'P'}
</span>
)}
</div>
@@ -0,0 +1,49 @@
import { render, screen } from '@tests/setup/test-utils';
import { describe, expect, it } from 'vitest';
import { AccountSurfaceCard } from '@/components/account/shared/account-surface-card';
import type { GeminiCliQuotaResult } from '@/lib/api-client';
function createGeminiQuotaResult(
overrides: Partial<GeminiCliQuotaResult> = {}
): GeminiCliQuotaResult {
return {
success: true,
buckets: [],
projectId: 'project-123',
tierLabel: 'Pro',
tierId: 'g1-pro-tier',
creditBalance: 12,
entitlement: {
normalizedTier: 'pro',
rawTierId: 'g1-pro-tier',
rawTierLabel: 'Pro',
source: 'runtime_api',
confidence: 'high',
accessState: 'entitled',
capacityState: 'available',
lastVerifiedAt: Date.now(),
notes: null,
},
lastUpdated: Date.now(),
...overrides,
};
}
describe('AccountSurfaceCard', () => {
it('prefers live quota entitlement tier over a stale account tier for Gemini badges', () => {
render(
<AccountSurfaceCard
mode="compact"
provider="gemini"
accountId="user@example.com"
email="user@example.com"
displayEmail="user@example.com"
tier="unknown"
quota={createGeminiQuotaResult()}
showQuota={false}
/>
);
expect(screen.getByText('pro')).toBeInTheDocument();
});
});