← back to Tk 10965 Zero Price Analysis

prevention/APPLY.md

66 lines

# TK-10965 — Fix B (prevention) apply guide — GATED for deploy

`inventory-stamp-guard.mjs` closes the root cause: it stops importers from ever
stamping positive stock (`2026`) on a $0 / quote-only **sellable** variant, so no
future activation can recreate the zero-price-orderable defect. Fix A (zeroing the
1,743 existing variants) is still required for the products already stamped; this
prevents the population from re-growing after A.

**Status:** SAFE ARTIFACT (pure code + passing test) committed in this repo. Editing
the live importers is a customer-facing behavior change → **Steve-gated deploy.**

## Two-site patch per importer

Each affected importer stamps `2026` in exactly two places. Import the guard once:

```js
import { safeStampQuantity } from './inventory-stamp-guard.mjs'; // adjust path
```

**Site 1 — product-create variant payload** (e.g. `command54-shopify-push.js:395`,
the `Full Roll` variant, and the identical block in `cadence-import.js` +
`templates/new-product-import-template.js`):

```js
// before:
{ option1: 'Full Roll', sku: row.dw_sku, price: '0.00', /* … */ inventory_quantity: 2026 }
// after:
{ option1: 'Full Roll', sku: row.dw_sku, price: buildPrice(row), /* … */
  inventory_quantity: safeStampQuantity({ title: 'Full Roll', price: buildPrice(row) },
                                        { vendor: row.vendor, tags: row.tags }) }
```
(For lines that are legitimately $0-by-design the value becomes `0`; priced lines
still get `2026`. NOTE the standing `price:'0.00'` literal is itself the deeper smell —
a sellable variant should carry a real price; guard makes the stock side safe regardless.)

**Site 2 — the reconcile restamp** (`setInventory2026()`, `command54-shopify-push.js:105`):

```js
// The function is passed bare SKUs, so it must also fetch price + product tags in its
// variant lookup, then compute the quantity per-variant instead of the hard-coded 2026:
const pairs = skus.filter(s => map.has(s)).map(s => ({
  inventoryItemId: map.get(s).inventoryItemId,
  locationId: INV_LOCATION_2026,
  quantity: safeStampQuantity(map.get(s).variant, map.get(s).product), // was: 2026
}));
```
(Extend the GraphQL in `setInventory2026` to also select `price` and the parent
`product{ tags vendor }` so the guard has its inputs — one-line query edit.)

## Affected importers (grep to confirm before deploy)

```sh
grep -rl "setInventory2026\|inventory_quantity: 2026\|quantity: 2026" \
  ~/Projects/Designer-Wallcoverings
```
Canonical live path: `shopify/scripts/cadence/cadence-import.js` +
`.../templates/new-product-import-template.js`. `command54-shopify-push.js` is
RETIRED (header line 3) — patch it only for consistency, it is not live.

## Acceptance

1. `node prevention/inventory-stamp-guard.test.mjs` → all pass (offline).
2. After deploy, activate one quote-only test product → its sellable variant reads
   `availableForSale=false` (qty 0), the $4.25 Sample still non-orderable.
3. `node ../verify.mjs` stays CLEAN over time (no NEW $0-orderable rows appear).