[object Object]

← back to Gmc Titlefix

TK-11731: add pre-built applier to attach link-override supplemental 10733203704 into primary GMC feed rule

144262643b52e0fbe8f1f5b1df6ab5e1066dabfa · 2026-09-16 12:21:32 -0700 · Steve

Dry-run-verified reversible variant of link-price-override-ds.mjs. Fixes the ineffective
456 link overrides (supplemental was never in primary 180695450 takeFromDataSources).
Gated fire: node link-tk11731-override-ds.mjs --apply --yes-i-am-steve; rollback via
link-price-override-ds-ROLLBACK.mjs. GATED external Google feed-structure write — dry-run default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Mtyx9YjTzzxpt6Sr1UqCZ

Files touched

Diff

commit 144262643b52e0fbe8f1f5b1df6ab5e1066dabfa
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Sep 16 12:21:32 2026 -0700

    TK-11731: add pre-built applier to attach link-override supplemental 10733203704 into primary GMC feed rule
    
    Dry-run-verified reversible variant of link-price-override-ds.mjs. Fixes the ineffective
    456 link overrides (supplemental was never in primary 180695450 takeFromDataSources).
    Gated fire: node link-tk11731-override-ds.mjs --apply --yes-i-am-steve; rollback via
    link-price-override-ds-ROLLBACK.mjs. GATED external Google feed-structure write — dry-run default.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_019Mtyx9YjTzzxpt6Sr1UqCZ
---
 link-tk11731-override-ds.mjs | 76 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/link-tk11731-override-ds.mjs b/link-tk11731-override-ds.mjs
new file mode 100644
index 0000000..6bc88e2
--- /dev/null
+++ b/link-tk11731-override-ds.mjs
@@ -0,0 +1,76 @@
+// GATED: link the TK-11731 "DW Feed Link Overrides" supplemental DS (10733203704)
+// into primary feed 180695450's defaultRule.takeFromDataSources, positioned BEFORE
+// self so the 456 renamed-handle `link` overrides WIN over the stale Shopify links
+// on the live GMC feed.
+//
+// WHY: TK-11731 fired 456 `link` overrides into supplemental 10733203704 on 2026-09-15
+// (apply-log 456/456 HTTP 200), but gmc-landing-handle-canary still reads serving_fail
+// ~750 because that supplemental is NOT in primary 180695450's takeFromDataSources rule
+// (referencingPrimaryDataSources empty). Google therefore never merges the link inputs —
+// the 200s proved STORAGE, not effect. IDENTICAL to the 2026-08-27 price-override incident
+// fixed by link-price-override-ds.mjs. This PATCH is the missing attach.
+//
+// This is a CUSTOMER-FACING GMC FEED STRUCTURE CHANGE (changes which datasource wins `link`
+// for 456 live offers on the live Google feed) => GATED. Dry-run by default; requires
+// --apply --yes-i-am-steve to fire. Reversible via link-price-override-ds-ROLLBACK.mjs
+// (restores the exact immutable pre-change snapshot written only by an armed run).
+//
+// GUARD (replace semantics): the PATCH body carries the FULL list built from the live GET
+// (all existing supplementals + 10733203704 + self). A partial list would silently drop the
+// title/weight/price overrides account-wide — this script never sends a partial list.
+import { createRequire } from 'module';
+import { writeImmutableSnapshot } from './track-c-safety.mjs';
+const require = createRequire(import.meta.url);
+const { token, MERCHANT } = require('./_auth.js');
+
+const PRIMARY = '180695450';
+const LINK_DS = `accounts/${MERCHANT}/dataSources/10733203704`; // TK-11731 "DW Feed Link Overrides"
+const args = new Set(process.argv.slice(2));
+const ARMED = args.has('--apply') && args.has('--yes-i-am-steve');
+
+const tok = await token(); const H = { Authorization: 'Bearer ' + tok, 'Content-Type': 'application/json' };
+const base = `https://merchantapi.googleapis.com/datasources/v1/accounts/${MERCHANT}/dataSources/${PRIMARY}`;
+
+const cur = await (await fetch(base, { headers: H })).json();
+const rule = cur.primaryProductDataSource?.defaultRule?.takeFromDataSources || [];
+const ids = rule.map(x => x.self ? 'SELF' : x.supplementalDataSourceName.split('/').pop());
+console.log('CURRENT takeFromDataSources:', ids.join(' > '));
+
+if (rule.some(x => x.supplementalDataSourceName === LINK_DS)) {
+  console.log('ALREADY LINKED — link-override DS 10733203704 is present. No change needed.');
+  process.exit(0);
+}
+
+// Build new rule: [existing supplementals..., LINK_DS, self]  (link override before self)
+const selfIdx = rule.findIndex(x => x.self);
+const newRule = rule.filter(x => !x.self);
+newRule.push({ supplementalDataSourceName: LINK_DS });
+if (selfIdx !== -1) newRule.push({ self: true });
+console.log('NEW takeFromDataSources:', newRule.map(x => x.self ? 'SELF' : x.supplementalDataSourceName.split('/').pop()).join(' > '));
+
+const body = {
+  primaryProductDataSource: {
+    ...cur.primaryProductDataSource,
+    defaultRule: { takeFromDataSources: newRule }
+  }
+};
+
+if (!ARMED) {
+  console.log('\nDRY-RUN (not armed). To apply the live feed-link attach:');
+  console.log('  node ~/Projects/gmc-titlefix/link-tk11731-override-ds.mjs --apply --yes-i-am-steve');
+  console.log('An armed run writes an immutable manifest; rollback requires that exact --manifest path.');
+  process.exit(0);
+}
+
+const saved = writeImmutableSnapshot(cur, new URL('./data/track-c-snapshots', import.meta.url));
+console.log('IMMUTABLE PRE-CHANGE SNAPSHOT:', saved.snapshotPath);
+console.log('ROLLBACK MANIFEST:', saved.manifestPath);
+console.log('SNAPSHOT SHA-256:', saved.manifest.snapshot_sha256);
+
+const url = `${base}?updateMask=primaryProductDataSource.defaultRule`;
+const r = await fetch(url, { method: 'PATCH', headers: H, body: JSON.stringify(body) });
+const j = await r.json();
+if (!r.ok) { console.error('FAILED', r.status, JSON.stringify(j).slice(0, 400)); process.exit(1); }
+console.log('\nLINKED OK. New rule:', (j.primaryProductDataSource?.defaultRule?.takeFromDataSources || []).map(x => x.self ? 'SELF' : x.supplementalDataSourceName.split('/').pop()).join(' > '));
+console.log('Next: wait for feed reprocess (~1-6h), then re-run gmc-landing-handle-canary to confirm serving_fail drops 753 -> ~297 before considering TK-11780 retirement.');
+console.log('ROLLBACK: node ~/Projects/gmc-titlefix/link-price-override-ds-ROLLBACK.mjs --manifest ' + saved.manifestPath);

← 85783b2 TK-11568: EXECUTED (Steve-approved) — FLS-2768 94px crop ->  ·  back to Gmc Titlefix  ·  auto-data-snapshot: 2026-09-16T13:57:01 (3 data files) — dat 5a32a40 →