- claudedocs 폴더 구조 재정리: archive/sessions, guides/migration·mobile·universal-list, refactoring 분류 - 오래된 세션 컨텍스트/체크리스트 문서 정리 (아카이브 이동 또는 삭제) - AuthContext → authStore(Zustand) 전환 시작, RootProvider 간소화 - GenericCRUDDialog 공통 다이얼로그 컴포넌트 추가 - PermissionDialog 삭제 → GenericCRUDDialog로 대체 - RankDialog/TitleDialog GenericCRUDDialog 기반으로 리팩토링 - toast-utils.ts 삭제 (미사용) - fileDownload.ts 개선, excel-download.ts 정리 - menuStore/themeStore Zustand 셀렉터 최적화 - useColumnSettings/useTableColumnStore 기능 보강 - 세금계산서/견적/작업자화면/결재 등 소규모 개선 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.3 KiB
7.3 KiB
품목관리 세션 체크포인트
작성일: 2025-12-12 이전 세션: 2025-12-10 상태: ✅ 프론트엔드 작업 완료 (백엔드 API 대기)
🎯 오늘의 작업 목표
전개도 상세 입력 (폭 합계 연동) - ✅ 완료
BOM 테이블 UI 수정 - ✅ 완료
BOM 데이터 전송/로드 - ✅ 완료
파일 업로드 오류 수정 - ✅ 완료
✅ 완료된 작업
1. BOM API 연동 완료
변경 사항:
child_item_type필드 추가 (PRODUCT/MATERIAL 구분)- BOM 저장 형식:
{ child_item_id, child_item_type, quantity }최소 필드만 저장 - 품목 유형 매핑: FG/PT → PRODUCT, SM/RM/CS → MATERIAL
수정 파일:
types.ts: BOMLine에childItemType필드 추가DynamicBOMSection.tsx:getChildItemType()헬퍼 함수 추가index.tsx: BOM 전송 형식 간소화
2. 수정 화면 BOM 로드 버그 수정
문제: mapApiResponseToFormData가 bom을 제외하여 initialData에 BOM이 없었음
해결: initialBomLines prop으로 BOM 데이터 별도 전달
수정 파일:
types.ts:DynamicItemFormProps에initialBomLines?: BOMLine[]추가edit/page.tsx: API 응답에서 BOM 추출 →initialBomLinesstate → prop 전달index.tsx:initialBomLinesprop 수신 → useEffect로setBomLines()호출
3. BOM key 값 중복 에러 수정
문제: BOM 항목에 id가 없을 때 빈 문자열로 key 중복 발생
해결: page.tsx의 mapApiResponseToItemMaster에서 fallback key 생성
id: String(bomItem.id || bomItem.child_item_id || `bom-${index}`)
4. 이미지 업로드 500 에러 수정
문제: bending_diagram에 Base64 이미지 데이터가 JSON 본문에 포함되어 백엔드 500 에러
해결: API 호출 전 base64 이미지 데이터 제거 (파일은 별도 API로 업로드)
수정 파일:
edit/page.tsx: base64 이미지 필드 제거 로직 추가create/page.tsx: 동일하게 적용
// API 호출 전 이미지 데이터 제거
if (submitData.bending_diagram?.startsWith('data:')) delete submitData.bending_diagram;
if (submitData.specification_file?.startsWith('data:')) delete submitData.specification_file;
if (submitData.certification_file?.startsWith('data:')) delete submitData.certification_file;
5. bending_details 배열 전송 오류 수정
문제: JSON.stringify()로 문자열 전송 → 백엔드에서 "배열이어야 합니다" 오류
해결: PHP가 이해하는 배열 형태로 FormData 전송
수정 파일: src/lib/api/items.ts
// 기존 (문자열)
formData.append('bending_details', JSON.stringify(options.bendingDetails));
// 수정 (배열 형태)
options.bendingDetails.forEach((detail, index) => {
Object.entries(detail).forEach(([key, value]) => {
formData.append(`bending_details[${index}][${key}]`, String(value));
});
});
6. 제품 정보 섹션 빈 카드 숨김
문제: FG 품목 상세에서 "제품 정보" 섹션이 내용 없이 빈 카드로 표시
해결: 내용이 있을 때만 섹션 표시
수정 파일: ItemDetailClient.tsx
// 기존
{item.itemType === 'FG' && (
// 수정
{item.itemType === 'FG' && (item.productCategory || item.lotAbbreviation || item.note) && (
⏳ 백엔드 대기 사항
1. 파일 다운로드 인증 문제 🔴
현재 문제:
- 파일 다운로드 URL(
/storage/{id})에 직접 접근 시"Unauthorized. Invalid or missing API key"에러 - 브라우저에서
<a href="url">다운로드</a>클릭 시 API 키가 없어서 401 에러 - 시방서(PDF), 인정서(PDF), 전개도(이미지) 모두 동일한 문제
수정 요청 옵션:
- 옵션 A (권장): Signed URL 방식 - 임시 토큰이 포함된 URL 생성 (만료 시간 설정)
- 옵션 B: 파일 다운로드 엔드포인트를 public으로 변경 (인증 불필요)
- 옵션 C: 프론트엔드 프록시 경유 (Next.js API route에서 API 키 추가)
2. 품목 조회 시 파일 URL 미반환 문제 🔴
현재 문제:
bending_diagram,specification_file,certification_file필드에 **file_id(숫자)**만 반환됨- 프론트엔드에서 이미지/PDF를 표시하려면 실제 다운로드 URL이 필요
- 현재 file_id만 있어서 파일을 불러올 수 없음
수정 요청: 품목 조회 응답에서 file_id와 함께 실제 URL도 반환:
{
"id": 813,
"bending_diagram": 123,
"bending_diagram_url": "/api/v1/files/download/xxx",
"specification_file": 456,
"specification_file_url": "/api/v1/files/download/yyy",
"certification_file": 789,
"certification_file_url": "/api/v1/files/download/zzz"
}
🔄 코드 변경 요약
| 파일 | 변경 내용 |
|---|---|
types.ts |
BOMLine에 childItemType 추가, DynamicItemFormProps에 initialBomLines 추가 |
DynamicBOMSection.tsx |
getChildItemType() 헬퍼 함수, 품목 선택 시 childItemType 설정 |
index.tsx |
BOM 전송 형식 간소화, initialBomLines prop 처리 |
edit/page.tsx |
initialBomLines 전달, base64 이미지 제거 로직 |
create/page.tsx |
base64 이미지 제거 로직 |
items/[id]/page.tsx |
BOM key fallback 처리 |
ItemDetailClient.tsx |
제품 정보 섹션 조건부 표시 |
lib/api/items.ts |
bending_details 배열 형태로 전송 |
📋 다음 세션 TODO
백엔드 API 완료 후
- 파일 다운로드 URL 처리 (백엔드 응답 형식에 맞춰 적용)
- 전개도 이미지 표시 테스트
- 시방서/인정서 PDF 다운로드 테스트
DynamicItemForm 분할 작업 🎯
index.tsx파일 분할 (현재 2000줄+ → 500줄 이하로)- 섹션별 컴포넌트 분리:
DynamicFormHeader.tsx- 헤더/제목DynamicFormActions.tsx- 저장/취소 버튼DynamicBendingSection.tsx- 전개도 섹션 (기존)DynamicFileSection.tsx- 파일 업로드 섹션useDynamicForm.ts- 메인 로직 훅
- 상태 관리 정리 (props drilling 최소화)
파일 업로드 필드 동적화 🆕
참고:
[DESIGN-2025-12-12] item-master-form-builder-roadmap.md
현재 문제:
- 파일 업로드가
FileUpload.tsx로 하드코딩되어 있음 - 품목기준관리에서 파일 필드를 동적으로 추가할 수 없음
목표:
- 새 필드 타입
file,files,image추가 - 품목기준관리에서 파일 업로드 필드 동적 생성 가능
구현 작업:
field_type에file|files|image타입 추가 (API 스키마)FileField.tsx컴포넌트 생성 (DynamicItemForm/fields/)ImageField.tsx컴포넌트 생성 (미리보기 포함)DynamicFieldRenderer.tsx에 file/image 케이스 추가properties확장:{ accept, maxSize, maxFiles }- 품목기준관리 UI에 파일 필드 타입 옵션 추가
- 기존 하드코딩된 FileUpload 컴포넌트 동적 필드로 마이그레이션
📚 관련 문서
| 문서 | 위치 |
|---|---|
| 이전 세션 컨텍스트 | [NEXT-2025-12-10] item-crud-session-context.md |
| DynamicForm 분리 계획 | [PLAN-2025-12-08] dynamic-form-separation-plan.md |
| Radix UI 버그 해결 | claudedocs/guides/[FIX-2025-12-05] radix-ui-select-controlled-mode-bug.md |