Apply four low-risk fixes from final code review of the consolidated
add-stock modal: reset newStock on modal close, dedupe stock-item
loading through the existing helper, correct stale empty-state copy
about inventory fallback, and remove a stray blank line left from the
old form deletion.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Editing an inventory-sourced job stock row opened the Edit Stock modal
with the Stock Length dropdown blank instead of showing the row's
current length. EditStock() correctly set newStock.StockItemId from
the row, but then called the fire-and-forget OnStockMaterialChanged(),
which (a) unconditionally reset StockItemId to null, and (b) never
triggered a re-render since its Task wasn't awaited by the event
handler pipeline. Made EditStock async and await a dedicated loader
that populates availableStockItems without touching StockItemId, so
Blazor re-renders once the candidate lengths arrive.
Found during Task 2 manual verification of the unified Add Stock
modal (Step 6).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the three separate surfaces (bulk import modal, inline custom-length
form, inline edit forms) with one "Add Stock" button and modal that handles
both add and edit, for both inventory-sourced and custom-length stock.
Job Edit page's Stock tab currently has three inconsistent entry points
(bulk import modal, inline custom-length form, inline edit forms) for
what should be a single add/edit stock flow.
Three small leftovers from Task 7 / the inventory-quantity-tracking
removal that a final review caught:
- Edit.razor's custom-stock quantity input still had min="1" even
though its own helper text says "Use -1 for unlimited", validation
already accepts -1, and the add-form defaults Quantity to -1 - so
the field rendered pre-populated with a value the browser's native
min validation flagged as invalid. Matches the min="-1" fix already
applied to the catalog-stock input in Task 7.
- optimize_job's MCP tool description still claimed the optimizer
falls back to "available inventory" when no stock is configured -
that auto-discovery fallback was removed in Task 3. An LLM reads
this description as ground truth, so stale wording here actively
misleads tool use. Also tightened add_job_stock's stockItemId/
isCustomLength wording, which still said "inventory" for what is
now just the stock catalog.
- CLAUDE.md's CutListPackingService summary said InStockBins comes
"from inventory", nudging future readers back toward the
auto-discovery mental model this plan removed.
Task 7 extended JobStock.Quantity = -1 (unlimited) to catalog-sourced
rows, but the post-pack classification step in CutListPackingService
only ever treated a catalog-sourced bin as "in stock" when its tracked
quantity was a positive finite number. An unlimited catalog row fell
through to "to be purchased" even though IsInStock=true just means the
bin is catalog-sourced, not a quantity check.
This made the classification effectively unreachable for the most
common path users take to stock a job: the "Import from Inventory"
modal defaults every candidate's quantity to -1, so every resulting
bin was mislabeled "to be purchased" on the Results tab, and the
"everything is available in stock" message could never appear for
jobs stocked that way.
Track unlimited catalog-sourced lengths in a separate set and check it
first; finite catalog quantities keep the existing decrementing-counter
behavior, and custom-length stock (any quantity) is unaffected.
Custom-length job stock already supported -1 (unlimited); catalog-
sourced stock only allowed >= 1. Closes that inconsistency per
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md.
Also updates the Results tab's unplaced-items message now that
insufficient configured quantity is a normal cause, not an edge case.
Final step of removing inventory quantity tracking - see
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md.
Destructive to any existing on-hand/transaction data; confirmed
acceptable since nothing read it automatically.
The fallback silently pulled from StockItem.QuantityOnHand and always
added an extra unlimited bin on top when a job had no stock configured
- i.e. it assumed unlimited purchasing. Per
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md,
a job's available stock must now be exactly what's explicitly entered.
No job workflow ever called these (receive/use/adjust/scrap/recalculate)
- inventory quantity tracking is being removed per
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md.
First step of removing inventory quantity tracking (see
docs/superpowers/specs/2026-08-01-remove-inventory-quantity-tracking-design.md).
UI no longer shows on-hand counts or offers transaction entry; the
underlying field/service methods are removed in follow-up commits.
Users need to enter parts/stock and get results without a disconnected
inventory system to manage; StockItem.QuantityOnHand and StockTransaction
today aren't read or written by the job workflow anywhere except an
auto-discovery fallback that silently assumes unlimited purchasing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CLAUDE.md still listed GetAverageCostAsync/GetLastPurchasePriceAsync, which
Task 1 of the vendor-data removal already deleted. Also stop tracking the
Playwright MCP browser session logs left behind by Task 10's smoke test.