import { useMutation, useQueryClient } from '@tanstack/react-query'; import { fetchData, type FetchDataResult, type FetchSelector } from '../api/ingestion'; import { useToast } from '../components/ui/Toast'; import { summarizeIngestionResult } from '../lib/ingestionStatus'; interface UseFetchSymbolDataOptions { includeSymbolPrefix?: boolean; invalidatePipelineReadiness?: boolean; } export interface FetchVars { symbol: string; sources?: FetchSelector; } type FetchArg = string | FetchVars; const argSymbol = (arg: FetchArg): string => (typeof arg === 'string' ? arg : arg.symbol); export function useFetchSymbolData(options: UseFetchSymbolDataOptions = {}) { const { includeSymbolPrefix = false, invalidatePipelineReadiness = false } = options; const queryClient = useQueryClient(); const { addToast } = useToast(); return useMutation({ // Accepts either a bare symbol (fetch all) or { symbol, sources } (granular) mutationFn: (arg: FetchArg) => typeof arg === 'string' ? fetchData(arg) : fetchData(arg.symbol, arg.sources), onSuccess: (result: FetchDataResult, arg: FetchArg) => { const symbol = argSymbol(arg); const normalized = symbol.toUpperCase(); const summary = summarizeIngestionResult(result, normalized); const toastMessage = includeSymbolPrefix ? `${normalized}: ${summary.message}` : summary.message; addToast(summary.toastType, toastMessage); queryClient.invalidateQueries({ queryKey: ['ohlcv', symbol] }); queryClient.invalidateQueries({ queryKey: ['sentiment', symbol] }); queryClient.invalidateQueries({ queryKey: ['fundamentals', symbol] }); queryClient.invalidateQueries({ queryKey: ['sr-levels', symbol] }); queryClient.invalidateQueries({ queryKey: ['gate-target-ladder', symbol] }); queryClient.invalidateQueries({ queryKey: ['scores', symbol] }); // Fetch re-runs the scanner → setups/confidence change. Refresh both the // per-ticker trades (['trades', symbol]) and the Overview list (['trades']). queryClient.invalidateQueries({ queryKey: ['trades'] }); if (invalidatePipelineReadiness) { queryClient.invalidateQueries({ queryKey: ['admin', 'pipeline-readiness'] }); } }, onError: (err: Error, arg: FetchArg) => { const normalized = argSymbol(arg).toUpperCase(); const prefix = includeSymbolPrefix ? `${normalized}: ` : ''; addToast('error', `${prefix}${err.message || 'Failed to fetch data'}`); }, }); }