Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds OpenAPI/Swagger documentation support to the server, including a shared OpenAPI registry, Prisma-mirrored Zod schemas, and route-level registry.registerPath(...) definitions across Slack/Manager/Analysis endpoints. It also exposes Swagger UI/JSON endpoints and updates API key rate limiting to use Redis.
Changes:
- Add OpenAPI document generation (Zod → OpenAPI) and serve Swagger UI (
/doc) + spec (/doc.json). - Register OpenAPI path definitions across many existing routes (Slack, Manager, Analysis).
- Add Prisma-mirrored Zod schemas and switch API-key rate limiting to Redis counters.
Reviewed changes
Copilot reviewed 23 out of 24 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/openapi.ts | New shared OpenAPI registry + doc generation + security schemes |
| src/lib/prisma-zod.ts | New Zod schemas mirroring Prisma models; registers them into OpenAPI |
| src/app.ts | Serves static public/, adds /doc and /doc.json endpoints |
| public/swaggerTheme.css | Swagger UI theme override |
| src/routes/slack/slack.routes.ts | Adds OpenAPI docs for Slack endpoints |
| src/routes/manager/manager.routes.ts | Adds OpenAPI docs for selected manager endpoints; mounts /apikey router |
| src/routes/manager/apikey.routes.ts | Adds OpenAPI docs for API key management routes |
| src/routes/manager/onboarding.routes.ts | Adds OpenAPI docs for onboarding endpoints |
| src/routes/manager/picklists.routes.ts | Adds OpenAPI docs + request/response schemas for picklists |
| src/routes/manager/mutablepicklists.routes.ts | Adds OpenAPI docs + schemas for mutable picklists |
| src/routes/manager/registeredteams.routes.ts | Adds OpenAPI docs + discriminated union for registration status |
| src/routes/manager/scouters.routes.ts | Adds OpenAPI docs for public + protected scouter endpoints |
| src/routes/manager/scoutreports.routes.ts | Adds OpenAPI docs and a create schema for scout reports |
| src/routes/manager/settings.routes.ts | Adds OpenAPI docs for settings endpoints |
| src/routes/manager/tournaments.routes.ts | Adds OpenAPI docs for tournament endpoints |
| src/routes/manager/scoutershifts.routes.ts | Adds OpenAPI docs for scoutershift update/delete endpoints |
| src/routes/analysis/analysis.routes.ts | Adds OpenAPI docs for analysis endpoints |
| src/routes/analysis/teamLookup.routes.ts | Adds OpenAPI docs for team lookup endpoints |
| src/routes/analysis/scoutreport.routes.ts | Adds OpenAPI docs for scoutreport analysis endpoints |
| src/routes/analysis/csv.routes.ts | Adds OpenAPI docs for CSV endpoints |
| src/redisClient.ts | Adds incr and exp helpers for Redis |
| src/lib/middleware/requireAuth.ts | Switches API-key rate limiting from DB timestamp to Redis counter |
| package.json | Adds OpenAPI/Swagger deps; bumps version |
| package-lock.json | Locks new dependencies |
Comments suppressed due to low confidence (2)
src/lib/middleware/requireAuth.ts:51
- API key rate-limiting logic is inverted and also doesn't stop execution after sending a 429. As written, the first API-key request (count=1) will be rate-limited, and the handler continues to run (risking "headers already sent" and still updating Prisma / calling next()). Flip the condition to only 429 when the counter exceeds the allowed threshold, and return immediately after sending the response.
const redisKey = `auth:apikey:${keyHash}:rate`;
const count = Number(await kv.incr(redisKey));
if (count === 1) await kv.exp(redisKey);
if (count <= 1) {
res.status(429).json({
message:
"You have exceeded the rate limit for an API Key. Please wait before making more requests.",
retryAfterSeconds: 3,
});
}
src/lib/middleware/requireAuth.ts:70
prisma.apiKey.update(...)throws if no record matcheskeyHash, so the subsequentif (!apiKey)check is unreachable. This will turn an invalid API key into a 500 instead of a 401. UsefindUniquefirst (or handle Prisma's not-found error / useupdateMany) and return a 401 when the key doesn't exist.
const apiKey = await prisma.apiKey.update({
where: {
keyHash: keyHash,
},
data: {
requests: {
increment: 1,
},
},
include: {
user: true,
},
});
if (!apiKey) {
res.status(401).send("Invalid API key");
return;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 52 out of 54 changed files in this pull request and generated 15 comments.
Comments suppressed due to low confidence (2)
src/lib/middleware/requireAuth.ts:69
prisma.apiKey.update(...)will throw if the keyHash doesn’t exist, so the subsequentif (!apiKey)is unreachable and invalid API keys will likely produce a 500 instead of a 401. Consider looking up the API key first (or usingupdateinside a try/catch for Prisma not-found) and only incrementing requests after passing the rate-limit check.
src/lib/middleware/requireAuth.ts:50- In the API key branch, the rate-limit condition is inverted and the handler doesn’t return after sending the 429. As written, the first API-key request will be treated as rate-limited (count is 1) and execution continues into the Prisma update/next(), which can lead to “headers already sent” and effectively breaks API-key auth. Flip the condition (rate-limit on subsequent requests within the TTL) and return immediately after sending the 429.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 52 out of 54 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 53 out of 55 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
No description provided.