v0.16.0 — HomeBox CSV import + sold lifecycle + custom fields
Bring an existing HomeBox inventory straight in, and capture the fields HomeBox has that we were missing (skipping asset IDs per Tony). - Item: soldTo/soldPrice/soldDate/soldNotes + flexible customFields (JSON, e.g. VIN / oil weight for vehicles); both editable in the item dialog and shown on the detail page - Pure HomeBox CSV parser (src/lib/inventory/homebox-import.ts, +5 tests) — RFC4180 quoting (commas/newlines/escaped quotes in fields), HomeBox's 0001-* null dates and 0 = empty price, semicolon labels, HB.field.* custom columns, nested 'A / B' location paths - Import service + /api/v1/items/import: find-or-creates the nested locations and labels, creates items, recomputes location paths, returns a summary - Inventory 'Import' button: paste/upload CSV, review every row with checkboxes (uncheck to skip), then import. Preview parses client-side (parser is pure) - Verified end-to-end: nested locations, split labels, sold + custom fields, skip, quoted names, null-date handling. tsc + 38 tests + build green Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
22
src/app/api/v1/items/import/route.ts
Normal file
22
src/app/api/v1/items/import/route.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { authenticateRequest, handleApiError } from "@/lib/api/authenticate";
|
||||
import { importHomeBoxItems } from "@/lib/services/inventory-import";
|
||||
|
||||
const schema = z.object({
|
||||
csv: z.string().min(1),
|
||||
skip: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
// POST /api/v1/items/import — import a HomeBox CSV export. `skip` lists item
|
||||
// names to leave out (e.g. the ones unchecked in the preview).
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const ctx = await authenticateRequest(req, "items:write");
|
||||
const { csv, skip } = schema.parse(await req.json());
|
||||
const summary = await importHomeBoxItems(ctx, { csv, skip });
|
||||
return NextResponse.json(summary, { status: 201 });
|
||||
} catch (err) {
|
||||
return handleApiError(err);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user