Files
autofirmer-expanded/app/api/accounts/wipe-all/route.ts
T
Brandon LiandClaude Opus 5.5 1eb0736fbe One-and-done counts confirmed fills; holds need a persistent refusal; wipes keep their yardstick
Fourth review round (52ed9c7):

- The one-and-done guard counts only entries the broker confirmed filled,
  so an entry that timed out or was rejected unfilled no longer benches the
  account for the day.
- TopstepX: an account is promoted only by a sync that actually checked its
  funds; one with no account type stays out (not traded) without costing a
  sync per pass, and once typed waits for that check. Wipe routes don't
  count untyped accounts as failures.
- Tradovate: an unchecked balance-hold release needs Cash History refused
  for a full hour straight (a 4xx other than 401/403/408/429, or an answer
  without data); any other outcome resets it, so one stray reply during a
  5xx outage can't release a payout.
- A wipe keeps the pre-wipe baseline and fund rows as its yardstick: the
  rebuild must explain today's balance against them, so a payout the
  rebuilt report hasn't booked yet stays held.
- The roll base of an unrolled record is kept per trade date in
  account_meta, so a restart later the same trade date counts from the same
  point instead of from a value that already includes the day's fills.

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

40 lines
1.7 KiB
TypeScript

import { NextResponse } from 'next/server';
import { getClients } from '@/lib/clients';
import { getAccountConfig } from '@/lib/account-type-resolver';
import { wipeAccountData } from '@/lib/db';
/**
* POST /api/accounts/wipe-all — the bulk form of /api/accounts/[id]/wipe:
* drop every account's cached rows on every firm and rebuild them all from
* fresh Tradovate reports. One report per account, so this takes a while on
* big rosters; firms run in parallel, accounts within a firm sequentially
* (that's fetchDaysTraded's own pacing against the flaky report server).
*
* Same destructive caveat as the single wipe: cached rows older than the
* report's 28-day window cannot be refetched. The UI confirms first.
*/
export async function POST() {
const clients = [...getClients().values()];
let wiped = 0;
let failedAccounts = 0;
await Promise.all(clients.map(async (client) => {
// Forgotten, the accounts read unloaded and stay out of trading
// until the refetch below (or, if it fails, a later one) lands.
const ids = client.accountList.map((account) => account.id);
for (const account of client.accountList) {
wipeAccountData(account.id);
client.forgetHistory(account.id, account.name);
wiped++;
}
await client.fetchDaysTraded();
// Counted from the result, not the fetch's own tally: a client with
// no session fetches nothing and reports no failures. Accounts with
// no type aren't traded, so they aren't failures either.
failedAccounts += ids.filter((id) => getAccountConfig(id).accountType && !client.historyReady(id)).length;
}));
return NextResponse.json({ ok: true, wiped, failedAccounts });
}