← back to York Yardgood Exec
York contract yard-good reprice: 73-product executor + dry-run clean + rollback
bc9720a84d695a02e19e7c25b5466c217825ade3 · 2026-09-09 15:39:41 -0700 · Steve
Files touched
A .gitignoreA data/york73-target.jsonA york73-rollback.mjsA york73.mjs
Diff
commit bc9720a84d695a02e19e7c25b5466c217825ade3
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Sep 9 15:39:41 2026 -0700
York contract yard-good reprice: 73-product executor + dry-run clean + rollback
---
.gitignore | 4 +
data/york73-target.json | 878 ++++++++++++++++++++++++++++++++++++++++++++++++
york73-rollback.mjs | 19 ++
york73.mjs | 72 ++++
4 files changed, 973 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1bcdbdc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+.env*
+*.log
+.DS_Store
diff --git a/data/york73-target.json b/data/york73-target.json
new file mode 100644
index 0000000..5b1fab6
--- /dev/null
+++ b/data/york73-target.json
@@ -0,0 +1,878 @@
+[
+ {
+ "product_id": "7882746822707",
+ "sell_sku": "DWJS-91645",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Dove",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882746855475",
+ "sell_sku": "DWJS-91646",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Fig",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882746888243",
+ "sell_sku": "DWJS-91647",
+ "pattern": "Linen Levels Ice",
+ "title": "Linen Levels Ice Blue",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882746921011",
+ "sell_sku": "DWJS-91648",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Indigo",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882746953779",
+ "sell_sku": "DWJS-91649",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Mediterranean",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882746986547",
+ "sell_sku": "DWJS-91650",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Portabella",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882747019315",
+ "sell_sku": "DWJS-91651",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Russet",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882747052083",
+ "sell_sku": "DWJS-91652",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Twilight",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882747084851",
+ "sell_sku": "DWJS-91653",
+ "pattern": "Linen Levels",
+ "title": "Linen Levels Whitecaps",
+ "net": 52.5,
+ "retail": 95.02,
+ "price_code": "G",
+ "current_price": "46.57",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882753081395",
+ "sell_sku": "DWJS-91793",
+ "pattern": "Sundrenched Linen Soft",
+ "title": "Sundrenched Linen Soft White",
+ "net": 85.0,
+ "retail": 153.85,
+ "price_code": "K",
+ "current_price": "75.98",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755571763",
+ "sell_sku": "DWJS-91869",
+ "pattern": "Boulevard",
+ "title": "Boulevard Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755604531",
+ "sell_sku": "DWJS-91870",
+ "pattern": "Boulevard",
+ "title": "Boulevard Lakefront",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755637299",
+ "sell_sku": "DWJS-91871",
+ "pattern": "Boulevard",
+ "title": "Boulevard Nesting",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755670067",
+ "sell_sku": "DWJS-91872",
+ "pattern": "Boulevard",
+ "title": "Boulevard Whitewash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755702835",
+ "sell_sku": "DWJS-91873",
+ "pattern": "Brindled",
+ "title": "Brindled Ash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755801139",
+ "sell_sku": "DWJS-91876",
+ "pattern": "Brindled",
+ "title": "Brindled Cotton",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755866675",
+ "sell_sku": "DWJS-91878",
+ "pattern": "Brindled",
+ "title": "Brindled Linen",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755932211",
+ "sell_sku": "DWJS-91880",
+ "pattern": "Brindled",
+ "title": "Brindled Mineral",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882755997747",
+ "sell_sku": "DWJS-91881",
+ "pattern": "Brindled",
+ "title": "Brindled Prairie",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756096051",
+ "sell_sku": "DWJS-91883",
+ "pattern": "Brindled",
+ "title": "Brindled Reservoir",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756194355",
+ "sell_sku": "DWJS-91886",
+ "pattern": "Brindled",
+ "title": "Brindled Shadow",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756227123",
+ "sell_sku": "DWJS-91887",
+ "pattern": "Center Square",
+ "title": "Center Square Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756259891",
+ "sell_sku": "DWJS-91888",
+ "pattern": "Center Square",
+ "title": "Center Square Indigo",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756325427",
+ "sell_sku": "DWJS-91889",
+ "pattern": "Center Square",
+ "title": "Center Square Loft",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756358195",
+ "sell_sku": "DWJS-91890",
+ "pattern": "Center Square",
+ "title": "Center Square Yarn",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756423731",
+ "sell_sku": "DWJS-91892",
+ "pattern": "Challenger Deep",
+ "title": "Challenger Deep Rock",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756489267",
+ "sell_sku": "DWJS-91894",
+ "pattern": "Challenger",
+ "title": "Challenger Mineral",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756554803",
+ "sell_sku": "DWJS-91896",
+ "pattern": "Challenger",
+ "title": "Challenger Nesting",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756620339",
+ "sell_sku": "DWJS-91898",
+ "pattern": "Challenger",
+ "title": "Challenger Nook",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756685875",
+ "sell_sku": "DWJS-91900",
+ "pattern": "Challenger",
+ "title": "Challenger Shadow",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882756915251",
+ "sell_sku": "DWJS-91907",
+ "pattern": "Crossroad",
+ "title": "Crossroad Denim",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882757013555",
+ "sell_sku": "DWJS-91910",
+ "pattern": "Crossroad",
+ "title": "Crossroad Linen",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882757079091",
+ "sell_sku": "DWJS-91912",
+ "pattern": "Crossroad",
+ "title": "Crossroad Oat",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882757111859",
+ "sell_sku": "DWJS-91913",
+ "pattern": "Crossroad",
+ "title": "Crossroad Reservoir",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882757177395",
+ "sell_sku": "DWJS-91915",
+ "pattern": "Crossroad",
+ "title": "Crossroad Trowel",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882757242931",
+ "sell_sku": "DWJS-91917",
+ "pattern": "Crossroad",
+ "title": "Crossroad Whitewash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882758291507",
+ "sell_sku": "DWJS-91944",
+ "pattern": "In The Details",
+ "title": "In The Details Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882758324275",
+ "sell_sku": "DWJS-91945",
+ "pattern": "In The Details",
+ "title": "In The Details Linen",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882758422579",
+ "sell_sku": "DWJS-91948",
+ "pattern": "In The Details",
+ "title": "In The Details Loft",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882758520883",
+ "sell_sku": "DWJS-91950",
+ "pattern": "In The Details",
+ "title": "In The Details Mineral",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760192051",
+ "sell_sku": "DWJS-91990",
+ "pattern": "Loomed",
+ "title": "Loomed Ash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760290355",
+ "sell_sku": "DWJS-91993",
+ "pattern": "Loomed",
+ "title": "Loomed Gravel",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760355891",
+ "sell_sku": "DWJS-91995",
+ "pattern": "Loomed",
+ "title": "Loomed Indigo",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760388659",
+ "sell_sku": "DWJS-91996",
+ "pattern": "Loomed",
+ "title": "Loomed Nesting",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760486963",
+ "sell_sku": "DWJS-91999",
+ "pattern": "Loomed",
+ "title": "Loomed Seed",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882760519731",
+ "sell_sku": "DWJS-92000",
+ "pattern": "Loomed",
+ "title": "Loomed Wheat",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761535539",
+ "sell_sku": "DWJS-92009",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761601075",
+ "sell_sku": "DWJS-92011",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Cotton",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761666611",
+ "sell_sku": "DWJS-92013",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Gravel",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761732147",
+ "sell_sku": "DWJS-92015",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Loft",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761830451",
+ "sell_sku": "DWJS-92018",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Nook",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761863219",
+ "sell_sku": "DWJS-92019",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Reservoir",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882761961523",
+ "sell_sku": "DWJS-92022",
+ "pattern": "Meadowbrook",
+ "title": "Meadowbrook Thread",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882762944563",
+ "sell_sku": "DWJS-92051",
+ "pattern": "Side By Side",
+ "title": "Side By Side Cotton",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882762977331",
+ "sell_sku": "DWJS-92052",
+ "pattern": "Side By Side",
+ "title": "Side By Side Loft",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763010099",
+ "sell_sku": "DWJS-92053",
+ "pattern": "Side By Side",
+ "title": "Side By Side Mineral",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763042867",
+ "sell_sku": "DWJS-92054",
+ "pattern": "Side By Side",
+ "title": "Side By Side Nook",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763075635",
+ "sell_sku": "DWJS-92055",
+ "pattern": "Side By Side",
+ "title": "Side By Side Whitewash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763599923",
+ "sell_sku": "DWJS-92070",
+ "pattern": "Stroll",
+ "title": "Stroll Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763632691",
+ "sell_sku": "DWJS-92071",
+ "pattern": "Stroll",
+ "title": "Stroll Greenhouse",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763665459",
+ "sell_sku": "DWJS-92072",
+ "pattern": "Stroll",
+ "title": "Stroll Midnight",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763698227",
+ "sell_sku": "DWJS-92073",
+ "pattern": "Stroll",
+ "title": "Stroll Nook",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763730995",
+ "sell_sku": "DWJS-92074",
+ "pattern": "Stroll",
+ "title": "Stroll Parchment",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882763763763",
+ "sell_sku": "DWJS-92075",
+ "pattern": "Stroll",
+ "title": "Stroll Whitewash",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882765303859",
+ "sell_sku": "DWJS-92122",
+ "pattern": "Weft And Weave",
+ "title": "Weft And Weave Charcoal",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882765336627",
+ "sell_sku": "DWJS-92123",
+ "pattern": "Weft And Weave",
+ "title": "Weft And Weave Eden",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882765369395",
+ "sell_sku": "DWJS-92124",
+ "pattern": "Weft And Weave",
+ "title": "Weft And Weave Gatherings",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882765402163",
+ "sell_sku": "DWJS-92125",
+ "pattern": "Weft And Weave",
+ "title": "Weft And Weave Indigo",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882765434931",
+ "sell_sku": "DWJS-92126",
+ "pattern": "Weft And Weave",
+ "title": "Weft And Weave Linen",
+ "net": 20.0,
+ "retail": 36.2,
+ "price_code": "A",
+ "current_price": "24.51",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882754195507",
+ "sell_sku": "DWJS-91827",
+ "pattern": "Vegan Suede Dark",
+ "title": "Vegan Suede Dark Slate",
+ "net": 45.0,
+ "retail": 81.45,
+ "price_code": "D",
+ "current_price": "39.22",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882754228275",
+ "sell_sku": "DWJS-91828",
+ "pattern": "Vegan Suede",
+ "title": "Vegan Suede Portabella",
+ "net": 45.0,
+ "retail": 81.45,
+ "price_code": "D",
+ "current_price": "39.22",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882754261043",
+ "sell_sku": "DWJS-91829",
+ "pattern": "Vegan Suede",
+ "title": "Vegan Suede Royal",
+ "net": 45.0,
+ "retail": 81.45,
+ "price_code": "D",
+ "current_price": "39.22",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ },
+ {
+ "product_id": "7882754293811",
+ "sell_sku": "DWJS-91830",
+ "pattern": "Vegan Suede",
+ "title": "Vegan Suede Taupe",
+ "net": 45.0,
+ "retail": 81.45,
+ "price_code": "D",
+ "current_price": "39.22",
+ "current_uom": "Priced Per Single Roll",
+ "current_min": "2"
+ }
+]
\ No newline at end of file
diff --git a/york73-rollback.mjs b/york73-rollback.mjs
new file mode 100644
index 0000000..ab0f9bf
--- /dev/null
+++ b/york73-rollback.mjs
@@ -0,0 +1,19 @@
+#!/usr/bin/env node
+// One-click revert of york73.mjs --apply. Reads data/restore-map.jsonl, restores old price + uom + position.
+import { readFileSync } from 'node:fs';
+const TOKEN = readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8')
+ .split('\n').find(l=>l.startsWith('SHOPIFY_ADMIN_TOKEN=')).split('=')[1].trim();
+const SHOP='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+const DIR=new URL('.',import.meta.url).pathname;
+const gql=(q,v)=>fetch(SHOP,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})}).then(r=>r.json());
+const rows=readFileSync(DIR+'data/restore-map.jsonl','utf8').trim().split('\n').filter(Boolean).map(l=>JSON.parse(l));
+let ok=0;
+for(const r of rows){
+ const pid=`gid://shopify/Product/${r.pid}`;
+ await gql(`mutation($m:[MetafieldsSetInput!]!){metafieldsSet(metafields:$m){userErrors{message}}}`,
+ {m:[{ownerId:pid,namespace:'global',key:'unit_of_measure',type:'single_line_text_field',value:r.old.uom||''}]});
+ await gql(`mutation($pid:ID!,$v:[ProductVariantsBulkInput!]!){productVariantsBulkUpdate(productId:$pid,variants:$v){userErrors{message}}}`,
+ {pid,v:[{id:r.sellVid,price:r.old.price,optionValues:[{optionName:'Size',name:r.old.title}]}]});
+ console.log('reverted',r.pid,'->',r.old.price,r.old.title); ok++;
+}
+console.log('ROLLBACK done —',ok,'products');
diff --git a/york73.mjs b/york73.mjs
new file mode 100644
index 0000000..5dcab5d
--- /dev/null
+++ b/york73.mjs
@@ -0,0 +1,72 @@
+#!/usr/bin/env node
+// York contract yard-good fix — 73 verified products. Generalizes the YGL7005 template.
+// DRY-RUN (default): resolves variants, prints before->after, writes NOTHING.
+// --apply: metafields (Sold Per Yard, min5/step1, MSRP, wholesale) + variant price=retail + option "Sold Per Yard" + sellable@pos1.
+// Reversible: writes data/restore-map.jsonl (old price/uom/min/position per product) BEFORE each apply.
+// Resumable: skips products already at target (idempotent). --limit N --offset N to batch.
+import { readFileSync, appendFileSync, existsSync } from 'node:fs';
+const APPLY = process.argv.includes('--apply');
+const arg = (f,d)=>{const i=process.argv.indexOf(f); return i>=0?process.argv[i+1]:d;};
+const LIMIT = parseInt(arg('--limit','999')); const OFFSET = parseInt(arg('--offset','0'));
+const TOKEN = readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8')
+ .split('\n').find(l=>l.startsWith('SHOPIFY_ADMIN_TOKEN=')).split('=')[1].trim();
+const SHOP='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+const T='single_line_text_field', ND='number_decimal';
+const MSRP={45:90.0,52.5:105.0,85.0:170.0,20:50.0}; // per-pattern MSRP by net (portal)
+const DIR=new URL('.',import.meta.url).pathname;
+const targets = JSON.parse(readFileSync(DIR+'data/york73-target.json')).slice(OFFSET, OFFSET+LIMIT);
+const REST = DIR+'data/restore-map.jsonl';
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+async function gql(q,v){for(let a=0;a<4;a++){try{const r=await fetch(SHOP,{method:'POST',headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});const j=await r.json();if(j.errors&&/throttl/i.test(JSON.stringify(j.errors))){await sleep(2000);continue;}return j;}catch(e){await sleep(1500);}}throw new Error('gql failed');}
+
+const Q=`query($id:ID!){ product(id:$id){ id title status
+ uomMf:metafield(namespace:"global",key:"unit_of_measure"){value}
+ variants(first:15){edges{node{id title price position sku}}} } }`;
+
+let ok=0,skip=0,fail=0,changes=[];
+for(const t of targets){
+ const pid=`gid://shopify/Product/${t.product_id}`;
+ const r=await gql(Q,{id:pid});
+ const p=r.data && r.data.product;
+ if(!p){console.log(' MISS',t.product_id,t.sell_sku,'(product not found)');fail++;continue;}
+ const vs=p.variants.edges.map(e=>e.node);
+ const sample=vs.find(v=>/sample/i.test(v.title)||v.price==='4.25'||/-sample$/i.test(v.sku||''));
+ const sell=vs.find(v=>v!==sample) || vs[0];
+ const curUom=p.uomMf?.value||'';
+ const already = curUom==='Sold Per Yard' && sell.price===String(t.retail) && sell.position===1;
+ const line={sku:t.sell_sku,pattern:t.pattern,pid:t.product_id,
+ price:{from:sell.price,to:String(t.retail)},uom:{from:curUom||t.current_uom,to:'Sold Per Yard'},
+ sellPos:sell.position,samplePos:sample?.position, retail:t.retail,net:t.net,msrp:MSRP[t.net]};
+ changes.push(line);
+ if(already){console.log(' = already',t.sell_sku,t.pattern,`$${sell.price}`);skip++;continue;}
+ if(!APPLY){console.log(` DRY ${t.sell_sku} ${t.pattern.padEnd(16)} $${sell.price}->$${t.retail} | ${curUom||'?'}->Sold Per Yard | sellPos ${sell.position}`);ok++;continue;}
+ // ---- APPLY (customer-facing) ----
+ appendFileSync(REST, JSON.stringify({ts:new Date().toISOString(),pid:t.product_id,sellVid:sell.id,sampleVid:sample?.id,
+ old:{price:sell.price,uom:curUom,sellPos:sell.position,samplePos:sample?.position,title:sell.title}})+'\n');
+ const mfs=[
+ {ownerId:pid,namespace:'global',key:'unit_of_measure',type:T,value:'Sold Per Yard'},
+ {ownerId:pid,namespace:'global',key:'v_prods_quantity_order_min',type:T,value:'5'},
+ {ownerId:pid,namespace:'global',key:'v_prods_quantity_order_units',type:T,value:'1'},
+ {ownerId:pid,namespace:'custom',key:'us_msrp',type:ND,value:String(MSRP[t.net].toFixed(2))},
+ {ownerId:pid,namespace:'custom',key:'wholesale_price',type:ND,value:String(t.net.toFixed(2))},
+ {ownerId:sell.id,namespace:'custom',key:'v_prod_quantity_order_min',type:T,value:'5'},
+ {ownerId:sell.id,namespace:'custom',key:'v_prods_quantity_order_units',type:T,value:'1'},
+ ];
+ if(sample) mfs.push({ownerId:sample.id,namespace:'custom',key:'v_prod_quantity_order_min',type:T,value:'1'});
+ let m=await gql(`mutation($m:[MetafieldsSetInput!]!){metafieldsSet(metafields:$m){userErrors{field message}}}`,{m:mfs});
+ const me=m.data.metafieldsSet.userErrors; if(me.length){console.log(' MF-ERR',t.sell_sku,JSON.stringify(me));fail++;continue;}
+ let vu=await gql(`mutation($pid:ID!,$v:[ProductVariantsBulkInput!]!){productVariantsBulkUpdate(productId:$pid,variants:$v){userErrors{field message}}}`,
+ {pid,v:[{id:sell.id,price:String(t.retail),optionValues:[{optionName:'Size',name:'Sold Per Yard'}]}]});
+ const ve=vu.data.productVariantsBulkUpdate.userErrors; if(ve.length){console.log(' VAR-ERR',t.sell_sku,JSON.stringify(ve));fail++;continue;}
+ if(sample && sell.position!==1){
+ await gql(`mutation($pid:ID!,$m:[ProductVariantPositionInput!]!){productVariantsBulkReorder(productId:$pid,positions:$m){userErrors{field message}}}`,
+ {pid,m:[{id:sell.id,position:1},{id:sample.id,position:2}]});
+ }
+ console.log(` OK ${t.sell_sku} ${t.pattern} $${sell.price}->$${t.retail} Sold Per Yard`);ok++;
+ await sleep(400);
+}
+console.log(`\n${APPLY?'APPLIED':'DRY-RUN'} — ok=${ok} skip=${skip} fail=${fail} of ${targets.length}`);
+if(!APPLY){
+ const totNow=changes.reduce((a,c)=>a+parseFloat(c.price.from),0), totNew=changes.reduce((a,c)=>a+c.retail,0);
+ console.log(`sum current $${totNow.toFixed(2)} -> sum retail $${totNew.toFixed(2)} (${(totNew/totNow).toFixed(2)}x avg lift)`);
+}
(oldest)
·
back to York Yardgood Exec
·
Short launchers apply.sh/rollback.sh (avoid paste wrap-break 4b0d976 →