refactor: 프론트엔드 TypeScript 타입 안전성 및 커스텀 훅 분리

- types/trading.ts: 중앙 타입 정의 (CandleData, Position, Trade 등)
- useMarketData.ts: 실시간 시세 처리 + 500ms 쓰로틀링
- usePortfolioData.ts: React Query 기반 포트폴리오 데이터 훅
- useTradeActions.ts: 매매 실행 액션 훅
- useWebSocket.ts: pong timeout 10초 감지 (좀비 연결 방지)
- TradingChart.tsx: @ts-nocheck 제거, CandleData 타입 적용
- PortfolioPanel/RecommendationPanel: any → 구체적 타입 교체
- Dashboard.tsx: 상태 관리 로직을 커스텀 훅으로 이전

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 17:26:27 +09:00
parent a477072bdc
commit dc9bc114da
10 changed files with 736 additions and 244 deletions

View File

@@ -0,0 +1,68 @@
import { useCallback } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import api from '../lib/api'
export const useTradeActions = () => {
const queryClient = useQueryClient()
const handleSell = useCallback(
async (
stockCode: string,
stockName: string,
quantity: number
): Promise<void> => {
try {
await api.post('/portfolio/sell', {
stock_code: stockCode,
quantity,
price: null,
})
// Invalidate queries to refresh portfolio
queryClient.invalidateQueries({
queryKey: ['portfolio-combined'],
})
queryClient.invalidateQueries({
queryKey: ['trade-history'],
})
console.log(`✅ ${stockName} sell order completed`)
} catch (error: any) {
console.error(
`❌ Sell order failed for ${stockName}:`,
error.response?.data?.detail || error.message
)
throw error
}
},
[queryClient]
)
const resetPendingTrades = useCallback(async (): Promise<void> => {
try {
const response = await api.delete('/trades/pending')
queryClient.invalidateQueries({
queryKey: ['trade-history'],
})
console.log('✅ Pending orders cleared:', response.data)
} catch (error: any) {
console.error(
'❌ Failed to clear pending orders:',
error.response?.data?.detail || error.message
)
throw error
}
}, [queryClient])
const invalidateTradeHistory = useCallback(() => {
queryClient.invalidateQueries({
queryKey: ['trade-history'],
})
}, [queryClient])
return {
handleSell,
resetPendingTrades,
invalidateTradeHistory,
}
}