# 변경 내용 요약 **날짜:** 2026-01-26 **작업자:** Claude Code **관련 계획:** docs/dev_plans/quote-management-url-migration-plan.md (Step 1.3, 1.4) ## 📋 변경 개요 V2 견적 상세/수정 테스트 페이지(test/[id])에서 Mock 데이터를 실제 API 연동으로 변경 ## 📁 수정된 파일 - `react/src/app/[locale]/(protected)/sales/quote-management/test/[id]/page.tsx` - API 연동 구현 ## 🔧 상세 변경 사항 ### 1. Import 추가 ```typescript import { getQuoteById, updateQuote } from "@/components/quotes/actions"; import { transformApiToV2, transformV2ToApi } from "@/components/quotes/types"; ``` ### 2. MOCK_DATA 제거 - 65줄의 하드코딩된 테스트 데이터 제거 ### 3. useEffect 수정 (데이터 로드) **변경 전:** ```typescript useEffect(() => { const loadQuote = async () => { setIsLoading(true); try { await new Promise((resolve) => setTimeout(resolve, 500)); // Mock delay setQuote({ ...MOCK_DATA, id: quoteId }); } catch (error) { toast.error("견적 정보를 불러오는데 실패했습니다."); router.push("/sales/quote-management"); } finally { setIsLoading(false); } }; loadQuote(); }, [quoteId, router]); ``` **변경 후:** ```typescript useEffect(() => { const loadQuote = async () => { setIsLoading(true); try { const result = await getQuoteById(quoteId); if (!result.success || !result.data) { toast.error(result.error || "견적 정보를 불러오는데 실패했습니다."); router.push("/sales/quote-management"); return; } // API 응답을 V2 폼 데이터로 변환 const v2Data = transformApiToV2(result.data); setQuote(v2Data); } catch (error) { toast.error("견적 정보를 불러오는데 실패했습니다."); router.push("/sales/quote-management"); } finally { setIsLoading(false); } }; if (quoteId) { loadQuote(); } }, [quoteId, router]); ``` ### 4. handleSave 수정 (수정 저장) **변경 전:** ```typescript const handleSave = useCallback(async (data: QuoteFormDataV2, saveType: "temporary" | "final") => { setIsSaving(true); try { console.log("[테스트] 수정 데이터:", data); await new Promise((resolve) => setTimeout(resolve, 1000)); // Mock delay toast.success(`[테스트] ${saveType === "temporary" ? "임시" : "최종"} 저장 완료`); if (saveType === "final") { router.push(`/sales/quote-management/test/${quoteId}`); } } catch (error) { toast.error("저장 중 오류가 발생했습니다."); } finally { setIsSaving(false); } }, [router, quoteId]); ``` **변경 후:** ```typescript const handleSave = useCallback(async (data: QuoteFormDataV2, saveType: "temporary" | "final") => { setIsSaving(true); try { // V2 폼 데이터를 API 형식으로 변환 const updatedData = { ...data, status: saveType }; const apiData = transformV2ToApi(updatedData); // API 호출 const result = await updateQuote(quoteId, apiData); if (!result.success) { toast.error(result.error || "저장 중 오류가 발생했습니다."); return; } toast.success(`${saveType === "temporary" ? "임시" : "최종"} 저장 완료`); // 저장 후 view 모드로 전환 router.push(`/sales/quote-management/test/${quoteId}`); } catch (error) { toast.error("저장 중 오류가 발생했습니다."); } finally { setIsSaving(false); } }, [router, quoteId]); ``` ## ✅ Phase 1 완료 - [x] Step 1.1: V2 데이터 변환 함수 구현 - [x] Step 1.2: test-new 페이지 API 연동 (createQuote) - [x] Step 1.3: test/[id] 상세 페이지 API 연동 (getQuoteById) - [x] Step 1.4: test/[id] 수정 API 연동 (updateQuote) ## 🔜 다음 작업 (Phase 2) - [ ] Step 2.1: test-new → new 경로 변경 - [ ] Step 2.2: test/[id] → [id] 경로 통합 - [ ] Step 2.3: 기존 V1 페이지 처리 결정 ## 🔗 관련 문서 - 계획 문서: `docs/dev_plans/quote-management-url-migration-plan.md` - Step 1.1 변경 내역: `docs/changes/20260126_quote_v2_transform_functions.md` - Step 1.2 변경 내역: `docs/changes/20260126_quote_v2_test_new_api.md` - V2 컴포넌트: `react/src/components/quotes/QuoteRegistrationV2.tsx`