← back to Filemaker Mcp

scripts/test-sync-dryrun.mjs

48 lines

// READ-ONLY end-to-end test of the order->invoice pipeline on THIS host.
// Fetches the N most recent Shopify orders and runs syncOrder(commit:false) on
// each — proving the fixed code would create exactly ONE invoice per order and
// NO per-SKU "second invoice" (createSkuRecords). No writes, no Slack posts.
//
//   node scripts/test-sync-dryrun.mjs        # last 5 orders
//   node scripts/test-sync-dryrun.mjs 8
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { syncOrder } from '../lib/sync-core.js';

const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
for (const l of readFileSync(join(ROOT, '.env'), 'utf8').split('\n')) {
  const m = l.match(/^([A-Z0-9_]+)=(.*)$/); if (m && !process.env[m[1]]) process.env[m[1]] = m[2];
}
const STORE = process.env.FM_SHOPIFY_STORE || process.env.SHOPIFY_STORE;
const TOKEN = process.env.SHOPIFY_ORDERS_TOKEN;
const N = parseInt(process.argv[2] || '5', 10);

async function main() {
  if (!STORE || !TOKEN) throw new Error('SHOPIFY_STORE / SHOPIFY_ORDERS_TOKEN not set');
  const url = `https://${STORE}/admin/api/2024-10/orders.json?status=any&limit=${N}`;
  const r = await fetch(url, { headers: { 'X-Shopify-Access-Token': TOKEN } });
  if (!r.ok) throw new Error(`Shopify fetch failed: ${r.status}`);
  const orders = (await r.json()).orders || [];
  console.log(`\n=== DRY-RUN pipeline test — ${orders.length} most-recent orders (NO writes, NO Slack) ===\n`);

  let pass = 0, fail = 0;
  for (const o of orders) {
    const items = (o.line_items || []).length;
    try {
      const res = await syncOrder(o, { commit: false });
      // The fix guarantees exactly one invoice and zero per-SKU second-invoice records.
      const ok = res.action === 'would-process' && (res.skuRecords ?? 0) === 0;
      console.log(`#${o.order_number}  ${(o.customer?.first_name||'')+' '+(o.customer?.last_name||'')}`.padEnd(34)
        + `${items} line-item(s) → ${ok ? '1 invoice' : '??'}  · perSKU-dups=${res.skuRecords ?? 0}`
        + `  · client=${res.client}${res.matchedOn ? ' (matched '+res.matchedOn.join('/')+')' : ''}  ${ok ? 'PASS ✓' : 'FAIL ✗'}`);
      ok ? pass++ : fail++;
    } catch (e) {
      console.log(`#${o.order_number}  ERROR: ${e.message}  FAIL ✗`); fail++;
    }
  }
  console.log(`\n=== RESULT: ${pass} PASS / ${fail} FAIL — one-invoice-per-order ${fail ? 'NOT ' : ''}confirmed ===`);
  process.exit(fail ? 1 : 0);
}
main().catch((e) => { console.error('test error:', e.message, e.fmCode || ''); process.exit(1); });