diff --git a/src/cloudcode/model-api.js b/src/cloudcode/model-api.js index 2ced754..9d32c56 100644 --- a/src/cloudcode/model-api.js +++ b/src/cloudcode/model-api.js @@ -197,57 +197,32 @@ export async function getSubscriptionTier(token) { } // Extract subscription tier - // Priority: paidTier (if not free) > allowedTiers (highest) > currentTier > paidTier (free) + // Priority: paidTier > currentTier > allowedTiers // - paidTier.id: "g1-pro-tier", "g1-ultra-tier" (Google One subscription) // - currentTier.id: "standard-tier" (pro), "free-tier" (free) - // - allowedTiers: may contain higher tiers than paidTier (e.g., standard-tier when paidTier is free) - // - // Special case: paidTier can be "free-tier" but allowedTiers may still grant "standard-tier" - // This happens when users are ineligible for Google One AI quotas but have access through other programs + // - allowedTiers: fallback when currentTier is missing + // Note: paidTier is sometimes missing from the response even for Pro accounts let tier = 'unknown'; let tierId = null; let tierSource = null; - // 1. Check paidTier first - if it's Pro/Ultra, use it immediately + // 1. Check paidTier first (Google One AI subscription - most reliable) if (data.paidTier?.id) { tierId = data.paidTier.id; tier = parseTierId(tierId); tierSource = 'paidTier'; } - // 2. If paidTier is free or unknown, check allowedTiers for higher tiers - // Some accounts have paidTier=free but allowedTiers includes standard-tier - if ((tier === 'free' || tier === 'unknown') && Array.isArray(data.allowedTiers) && data.allowedTiers.length > 0) { - // Check for ultra first, then pro/standard - const hasUltra = data.allowedTiers.some(t => t?.id?.toLowerCase().includes('ultra')); - const hasPro = data.allowedTiers.some(t => { - const id = t?.id?.toLowerCase() || ''; - return id.includes('pro') || id.includes('premium') || id === 'standard-tier'; - }); - - if (hasUltra) { - tier = 'ultra'; - tierId = data.allowedTiers.find(t => t?.id?.toLowerCase().includes('ultra'))?.id; - tierSource = 'allowedTiers'; - } else if (hasPro) { - tier = 'pro'; - tierId = data.allowedTiers.find(t => { - const id = t?.id?.toLowerCase() || ''; - return id.includes('pro') || id.includes('premium') || id === 'standard-tier'; - })?.id; - tierSource = 'allowedTiers'; - } - } - - // 3. Fall back to currentTier if still unknown + // 2. Fall back to currentTier if paidTier didn't give us a tier if (tier === 'unknown' && data.currentTier?.id) { tierId = data.currentTier.id; tier = parseTierId(tierId); tierSource = 'currentTier'; } - // 4. Final fallback to allowedTiers default if still unknown + // 3. Fall back to allowedTiers (find the default or first non-free tier) if (tier === 'unknown' && Array.isArray(data.allowedTiers) && data.allowedTiers.length > 0) { + // First look for the default tier let defaultTier = data.allowedTiers.find(t => t?.isDefault); if (!defaultTier) { defaultTier = data.allowedTiers[0];