fix: improve subscription tier detection with paidTier priority and verbose logging

- Use parseTierId() consistently for all tier sources (paidTier, currentTier, allowedTiers)
- Add tierSource tracking to identify which field tier was detected from
- Add verbose debug logging to show all tier-related fields from loadCodeAssist API
- Fix onboarding to prioritize paidTier > currentTier > allowedTiers (consistent with model-api.js)

This helps diagnose issues where Pro/Ultra accounts are incorrectly detected as free.
Fixes #128

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Badri Narayanan S
2026-01-15 20:08:30 +05:30
parent fa700dabac
commit 9809337190
2 changed files with 28 additions and 10 deletions

View File

@@ -159,8 +159,9 @@ export async function discoverProject(token) {
return data.cloudaicompanionProject.id;
}
// No project found - try to onboard the user
// No project found - log tier data and try to onboard the user
logger.info(`[AccountManager] No project in loadCodeAssist response, attempting onboardUser...`);
logger.debug(`[AccountManager] Tier data for onboarding: paidTier=${JSON.stringify(data.paidTier)}, currentTier=${JSON.stringify(data.currentTier)}, allowedTiers=${JSON.stringify(data.allowedTiers?.map(t => ({ id: t?.id, isDefault: t?.isDefault })))}`);
break;
} catch (error) {
lastError = error.message;
@@ -170,8 +171,23 @@ export async function discoverProject(token) {
// If we got a successful response but no project, try onboarding
if (gotSuccessfulResponse && loadCodeAssistData) {
const tierId = getDefaultTierId(loadCodeAssistData.allowedTiers) || 'FREE';
logger.info(`[AccountManager] Onboarding user with tier: ${tierId}`);
// Priority: paidTier > currentTier > allowedTiers (consistent with model-api.js)
let tierId = null;
let tierSource = null;
if (loadCodeAssistData.paidTier?.id) {
tierId = loadCodeAssistData.paidTier.id;
tierSource = 'paidTier';
} else if (loadCodeAssistData.currentTier?.id) {
tierId = loadCodeAssistData.currentTier.id;
tierSource = 'currentTier';
} else {
tierId = getDefaultTierId(loadCodeAssistData.allowedTiers);
tierSource = 'allowedTiers';
}
tierId = tierId || 'FREE';
logger.info(`[AccountManager] Onboarding user with tier: ${tierId} (source: ${tierSource})`);
const onboardedProject = await onboardUser(token, tierId);
if (onboardedProject) {

View File

@@ -185,6 +185,9 @@ export async function getSubscriptionTier(token) {
const data = await response.json();
// Debug: Log all tier-related fields from the response
logger.debug(`[CloudCode] loadCodeAssist tier data: paidTier=${JSON.stringify(data.paidTier)}, currentTier=${JSON.stringify(data.currentTier)}, allowedTiers=${JSON.stringify(data.allowedTiers?.map(t => ({ id: t?.id, isDefault: t?.isDefault })))}`);
// Extract project ID
let projectId = null;
if (typeof data.cloudaicompanionProject === 'string') {
@@ -201,22 +204,20 @@ export async function getSubscriptionTier(token) {
// 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 (Google One AI subscription - most reliable)
if (data.paidTier?.id) {
tierId = data.paidTier.id;
const lower = tierId.toLowerCase();
if (lower.includes('ultra')) {
tier = 'ultra';
} else if (lower.includes('pro')) {
tier = 'pro';
}
tier = parseTierId(tierId);
tierSource = 'paidTier';
}
// 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';
}
// 3. Fall back to allowedTiers (find the default or first non-free tier)
@@ -229,10 +230,11 @@ export async function getSubscriptionTier(token) {
if (defaultTier?.id) {
tierId = defaultTier.id;
tier = parseTierId(tierId);
tierSource = 'allowedTiers';
}
}
logger.debug(`[CloudCode] Subscription detected: ${tier} (tierId: ${tierId}), Project: ${projectId}`);
logger.debug(`[CloudCode] Subscription detected: ${tier} (tierId: ${tierId}, source: ${tierSource}), Project: ${projectId}`);
return { tier, projectId };
} catch (error) {