fix: backtest submission shows no results — 4 bugs fixed

- ID mismatch: API generated a throwaway UUID while BacktestReplay
  generated its own internally. Frontend polled with wrong ID and
  never found the DB row. Now pre-generate ID in endpoint and pass
  it to BacktestReplay.
- Field name: API returned 'backtest_id' but frontend read 'data.id'.
  Unified to 'id' everywhere.
- No polling: useBacktestResult fired once and never refreshed.
  Added refetchInterval that polls every 2s while status is running.
- Response shape: GET endpoint nested results under 'result' object
  but frontend expected flat fields. Flattened response to match
  BacktestResult type.
- Added running/failed/completed status indicators in BacktestPanel.
This commit is contained in:
Celes Renata
2026-04-17 00:31:17 +00:00
parent f11aa0a1ee
commit f2d8744a4f
5 changed files with 74 additions and 51 deletions
+6 -1
View File
@@ -234,12 +234,17 @@ export function useTradingConfig() {
});
}
/** Fetch a backtest result by ID. */
/** Fetch a backtest result by ID. Polls every 2s while status is pending/running. */
export function useBacktestResult(id: string | undefined) {
return useQuery<BacktestResult>({
queryKey: ['backtest-result', id],
queryFn: () => apiGet<BacktestResult>('trading', `/api/trading/backtest/${id}`),
enabled: !!id,
refetchInterval: (query) => {
const status = query.state.data?.status;
if (!status || status === 'running' || status === 'pending') return 2000;
return false;
},
});
}
+23 -3
View File
@@ -25,7 +25,7 @@ export function BacktestPanel() {
const [backtestId, setBacktestId] = useState<string | undefined>(undefined);
const launch = useBacktestLaunch();
const { data: result, isLoading: resultLoading } = useBacktestResult(backtestId);
const { data: result } = useBacktestResult(backtestId);
function handleLaunch() {
if (!startDate || !endDate) return;
@@ -108,8 +108,28 @@ export function BacktestPanel() {
</Card>
{/* Results */}
{resultLoading && <LoadingSpinner />}
{result && (
{backtestId && !result && (
<Card>
<div className="flex items-center gap-3">
<LoadingSpinner />
<span className="text-sm text-gray-400">Backtest running</span>
</div>
</Card>
)}
{result && result.status === 'running' && (
<Card>
<div className="flex items-center gap-3">
<LoadingSpinner />
<span className="text-sm text-gray-400">Backtest in progress</span>
</div>
</Card>
)}
{result && result.status === 'failed' && (
<Card>
<p className="text-sm text-red-400">Backtest failed. Check server logs for details.</p>
</Card>
)}
{result && result.status === 'completed' && (
<>
{/* Summary Metrics */}
<Card>