Commit Graph

3 Commits

Author SHA1 Message Date
Josh Rogers fa465ac29c Section defaults on products with prompt-on-divergence
- Add DefaultSection (string?) to Product, FamilyProduct, and
  FamilyProductOverride. Resolution order on item add: per-store memory
  (ProductStoreSection) → family default (override or family product) →
  global product default, matched case-insensitively by name to the
  current store''s StoreSection rows.
- Drop the section dropdown from the add-item form; the backend resolves
  on POST. Section change on a list row syncs the family default:
  silently creates it when none exists, no-op when it matches, returns
  promptSaveDefault=true when it differs so the client confirms before
  updating.
- Expose DefaultSection on the catalog page form. Replace the native
  datalist with a styled TextCombobox component for autocomplete
  suggestions (seeded from typicalSections) while still allowing
  free-text entry. Pattern doc-noted as the sibling of ProductTypeahead.
- Remove the now-unused GET /api/products/{kind}/{id}/section endpoint
  and its tests; the add-form pre-fill they backed is gone.
2026-05-15 22:21:56 -05:00
Josh Rogers fd6b0accc8 Filter unit dropdown by product allowed-unit categories
Adds a UnitCategoryFlags column to Product, FamilyProduct, and
FamilyProductOverride so each product can advertise which unit categories
it is typically packaged by (e.g. flour: Weight | Volume). The product
endpoints round-trip the flag, search projects the effective value with
the override applied, and the frontend QuantityInput soft-filters its
dropdown by the selected product's flag, with a "show all units" escape
hatch for ad-hoc overrides.

No backend rejection on a unit outside the allowed set — the flag is
purely a hint. Default value is None (no filter), so existing data is
unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:17:43 -05:00
Josh Rogers 6c8f0167e5 Add product catalog with per-store section memory
Introduces a global Products catalog plus per-family overrides and
private FamilyProducts, exposed via /api/products with a merged
search. Shopping list items and recipe ingredients gain optional
ProductId/FamilyProductId links, and a new ProductStoreSection
table remembers which section a product was last placed in at a
given store so future adds auto-assign the right section.

Frontend gets a reusable ProductTypeahead component, wired into
list-item add and recipe ingredient entry with free-form fallback.

A startup CatalogSeeder loads ~115 curated staples from an embedded
JSON resource via INSERT ... ON CONFLICT DO NOTHING; skipped under
the Testing environment so integration tests keep a clean slate.
2026-05-09 21:29:51 -05:00