- 견적 V2 API 연동 변경 이력 (4개 파일) - 입고관리 분석 계획 - 재고 통합 계획 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
변경 내용 요약
날짜: 2026-01-26 작업자: Claude Code 관련 계획: docs/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 추가
import { getQuoteById, updateQuote } from "@/components/quotes/actions";
import { transformApiToV2, transformV2ToApi } from "@/components/quotes/types";
2. MOCK_DATA 제거
- 65줄의 하드코딩된 테스트 데이터 제거
3. useEffect 수정 (데이터 로드)
변경 전:
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]);
변경 후:
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 수정 (수정 저장)
변경 전:
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]);
변경 후:
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 완료
- Step 1.1: V2 데이터 변환 함수 구현
- Step 1.2: test-new 페이지 API 연동 (createQuote)
- Step 1.3: test/[id] 상세 페이지 API 연동 (getQuoteById)
- 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/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