Customers with large catalogs can upload a CSV instead of adding products one by
one. Mode-aware: restaurant imports into the local catalog (chunked INSERT,
categories resolved/created by name); retail batches to the CRM products/bulk
endpoint. Streamed parsing + batched writes handle thousands of rows in one
request. Includes a downloadable template, an Import button on both product
pages, and a skipped-rows report.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Products are now mode-aware:
- Retail: the catalog lives in Ladill CRM. The Products page proxies CRUD to the
CRM products API (CrmClient gains product/create/update/delete), and the
register reads CRM products live; a sold line is stored as a name/price
snapshot (product_id null, since CRM products aren't local rows). Resilient —
the register shows an empty catalog if CRM is unreachable. CRM import is hidden
in Settings (not needed when reading live).
- Restaurant: unchanged — the local pos_products catalog keeps its POS-only depth
(category, kitchen station, course, modifier groups).
ProductController routes take a raw {product} id (CRM id in retail, local id in
restaurant). Suite green (17), covering both modes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>