다른 공급사 소유(또는 없는) session_id 로 /chat 진입 시 일반 에러+재시도 대신 '잘못된 접근입니다.' 토스트를 띄우고 협상 목록(/list)으로 돌려보낸다. 로그인은 유효하므로 로그아웃하지 않는다(인증≠인가 — 로그아웃은 401/403/43x 토큰 오류에서만, 기존 인터셉터 동작 유지). - useChatController: 진입 로드(init/messages) 에러가 NEGO_FORBIDDEN(1300)/ NEGO_NOT_FOUND(1304) 이면 토스트 후 /list 로 replace 이동(ref 가드로 1회). 리다이렉트 동안 스피너 유지(ErrorPage 깜빡임 방지), 그 외 서버/네트워크 에러는 기존 ErrorPage(재시도) 유지. - chat.queries: init/messages 쿼리에 retry 추가 — 1300/1304 는 재시도해도 안 바뀌어 즉시 실패시켜 목록 복귀 지연 제거(그 외 에러는 기존 재시도 유지). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
// 채팅 도메인의 조회(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<number>([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,
|
|
})
|
|
}
|