Files
autofirmer-expanded/app/api/accounts/[id]/wipe/route.ts
T
Brandon LiandClaude Opus 5.5 77d8c2ecdb Trade only on loaded history; catch early TopstepX fills; fix SI/M2K point values
- Both clients track which accounts this process has loaded history for
  (historyReady). An account restarted, rebuilt, wiped or newly listed is
  ineligible until its fetch lands, instead of trading as a fresh stage-1
  first day; a failed fetch with no cache no longer reads as empty history.
  Waiting accounts get a targeted fetch on the next sync.
- Tradovate holds an account whose start-of-day balance moves without a fill
  (a payout between hourly Cash History runs) until a Cash History books it,
  so a payout-pending account isn't re-traded on its ended cycle.
- Wipe routes forget history through the client and count accounts whose
  history didn't come back as failures.
- TopstepX sendOrder picks up a fill that arrived before the place response,
  and its REST backstop uses the documented Trade/search and Order/search.
- POINT_VALUES: SI 5000 (was 50), M2K 5 (was 10).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 17:04:09 -05:00

44 lines
1.7 KiB
TypeScript

import { NextResponse } from 'next/server';
import { getClients } from '@/lib/clients';
import { wipeAccountData } from '@/lib/db';
/**
* POST /api/accounts/[id]/wipe — drop every cached row for the account and
* rebuild it from a fresh Tradovate report.
*
* Destructive on purpose: cached rows older than the report's 28-day window
* cannot be refetched. The UI warns and confirms before calling this.
*/
export async function POST(_req: Request, { params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const accountId = Number(id);
if (!Number.isInteger(accountId)) {
return NextResponse.json({ error: 'Bad account id' }, { status: 400 });
}
for (const client of getClients().values()) {
const account = client.accountList.find((a) => a.id === accountId);
if (!account) continue;
wipeAccountData(accountId);
// Clear the in-memory view too — a failed refetch must leave the
// account visibly empty, not showing the data that was just wiped —
// and out of trading until a fetch rebuilds it.
client.forgetHistory(accountId, account.name);
await client.fetchDaysTraded([accountId]);
const loaded = client.historyReady(accountId);
return NextResponse.json({
ok: true,
entries: (client.dailyPnL[accountId] ?? []).length,
daysTraded: client.daysTraded[accountId] ?? 0,
fetchError: client.lastFetchErrors[account.name]
?? (loaded ? null : 'History did not reload — the account stays out of trading until it does'),
});
}
return NextResponse.json({ error: 'Account not found' }, { status: 404 });
}