← back to Filemaker Mcp

scripts/fetch-clients.js

70 lines

#!/usr/bin/env node
/*
 * fetch-clients.js — page the entire FileMaker Clients file into a compact
 * staged dataset the MCC "Clients" panel reads. Read-only. Reuses the project's
 * fm-client.js (FileMaker Cloud + Cognito auth).
 *
 *   node scripts/fetch-clients.js            → all records
 *   FM_LIMIT_PAGES=2 node scripts/fetch-clients.js  → first 2 pages (pilot)
 *
 * Writes: ~/Projects/marketing-command-center/public/data/clients-fm.json
 * Social-discovery URLs (LinkedIn / Instagram) are built client-side in the
 * panel from company/name, so we store only the compact source fields here.
 */
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import os from 'node:os';

const __dir = dirname(fileURLToPath(import.meta.url));
// Load .env into process.env (fm-client/auth read from process.env).
for (const line of readFileSync(join(__dir, '..', '.env'), 'utf8').split('\n')) {
  const m = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)$/);
  if (m) process.env[m[1]] = m[2].replace(/^['"]|['"]$/g, '');
}
const { listRecords } = await import('../src/fm-client.js');

const DB = 'Clients', LAYOUT = 'wALLPAPER oPTIONS';
const PAGE = 1000;
const MAX_PAGES = process.env.FM_LIMIT_PAGES ? Number(process.env.FM_LIMIT_PAGES) : Infinity;
const OUT = join(os.homedir(), 'Projects', 'marketing-command-center', 'public', 'data', 'clients-fm.json');

const clean = s => String(s ?? '').trim();
const out = [];
let offset = 1, page = 0, total = null;

while (page < MAX_PAGES) {
  const res = await listRecords(DB, LAYOUT, { limit: PAGE, offset });
  const recs = res.records || [];
  if (total == null) total = res.dataInfo?.totalRecordCount ?? null;
  for (const r of recs) {
    const f = r.fieldData || {};
    const company = clean(f.Company), name = clean(f.Name);
    if (!company && !name) continue;                 // skip empty shells
    out.push({
      account: clean(f['Account Number']),
      company, name,
      city: clean(f.City), state: clean(f.State),
      email: clean(f['Email address']),
      phone: clean(f.Phone),
    });
  }
  page++;
  process.stdout.write(`\r  page ${page} · offset ${offset} · kept ${out.length}${total ? ' / ~' + total : ''}   `);
  if (recs.length < PAGE) break;
  offset += PAGE;
}

mkdirSync(dirname(OUT), { recursive: true });
const withEmail = out.filter(c => /@/.test(c.email)).length;
const payload = {
  source: 'FileMaker · Clients / wALLPAPER oPTIONS',
  updated: new Date().toISOString().slice(0, 10),
  total: out.length,
  with_email: withEmail,
  clients: out,
};
writeFileSync(OUT, JSON.stringify(payload));
console.log(`\n✓ wrote ${OUT}`);
console.log(`  ${out.length} clients (${withEmail} with an email) from ${total ?? '?'} FM records`);