/* Shape of every CRM dashboard endpoint, so the agent tools can be written against what they actually return rather than against a guess. */ import jwt from 'jsonwebtoken'; import dotenv from 'dotenv'; 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' }); const today = new Date(Date.now() + 5.5 * 3600e3).toISOString().slice(0, 10); const from = '2026-08-01'; const ENDPOINTS = [ 'dashboard/leads', 'dashboard/marketing', 'dashboard/retargeting', 'dashboard/budget', 'dashboard/courses', 'dashboard/analytics', 'dashboard/meta-analytics', ]; const shape = (v, depth = 0) => { if (Array.isArray(v)) return v.length ? `[${v.length} × ${shape(v[0], depth + 1)}]` : '[]'; if (v && typeof v === 'object') { const keys = Object.keys(v); if (depth >= 1) return `{${keys.slice(0, 8).join(', ')}${keys.length > 8 ? ', …' : ''}}`; return `{\n${keys.map((k) => ` ${k}: ${shape(v[k], depth + 1)}`).join('\n')}\n }`; } return typeof v === 'string' ? `"${String(v).slice(0, 24)}"` : String(v); }; for (const ep of ENDPOINTS) { const url = `${CRM}/api/${ep}?from=${from}&to=${today}`; try { const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(90000) }); const body = await res.text(); if (!res.ok) { console.log(`\n${ep} HTTP ${res.status} ${body.slice(0, 120)}`); continue; } const j = JSON.parse(body); const d = j.data ?? j; console.log(`\n${'─'.repeat(70)}\n${ep} (${(body.length / 1024).toFixed(1)} kB)`); console.log(` ${shape(d)}`); // Headline numbers are what the assistant will most often be asked for. if (d.cards) console.log(` cards → ${JSON.stringify(d.cards)}`); if (d.totals) console.log(` totals → ${JSON.stringify(d.totals).slice(0, 300)}`); if (d.summary) console.log(` summary → ${JSON.stringify(d.summary).slice(0, 300)}`); } catch (e) { console.log(`\n${ep} ERROR ${e.message.slice(0, 90)}`); } } process.exit(0);