전체적인 리팩토링
This commit is contained in:
98
features/layout/hooks/use-market-indices.ts
Normal file
98
features/layout/hooks/use-market-indices.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user