← back to Rebel Walls Push
scripts/reconcile-from-shopify.js
61 lines
'use strict';
/* READ Shopify live Rebel Walls products -> stamp local PG shopify_product_id by dw_sku.
* Local-PG write ONLY. No Shopify writes. Fixes the PG<->Shopify drift before any resume. */
const { gqlRetry, psql } = require('./_shop');
const DRY = process.argv.includes('--dry');
const Q = `query($cursor:String){
products(first:250, query:"vendor:'Rebel Walls'", after:$cursor){
pageInfo{ hasNextPage endCursor }
edges{ node{ id status variants(first:5){ edges{ node{ sku } } } } }
}
}`;
(async () => {
let cursor = null, page = 0, seen = 0;
const map = []; // {sku, id}
do {
const r = await gqlRetry(Q, { cursor }, 'recon');
if (r.json.errors) throw new Error(JSON.stringify(r.json.errors).slice(0,300));
const d = r.json.data.products;
for (const e of d.edges) {
const numId = e.node.id.split('/').pop();
// main variant SKU = the DWRW-xxxxxx that does NOT end in -Sample
let sku = null;
for (const v of e.node.variants.edges) {
const s = (v.node.sku||'').trim();
if (/^DWRW-\d+$/.test(s)) { sku = s; break; }
}
if (sku) { map.push({ sku, id: numId }); }
seen++;
}
page++;
process.stderr.write(`\r page ${page} | products seen ${seen} | matched DWRW ${map.length}`);
cursor = d.pageInfo.hasNextPage ? d.pageInfo.endCursor : null;
} while (cursor);
process.stderr.write('\n');
console.log(`Shopify Rebel Walls products: ${seen}, with DWRW main SKU: ${map.length}`);
if (DRY) { console.log('DRY — no PG writes. sample:', JSON.stringify(map.slice(0,3))); return; }
// Bulk update via a single VALUES join (chunked).
let updated = 0;
for (let i = 0; i < map.length; i += 500) {
const chunk = map.slice(i, i + 500);
const values = chunk.map(m => `('${m.sku.replace(/'/g,"''")}','${m.id}')`).join(',');
const sql = `UPDATE rebelwalls_catalog t SET shopify_product_id=v.id, updated_at=NOW()
FROM (VALUES ${values}) AS v(sku,id)
WHERE t.dw_sku = v.sku
AND (t.shopify_product_id IS NULL OR t.shopify_product_id='' OR t.shopify_product_id <> v.id);`;
const out = psql(sql + " \\echo done"); // psql prints UPDATE n? use RETURNING count instead
updated += chunk.length;
process.stderr.write(`\r stamping ${Math.min(i+500,map.length)}/${map.length}`);
}
process.stderr.write('\n');
const after = psql(`SELECT count(*) FILTER (WHERE shopify_product_id IS NOT NULL AND shopify_product_id<>'') ,
count(*) FILTER (WHERE shopify_product_id IS NULL OR shopify_product_id='')
FROM rebelwalls_catalog;`).trim();
console.log('PG after reconcile (stamped \\t unstamped):', after);
})().catch(e => { console.error('\nERR', e.message); process.exit(1); });