import { NextResponse } from "next/server"; import { auth } from "@/auth"; import { createAssetItem, listAssetItems, validateCreateAssetItemInput, type AssetItemStatus, } from "@/lib/assets"; // Mirrors src/app/api/employees/route.ts's pattern — middleware.ts excludes // /api from route protection, so this checks the session itself. Flat // permission model (CLAUDE.md): only "logged in or not", no role check. export async function POST(request: Request): Promise { const session = await auth(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } let body: unknown; try { body = await request.json(); } catch { return NextResponse.json({ error: "Request body must be valid JSON" }, { status: 400 }); } if (typeof body !== "object" || body === null) { return NextResponse.json({ error: "Request body must be a JSON object" }, { status: 400 }); } const { serialNumber, assetTag, modelId, purchaseDate, warrantyEndDate, purchaseOrderId, cost, costCurrency, externalPoNumber, areaId, } = body as Record; const validation = validateCreateAssetItemInput({ serialNumber, assetTag, modelId, purchaseDate, warrantyEndDate, purchaseOrderId, cost, costCurrency, externalPoNumber, areaId, }); if (!validation.ok) { return NextResponse.json({ error: validation.error }, { status: 400 }); } const created = await createAssetItem(validation.value); if (!created.ok) { return NextResponse.json({ error: created.error }, { status: 400 }); } return NextResponse.json(created.value, { status: 201 }); } // The one entity route in this app whose GET response is NOT a bare array // (see src/hooks/use-api-list.ts's doc comment on that being the norm // everywhere else) -- it's `{items, total}` instead, because /assets is // paginated (2026-08-25, see listAssetItems()'s doc comment) and the // client needs `total` to render page controls. src/app/assets/page.tsx // fetches this directly rather than through useApiList for that reason. export async function GET(request: Request): Promise { const session = await auth(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const url = new URL(request.url); const params = url.searchParams; const page = params.has("page") ? Number(params.get("page")) : undefined; const pageSize = params.has("pageSize") ? Number(params.get("pageSize")) : undefined; const status = params.get("status") ?? undefined; const modelId = params.get("modelId") ?? undefined; const categoryId = params.get("categoryId") ?? undefined; const areaId = params.get("areaId") ?? undefined; const search = params.get("search") ?? undefined; const validStatuses = ["in_stock", "assigned", "repair", "retired", "lost"]; const result = await listAssetItems({ page, pageSize, status: status && validStatuses.includes(status) ? (status as AssetItemStatus) : undefined, modelId, categoryId, areaId, search, }); return NextResponse.json(result, { status: 200 }); }