QoL changes and additions
Build and Push Docker Image / build (push) Successful in 45s

This commit is contained in:
jason
2026-04-22 13:16:42 -05:00
parent a165428f14
commit 04ae88ca0d
14 changed files with 1424 additions and 29 deletions
+42
View File
@@ -0,0 +1,42 @@
import { type NextRequest } from "next/server";
import { ok, errorResponse, requireRole, parseJson } from "@/lib/api";
import { DuplicatePartSchema } from "@/lib/schemas";
import { audit } from "@/lib/audit";
import { clientIp } from "@/lib/request";
import { duplicatePart } from "@/lib/duplicate";
/**
* Admin-only. Clone a Part into its existing assembly with a new `code`
* (and optionally a new `name`). By default every Operation is cloned too —
* with fresh qrTokens, reset to `pending` status and zero units. Useful for
* spinning up a left/right variant, or re-running a completed part.
*
* Not used for cross-assembly / cross-project moves — admin can edit the
* code / qty / notes on the copy afterwards.
*/
export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
try {
const actor = await requireRole("admin");
const { id } = await ctx.params;
const body = await parseJson(req, DuplicatePartSchema);
const result = await duplicatePart({
sourcePartId: id,
code: body.code,
name: body.name,
includeOperations: body.includeOperations ?? true,
});
await audit({
actorId: actor.id,
action: "duplicate",
entity: "Part",
entityId: result.id,
after: { sourcePartId: id, ...result },
ipAddress: clientIp(req),
});
return ok({ part: { id: result.id }, operationsCopied: result.operationsCopied }, { status: 201 });
} catch (err) {
return errorResponse(err);
}
}