refactor: add centralized Zod validators for all API inputs

Create server/src/lib/validators.ts with reusable schemas for all API
inputs (auth, fights, bets, payments, tournaments, queue, docs).
Import and use in all route handlers, replacing inline validation.
Add formatZodError helper for user-friendly error messages.
77 test cases in validators.test.ts cover valid, invalid, boundary,
and attack inputs (SQL injection, XSS, prototype pollution).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-13 09:16:04 +00:00
co-authored by Claude Opus 4.6
parent 55d0f84251
commit 2051a95e13
11 changed files with 549 additions and 122 deletions
+5 -4
View File
@@ -4,6 +4,7 @@ import { eq } from 'drizzle-orm'
import { joinQueue, leaveQueue, getQueueSize, getQueueSnapshot } from '../engine/queue.js'
import { joinRankedQueue, getRankedQueueStatus } from '../engine/ranked-queue.js'
import { rateLimit } from '../middleware/rate-limit.js'
import { joinRankedSchema } from '../lib/validators.js'
export const queueRouter = new Hono()
@@ -53,11 +54,11 @@ queueRouter.get('/ranked-status', (c) => {
// Join ranked queue — requires confirmed payment + bot ownership
queueRouter.post('/join-ranked/:botId', async (c) => {
const botId = c.req.param('botId')
const { paymentId, pubkey } = await c.req.json<{ paymentId: string; pubkey?: string }>()
if (!paymentId) {
return c.json({ error: 'Missing paymentId' }, 400)
const parsed = joinRankedSchema.safeParse(await c.req.json().catch(() => ({})))
if (!parsed.success) {
return c.json({ error: parsed.error.issues[0]?.message || 'Missing paymentId' }, 400)
}
const { paymentId, pubkey } = parsed.data
// Verify bot ownership in production
if (process.env.NODE_ENV === 'production') {