feat(stock-quick-draft): PATCH /api/v1/stock-quick-draft/line/[lineId]
Adds a PATCH handler next to the existing DELETE handler. Validates JSON body, maps service result reasons to HTTP status codes, and uses admin PB to bypass user-side collection rules. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
parent
da0a689507
commit
811b2dca1c
1 changed files with 76 additions and 1 deletions
|
|
@ -1,6 +1,10 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getAdminPocketBase } from "@/lib/server/pocketbase-admin";
|
||||
import { removeQuickDraftLine } from "@/lib/server/stock-quick-draft-service";
|
||||
import {
|
||||
removeQuickDraftLine,
|
||||
updateQuickDraftLine,
|
||||
type UpdateQuickDraftLineResult,
|
||||
} from "@/lib/server/stock-quick-draft-service";
|
||||
|
||||
/**
|
||||
* DELETE /api/v1/stock-quick-draft/line/[lineId]
|
||||
|
|
@ -44,3 +48,74 @@ export async function DELETE(
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
type FailureReason = Extract<UpdateQuickDraftLineResult, { ok: false }>["reason"];
|
||||
const STATUS_BY_REASON: Record<FailureReason, number> = {
|
||||
validation: 400,
|
||||
line_not_found: 404,
|
||||
update_failed: 500,
|
||||
};
|
||||
|
||||
/**
|
||||
* PATCH /api/v1/stock-quick-draft/line/[lineId]
|
||||
*
|
||||
* Updates `quantity` and/or `cost_price` on a stock_purchase_items
|
||||
* row. Backed by `updateQuickDraftLine` in the service module.
|
||||
*
|
||||
* Request body: { quantity?: number (>0), costPrice?: number (>=0) }
|
||||
* At least one of the two fields is required.
|
||||
*
|
||||
* Response (success): { ok: true }
|
||||
* Error mapping (reason → status):
|
||||
* "validation" → 400
|
||||
* "line_not_found" → 404
|
||||
* "update_failed" → 500
|
||||
*/
|
||||
export async function PATCH(
|
||||
req: NextRequest,
|
||||
ctx: { params: Promise<{ lineId: string }> },
|
||||
) {
|
||||
const { lineId } = await ctx.params;
|
||||
if (!lineId) {
|
||||
return NextResponse.json(
|
||||
{ ok: false, reason: "validation", message: "lineId is required" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
let body: Record<string, unknown>;
|
||||
try {
|
||||
body = (await req.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
return NextResponse.json(
|
||||
{ ok: false, reason: "validation", message: "invalid JSON body" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const quantity = typeof body.quantity === "number" ? body.quantity : undefined;
|
||||
const costPrice = typeof body.costPrice === "number" ? body.costPrice : undefined;
|
||||
|
||||
try {
|
||||
const pb = await getAdminPocketBase();
|
||||
const result = await updateQuickDraftLine(pb as never, {
|
||||
lineId,
|
||||
quantity,
|
||||
costPrice,
|
||||
});
|
||||
if (!result.ok) {
|
||||
const status = STATUS_BY_REASON[result.reason] ?? 500;
|
||||
return NextResponse.json(result, { status });
|
||||
}
|
||||
return NextResponse.json(result);
|
||||
} catch (err) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
ok: false,
|
||||
reason: "update_failed",
|
||||
message: err instanceof Error ? err.message : "unknown error",
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue