Four UX changes after using the rework for a bit:
1. Asset ids are 6-digit numbers from a roll of physical labels — server
no longer generates them. POST /api/inventory requires assetId; the
add-inventory form has a digits-only input that auto-focuses on entry.
2. Strain and product name are the same thing. Drop products.name; the
strain's name supplies the display. Product creation just asks for
"Name (strain)" and matches/creates a strain by that name.
3. Brand moves from inventory_items to products. SKUs are brand-specific,
so all instances of a product share the brand. Brand selector lives
on the product create/edit form, not the per-instance form.
4. Scanning an unknown SKU on the add-inventory step now opens the
create-product subform with the SKU prefilled — one less click.
Migration: detect prior shape (products.name column present) and rename
products/inventory_items/audits to *_v1 archives, recreate empty.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The products table conflated catalog ("kind of thing you scan") with
instance ("this jar I bought") — splitting it lets us record every
purchase as its own asset and autofill brand/shop/price/THC from the
last instance when scanning a known SKU.
- products: sku + strain + name + type + kind (catalog only)
- inventory_items: physical jars with short-UUID asset ids, per-batch
brand/shop/bin/price/cannabinoids/weight, audits, lifecycle
- audits now key on inventory_id; strains lose brand_id and type
- migration: rename existing products/audits/strains to *_legacy on
first boot so users keep historical reference, fresh start otherwise
- two-step add flow: scan SKU → select/create product → instance
details (autofilled from last instance) → generated asset id shown
- ScanField matches asset id first, falls back to SKU
- inventory list defaults flat, "By product" toggle groups instances
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds PATCH /products/:id and an EditProductFlow modal opened from the
product drawer. Editable fields cover name, brand, shop, bin, asset tag,
price, purchase date, size (weight or count + unit weight), and the
cannabinoid profile. SKU, type, kind, and status-derived dates stay
locked because changing them would invalidate audit history math; type
changes are surfaced as "mark gone, add new" in the modal.
The strain row is re-resolved on name or brand change so analytics stay
aligned, and the last-audit mirror (last_audit_weight / count_last_audit)
only syncs with the original size when there are no audits yet.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>