codeflash-internal/js/cf-api/middlewares/rate-limit.ts
Kevin Turcios d7a8b8f227
perf: fix CI build + lazy-load heavy libs + parallelize DB queries (#2601)
## Summary
- **Fix CI build failure**: Auth0Client crashes during Next.js
prerendering when env vars aren't set. Returns a no-op stub (`getSession
→ null`) when domain is missing — semantically correct for static
generation
- **Lazy-load markdown libs (~260kb)**: ReactMarkdown, remarkGfm, and
react-syntax-highlighter were eagerly imported in monaco-diff-viewer but
only rendered when user expands "Generated Tests". Extracted into a
dynamic component
- **Parallelize repo detail query**: `getRepositoryById` ran the
activity count sequentially after the repo lookup. Since `repoId` is
already available, all three queries now run in parallel

## Test plan
- [ ] CI `build` check passes (was failing since #2598)
- [ ] Trace page still renders generated tests correctly when expanded
- [ ] Repository detail page loads correctly with activity status
2026-04-13 11:03:05 -05:00

45 lines
1.4 KiB
TypeScript

import rateLimit from "express-rate-limit"
import * as Sentry from "@sentry/node"
import { AuthorizedUserReq } from "../types.js"
import { isCodeflashEmployee } from "../utils/employee-utils.js"
// Load values from environment or use defaults
const RATE_LIMIT_WINDOW_MS = parseInt(process.env.RATE_LIMIT_WINDOW_MS || "60000", 10)
const RATE_LIMIT_MAX = parseInt(process.env.RATE_LIMIT_MAX || "30", 10)
// Common configuration for rate limiters
const baseRateLimitConfig = {
windowMs: RATE_LIMIT_WINDOW_MS, // in milliseconds
max: RATE_LIMIT_MAX,
standardHeaders: true,
legacyHeaders: false,
handler: (req, res, next, options) => {
// Log rate limit hit to Sentry
Sentry.captureMessage("Rate limit exceeded", {
level: "warning",
extra: {
ip: req.ip,
path: req.path,
method: req.method,
limiterType: "id",
},
})
// Send standard rate limit response
res.status(options.statusCode).send(options.message)
},
}
// ID-based rate limiter
export const idLimiter = rateLimit({
...baseRateLimitConfig,
skip: (req: AuthorizedUserReq) => {
// Skip if no userId is set — typically means checkForValidAPIKey hasn't run yet
if (!req.userId) return true
if (isCodeflashEmployee(req.userId)) return true
return false
},
keyGenerator: (req: AuthorizedUserReq) => `ratelimit:user:${req.userId}:${req.path}`,
})