Adds a search box (matches name, location, and labels) and a Location/Label
grouping toggle to Inventory, and fixes the unstyled Suggestions page.
(Renumbered from 0.19.0 → 0.22.0: Pantry work took 0.19–0.21 in parallel.)
Hardening from a max-effort code review of the new grid:
- Contained items resolve to their container's effective location, so search
finds them and the flat view groups them under the right place (not "No
location").
- Location/label groups key on id, not name, so same-named places/labels stay
separate; synthetic bucket renamed "No labels" to avoid colliding with a real
label; fixed duplicate React keys and two empty-state regressions.
- deleteItem now reparents a deleted container's contents into its own spot
(its place or parent item) instead of orphaning them; the grid also treats
any still-orphaned child as top-level so nothing silently vanishes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring an existing HomeBox inventory straight in, and capture the fields HomeBox
has that we were missing (skipping asset IDs per Tony).
- Item: soldTo/soldPrice/soldDate/soldNotes + flexible customFields (JSON, e.g.
VIN / oil weight for vehicles); both editable in the item dialog and shown on
the detail page
- Pure HomeBox CSV parser (src/lib/inventory/homebox-import.ts, +5 tests) —
RFC4180 quoting (commas/newlines/escaped quotes in fields), HomeBox's 0001-*
null dates and 0 = empty price, semicolon labels, HB.field.* custom columns,
nested 'A / B' location paths
- Import service + /api/v1/items/import: find-or-creates the nested locations
and labels, creates items, recomputes location paths, returns a summary
- Inventory 'Import' button: paste/upload CSV, review every row with checkboxes
(uncheck to skip), then import. Preview parses client-side (parser is pure)
- Verified end-to-end: nested locations, split labels, sold + custom fields,
skip, quoted names, null-date handling. tsc + 38 tests + build green
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rounds out Inventory toward HomeBox, and gives Locations a real home.
Inventory:
- Attach manuals, receipts, and warranty docs (any file), not just photos —
attachment uploader now has a kind picker; WARRANTY kind added
- Richer purchase/warranty: purchasedFrom, warrantyDetails, lifetimeWarranty,
insured (item dialog + detail facts + header badge)
- Schedule recurring maintenance from an item (creates a Task linked via
itemId); item detail shows its maintenance with overdue flagged. Task create
now accepts itemId/animalId
Locations:
- New Locations page + nav: browse/add/rename/move/delete the whole place tree
(LocationManager over the existing /api/locations routes); shows plant/item
counts per place. The spot to merge near-dupes before dropping legacy zone
Verified end-to-end against a running server (new fields round-trip, maintenance
task links to item, MANUAL attachment stored). tsc + 33 tests + build green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first inventory vertical on the shared spine. Things you own — tools, gear,
equipment — each living in a Location or inside another Item.
- Item model (kind DURABLE|CONSUMABLE; consumable fields present but unused so
Pantry needs no migration), self-nesting via parentItemId (toolbox holds drill,
with a cycle guard), value/warranty/serial/brand/qty, qrSlug, photo
- Label (m2m) + ItemAttachment (photos/manuals/receipts) + ItemLog
(maintenance/repair/move/dispose) history; Task.itemId
- API-first: /api/v1/items (CRUD), labels, logs, multipart attachments — the UI
consumes the same scoped endpoints. items service shared with the coming MCP
- Inventory pages: tree grouped by Location with items nested inside items;
item detail with warranty status, photos, contents, history; add/edit/delete,
log, photo upload. Nav entry. Backup/restore cover the new tables
- Pure value.ts (warrantyStatus, totalValue) with tests; verified end-to-end
against a running server (nest, cycle-guard 400, log 201)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>