← back to Dw Sarah Rowland Searchfix
apply.mjs
50 lines
// TK-10037 — make the Sarah Rowland collection searchable.
// Adds tag "Sarah Rowland" (search fix) + custom.designer="Sarah Rowland" (structured data)
// to every product in the collection. Idempotent. Writes to LIVE production Shopify.
//
// node apply.mjs canary -> first 1 product only, then verify
// node apply.mjs all -> all products (safe to re-run; idempotent)
import fs from 'node:fs';
import { gql } from './lib.mjs';
const TAG = 'Sarah Rowland';
const mode = process.argv[2];
if (!['canary', 'all'].includes(mode)) { console.error('usage: node apply.mjs canary|all'); process.exit(1); }
const products = JSON.parse(fs.readFileSync(new URL('./products.json', import.meta.url)));
const batch = mode === 'canary' ? products.slice(0, 1) : products;
const TAGS_ADD = `mutation($id:ID!,$tags:[String!]!){ tagsAdd(id:$id, tags:$tags){ userErrors{ message } } }`;
const MF_SET = `mutation($mf:[MetafieldsSetInput!]!){ metafieldsSet(metafields:$mf){ userErrors{ field message } } }`;
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
let ok = 0, fail = 0;
console.log(`MODE=${mode} — processing ${batch.length} product(s)\n`);
for (const p of batch) {
try {
await gql(TAGS_ADD, { id: p.id, tags: [TAG] });
await gql(MF_SET, { mf: [{ ownerId: p.id, namespace: 'custom', key: 'designer',
type: 'single_line_text_field', value: TAG }] });
ok++;
if (mode === 'canary' || ok % 20 === 0) console.log(` ✓ ${ok}/${batch.length} ${p.title.slice(0,45)}`);
} catch (e) {
fail++;
console.log(` ✗ FAIL ${p.title.slice(0,45)} — ${e.message}`);
}
await sleep(120);
}
console.log(`\nDone: ${ok} ok, ${fail} failed.`);
// verify
const VERIFY = `query($id:ID!){ product(id:$id){ tags metafield(namespace:"custom",key:"designer"){ value } } }`;
console.log('\nVerifying...');
let vTag = 0, vMeta = 0;
for (const p of batch) {
const d = await gql(VERIFY, { id: p.id });
if (d.product.tags.includes(TAG)) vTag++;
if (d.product.metafield && d.product.metafield.value === TAG) vMeta++;
await sleep(60);
}
console.log(`Verified: ${vTag}/${batch.length} carry the tag, ${vMeta}/${batch.length} carry custom.designer.`);