← back to Dw Pitch Followup

scripts/pretriage.js

41 lines

// pretriage.js — pre-warm the follow-up cache for the WHOLE board so every card shows a
// Follow up? verdict without anyone opening it. Runs against the live server (which owns the
// persistent cache); the batch endpoint skips any verdict fresh <24h, so re-runs are cheap.
// Local Ollama only → $0. Meant to run right after build-lists.js (see refresh.sh).

const BASE = process.env.PITCH_URL || 'http://127.0.0.1:9768';
const CHUNK = 40;

async function main() {
  const t0 = Date.now();
  let L;
  try { L = await (await fetch(BASE + '/api/lists', { signal: AbortSignal.timeout(15000) })).json(); }
  catch (e) { console.error('[pretriage] server unreachable at ' + BASE + ' — skipping:', e.message); process.exit(0); }

  const seen = new Set(), clients = [];
  for (const list of ['list1', 'list2']) for (const r of (L[list] || [])) {
    const email = String(r.email || '').trim(); const lc = email.toLowerCase();
    if (!email || seen.has(lc)) continue; seen.add(lc);
    const q = (Array.isArray(r.merch_invoices) ? r.merch_invoices : []).find((x) => !x.booked);
    clients.push({ email, company: r.company || '', quote: q && q.invoice ? ('#' + q.invoice) : '' });
  }
  console.log('[pretriage] ' + clients.length + ' unique clients with email to score');

  let done = 0, analyzed = 0;
  for (let i = 0; i < clients.length; i += CHUNK) {
    const chunk = clients.slice(i, i + CHUNK);
    try {
      const r = await fetch(BASE + '/api/followup-batch', {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ clients: chunk }), signal: AbortSignal.timeout(600000),
      });
      const j = await r.json(); analyzed += (j.analyzed || 0);
    } catch (e) { console.error('[pretriage] chunk @' + i + ' failed:', e.message); }
    done += chunk.length;
    console.log('[pretriage] ' + done + '/' + clients.length + ' processed (' + analyzed + ' freshly scored) · ' + ((Date.now() - t0) / 1000).toFixed(0) + 's');
  }
  console.log('[pretriage] done in ' + ((Date.now() - t0) / 1000).toFixed(0) + 's ($0 — local Ollama)');
}

main().catch((e) => { console.error('[pretriage] FATAL', e); process.exit(1); });