import { NextResponse } from 'next/server'; import { getClients, resetClients } from '@/lib/clients'; import { getFirms } from '@/lib/db'; export async function GET() { try { const clients = getClients(); const firms = getFirms(); const debug = firms.map((firm) => { const client = clients.get(firm.id); if (!client) return { firmId: firm.id, firmName: firm.name, status: 'no_client' }; return { firmId: firm.id, firmName: firm.name, status: 'connected', accountCount: client.accountList.length, fetchDaysComplete: (client as any).fetchDaysComplete ?? 'n/a (old instance)', lastFetchErrors: (client as any).lastFetchErrors ?? {}, lastFetchRaw: (client as any).lastFetchRaw ?? {}, accounts: client.accountList.map((acc) => ({ id: acc.id, name: acc.name, cash: client.accountCashBalances[acc.id] ?? null, daysTraded: client.daysTraded[acc.id] ?? '(not set)', dailyPnLEntries: (client.dailyPnL[acc.id] ?? []).length, dailyPnL: client.dailyPnL[acc.id] ?? [], })), recentEntityEvents: client.recentEntityEvents.slice(-3).map((e) => ({ ts: new Date(e.ts).toISOString(), entityType: e.entityType, eventType: e.eventType, })), }; }); return NextResponse.json({ ok: true, ts: new Date().toISOString(), firms: debug }); } catch (err) { console.error('[GET /api/debug]', err); return NextResponse.json({ error: String(err) }, { status: 500 }); } } /** POST /api/debug — manually trigger fetchDaysTraded on all clients and return results */ export async function POST() { try { const clients = getClients(); const firms = getFirms(); const results = await Promise.all( firms.map(async (firm) => { const client = clients.get(firm.id); if (!client || client.accountList.length === 0) { return { firmId: firm.id, firmName: firm.name, status: 'skipped' }; } try { await (client as any).fetchDaysTraded(); } catch (err) { return { firmId: firm.id, firmName: firm.name, status: 'error', error: String(err) }; } return { firmId: firm.id, firmName: firm.name, status: 'done', fetchDaysComplete: (client as any).fetchDaysComplete ?? 'n/a', errors: (client as any).lastFetchErrors ?? {}, rawSamples: (client as any).lastFetchRaw ?? {}, daysTraded: client.daysTraded, dailyPnLCounts: Object.fromEntries( Object.entries(client.dailyPnL).map(([k, v]) => [k, (v as any[]).length]) ), }; }) ); return NextResponse.json({ ok: true, ts: new Date().toISOString(), results }); } catch (err) { console.error('[POST /api/debug]', err); return NextResponse.json({ error: String(err) }, { status: 500 }); } } /** * DELETE /api/debug — force-reinitialize all Tradovate clients with fresh instances * Clears the global pool so getClients() recreates everything from DB on next call. */ export async function DELETE() { try { const g = global as any; const oldCount = (g.__tradovateClients as Map | undefined)?.size ?? 0; // Disconnect all existing WebSocket connections before clearing resetClients(); // Re-initialize immediately with fresh instances getClients(); return NextResponse.json({ ok: true, message: `Disconnected ${oldCount} old client(s) — fresh instances initializing`, ts: new Date().toISOString(), }); } catch (err) { console.error('[DELETE /api/debug]', err); return NextResponse.json({ error: String(err) }, { status: 500 }); } }