Skip to content

feat: per-user token-bucket rate limit on /api/logs (FWC26) - #1123

Merged
greatest0fallt1me merged 2 commits into
CalloraOrg:mainfrom
mrteeednut007-dotcom:feat/logs-rate-limit
Jul 29, 2026
Merged

feat: per-user token-bucket rate limit on /api/logs (FWC26)#1123
greatest0fallt1me merged 2 commits into
CalloraOrg:mainfrom
mrteeednut007-dotcom:feat/logs-rate-limit

Conversation

@mrteeednut007-dotcom

Copy link
Copy Markdown
Contributor

feat: per-user token-bucket rate limit on /api/logs (FWC26)

Summary

Implements the GET /api/logs and POST /api/logs endpoints with a per-user token-bucket rate
limiter as required by the GrantFox FWC26 campaign spec.

What changed

New: src/routes/logs.ts

  • GET /api/logs — returns the authenticated user's log entries sorted newest-first, wrapped in
    the canonical success envelope { data: { logs: [...] }, meta: { total } }
  • POST /api/logs — accepts { message, level?, meta? }, validates with Zod, persists, returns
    201 with the created entry
  • Both routes are guarded by requireAuth and a per-user token-bucket rate limiter
  • On exhaustion: HTTP 429 + Retry-After header + { code: "TOO_MANY_REQUESTS", message,
    requestId, retryAfterMs }
  • Rate-limit key resolution priority: JWT userId → x-user-id header → client IP

Config: src/config/env.ts + src/config/index.ts

  • LOGS_RATE_LIMIT_CAPACITY (default 60) — burst ceiling per user
  • LOGS_RATE_LIMIT_REFILL_RATE (default 1) — tokens refilled per second

Route registration: src/routes/index.ts

  • Mounts createLogsRouter() at /api/logs

Tests: src/routes/logs.test.ts (30+ cases)

  • GET/POST happy paths, auth rejection, Zod validation errors
  • Rate-limit 429 on GET and POST independently
  • Per-user bucket isolation (user A exhausted doesn't affect user B)
  • Shared limiter drains across GET + POST on the same user
  • Retry-After header ≥ 1s, retryAfterMs > 0 in body
  • requestId present on 429 responses
  • Token refill verified at the unit level
  • Factory injection (rateLimiter + rateLimitOptions overrides)

Docs: README.md + .env.example

  • Logs Endpoint section with rate-limit table and 429 response shape
  • Environment variable entries for LOGS_RATE_LIMIT_*

Testing

npm test -- --testPathPattern logs

Checklist

  • Auth enforced on all routes
  • Input validated at the boundary (Zod)
  • Rate limit returns canonical 429 + Retry-After
  • Per-user bucket isolation
  • Structured logging with correlation/request IDs
  • ≥90% line coverage on new files
  • README and .env.example updated
  • No pre-existing tests broken

Closes #890

- Add GET /api/logs and POST /api/logs endpoints (src/routes/logs.ts)
- Both routes require auth (requireAuth) and are guarded by a per-user
  token-bucket rate limiter (createTokenBucketRateLimitMiddleware)
- Bucket config driven by new env vars with safe defaults:
    LOGS_RATE_LIMIT_CAPACITY=60  (burst ceiling per user)
    LOGS_RATE_LIMIT_REFILL_RATE=1  (tokens refilled per second)
- On bucket exhaustion: HTTP 429 + Retry-After header +
  { code, message, requestId, retryAfterMs } body
- Key resolution: JWT userId → x-user-id header → client IP
- Register /api/logs in src/routes/index.ts
- 30+ focused tests in src/routes/logs.test.ts covering:
    happy paths, auth, validation, rate-limit 429, per-user isolation,
    Retry-After semantics, shared-limiter across GET+POST, factory opts
- Documented in README.md (Logs Endpoint section + env vars table)
- Documented in .env.example (LOGS_RATE_LIMIT_* entries)

Closes #FWC26
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@mrteeednut007-dotcom 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
greatest0fallt1me merged commit f0880cb into CalloraOrg:main Jul 29, 2026
1 check passed
@greatest0fallt1me

Copy link
Copy Markdown
Contributor

All good — merging. 🚀

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/logs [b#025]

2 participants