feat: add supplier scoring and UPC file analysis functionality

- Implemented supplier scoring logic in `supplier-scoring.ts` with functions to compute demand score, competition penalty, and overall supplier product score.
- Created unit tests for supplier scoring in `supplier-scoring.test.ts` to validate scoring logic against various scenarios.
- Developed UPC file analysis tool in `upc-file-analysis.ts` to process UPCs in batches, fetch product data from Keepa and SP-API, and generate supplier results.
- Added UPC input reading functionality in `upc-file-reader.ts` to handle XLSX and XLS files, including validation for UPC formats.
- Introduced a command-line tool in `upc-lookup.ts` for looking up UPCs and displaying detailed results or mappings to ASINs.
- Enhanced error handling and logging throughout the new modules for better traceability and user feedback.
This commit is contained in:
Victor Noguera
2026-05-25 00:53:47 -04:00
parent b982edd160
commit c006d87c54
36 changed files with 1905 additions and 113 deletions

View File

@@ -0,0 +1,46 @@
import { expect, test } from "bun:test";
import { parseCatalogUpcLookupResponse } from "./sp-api.ts";
test("parseCatalogUpcLookupResponse resolves one ASIN", () => {
const detail = parseCatalogUpcLookupResponse("012345678901", {
items: [{ asin: "b000found1" }],
});
expect(detail.status).toBe("found");
expect(detail.asin).toBe("B000FOUND1");
expect(detail.candidateAsins).toEqual(["B000FOUND1"]);
});
test("parseCatalogUpcLookupResponse marks no match", () => {
const detail = parseCatalogUpcLookupResponse("012345678901", {
payload: { items: [] },
});
expect(detail.status).toBe("not_found");
expect(detail.asin).toBeNull();
});
test("parseCatalogUpcLookupResponse marks multiple ASINs", () => {
const detail = parseCatalogUpcLookupResponse("012345678901", {
payload: {
items: [{ asin: "B000000001" }, { asin: "B000000002" }],
},
});
expect(detail.status).toBe("multiple_asins");
expect(detail.candidateAsins).toEqual(["B000000001", "B000000002"]);
});
test("parseCatalogUpcLookupResponse marks invalid UPCs", () => {
const detail = parseCatalogUpcLookupResponse("123", { items: [] });
expect(detail.status).toBe("invalid_upc");
});
test("parseCatalogUpcLookupResponse marks malformed response as failed", () => {
const detail = parseCatalogUpcLookupResponse("012345678901", {
unexpected: true,
});
expect(detail.status).toBe("request_failed");
});