- 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.
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>
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.