(params: {
userId: string
logger: Logger
})
| 208 | } |
| 209 | |
| 210 | export async function checkAndTriggerAutoTopup(params: { |
| 211 | userId: string |
| 212 | logger: Logger |
| 213 | }): Promise<number | undefined> { |
| 214 | const { userId, logger } = params |
| 215 | const logContext = { userId } |
| 216 | |
| 217 | try { |
| 218 | // Get user info |
| 219 | const user = await db.query.user.findFirst({ |
| 220 | where: eq(schema.user.id, userId), |
| 221 | columns: { |
| 222 | auto_topup_enabled: true, |
| 223 | auto_topup_threshold: true, |
| 224 | auto_topup_amount: true, |
| 225 | stripe_customer_id: true, |
| 226 | next_quota_reset: true, |
| 227 | }, |
| 228 | }) |
| 229 | |
| 230 | if ( |
| 231 | !user || |
| 232 | !user.auto_topup_enabled || |
| 233 | user.auto_topup_threshold === null || |
| 234 | user.auto_topup_amount === null || |
| 235 | !user.stripe_customer_id |
| 236 | ) { |
| 237 | return undefined |
| 238 | } |
| 239 | |
| 240 | // Calculate balance |
| 241 | const { balance } = await calculateUsageAndBalance({ |
| 242 | ...params, |
| 243 | quotaResetDate: user.next_quota_reset ?? new Date(0), |
| 244 | }) |
| 245 | |
| 246 | if ( |
| 247 | balance.totalRemaining >= user.auto_topup_threshold && |
| 248 | balance.totalDebt === 0 |
| 249 | ) { |
| 250 | logger.info( |
| 251 | { |
| 252 | ...logContext, |
| 253 | currentBalance: balance.totalRemaining, |
| 254 | threshold: user.auto_topup_threshold, |
| 255 | totalDebt: balance.totalDebt, |
| 256 | }, |
| 257 | `Auto top-up not needed for user ${userId}. Balance ${balance.totalRemaining} is above threshold ${user.auto_topup_threshold} and no debt.`, |
| 258 | ) |
| 259 | return undefined |
| 260 | } |
| 261 | |
| 262 | const amountToTopUp = |
| 263 | balance.totalDebt > 0 |
| 264 | ? Math.max(user.auto_topup_amount, balance.totalDebt) |
| 265 | : user.auto_topup_amount |
| 266 | |
| 267 | if (amountToTopUp < MINIMUM_PURCHASE_CREDITS) { |
no test coverage detected