feat(raw-materials): add bulk JSON import with upsert and full-page edit routes (#10)

Fixes #9

---------

Co-authored-by: Your Name <you@example.com>
Reviewed-on: #10
Co-authored-by: antigravity-bot <bot@kittisak.com>
This commit was merged in pull request #10.
This commit is contained in:
antigravity-bot BotandYour Name authored and admin committed 2026-10-18 03:30:19 +00:00
1 parent b13f37cf7e
commit a647c9682d
6 files changed
+1153 -171

No files matched your search

+66
View File
@@ -14,11 +14,77 @@ export const rawMaterialsRoute = new Elysia({ prefix: "/raw-materials" })
const rawMaterial = await prisma.rawMaterial.findUnique({
where: { id },
include: {
bomItems: {
include: {
productVariant: {
include: {
product: {
select: { id: true, name: true, sku: true }
}
}
}
}
}
}
});
if (!rawMaterial) return status(404, { message: "Raw material not found" });
return rawMaterial;
})
.post("/bulk", async ({ body, status }) => {
try {
const items = Array.isArray(body) ? body : [body];
if (items.length === 0) {
return status(400, { message: "Payload must be a non-empty array" });
}
const results = await prisma.$transaction(async (tx) => {
const records = [];
for (const item of items) {
const name = String(item.name || "").trim();
if (!name) continue;
const unit = String(item.unit || "piece").trim() || "piece";
const rawPrice = item.pricePerUnit;
const pricePerUnit = typeof rawPrice === "string" ? (parseFloat(rawPrice) || 0) : Number(rawPrice) || 0;
const record = await tx.rawMaterial.upsert({
where: { name },
create: {
name,
unit,
pricePerUnit,
},
update: {
unit,
pricePerUnit,
},
});
records.push(record);
}
return records;
});
return status(200, {
success: true,
count: results.length,
items: results,
});
} catch (err: any) {
console.error("Bulk raw material import failed:", err);
return status(500, { message: "Failed to bulk import raw materials", error: err.message });
}
}, {
body: t.Array(
t.Object({
name: t.String(),
unit: t.Optional(t.String()),
pricePerUnit: t.Union([t.Number(), t.String()]),
})
),
detail: { tags: ["raw-materials"] }
})
.post("/", async ({ body, status }) => {
try {
const rawMaterial = await prisma.rawMaterial.create({