← back to Designer Wallcoverings
auto-save: 2026-06-24T10:26:20 (2 files) — vendor-scrapers/china-seas-refresh shopify/scripts/archive-skn.js
2f5131a9de85ea1ee47d7c9267db8c1ecc40e451 · 2026-06-24 10:26:25 -0700 · Steve Abrams
Files touched
A shopify/scripts/archive-skn.js
Diff
commit 2f5131a9de85ea1ee47d7c9267db8c1ecc40e451
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jun 24 10:26:25 2026 -0700
auto-save: 2026-06-24T10:26:20 (2 files) — vendor-scrapers/china-seas-refresh shopify/scripts/archive-skn.js
---
shopify/scripts/archive-skn.js | 68 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/shopify/scripts/archive-skn.js b/shopify/scripts/archive-skn.js
new file mode 100644
index 00000000..dcc69654
--- /dev/null
+++ b/shopify/scripts/archive-skn.js
@@ -0,0 +1,68 @@
+#!/usr/bin/env node
+/**
+ * archive-skn.js — archive the SKN- ("animal skin" house line) from the DW storefront.
+ *
+ * Steve 2026-06-24: "archive skn- products on shopify." 40 ACTIVE products carry the
+ * SKN- SKU prefix (vendor 'Designer Wallcoverings'): Zoe Zebra, Carlos Cheetah,
+ * Featherama, Zoro Zebra, etc. Sets status=ARCHIVED via Shopify Admin GraphQL —
+ * reversible (flip back to ACTIVE any time). Mirrors the change into shopify_products.
+ *
+ * Scoped: sku/dw_sku/variant_sku ILIKE 'SKN-%' (or vendor_prefix 'SKN') AND status='ACTIVE'.
+ * Dry-run unless --go.
+ */
+const https = require('https');
+const fs = require('fs');
+const os = require('os');
+const { execFileSync } = require('child_process');
+
+const GO = process.argv.includes('--go');
+const env = fs.readFileSync(os.homedir() + '/Projects/secrets-manager/.env', 'utf8');
+const TOKEN = (env.match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m) || [])[1].replace(/['"]/g, '').trim();
+const STORE = 'designer-laboratory-sandbox.myshopify.com', API = '2024-10';
+const sleep = ms => new Promise(r => setTimeout(r, ms));
+const psql = sql => execFileSync('psql', ['-d', 'dw_unified', '-At', '-F', '\t', '-c', sql], { encoding: 'utf8', maxBuffer: 1 << 28 }).trim();
+
+const WHERE = `(sku ILIKE 'SKN-%' OR dw_sku ILIKE 'SKN-%' OR variant_sku ILIKE 'SKN-%' OR vendor_prefix ILIKE 'SKN%') AND status='ACTIVE' AND shopify_id IS NOT NULL`;
+
+function gql(query, variables) {
+ const d = JSON.stringify({ query, variables });
+ return new Promise(res => {
+ const r = https.request({ host: STORE, path: `/admin/api/${API}/graphql.json`, method: 'POST',
+ headers: { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(d) } },
+ x => { let b = ''; x.on('data', c => b += c); x.on('end', () => { try { res(JSON.parse(b)); } catch { res({}); } }); });
+ r.on('error', () => res({})); r.write(d); r.end();
+ });
+}
+
+const MUT = `mutation($id:ID!){ productUpdate(input:{id:$id, status:ARCHIVED}){ product{id status} userErrors{field message} } }`;
+
+(async () => {
+ const rows = psql(`SELECT DISTINCT shopify_id FROM shopify_products WHERE ${WHERE}`);
+ const ids = rows ? rows.split('\n').filter(Boolean) : [];
+ console.log(`SKN- ACTIVE products to archive: ${ids.length}`);
+ if (!ids.length) { console.log('nothing to archive'); return; }
+ if (!GO) {
+ console.log('DRY RUN — re-run with --go to archive. Titles:');
+ console.log(psql(`SELECT sku, left(title,50) FROM shopify_products WHERE ${WHERE} ORDER BY sku`));
+ return;
+ }
+
+ let ok = 0, fail = 0;
+ for (const id of ids) {
+ const gid = id.startsWith('gid://') ? id : `gid://shopify/Product/${id}`;
+ const r = await gql(MUT, { id: gid });
+ const ue = r?.data?.productUpdate?.userErrors;
+ if (r?.data?.productUpdate?.product?.status === 'ARCHIVED') {
+ ok++;
+ psql(`UPDATE shopify_products SET status='ARCHIVED' WHERE shopify_id='${id.replace(/'/g, "''")}'`);
+ if (ok % 10 === 0) process.stdout.write(`\r archived ${ok}…`);
+ } else {
+ fail++;
+ console.log(`\n ✗ ${gid} ${JSON.stringify(ue || r).slice(0, 160)}`);
+ }
+ await sleep(250);
+ }
+ console.log(`\n✓ archived ${ok} / ${ids.length} (failed ${fail})`);
+ const remain = psql(`SELECT count(DISTINCT shopify_id) FROM shopify_products WHERE ${WHERE}`);
+ console.log(`Remaining SKN- ACTIVE: ${remain}`);
+})();
← 5b044ca7 burst: option name must be 'Size' + Roll-first variant (DW t
·
back to Designer Wallcoverings
·
cadence: draft INERT Fentucci vendor entry (TWIL grasscloth 4d8d4b83 →