fix: improve onboarding flow for non-free tier accounts
- Use raw API tier IDs (e.g., 'free-tier', 'g1-pro-tier') consistently
- Pass DEFAULT_PROJECT_ID for non-free tiers during onboarding
- Fix free tier detection to use .includes('free') instead of exact match
- Upgrade onboarding error logs from debug to warn for visibility
- Add debug logging for onboarding request parameters
Fixes onboarding failures for Pro/Ultra accounts that were previously
failing because the API requires a project ID for paid tier onboarding.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -186,10 +186,19 @@ export async function discoverProject(token) {
|
|||||||
tierSource = 'allowedTiers';
|
tierSource = 'allowedTiers';
|
||||||
}
|
}
|
||||||
|
|
||||||
tierId = tierId || 'FREE';
|
tierId = tierId || 'free-tier';
|
||||||
logger.info(`[AccountManager] Onboarding user with tier: ${tierId} (source: ${tierSource})`);
|
logger.info(`[AccountManager] Onboarding user with tier: ${tierId} (source: ${tierSource})`);
|
||||||
|
|
||||||
const onboardedProject = await onboardUser(token, tierId);
|
// Check if this is a free tier (raw API values contain 'free')
|
||||||
|
const isFree = tierId.toLowerCase().includes('free');
|
||||||
|
|
||||||
|
// For non-free tiers, pass DEFAULT_PROJECT_ID as the GCP project
|
||||||
|
// The API requires a project for paid tier onboarding
|
||||||
|
const onboardedProject = await onboardUser(
|
||||||
|
token,
|
||||||
|
tierId,
|
||||||
|
isFree ? null : DEFAULT_PROJECT_ID
|
||||||
|
);
|
||||||
if (onboardedProject) {
|
if (onboardedProject) {
|
||||||
logger.success(`[AccountManager] Successfully onboarded, project: ${onboardedProject}`);
|
logger.success(`[AccountManager] Successfully onboarded, project: ${onboardedProject}`);
|
||||||
return onboardedProject;
|
return onboardedProject;
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ export function getDefaultTierId(allowedTiers) {
|
|||||||
* Onboard a user to get a managed project
|
* Onboard a user to get a managed project
|
||||||
*
|
*
|
||||||
* @param {string} token - OAuth access token
|
* @param {string} token - OAuth access token
|
||||||
* @param {string} tierId - Tier ID (e.g., 'FREE', 'PRO', 'ULTRA')
|
* @param {string} tierId - Tier ID (raw API value, e.g., 'free-tier', 'standard-tier', 'g1-pro-tier')
|
||||||
* @param {string} [projectId] - Optional GCP project ID (required for non-FREE tiers)
|
* @param {string} [projectId] - Optional GCP project ID (required for non-free tiers)
|
||||||
* @param {number} [maxAttempts=10] - Maximum polling attempts
|
* @param {number} [maxAttempts=10] - Maximum polling attempts
|
||||||
* @param {number} [delayMs=5000] - Delay between polling attempts
|
* @param {number} [delayMs=5000] - Delay between polling attempts
|
||||||
* @returns {Promise<string|null>} Managed project ID or null if failed
|
* @returns {Promise<string|null>} Managed project ID or null if failed
|
||||||
@@ -59,11 +59,16 @@ export async function onboardUser(token, tierId, projectId = null, maxAttempts =
|
|||||||
metadata
|
metadata
|
||||||
};
|
};
|
||||||
|
|
||||||
// Non-FREE tiers require a cloudaicompanionProject
|
// Check if this is a free tier (handles raw API values like 'free-tier')
|
||||||
if (tierId !== 'FREE' && projectId) {
|
const isFree = tierId.toLowerCase().includes('free');
|
||||||
|
|
||||||
|
// Non-free tiers require a cloudaicompanionProject
|
||||||
|
if (!isFree && projectId) {
|
||||||
requestBody.cloudaicompanionProject = projectId;
|
requestBody.cloudaicompanionProject = projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.debug(`[Onboarding] Starting onboard with tierId: ${tierId}, projectId: ${projectId}, isFree: ${isFree}`);
|
||||||
|
|
||||||
for (const endpoint of ONBOARD_USER_ENDPOINTS) {
|
for (const endpoint of ONBOARD_USER_ENDPOINTS) {
|
||||||
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
||||||
try {
|
try {
|
||||||
@@ -79,7 +84,7 @@ export async function onboardUser(token, tierId, projectId = null, maxAttempts =
|
|||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorText = await response.text();
|
const errorText = await response.text();
|
||||||
logger.debug(`[Onboarding] onboardUser failed at ${endpoint}: ${response.status} - ${errorText}`);
|
logger.warn(`[Onboarding] onboardUser failed at ${endpoint}: ${response.status} - ${errorText}`);
|
||||||
break; // Try next endpoint
|
break; // Try next endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +106,12 @@ export async function onboardUser(token, tierId, projectId = null, maxAttempts =
|
|||||||
await sleep(delayMs);
|
await sleep(delayMs);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.debug(`[Onboarding] onboardUser error at ${endpoint}:`, error.message);
|
logger.warn(`[Onboarding] onboardUser error at ${endpoint}:`, error.message);
|
||||||
break; // Try next endpoint
|
break; // Try next endpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.warn(`[Onboarding] All onboarding attempts failed for tierId: ${tierId}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user