feat: Zod validation on all API inputs (PRD §5.2)

26 files with Zod schemas, 27 safeParse calls.
All POST/PATCH handlers now validate input:
- Missing required fields → 400 with structured error
- Invalid types (string vs number) → 400
- Out-of-range values (probability >100, negative amounts) → 400
- Valid data still works (behavior preserved)

Pattern: schema.safeParse(await req.json()) → 400 on failure
This commit is contained in:
Z User committed 2026-10-27 21:29:51 +00:00
1 parent 3d56770669
commit 2614ce4e3d
25 files changed
+316 -116

No files matched your search

+14 -6
View File
@@ -1,8 +1,18 @@
import { NextResponse } from 'next/server'
import { z } from 'zod'
import { db } from '@/lib/db'
export const dynamic = 'force-dynamic'
const createAnlageSchema = z.object({
name: z.string().min(1),
category: z.string().optional().default('hardware'),
purchaseDate: z.string().min(1),
purchaseCostCents: z.number().int().positive(),
usefulLifeYears: z.number().int().min(1).optional(),
afaMethod: z.string().optional(),
})
// GET /api/aos/anlagen — list asset register with AfA
export async function GET() {
try {
@@ -26,13 +36,11 @@ export async function GET() {
// POST /api/aos/anlagen — create an asset with AfA computation
export async function POST(req: Request) {
try {
const { name, category, purchaseDate, purchaseCostCents, usefulLifeYears, afaMethod } = (await req.json()) as {
name: string; category: string; purchaseDate: string; purchaseCostCents: number
usefulLifeYears?: number; afaMethod?: string
const parsed = createAnlageSchema.safeParse(await req.json())
if (!parsed.success) {
return NextResponse.json({ error: 'validation failed', details: parsed.error.flatten() }, { status: 400 })
}
if (!name?.trim()) return NextResponse.json({ error: 'name required' }, { status: 400 })
if (!purchaseCostCents || purchaseCostCents <= 0) return NextResponse.json({ error: 'purchaseCostCents must be > 0' }, { status: 400 })
const { name, category, purchaseDate, purchaseCostCents, usefulLifeYears, afaMethod } = parsed.data
const cost = Math.round(purchaseCostCents)
const years = usefulLifeYears ?? 3