From 9cfd10a265a3885453ab851eeb10fd87fbc2f133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Fri, 23 Jan 2026 09:04:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(CEODashboard):=20Phase=204=20-=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C/=EA=B0=80=EC=A7=80=EA=B8=89=EA=B8=88=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=84=B9=EC=85=98=20=EC=B9=B4=EB=93=9C=20API=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 카드/가지급금 관리 섹션의 4개 카드(cm1~cm4)를 실제 API 데이터로 연동: - cm1: 카드 사용액 - CardTransaction API (기존) - cm2: 가지급금 - LoanDashboard API (신규 연동) - cm3: 법인세 예상 가중 - TaxSimulation API (신규 연동) - cm4: 대표자 종합세 예상 가중 - TaxSimulation API (신규 연동) 변경 사항: - transformCardManagementResponse: LoanDashboard, TaxSimulation 파라미터 추가 - useCEODashboard: 3개 API 병렬 호출 (Promise.all) - useCardManagement: 동일하게 다중 API 호출 적용 - 각 API 실패 시 fallback 데이터 사용 (graceful degradation) --- src/hooks/useCEODashboard.ts | 38 +++++++++++++++++++--- src/lib/api/dashboard/transformers.ts | 47 +++++++++++++++++++-------- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/hooks/useCEODashboard.ts b/src/hooks/useCEODashboard.ts index d5ede586..2d9d5dea 100644 --- a/src/hooks/useCEODashboard.ts +++ b/src/hooks/useCEODashboard.ts @@ -23,8 +23,15 @@ import type { WelfareApiResponse, WelfareDetailApiResponse, ExpectedExpenseDashboardDetailApiResponse, + LoanDashboardApiResponse, + TaxSimulationApiResponse, } from '@/lib/api/dashboard/types'; +import { + fetchLoanDashboard, + fetchTaxSimulation, +} from '@/lib/api/dashboard/endpoints'; + import { transformDailyReportResponse, transformReceivableResponse, @@ -226,8 +233,18 @@ export function useCardManagement(fallbackData?: CardManagementData) { setLoading(true); setError(null); - const apiData = await fetchApi('card-transactions/summary'); - const transformed = transformCardManagementResponse(apiData, fallbackData); + // 3개 API 병렬 호출: 카드거래, 가지급금, 세금 시뮬레이션 + const [cardApiData, loanResponse, taxResponse] = await Promise.all([ + fetchApi('card-transactions/summary'), + fetchLoanDashboard(), + fetchTaxSimulation(), + ]); + + // LoanDashboard와 TaxSimulation은 ApiResponse wrapper가 있으므로 data 추출 + const loanData = loanResponse.success ? loanResponse.data : null; + const taxData = taxResponse.success ? taxResponse.data : null; + + const transformed = transformCardManagementResponse(cardApiData, loanData, taxData, fallbackData); setData(transformed); } catch (err) { @@ -1028,8 +1045,21 @@ export function useCEODashboard(options: UseCEODashboardOptions = {}): CEODashbo try { setCardManagementLoading(true); setCardManagementError(null); - const apiData = await fetchApi('card-transactions/summary'); - setCardManagementData(transformCardManagementResponse(apiData, cardManagementFallback)); + + // 3개 API 병렬 호출: 카드거래, 가지급금, 세금 시뮬레이션 + const [cardApiData, loanResponse, taxResponse] = await Promise.all([ + fetchApi('card-transactions/summary'), + fetchLoanDashboard(), + fetchTaxSimulation(), + ]); + + // LoanDashboard와 TaxSimulation은 ApiResponse wrapper가 있으므로 data 추출 + const loanData = loanResponse.success ? loanResponse.data : null; + const taxData = taxResponse.success ? taxResponse.data : null; + + setCardManagementData( + transformCardManagementResponse(cardApiData, loanData, taxData, cardManagementFallback) + ); } catch (err) { setCardManagementError(err instanceof Error ? err.message : '데이터 로딩 실패'); } finally { diff --git a/src/lib/api/dashboard/transformers.ts b/src/lib/api/dashboard/transformers.ts index fb2b5acd..7d000159 100644 --- a/src/lib/api/dashboard/transformers.ts +++ b/src/lib/api/dashboard/transformers.ts @@ -21,6 +21,8 @@ import type { CardDashboardDetailApiResponse, BillDashboardDetailApiResponse, ExpectedExpenseDashboardDetailApiResponse, + LoanDashboardApiResponse, + TaxSimulationApiResponse, } from './types'; import type { @@ -485,43 +487,60 @@ function generateCardManagementCheckPoints(api: CardTransactionApiResponse): Che /** * CardTransaction API 응답 → Frontend 타입 변환 - * 4개 카드 구조 유지: 카드, 가지급금, 법인세 예상 가중, 대표자 종합세 예상 가중 - * 주의: 가지급금, 법인세, 종합세 관련 데이터는 별도 API 필요 (현재 목업 유지) + * 4개 카드 구조: + * - cm1: 카드 사용액 (CardTransaction API) + * - cm2: 가지급금 (LoanDashboard API) + * - cm3: 법인세 예상 가중 (TaxSimulation API - corporate_tax.difference) + * - cm4: 대표자 종합세 예상 가중 (TaxSimulation API - income_tax.difference) */ export function transformCardManagementResponse( summaryApi: CardTransactionApiResponse, + loanApi?: LoanDashboardApiResponse | null, + taxApi?: TaxSimulationApiResponse | null, fallbackData?: CardManagementData ): CardManagementData { const changeRate = calculateChangeRate(summaryApi.current_month_total, summaryApi.previous_month_total); + // cm2: 가지급금 금액 (LoanDashboard API 또는 fallback) + const loanAmount = loanApi?.summary?.total_outstanding ?? fallbackData?.cards[1]?.amount ?? 0; + + // cm3: 법인세 예상 가중 (TaxSimulation API 또는 fallback) + const corporateTaxDifference = taxApi?.corporate_tax?.difference ?? fallbackData?.cards[2]?.amount ?? 0; + + // cm4: 대표자 종합세 예상 가중 (TaxSimulation API 또는 fallback) + const incomeTaxDifference = taxApi?.income_tax?.difference ?? fallbackData?.cards[3]?.amount ?? 0; + + // 가지급금 경고 배너 표시 여부 결정 (가지급금 잔액 > 0이면 표시) + const hasLoanWarning = loanAmount > 0; + return { - // 가지급금 관련 경고 배너 (별도 API 필요) - warningBanner: fallbackData?.warningBanner, + // 가지급금 관련 경고 배너 (가지급금 있을 때만 표시) + warningBanner: hasLoanWarning ? fallbackData?.warningBanner : undefined, cards: [ - // cm1: 카드 사용액 (API 데이터) + // cm1: 카드 사용액 (CardTransaction API) { id: 'cm1', label: '카드', amount: summaryApi.current_month_total, previousLabel: `전월 대비 ${changeRate > 0 ? '+' : ''}${changeRate.toFixed(1)}%`, }, - // cm2: 가지급금 (별도 API 필요 - 현재 fallback) - fallbackData?.cards[1] ?? { + // cm2: 가지급금 (LoanDashboard API) + { id: 'cm2', label: '가지급금', - amount: 0, + amount: loanAmount, }, - // cm3: 법인세 예상 가중 (별도 API 필요 - 현재 fallback) - fallbackData?.cards[2] ?? { + // cm3: 법인세 예상 가중 (TaxSimulation API) + { id: 'cm3', label: '법인세 예상 가중', - amount: 0, + amount: corporateTaxDifference, }, - // cm4: 대표자 종합세 예상 가중 (별도 API 필요 - 현재 fallback) - fallbackData?.cards[3] ?? { + // cm4: 대표자 종합세 예상 가중 (TaxSimulation API) + { id: 'cm4', label: '대표자 종합세 예상 가중', - amount: 0, + amount: incomeTaxDifference, }, ], checkPoints: generateCardManagementCheckPoints(summaryApi),