← back to Dwjs Consolidation 2026 04 23

send_sku_csv.js

106 lines

#!/usr/bin/env node
/**
 * Build CSV of legacy SKU renumber (old → new) and send via George Gmail Agent
 * to info@designerwallcoverings.com.
 */
const fs = require('fs');
const http = require('http');
const path = require('path');

const EXEC = '/Users/macstudio3/Projects/dwjs-consolidation-2026-04-23/phase3_legacy_execution.ndjson';
const GEORGE_HOST = '45.61.58.125';
const GEORGE_PORT = 9850;
const TO = 'info@designerwallcoverings.com';

// Read execution log
const rows = fs.readFileSync(EXEC, 'utf8').split('\n').filter(Boolean).map(JSON.parse);
console.log(`loaded ${rows.length} renumbered products`);

// CSV columns: product_id, old_prefix, series, resolved_mfr, old_sku, new_sku, variant_type
const cols = ['product_id','series','old_prefix','resolved_mfr','old_sku','new_sku','variant_type'];
const lines = [cols.join(',')];
const esc = s => { if (s==null) return ''; const str=String(s); return /[",\n]/.test(str) ? '"'+str.replace(/"/g,'""')+'"' : str; };
let variantCount = 0;
for (const r of rows) {
  for (const v of r.variants) {
    const type = /sample/i.test(v.new) ? 'sample' : 'bolt';
    lines.push(cols.map(c => esc(({
      product_id: r.pid.replace('gid://shopify/Product/',''),
      series: r.series,
      old_prefix: r.old_prefix,
      resolved_mfr: r.resolved_mfr,
      old_sku: v.old,
      new_sku: v.new,
      variant_type: type,
    })[c])).join(','));
    variantCount++;
  }
}
const csv = lines.join('\n');
const ts = new Date().toISOString().slice(0,10);
const filename = `dwjs-legacy-sku-renumber-${ts}.csv`;
fs.writeFileSync(path.join(path.dirname(EXEC), filename), csv);
console.log(`CSV: ${variantCount} variant rows, ${rows.length} products, size=${csv.length} bytes`);

// Summary by prefix + series
const summary = {};
for (const r of rows) {
  const k = `${r.old_prefix} → ${r.series}`;
  summary[k] = (summary[k]||0)+1;
}
const summaryHtml = Object.entries(summary).sort((a,b)=>b[1]-a[1]).map(([k,v])=>`<li><b>${k}</b>: ${v} products</li>`).join('');

const subject = `[DW] Legacy SKU Renumber Complete — ${rows.length} products → DWJS-90000+`;
const body = `
<html><body style="font-family:-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;max-width:720px;color:#111">
<h2>Legacy SKU Renumber — DWBR / CCA / TRF / GGA → DWJS-90000+</h2>
<p>Completed <b>${new Date().toISOString().slice(0,10)}</b>. Attached CSV has every variant's old and new SKU.</p>
<p><b>Totals:</b> ${rows.length} products / ${variantCount} variants renumbered, zero failures.</p>
<h3>Breakdown (old prefix → series)</h3>
<ul style="line-height:1.6">${summaryHtml}</ul>
<h3>What changed, per product</h3>
<ul>
  <li>Variant SKU renamed from <code>OLD-#####</code> to <code>DWJS-9####</code></li>
  <li><code>custom.manufacturer_sku</code> metafield refreshed with the real mfr SKU (recovered from fmpro master)</li>
  <li><code>global.old_dw_sku</code> metafield stores the original DW SKU (audit trail / rollback reference)</li>
  <li>Tag <code>Series: York</code> (TRF) or <code>Series: Brewster</code> (DWBR / CCA / GGA) added</li>
  <li>Title, vendor, status, images, prices, and inventory untouched</li>
</ul>
<h3>CSV columns</h3>
<code>product_id, series, old_prefix, resolved_mfr, old_sku, new_sku, variant_type</code>
<hr><p style="color:#666;font-size:12px">Generated by Designer Wallcoverings automation. Questions → reply to this email.</p>
</body></html>`;

const payload = JSON.stringify({
  to: TO,
  subject,
  body,
  attachments: [{
    filename,
    content_base64: Buffer.from(csv).toString('base64'),
    mime_type: 'text/csv',
  }],
});

const auth = 'Basic ' + Buffer.from('admin:DWSecure2024!').toString('base64');
const req = http.request({
  hostname: GEORGE_HOST, port: GEORGE_PORT, method: 'POST',
  path: '/api/send-with-attachment',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(payload),
    'Authorization': auth,
  },
}, res => {
  let c = '';
  res.on('data', d => c += d);
  res.on('end', () => {
    console.log(`HTTP ${res.statusCode}`);
    console.log(c);
  });
});
req.on('error', e => { console.error('request error:', e.message); process.exit(1); });
req.setTimeout(30000, () => { req.destroy(); console.error('timeout'); process.exit(1); });
req.write(payload);
req.end();