/** * @file features/layout/hooks/use-market-indices.ts * @description 시장 지수 데이터를 가져오고 상태를 관리하는 커스텀 훅 * * @description [주요 책임] * - `useMarketIndicesStore`와 연동하여 상태(지수, 로딩, 에러)를 제공 * - KIS 검증 세션이 있을 때 `/api/kis/domestic/indices` API를 인증 헤더와 함께 호출 * - API 호출 로직을 `useCallback`으로 메모이제이션하여 성능을 최적화 */ import { useCallback } from "react"; import { buildKisRequestHeaders, resolveKisApiErrorMessage, type KisApiErrorPayload, } from "@/features/settings/apis/kis-api-utils"; import { useKisRuntimeStore } from "@/features/settings/store/use-kis-runtime-store"; import { useMarketIndicesStore } from "@/features/layout/stores/market-indices-store"; import type { DomesticMarketIndexResult } from "@/lib/kis/dashboard"; import type { DashboardIndicesResponse } from "@/features/dashboard/types/dashboard.types"; interface LegacyMarketIndicesResponse { indices: DomesticMarketIndexResult[]; fetchedAt: string; } export function useMarketIndices() { const verifiedCredentials = useKisRuntimeStore((state) => state.verifiedCredentials); const isKisVerified = useKisRuntimeStore((state) => state.isKisVerified); const { indices, isLoading, error, fetchedAt, setIndices, setLoading, setError, } = useMarketIndicesStore(); const fetchIndices = useCallback(async () => { // [Step 1] KIS 검증이 안 된 상태에서는 지수 API를 호출하지 않습니다. if (!isKisVerified || !verifiedCredentials) { setLoading(false); setError(null); return; } setLoading(true); try { // [Step 2] 인증 헤더를 포함한 신규 지수 API를 호출합니다. const response = await fetch("/api/kis/domestic/indices", { method: "GET", headers: buildKisRequestHeaders(verifiedCredentials, { includeSessionOverride: true, }), cache: "no-store", }); const payload = (await response.json()) as | DashboardIndicesResponse | LegacyMarketIndicesResponse | KisApiErrorPayload; if (!response.ok) { throw new Error(resolveKisApiErrorMessage(payload, "지수 조회 중 오류가 발생했습니다.")); } // [Step 3] 신규/레거시 응답 형식을 모두 수용해 스토어에 반영합니다. if ("items" in payload) { setIndices({ indices: payload.items, fetchedAt: payload.fetchedAt, }); return; } if ("indices" in payload && "fetchedAt" in payload) { setIndices({ indices: payload.indices, fetchedAt: payload.fetchedAt, }); return; } throw new Error("지수 응답 형식이 올바르지 않습니다."); } catch (e) { setError(e instanceof Error ? e : new Error("An unknown error occurred")); } }, [isKisVerified, setError, setIndices, setLoading, verifiedCredentials]); return { indices, isLoading, error, fetchedAt, fetchIndices, }; }