(params: {
userId: string
logger: Logger
includeSubscriptionCredits?: boolean
})
| 51 | * This consolidates logic from web/src/app/api/user/usage/route.ts |
| 52 | */ |
| 53 | export async function getUserUsageData(params: { |
| 54 | userId: string |
| 55 | logger: Logger |
| 56 | includeSubscriptionCredits?: boolean |
| 57 | }): Promise<UserUsageData> { |
| 58 | const { userId, logger, includeSubscriptionCredits } = params |
| 59 | try { |
| 60 | const now = new Date() |
| 61 | |
| 62 | // Check if we need to reset quota and grant new credits |
| 63 | // This also returns autoTopupEnabled to avoid a separate query |
| 64 | const { quotaResetDate, autoTopupEnabled } = |
| 65 | await triggerMonthlyResetAndGrant(params) |
| 66 | |
| 67 | // Check if we need to trigger auto top-up |
| 68 | let autoTopupTriggered = false |
| 69 | try { |
| 70 | const topupAmount = await checkAndTriggerAutoTopup(params) |
| 71 | autoTopupTriggered = topupAmount !== undefined |
| 72 | } catch (error) { |
| 73 | logger.error( |
| 74 | { error, userId }, |
| 75 | 'Error during auto top-up check in getUserUsageData', |
| 76 | ) |
| 77 | // Continue execution to return usage data even if auto top-up fails |
| 78 | } |
| 79 | |
| 80 | // Use the canonical balance calculation function with the effective reset date |
| 81 | // Pass isPersonalContext: true to exclude organization credits from personal usage |
| 82 | const { usageThisCycle, balance } = await calculateUsageAndBalance({ |
| 83 | userId, |
| 84 | logger, |
| 85 | quotaResetDate, |
| 86 | now, |
| 87 | isPersonalContext: true, |
| 88 | includeSubscriptionCredits: includeSubscriptionCredits ?? false, |
| 89 | }) |
| 90 | |
| 91 | // Check for active subscription |
| 92 | let subscription: UserUsageData['subscription'] |
| 93 | const activeSub = await getActiveSubscription({ userId, logger }) |
| 94 | if (activeSub) { |
| 95 | subscription = { |
| 96 | status: activeSub.status, |
| 97 | billingPeriodEnd: activeSub.billing_period_end.toISOString(), |
| 98 | cancelAtPeriodEnd: activeSub.cancel_at_period_end, |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | return { |
| 103 | usageThisCycle, |
| 104 | balance, |
| 105 | nextQuotaReset: quotaResetDate.toISOString(), |
| 106 | autoTopupTriggered, |
| 107 | autoTopupEnabled, |
| 108 | subscription, |
| 109 | } |
| 110 | } catch (error) { |
no test coverage detected