feat(billing): add requireQuota middleware for plan-based limits#3275
feat(billing): add requireQuota middleware for plan-based limits#3275PierreBrisorgueil merged 2 commits intomasterfrom
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR introduces a new Express middleware factory Changes
Sequence DiagramsequenceDiagram
participant Client
participant Middleware as Quota Middleware
participant SubRepo as SubscriptionRepository
participant Config
participant UsageService as BillingUsageService
participant Response
Client->>Middleware: HTTP Request (resource, action)
Middleware->>Middleware: Check org in request
alt No organization
Middleware->>Response: 403 Forbidden
else Organization present
Middleware->>SubRepo: Get subscription by org
alt No subscription or past_due
Middleware->>Middleware: Set plan = 'free'
else Subscription active
Middleware->>Middleware: Set plan = subscription.plan
end
Middleware->>Config: Read quota limit<br/>quotas[plan][resource][action]
alt No quota configured or Infinity
Middleware->>Client: Call next()
else Quota exists
Middleware->>UsageService: Get current usage<br/>(org, resource, action)
alt Current >= Limit
Middleware->>Response: 429 QUOTA_EXCEEDED<br/>(details + upgradeUrl)
else Under limit
Middleware->>Client: Call next()
end
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds a new billing middleware to enforce plan-based monthly usage quotas, enabling downstream projects to gate specific actions based on configured limits and current usage.
Changes:
- Introduces
requireQuota(resource, action)middleware that resolves plan and enforcesconfig.billing.quotaslimits usingBillingUsageService. - Returns a 429
QUOTA_EXCEEDEDpayload includingresource,action,limit,current, andupgradeUrlwhen the quota is reached/exceeded. - Adds unit tests covering free/past_due handling, unlimited (Infinity), missing subscription/org context, and unconfigured quotas.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| modules/billing/middlewares/billing.quota.middleware.js | New quota-enforcement middleware using subscription plan + monthly usage counters. |
| modules/billing/tests/billing.quota.unit.tests.js | Unit tests validating quota decisions and error payload behavior. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@modules/billing/middlewares/billing.quota.middleware.js`:
- Line 22: The returned async middleware function requireQuotaMiddleware is
missing a JSDoc header; add a JSDoc block immediately above "return async
function requireQuotaMiddleware(req, res, next) {" with a one-line description,
`@param` {Request} req, `@param` {Response} res, `@param` {Function} next, and
`@returns` {Promise<void>} to satisfy the repository rule that every new/modified
JS function has a one-line description and param/returns tags.
- Around line 48-55: Replace the raw res.status(429).json(...) in the billing
quota middleware with the shared responses helper so the response uses the
standard { type, message, data } envelope; specifically, in the function that
currently returns the 429 (the billing quota middleware around the return
statement using variables resource, action, limit, current), call the
centralized responses helper (e.g., responses.error or responses.send depending
on project helper) to send status 429 and pass { type: 'QUOTA_EXCEEDED',
message: 'Quota exceeded', data: { resource, action, limit, current, upgradeUrl:
config.billing?.upgradeUrl || '/billing/plans' } } instead of the raw JSON.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2b6fe068-ba0c-4a97-b933-98992528d9eb
📒 Files selected for processing (2)
modules/billing/middlewares/billing.quota.middleware.jsmodules/billing/tests/billing.quota.unit.tests.js
- Rename billing.quota.middleware.js → billing.requireQuota.js for naming consistency with billing.requirePlan.js - Add JSDoc to inner middleware function per repository coding guidelines - Document bypass cases (null/undefined limit, Infinity) in outer JSDoc - Use responses.error envelope for 429 quota response instead of raw JSON - Update test assertions to match standardized response envelope
Summary
requireQuota(resource, action)factory middleware that gates routes by plan-based usage quotasconfig.billing.quotas[plan][resource][action], checks current month usage via BillingUsage serviceQUOTA_EXCEEDEDpayload (resource, action, limit, current, upgradeUrl) when over limitpast_duestatus are treated asfreeplan;Infinitymeans unlimitedTest plan
Closes #3270
Summary by CodeRabbit