(params: {
userId: string
subscription: SubscriptionRow
logger: Logger
conn?: DbConn
})
| 452 | * - **Weekly**: billing-aligned weekly cap |
| 453 | */ |
| 454 | export async function checkRateLimit(params: { |
| 455 | userId: string |
| 456 | subscription: SubscriptionRow |
| 457 | logger: Logger |
| 458 | conn?: DbConn |
| 459 | }): Promise<RateLimitStatus> { |
| 460 | const { userId, subscription, logger, conn = db } = params |
| 461 | const now = new Date() |
| 462 | |
| 463 | const limits = await getSubscriptionLimits({ |
| 464 | userId, |
| 465 | logger, |
| 466 | conn, |
| 467 | tier: subscription.tier, |
| 468 | }) |
| 469 | |
| 470 | const weekly = await getWeeklyUsage({ |
| 471 | userId, |
| 472 | billingPeriodStart: subscription.billing_period_start, |
| 473 | weeklyCreditsLimit: limits.weeklyCreditsLimit, |
| 474 | logger, |
| 475 | conn, |
| 476 | }) |
| 477 | |
| 478 | // Weekly limit takes precedence |
| 479 | if (weekly.used >= weekly.limit) { |
| 480 | return { |
| 481 | limited: true, |
| 482 | reason: 'weekly_limit', |
| 483 | canStartNewBlock: false, |
| 484 | weeklyUsed: weekly.used, |
| 485 | weeklyLimit: weekly.limit, |
| 486 | weeklyResetsAt: weekly.resetsAt, |
| 487 | weeklyPercentUsed: weekly.percentUsed, |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | // Find most recent active subscription block grant for this user |
| 492 | const blocks = await conn |
| 493 | .select() |
| 494 | .from(schema.creditLedger) |
| 495 | .where( |
| 496 | and( |
| 497 | eq(schema.creditLedger.user_id, userId), |
| 498 | eq(schema.creditLedger.type, 'subscription'), |
| 499 | gt(schema.creditLedger.expires_at, now), |
| 500 | ), |
| 501 | ) |
| 502 | .orderBy(desc(schema.creditLedger.created_at)) |
| 503 | .limit(1) |
| 504 | |
| 505 | const currentBlock = blocks[0] |
| 506 | |
| 507 | // No active block → can start a new one |
| 508 | if (!currentBlock) { |
| 509 | return { |
| 510 | limited: false, |
| 511 | canStartNewBlock: true, |
no test coverage detected