← back to Mfr Recovery 2026 08 23
TK-10827: fix Novasuede join-key bug in mfr push (nc.sku=handle, exclude slug placeholders)
25fe485e4d8d50bf1a638ef594b3570354bafcb9 · 2026-08-27 10:57:24 -0700 · Steve Abrams
The old join nc.mfr_sku=stripped_handle recovered 0 rows. Correct join
nc.sku=handle recovers exactly 1: novasuede-sand -> T3D8W (real vendor code,
verified vs authoritative novasuede.com). Dry-run confirmed planned=1 wrote=0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M push-mfr-to-shopify.mjs
Diff
commit 25fe485e4d8d50bf1a638ef594b3570354bafcb9
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Aug 27 10:57:24 2026 -0700
TK-10827: fix Novasuede join-key bug in mfr push (nc.sku=handle, exclude slug placeholders)
The old join nc.mfr_sku=stripped_handle recovered 0 rows. Correct join
nc.sku=handle recovers exactly 1: novasuede-sand -> T3D8W (real vendor code,
verified vs authoritative novasuede.com). Dry-run confirmed planned=1 wrote=0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
push-mfr-to-shopify.mjs | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/push-mfr-to-shopify.mjs b/push-mfr-to-shopify.mjs
index 5de1301..c34d912 100644
--- a/push-mfr-to-shopify.mjs
+++ b/push-mfr-to-shopify.mjs
@@ -53,15 +53,27 @@ function loadZoffany() {
// Novasuede: derive live from dw_unified so we never push stale rows.
// (The old SQL claimed 14; current truth = 1 recoverable. Derive, don't hardcode.)
+//
+// JOIN-KEY FIX (TK-10827, 2026-08-27): the previous version joined
+// `nc.mfr_sku = stripped_handle`, which recovered 0 rows — the catalog's
+// mfr_sku is a REAL vendor T-code (e.g. T3D8W), never the color slug, so it
+// can't equal a stripped handle. The correct join is `nc.sku = handle`
+// (the catalog `sku` column IS the color-slug handle, e.g. 'novasuede™-sand'),
+// then read the real code from `nc.mfr_sku`. We also HARD-EXCLUDE any placeholder
+// code that is itself a slug (`^novasuede`) so a stripped-handle can never be
+// pushed as a manufacturer_sku (worse than leaving blank — the prior HOLD reason).
+// With Gate-1 staging reconciled to authoritative novasuede.com codes, this
+// recovers exactly 1: novasuede™-sand -> T3D8W.
function loadNovasuede() {
const sql = `
- WITH stripped AS (
- SELECT handle, regexp_replace(handle, '-luxury-suede.*|(-fabric-wallcovering)', '', 'g') AS sh
+ WITH nulls AS (
+ SELECT handle
FROM shopify_products
WHERE vendor='Novasuede' AND status='ACTIVE' AND (mfr_sku IS NULL OR mfr_sku='')
)
- SELECT s.handle || '|' || nc.mfr_sku
- FROM stripped s JOIN novasuede_catalog nc ON nc.mfr_sku = s.sh;`;
+ SELECT n.handle || '|' || nc.mfr_sku
+ FROM nulls n JOIN novasuede_catalog nc ON nc.sku = n.handle
+ WHERE nc.mfr_sku IS NOT NULL AND nc.mfr_sku <> '' AND nc.mfr_sku !~ '^novasuede';`;
let out;
try {
out = execFileSync('psql', ['-h', '/tmp', '-d', 'dw_unified', '-tA', '-c', sql], { encoding: 'utf8' });
← e08f75e TK-10829 Gate 1 (Steve-approved): adopt-live for 32 mis-scra
·
back to Mfr Recovery 2026 08 23
·
auto-data-snapshot: 2026-08-27T18:10:50 (1 data files) — out d137c99 →