Skip to content

feat: per-user token-bucket rate limit on /api/quotas with 429 + Retr… - #1029

Merged
greatest0fallt1me merged 3 commits into
CalloraOrg:mainfrom
vally111:feat/quota-token-bucket-rate-limit
Jul 29, 2026
Merged

feat: per-user token-bucket rate limit on /api/quotas with 429 + Retr…#1029
greatest0fallt1me merged 3 commits into
CalloraOrg:mainfrom
vally111:feat/quota-token-bucket-rate-limit

Conversation

@vally111

Copy link
Copy Markdown
Contributor

…y-After

  • Add createQuotaRateLimitMiddleware to src/middleware/rateLimit.ts

    • Token-bucket algorithm (TokenBucketRateLimiter) keyed by user id, falling back to client IP for unauthenticated requests
    • Delegates to global error handler via next(new TooManyRequestsError()) so responses use the standardised error envelope
    • Sets Retry-After header (seconds) on every 429 response
  • Add src/routes/quotas.ts (createQuotasRouter)

    • Applies the rate limit middleware to all /api/quotas/** sub-routes
    • Mounts the existing /quotas/counts handler at /counts
    • Accepts an injected middleware via QuotasRouterDeps for unit tests
  • Wire createQuotasRouter into src/app.ts at /api/quotas, replacing the direct per-file mount of quotas/counts

  • Add QUOTA_RATE_LIMIT_CAPACITY (default 60) and QUOTA_RATE_LIMIT_REFILL_RATE (default 1 token/s) to:

    • src/config/env.ts (Zod schema + validation)
    • src/config/index.ts (config.quotaRateLimit)
    • .env.example (documented, commented out)
  • Add focused tests in src/routes/quotas.ratelimit.test.ts

    • createQuotaRateLimitMiddleware: burst capacity, 429 shape, Retry-After, per-user isolation, IP fallback, retryAfterMs in envelope
    • createQuotasRouter: route wiring, DI injection, multi-user isolation, unauthenticated IP gating
  • Update README.md: feature bullet + environment variable table rows

Closes #910

…y-After

- Add createQuotaRateLimitMiddleware to src/middleware/rateLimit.ts
  - Token-bucket algorithm (TokenBucketRateLimiter) keyed by user id,
    falling back to client IP for unauthenticated requests
  - Delegates to global error handler via next(new TooManyRequestsError())
    so responses use the standardised error envelope
  - Sets Retry-After header (seconds) on every 429 response

- Add src/routes/quotas.ts (createQuotasRouter)
  - Applies the rate limit middleware to all /api/quotas/** sub-routes
  - Mounts the existing /quotas/counts handler at /counts
  - Accepts an injected middleware via QuotasRouterDeps for unit tests

- Wire createQuotasRouter into src/app.ts at /api/quotas, replacing
  the direct per-file mount of quotas/counts

- Add QUOTA_RATE_LIMIT_CAPACITY (default 60) and
  QUOTA_RATE_LIMIT_REFILL_RATE (default 1 token/s) to:
  - src/config/env.ts  (Zod schema + validation)
  - src/config/index.ts (config.quotaRateLimit)
  - .env.example (documented, commented out)

- Add focused tests in src/routes/quotas.ratelimit.test.ts
  - createQuotaRateLimitMiddleware: burst capacity, 429 shape,
    Retry-After, per-user isolation, IP fallback, retryAfterMs in envelope
  - createQuotasRouter: route wiring, DI injection, multi-user isolation,
    unauthenticated IP gating

- Update README.md: feature bullet + environment variable table rows

Closes #(quota-rate-limit)
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@vally111 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@greatest0fallt1me

Copy link
Copy Markdown
Contributor

Merged into main via admin resolver (-X theirs).

@greatest0fallt1me
greatest0fallt1me merged commit c880299 into CalloraOrg:main Jul 29, 2026
1 check passed
@greatest0fallt1me

Copy link
Copy Markdown
Contributor

CI passed, solid PR — merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add rate limit on /api/quotas [b#045]

2 participants