// 채팅 도메인의 조회(useQuery) 훅. import { useQuery } from '@tanstack/react-query' import { ErrorCode, isApiError } from '@/apis/types' import { chatApi } from './chat.api' import { chatKeys } from './chat.keys' import { mapInit, mapMessage } from './chat.type' // 재시도해도 결과가 바뀌지 않는 클라이언트 에러(권한없음/없는 세션) → 즉시 실패시켜 목록 복귀를 지연 없이 처리. const NON_RETRYABLE = new Set([ErrorCode.NEGO_FORBIDDEN, ErrorCode.NEGO_NOT_FOUND]) function retryQuery(failureCount: number, error: unknown): boolean { if (isApiError(error) && NON_RETRYABLE.has(error.code)) return false return failureCount < 3 } /** 채팅 진입 메타(상품·견적). 마감 시각은 거의 불변이라 오래 캐싱한다. */ export function useChatInitQuery(sessionId: string) { return useQuery({ queryKey: chatKeys.init(sessionId), queryFn: () => chatApi.getInit(sessionId).then(mapInit), enabled: !!sessionId, staleTime: 5 * 60 * 1000, retry: retryQuery, }) } /** * 대화 히스토리. 진입 시 1회만 받고 이후엔 send 응답을 로컬에 append 한다(append-only). * 따라서 백그라운드 refetch 가 로컬 상태를 덮지 않도록 staleTime 을 무한대로 둔다. */ export function useChatMessagesQuery(sessionId: string) { return useQuery({ queryKey: chatKeys.messages(sessionId), queryFn: () => chatApi.getMessages(sessionId).then((r) => r.items.map(mapMessage)), enabled: !!sessionId, staleTime: Infinity, refetchOnWindowFocus: false, retry: retryQuery, }) }