← back to Designer Wallcoverings
TK-135: BARE-VALUE color tags (no color: prefix) + self-heal removes old color:Bucket; Shopify-authoritative
1ad1dff432fcc01e0a111464dc29498471d3d169 · 2026-07-27 19:34:58 -0700 · Steve
Files touched
M shopify/scripts/tk135-apply-palette.js
Diff
commit 1ad1dff432fcc01e0a111464dc29498471d3d169
Author: Steve <steve@designerwallcoverings.com>
Date: Mon Jul 27 19:34:58 2026 -0700
TK-135: BARE-VALUE color tags (no color: prefix) + self-heal removes old color:Bucket; Shopify-authoritative
---
shopify/scripts/tk135-apply-palette.js | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/shopify/scripts/tk135-apply-palette.js b/shopify/scripts/tk135-apply-palette.js
index 7b62bc97..69db0117 100644
--- a/shopify/scripts/tk135-apply-palette.js
+++ b/shopify/scripts/tk135-apply-palette.js
@@ -50,6 +50,7 @@ async function gqlR(q, v, tries = 4) {
}
const M_MF = `mutation($mf:[MetafieldsSetInput!]!){metafieldsSet(metafields:$mf){userErrors{field message}}}`;
const M_TAG = `mutation($id:ID!,$tags:[String!]!){tagsAdd(id:$id,tags:$tags){userErrors{field message}}}`;
+const M_TAGDEL = `mutation($id:ID!,$tags:[String!]!){tagsRemove(id:$id,tags:$tags){userErrors{field message}}}`;
// PG-first: append color tag idempotently in the mirror
function pgAppendTags(rows) {
@@ -78,7 +79,10 @@ function load() {
for (const l of lines) {
const [gid, tag, pj] = l.split('\t');
if (!gid || !tag || !pj || pj.startsWith('ERR:')) continue;
- out.push({ gid, tag, palette: pj });
+ // Steve: BARE-VALUE tag (no color: label). `bare` is the tag we write; `prefixed`
+ // is the old color:Bucket form we may have written earlier and now remove (self-heal).
+ const bare = tag.replace(/^\s*[Cc]olor:\s*/, '').trim();
+ out.push({ gid, tag: bare, prefixed: tag, palette: pj });
}
return out;
}
@@ -97,13 +101,12 @@ function load() {
const report = { ticket: 'TK-135', started: new Date().toISOString(), apply: APPLY, updated: [], failed: [] };
if (APPLY) {
- // PG mirror is best-effort: Shopify is the authoritative customer-facing write and the mirror re-syncs from it,
- // so a mirror hiccup (e.g. integrity trigger) must NEVER block the Shopify write.
- try { const c = pgAppendTags(rows); console.log(`PG mirror tags appended — matched ${c}\n`); report.pg = c; }
- catch (e) { console.error('⚠ PG mirror write skipped (non-fatal — Shopify authoritative, mirror re-syncs):', (e.message || e).toString().split('\n')[0]); report.pgSkipped = true; }
+ // Tags: Shopify-authoritative (mirror re-syncs). We skip the PG-mirror tag write here because
+ // (a) bare values like "Red" false-match via substring ILIKE, and (b) the mfr_sku trigger blocks some rows.
+ console.log(`(tags/metafields written Shopify-first; dw_unified mirror re-syncs from Shopify)\n`);
} else {
- console.log(`(dry-run) would PG-append ${rows.length} color tags, then Shopify metafield+tag each\n`);
- rows.slice(0, 8).forEach(r => console.log(` · ${r.gid.split('/').pop()} ${r.tag} palette=${r.palette}`));
+ console.log(`(dry-run) per product: metafield color_palette + remove old "${rows[0]?rows[0].prefixed:'color:X'}"-style tag + add BARE value tag\n`);
+ rows.slice(0, 8).forEach(r => console.log(` · ${r.gid.split('/').pop()} tag="${r.tag}" (was "${r.prefixed}") palette=${r.palette}`));
console.log(`\n (dry-run) no writes made.`);
if (REPORT) { fs.mkdirSync(path.dirname(REPORT), { recursive: true }); fs.writeFileSync(REPORT, JSON.stringify({ ...report, totals: { would_update: rows.length } }, null, 2)); }
return;
@@ -112,6 +115,8 @@ function load() {
for (const r of rows) {
const mf = await gqlR(M_MF, { mf: [{ ownerId: r.gid, namespace: 'custom', key: 'color_palette', type: 'json', value: r.palette }] });
const me = mf.data?.metafieldsSet?.userErrors || [];
+ // self-heal: remove the old prefixed color:Bucket if we wrote it earlier, then add the BARE value
+ if (r.prefixed && r.prefixed !== r.tag) await gqlR(M_TAGDEL, { id: r.gid, tags: [r.prefixed] });
const tg = await gqlR(M_TAG, { id: r.gid, tags: [r.tag] });
const te = tg.data?.tagsAdd?.userErrors || [];
if (me.length || te.length) { report.failed.push({ gid: r.gid, me, te }); console.log(` ❌ ${r.gid.split('/').pop()} ${JSON.stringify(me.concat(te))}`); }
← 525345fa auto-save: 2026-07-27T19:23:22 (3 files) — package-lock.json
·
back to Designer Wallcoverings
·
TK-135: unified color-tag normalizer — strip all color:/Colo 51ad1beb →