← back to Dw Scrape Scheduler

verify-coverage.js

34 lines

#!/usr/bin/env node
// Probe each Tier-A vendor's adapter (1 page only) and set enabled=true/false from
// real evidence, so the scheduled dispatcher never blindly retries a dead feed.
// Vendors whose adapter isn't implemented yet (e.g. magento) => enabled=false,
// note 'adapter pending'. Rewrites data/manifest.json in place.
const fs = require('fs');
const path = require('path');

const ADAPTERS = { shopify: require('./adapters/shopify'), woo: require('./adapters/woo') };
const MANIFEST = path.join(__dirname, 'data', 'manifest.json');
const PROBE_TIMEOUT = 25000;

const withTimeout = (p, ms) => Promise.race([p, new Promise((_, rej) => setTimeout(() => rej(new Error('probe timeout')), ms))]);

(async () => {
  const m = JSON.parse(fs.readFileSync(MANIFEST, 'utf8'));
  const nowIso = new Date().toISOString();
  let live = 0, dead = 0, pending = 0;
  for (const e of m.tier_a) {
    const adapter = ADAPTERS[e.adapter];
    if (!adapter) { e.enabled = false; e.coverage = 'adapter pending'; pending++; continue; }
    try {
      const products = await withTimeout(adapter.scrape(e.base_url, { maxPages: 1 }), PROBE_TIMEOUT);
      if (products.length > 0) { e.enabled = true; e.coverage = 'live'; e.probe_count = products.length; live++; }
      else { e.enabled = false; e.coverage = 'empty feed'; dead++; }
    } catch (err) { e.enabled = false; e.coverage = `no feed: ${err.message}`; dead++; }
    e.verified_at = nowIso;
    process.stdout.write(`  ${e.enabled ? '✓' : '✗'} ${e.vendor} [${e.adapter}] ${e.coverage}${e.probe_count ? ' ('+e.probe_count+'/pg)' : ''}\n`);
  }
  m.coverage = { live, dead, pending, verified_at: nowIso };
  fs.writeFileSync(MANIFEST, JSON.stringify(m, null, 2));
  console.log(`\ncoverage: ${live} live, ${dead} dead/empty, ${pending} adapter-pending (of ${m.tier_a.length} tier_a)`);
})().catch(e => { console.error('FATAL', e); process.exit(1); });