fix(stock): return 400 (not 500) for malformed PB id in set-pricing route

Code-review feedback from Task 4: the verbatim plan source had a
`throw new Error(...)` inside the per-row .map() that escaped
synchronously as an HTTP 500 instead of the structured 400 envelope
the rest of the route uses for validation errors. Swap .map() for a
for-of loop that returns the structured 400.

Verified:
- Bad id → 400 {code: "validation_error", ...}
- Happy path → 200 unchanged
This commit is contained in:
Claude 2026-08-31 16:56:03 +02:00
parent 6f8c6da0fe
commit a4bfef123b

View file

@ -44,9 +44,22 @@ export async function POST(req: Request) {
); );
} }
const updates = body.updates.map((u, i) => { const updates: Array<{
if (typeof u.id !== "string" || !PB_ID_RE.test(u.id)) { id: string;
throw new Error(`updates[${i}].id must be a 15-char PB id`); costPrice?: number;
sellingPrice?: number;
markup?: number;
}> = [];
for (let i = 0; i < body.updates.length; i++) {
const u = body.updates[i];
if (!u || typeof u.id !== "string" || !PB_ID_RE.test(u.id)) {
return NextResponse.json(
{
code: "validation_error",
message: `updates[${i}].id must be a 15-char PB id`,
},
{ status: 400 },
);
} }
const out: { id: string; costPrice?: number; sellingPrice?: number; markup?: number } = { const out: { id: string; costPrice?: number; sellingPrice?: number; markup?: number } = {
id: u.id, id: u.id,
@ -54,8 +67,8 @@ export async function POST(req: Request) {
if (u.costPrice !== undefined) out.costPrice = Number(u.costPrice); if (u.costPrice !== undefined) out.costPrice = Number(u.costPrice);
if (u.sellingPrice !== undefined) out.sellingPrice = Number(u.sellingPrice); if (u.sellingPrice !== undefined) out.sellingPrice = Number(u.sellingPrice);
if (u.markup !== undefined) out.markup = Number(u.markup); if (u.markup !== undefined) out.markup = Number(u.markup);
return out; updates.push(out);
}); }
let pb; let pb;
try { try {