70 lines
3.1 KiB
JavaScript
70 lines
3.1 KiB
JavaScript
/* How far do the agent's numbers drift from the CRM dashboard?
|
|
|
|
The dashboard resolves a lead's stage by looking up `leadstages` and taking
|
|
the furthest stage across pipelines; the CRM's own code comments say
|
|
`Lead.current_stage` is "stale and never written". The agent's lead tools
|
|
read that stale field, so this measures the resulting gap.
|
|
*/
|
|
import jwt from 'jsonwebtoken';
|
|
import dotenv from 'dotenv';
|
|
import { connectMongo } from '../src/data/mongo.js';
|
|
import { Lead } from '../src/data/models/index.js';
|
|
|
|
dotenv.config();
|
|
const CRM = process.env.CRM_PUBLIC_URL || 'https://crm.wele.in';
|
|
const token = jwt.sign({ id: '6a00cefe524bebd27037a968' }, process.env.CRM_JWT_SECRET, { expiresIn: '15m' });
|
|
|
|
await connectMongo();
|
|
|
|
// ── what the AGENT currently reports (stale field) ──────────────────────────
|
|
const agentStages = await Lead.aggregate([
|
|
{ $group: { _id: '$current_stage', n: { $sum: 1 } } },
|
|
{ $sort: { n: -1 } },
|
|
]);
|
|
const agent = Object.fromEntries(agentStages.map((r) => [r._id || 'unset', r.n]));
|
|
const agentTotal = agentStages.reduce((s, r) => s + r.n, 0);
|
|
|
|
// ── what the DASHBOARD reports (leadstages lookup, workshop excluded) ───────
|
|
// parseRange takes from/to as YYYY-MM-DD in IST and DEFAULTS TO TODAY — a
|
|
// missing range silently returns one day, which is the first trap here.
|
|
const today = new Date(Date.now() + 5.5 * 3600e3).toISOString().slice(0, 10);
|
|
const res = await fetch(`${CRM}/api/dashboard/leads?from=2020-01-01&to=${today}`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
signal: AbortSignal.timeout(60000),
|
|
});
|
|
if (!res.ok) {
|
|
console.log(`dashboard call failed: ${res.status} ${(await res.text()).slice(0, 200)}`);
|
|
process.exit(1);
|
|
}
|
|
const dash = await res.json();
|
|
|
|
console.log('=== DASHBOARD response shape ===');
|
|
console.log(' ', Object.keys(dash).join(', '));
|
|
const d = dash.data ?? dash;
|
|
console.log(' data keys:', Object.keys(d).join(', '));
|
|
|
|
console.log('\n=== TOTAL LEADS ===');
|
|
console.log(` agent (Lead collection) ${agentTotal}`);
|
|
console.log(` dashboard totalLeads ${d.totalLeads ?? d.total ?? '(not found)'}`);
|
|
|
|
console.log('\n=== STAGE DISTRIBUTION ===');
|
|
console.log(` ${'stage'.padEnd(24)} ${'agent'.padStart(7)} ${'dashboard'.padStart(10)} gap`);
|
|
console.log(` dashboard cards.total_leads ${d.cards?.total_leads}`);
|
|
console.log(` dashboard range ${d.range?.from} → ${d.range?.to}`);
|
|
const funnel = d.funnel || d.stages || {};
|
|
const dashStages = Array.isArray(funnel)
|
|
? Object.fromEntries(funnel.map((f) => [f._id || f.stage || f.name, f.count ?? f.total]))
|
|
: funnel;
|
|
|
|
const keys = [...new Set([...Object.keys(agent), ...Object.keys(dashStages)])];
|
|
for (const k of keys) {
|
|
const a = agent[k] ?? 0;
|
|
const b = dashStages[k] ?? 0;
|
|
const gap = b - a;
|
|
console.log(` ${String(k).padEnd(24)} ${String(a).padStart(7)} ${String(b).padStart(10)} ${gap === 0 ? '—' : (gap > 0 ? '+' : '') + gap}`);
|
|
}
|
|
|
|
console.log('\nRaw dashboard payload (first 900 chars) for field mapping:');
|
|
console.log(JSON.stringify(d).slice(0, 900));
|
|
process.exit(0);
|