Skip to content

feat(locations): per-location ItemStock split + scoped pantry (PR D) - #239

Open
ETBlue wants to merge 14 commits into
mainfrom
worktree-feature-item-stock-split
Open

feat(locations): per-location ItemStock split + scoped pantry (PR D)#239
ETBlue wants to merge 14 commits into
mainfrom
worktree-feature-item-stock-split

Conversation

@ETBlue

@ETBlue ETBlue commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

PR D of 5 — the core of the Location feature. Splits stock off the global Item into a per-(item × location) ItemStock, migrates existing data, and turns on the multi-location UX. Two commits:

Phase 1 — refactor: ItemStock split + Dexie v15 (behaviour-preserving)

  • Item trimmed to id/name/tagIds/vendorIds/wikidataUrl/note/timestamps; new ItemStock holds stock/units/expiration per location.
  • Dexie v15: itemStocks store, locationId on inventoryLogs, carts re-keyed to ${locationId}:${vendorId|'no-vendor'}. Idempotent upgrade splits each Item's stock into a 'local' ItemStock, stamps logs, re-keys carts.
  • Operations take an explicit locationId (default 'local'); hooks thread useActiveLocation().activeLocationId and key queries by it. Components read stock via a joined PantryItem (no Dexie access). With the single default location, the app behaves identically.

Phase 2 — feat: scope pantry + combobox add

  • Pantry (list + all group/detail views) shows only items stocked in the active location (useStockedItems); switching re-scopes.
  • The Add dialog is now an accessible combobox over the full catalog: pick an existing item → addItemToLocation (copy-on-add, no-op if already stocked); no match → Create "<name>"createItem in the active location. Already-stocked items show as disabled "Already here" options.
  • Cooking: recipe items not stocked in the active location render unavailable (greyed, not consumed).

Test Plan

  • lint / check / build (no TS6385) / build-storybook
  • pnpm test1430 unit/integration pass (migration-adjacent ops, copy-on-add, scoping, combobox, cooking-unavailable)
  • pnpm test:e2e — multi-location flow (create in My Home → switch to empty location → add existing via combobox → appears → switch back → original intact)
  • Pre-existing only: 4 pantry group-by color-contrast a11y; [cloud] tests need a backend on :4001 (ItemStock is local-only — cloud is a documented TODO)

Notes / decisions

  • Cloud ItemStock is deferred (local-first); cloud mode still uses the GraphQL Item with inline stock. Documented TODO.
  • Export/import still round-trips the legacy combined-Item shape (stock inline) — a documented TODO, not split into Item+ItemStock yet.
  • Shopping vendor-page item listing still shows all of a vendor's items (carts/checkout ARE location-scoped). Flagging: the design hints shopping could be scoped to stocked items, but shopping is also where you restock — left as-is pending your call.
  • The Stock-tab all-locations pager is PR E (this PR keeps the Stock tab single-location = active location). INDEX row stays 🔲 until PR E.

Next

PR E — item-detail Stock-tab all-locations pager (add/remove from location) + final docs.

🤖 Generated with Claude Code

@ETBlue ETBlue added this to the v0.3.0 — Local Polish milestone Jun 12, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploying player1inventory-storybook with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6255864
Status: ✅  Deploy successful!
Preview URL: https://3f3d8c82.player1inventory-storybook.pages.dev
Branch Preview URL: https://worktree-feature-item-stock.player1inventory-storybook.pages.dev

View logs

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploying player1inventory with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6255864
Status: ✅  Deploy successful!
Preview URL: https://443c5791.player1inventory.pages.dev
Branch Preview URL: https://worktree-feature-item-stock.player1inventory.pages.dev

View logs

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 12, 2026

Copy link
Copy Markdown

Deploying player1inventory-design with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6255864
Status: ✅  Deploy successful!
Preview URL: https://bb300785.player1inventory-design.pages.dev
Branch Preview URL: https://worktree-feature-item-stock.player1inventory-design.pages.dev

View logs

ETBlue and others added 14 commits June 14, 2026 16:52
ItemStock holds stock/units/expiration per (item × location). Item keeps
id/name/tagIds/vendorIds/wikidataUrl/note/timestamps. Adds StockFields, the
joined PantryItem, cartIdFor/parseCartId, and locationId on InventoryLog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the itemStocks store, locationId on inventoryLogs, and re-keys carts to
`${locationId}:${vendorId|'no-vendor'}`. Idempotent v14-to-v15 upgrade splits
each Item's stock into a 'local' ItemStock, stamps logs, and re-keys carts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Operations take an explicit locationId (default 'local'): itemStock CRUD,
createItem splits into Item + ItemStock, addItemToLocation (copy-on-add —
inherits all fields except packed/unpacked), checkout/consume/quick-update/
log queries scoped by (itemId, locationId), and deleteLocation cascades the
location's stock, carts, and logs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
quantityUtils, expiration, and sort take stock fields instead of an Item;
filterUtils is generic over Item so it preserves PantryItem; cloud
deserialization returns a joined PantryItem. Import still round-trips the
legacy combined-Item shape (documented TODO).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hooks

Hooks read useActiveLocation().activeLocationId and key queries by it so
switching re-fetches. Adds useItemStock/useItemStocks/useStockedItems and
useAddItemToLocation; useItems returns the joined PantryItem. Cloud path
stays on the GraphQL Item (ItemStock is local-only — documented TODO).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…k-update

ItemCard and QuickUpdateDialog now take a PantryItem (Item joined with its
active-location stock) instead of reading stock fields off Item directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All pantry views (list + shelf/vendor/recipe group & detail) use
useStockedItems(), showing only items stocked in the active location;
switching the location re-scopes the list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The add-item name field is now an accessible combobox over the full catalog:
pick an existing item to stock it here (copy-on-add, no-op if already
stocked), or Create "<name>" to make a new item in the active location.
Already-stocked items render as disabled "Already here" options.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n stock

The item-detail Stock/Info tabs and the tag/vendor/recipe item-assignment
tabs read and write the active location's ItemStock instead of stock fields
on Item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Carts are keyed per (location × vendor); checkout writes the active
location's ItemStock and stamps logs with its locationId.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… unavailable

Cooking consumes the active location's ItemStock; a recipe item not stocked
in that location renders unavailable (greyed, checkbox disabled, excluded
from consumption).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the create-second-location + copy-on-add combobox flow to the
location-switcher spec, a locationSeed helper, and updates inline-stock /
raw-cart seeds across specs to write itemStocks rows under the v15 schema.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ETBlue
ETBlue force-pushed the worktree-feature-item-stock-split branch from 5d9d3a7 to 6255864 Compare June 14, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant