- BOM 항목 추가/수정/삭제 시 섹션탭 즉시 반영 - 섹션 복제 시 UI 즉시 업데이트 (null vs undefined 이슈 해결) - 항목 수정 기능 추가 (useTemplateManagement) - 실시간 동기화 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
446 lines
14 KiB
Markdown
446 lines
14 KiB
Markdown
# ItemMasterDataManagement 훅 분리 리팩토링
|
|
|
|
## 개요
|
|
- **목표**: 2000줄+ 컴포넌트를 도메인별 커스텀 훅으로 분리
|
|
- **예상 결과**: 메인 컴포넌트 ~200줄로 축소 (90% 감소)
|
|
- **시작일**: 2025-11-26
|
|
|
|
## 진행 상태
|
|
|
|
### Phase 1: 커스텀 훅 생성 ✅ 완료
|
|
|
|
| # | 훅 이름 | 상태 수 | 핸들러 수 | 상태 | 비고 |
|
|
|---|---------|---------|----------|------|------|
|
|
| 1 | usePageManagement | ~8 | 3 | [x] 완료 | 가장 단순, 먼저 시작 |
|
|
| 2 | useSectionManagement | ~10 | 5 | [x] 완료 | Page에 의존 |
|
|
| 3 | useFieldManagement | ~15 | 4 | [x] 완료 | Section에 의존 |
|
|
| 4 | useMasterFieldManagement | ~12 | 4 | [x] 완료 | 독립적 |
|
|
| 5 | useTemplateManagement | ~18 | 11 | [x] 완료 | 가장 복잡 (BOM 포함) |
|
|
| 6 | useAttributeManagement | ~15 | 6 | [x] 완료 | 옵션/칼럼 관리 |
|
|
| 7 | useTabManagement | ~12 | 14 | [x] 완료 | 탭 상태 관리 |
|
|
|
|
### Phase 2: 메인 컴포넌트 정리 ✅ 완료
|
|
|
|
| # | 작업 | 상태 | 비고 |
|
|
|---|------|------|------|
|
|
| 2.1 | 훅 import 추가 | [x] 완료 | 7개 훅 import |
|
|
| 2.2 | 훅 초기화 코드 추가 | [x] 완료 | 컴포넌트 상단에 훅 호출 |
|
|
| 2.3 | useState 제거 - 페이지 관련 | [x] 완료 | usePageManagement로 대체 |
|
|
| 2.4 | useState 제거 - 섹션 관련 | [x] 완료 | useSectionManagement로 대체 |
|
|
| 2.5 | useState 제거 - 필드 관련 | [x] 완료 | useFieldManagement로 대체 |
|
|
| 2.6 | useState 제거 - 마스터필드 관련 | [x] 완료 | useMasterFieldManagement로 대체 |
|
|
| 2.7 | useState 제거 - 템플릿 관련 | [x] 완료 | useTemplateManagement로 대체 |
|
|
| 2.8 | useState 제거 - 속성 관련 | [x] 완료 | useAttributeManagement로 대체 |
|
|
| 2.9 | useState 제거 - 탭 관련 | [x] 완료 | useTabManagement로 대체 |
|
|
| 2.10 | 핸들러 함수 제거 | [x] 완료 | 훅에서 가져온 핸들러로 대체 |
|
|
| 2.11 | useEffect 제거 | [x] 완료 | 훅 내부로 이동된 것들 |
|
|
| 2.12 | 하위 컴포넌트 props 연결 | [x] 완료 | 다이얼로그/탭 컴포넌트에 훅 값 전달 + wrapper 함수 |
|
|
| 2.13 | 타입 체크 | [x] 완료 | 기존 타입 에러만 남음 (훅과 무관) |
|
|
| 2.14 | 빌드 테스트 | [x] 완료 | npm run build 성공! |
|
|
| 2.15 | 기능 테스트 | [ ] 대기 | 브라우저에서 동작 확인 필요 |
|
|
|
|
---
|
|
|
|
## Phase 2 상세 가이드
|
|
|
|
### 2.1 훅 Import 추가
|
|
```typescript
|
|
// ItemMasterDataManagement.tsx 상단에 추가
|
|
import {
|
|
usePageManagement,
|
|
useSectionManagement,
|
|
useFieldManagement,
|
|
useMasterFieldManagement,
|
|
useTemplateManagement,
|
|
useAttributeManagement,
|
|
useTabManagement,
|
|
} from './ItemMasterDataManagement/hooks';
|
|
```
|
|
|
|
### 2.2 훅 초기화 코드
|
|
```typescript
|
|
// 컴포넌트 함수 내부 상단에 추가
|
|
export function ItemMasterDataManagement() {
|
|
const pageManagement = usePageManagement();
|
|
const sectionManagement = useSectionManagement();
|
|
const fieldManagement = useFieldManagement();
|
|
const masterFieldManagement = useMasterFieldManagement();
|
|
const templateManagement = useTemplateManagement();
|
|
const attributeManagement = useAttributeManagement();
|
|
const tabManagement = useTabManagement();
|
|
|
|
// ... 기존 코드
|
|
}
|
|
```
|
|
|
|
### 2.3~2.9 useState 제거 패턴
|
|
**변경 전:**
|
|
```typescript
|
|
const [selectedPageId, setSelectedPageId] = useState<number | null>(null);
|
|
```
|
|
|
|
**변경 후:**
|
|
```typescript
|
|
const { selectedPageId, setSelectedPageId } = pageManagement;
|
|
// 또는 구조분해 없이 pageManagement.selectedPageId 사용
|
|
```
|
|
|
|
### 2.10 핸들러 교체 패턴
|
|
**변경 전:**
|
|
```typescript
|
|
const handleAddPage = async () => {
|
|
// 100줄의 핸들러 코드
|
|
};
|
|
```
|
|
|
|
**변경 후:**
|
|
```typescript
|
|
// 삭제하고, pageManagement.handleAddPage 사용
|
|
// 또는 상단에서 구조분해
|
|
const { handleAddPage } = pageManagement;
|
|
```
|
|
|
|
### 2.12 하위 컴포넌트 Props 연결 예시
|
|
```typescript
|
|
<PageDialog
|
|
isOpen={pageManagement.isPageDialogOpen}
|
|
onClose={() => pageManagement.setIsPageDialogOpen(false)}
|
|
onSubmit={pageManagement.handleAddPage}
|
|
pageName={pageManagement.newPageName}
|
|
setPageName={pageManagement.setNewPageName}
|
|
// ...
|
|
/>
|
|
```
|
|
|
|
### Phase 2 완료 기준 (실제 결과)
|
|
- [x] 메인 컴포넌트 줄 수: 2893줄 → 1575줄 (45% 감소) *목표는 90%였으나 렌더링 로직이 많아 45% 달성*
|
|
- [x] 모든 useState가 훅으로 이동 (핵심 상태 ~100개)
|
|
- [x] 모든 핸들러가 훅에서 제공 (~50개 핸들러)
|
|
- [x] 타입 에러: 훅 관련 새 에러 없음 (기존 에러만 존재)
|
|
- [x] 빌드 성공
|
|
- [ ] 기능 동작 정상 (브라우저 테스트 대기)
|
|
|
|
---
|
|
|
|
## 상세 작업 내역
|
|
|
|
### 1. usePageManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- selectedPageId
|
|
- editingPageId
|
|
- editingPageName
|
|
- isPageDialogOpen
|
|
- newPageName
|
|
- newPageItemType
|
|
- editingPathPageId
|
|
- editingAbsolutePath
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddPage
|
|
- handleDuplicatePage
|
|
- handleDeletePageWithTracking
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/usePageManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 2. useSectionManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- editingSectionId
|
|
- editingSectionTitle
|
|
- isSectionDialogOpen
|
|
- newSectionTitle
|
|
- newSectionDescription
|
|
- newSectionType
|
|
- sectionInputMode
|
|
- selectedSectionTemplateId
|
|
- expandedSections
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddSection
|
|
- handleLinkTemplate
|
|
- handleEditSectionTitle
|
|
- handleSaveSectionTitle
|
|
- handleDeleteSectionWithTracking
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useSectionManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 3. useFieldManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- isFieldDialogOpen
|
|
- selectedSectionForField
|
|
- editingFieldId
|
|
- fieldInputMode
|
|
- showMasterFieldList
|
|
- selectedMasterFieldId
|
|
- newFieldName, newFieldKey, newFieldInputType, newFieldRequired
|
|
- newFieldOptions, newFieldDescription
|
|
- textboxColumns, isColumnDialogOpen, editingColumnId, columnName, columnKey
|
|
- newFieldConditionEnabled, newFieldConditionTargetType
|
|
- newFieldConditionFields, newFieldConditionSections
|
|
- tempConditionFieldKey, tempConditionValue
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddField
|
|
- handleEditField
|
|
- handleDeleteFieldWithTracking
|
|
- (useEffect for masterField selection)
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useFieldManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 4. useMasterFieldManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- isMasterFieldDialogOpen
|
|
- editingMasterFieldId
|
|
- newMasterFieldName, newMasterFieldKey, newMasterFieldInputType
|
|
- newMasterFieldRequired, newMasterFieldCategory, newMasterFieldDescription
|
|
- newMasterFieldOptions, newMasterFieldAttributeType
|
|
- newMasterFieldMultiColumn, newMasterFieldColumnCount, newMasterFieldColumnNames
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddMasterField
|
|
- handleEditMasterField
|
|
- handleUpdateMasterField
|
|
- handleDeleteMasterField
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useMasterFieldManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 5. useTemplateManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- isSectionTemplateDialogOpen
|
|
- editingSectionTemplateId
|
|
- newSectionTemplateTitle, newSectionTemplateDescription
|
|
- newSectionTemplateCategory, newSectionTemplateType
|
|
- isLoadTemplateDialogOpen, selectedTemplateId
|
|
- expandedTemplateId
|
|
- isTemplateFieldDialogOpen, currentTemplateId, editingTemplateFieldId
|
|
- templateFieldName, templateFieldKey, templateFieldInputType
|
|
- templateFieldRequired, templateFieldOptions, templateFieldDescription
|
|
- templateFieldMultiColumn, templateFieldColumnCount, templateFieldColumnNames
|
|
- templateFieldInputMode, templateFieldShowMasterFieldList, templateFieldSelectedMasterFieldId
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddSectionTemplate
|
|
- handleEditSectionTemplate
|
|
- handleUpdateSectionTemplate
|
|
- handleDeleteSectionTemplate
|
|
- handleLoadTemplate
|
|
- handleAddTemplateField
|
|
- handleEditTemplateField
|
|
- handleDeleteTemplateField
|
|
- handleAddBOMItemToTemplate
|
|
- handleUpdateBOMItemInTemplate
|
|
- handleDeleteBOMItemFromTemplate
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useTemplateManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 6. useAttributeManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- unitOptions, materialOptions, surfaceTreatmentOptions
|
|
- customAttributeOptions
|
|
- isOptionDialogOpen, editingOptionType
|
|
- newOptionValue, newOptionLabel, newOptionColumnValues
|
|
- newOptionInputType, newOptionRequired, newOptionOptions
|
|
- newOptionPlaceholder, newOptionDefaultValue
|
|
- isColumnManageDialogOpen, managingColumnType
|
|
- attributeColumns
|
|
- newColumnName, newColumnKey, newColumnType, newColumnRequired
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddOption
|
|
- handleDeleteOption
|
|
- (useEffect for attribute sync)
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useAttributeManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
### 7. useTabManagement
|
|
|
|
**포함될 상태:**
|
|
```typescript
|
|
- customTabs
|
|
- activeTab
|
|
- attributeSubTabs, activeAttributeTab
|
|
- isAddTabDialogOpen, isManageTabsDialogOpen
|
|
- newTabLabel, editingTabId, deletingTabId, isDeleteTabDialogOpen
|
|
- isManageAttributeTabsDialogOpen, isAddAttributeTabDialogOpen
|
|
- newAttributeTabLabel, editingAttributeTabId
|
|
- deletingAttributeTabId, isDeleteAttributeTabDialogOpen
|
|
```
|
|
|
|
**포함될 핸들러:**
|
|
```typescript
|
|
- handleAddTab
|
|
- handleEditTab
|
|
- handleDeleteTab
|
|
- handleAddAttributeTab
|
|
- (useEffect for attributeSubTabs sync)
|
|
```
|
|
|
|
**작업 체크리스트:**
|
|
- [ ] hooks/useTabManagement.ts 파일 생성
|
|
- [ ] 상태 이동
|
|
- [ ] 핸들러 이동
|
|
- [ ] 메인 컴포넌트에서 훅 사용으로 변경
|
|
- [ ] 기능 테스트
|
|
|
|
---
|
|
|
|
## 작업 로그
|
|
|
|
### 2025-11-26
|
|
- 체크리스트 문서 생성
|
|
- 분석 완료: 총 7개 훅으로 분리 예정
|
|
- ✅ usePageManagement.ts 생성 완료 (타입 에러 없음)
|
|
- ✅ useSectionManagement.ts 생성 완료 (타입 에러 없음)
|
|
- ✅ useFieldManagement.ts 생성 완료 (타입 에러 수정 완료)
|
|
- ✅ useMasterFieldManagement.ts 생성 완료 (타입 에러 수정: 'ㄹ' 오타 제거)
|
|
- ✅ useTemplateManagement.ts 생성 완료 (타입 에러 없음, ~350줄)
|
|
- ✅ useAttributeManagement.ts 생성 완료 (타입 에러 없음, ~250줄)
|
|
- ✅ useTabManagement.ts 생성 완료 (타입 에러 없음, ~330줄)
|
|
- 🎉 **Phase 1 완료!** 모든 7개 훅 생성 완료
|
|
- 📁 hooks/index.ts에 모든 훅 export 완료
|
|
|
|
### Phase 2 완료 (2025-11-26 추가)
|
|
- ✅ 메인 컴포넌트에서 훅 import 및 연결 완료
|
|
- ✅ props drilling 정리 - wrapper 함수 패턴 적용
|
|
- ✅ 렌더링 로직만 남기기 - 2893줄 → 1575줄 (45% 감소)
|
|
- ✅ 빌드 테스트 성공
|
|
- ⏳ 기능 테스트 - 브라우저에서 확인 필요
|
|
|
|
### 주요 기술 결정 (Phase 2)
|
|
1. **Wrapper 함수 패턴**: 훅 함수에 selectedPage 바인딩 필요한 경우 wrapper 사용
|
|
- `handleAddSectionWrapper`, `handleLinkTemplateWrapper` 등
|
|
2. **타입 호환성**: setter 함수 타입 불일치는 `as any`로 우회
|
|
- `setNewSectionTypeWrapper`, `setNewPageItemTypeWrapper`
|
|
3. **기존 타입 에러**: `default_properties` 등 기존 타입 정의 문제는 Phase 2 범위 외
|
|
|
|
### 다음 단계
|
|
- [ ] 기능 테스트 (브라우저)
|
|
- [ ] 추가 최적화 (선택)
|
|
|
|
---
|
|
|
|
## 참고 사항
|
|
|
|
### 훅 간 의존성
|
|
```
|
|
usePageManagement (독립)
|
|
↓
|
|
useSectionManagement (selectedPageId 필요)
|
|
↓
|
|
useFieldManagement (selectedSectionId 필요)
|
|
|
|
useMasterFieldManagement (독립)
|
|
useTemplateManagement (독립, but masterFields 참조)
|
|
useAttributeManagement (독립, but masterFields와 연동)
|
|
useTabManagement (독립)
|
|
```
|
|
|
|
### 파일 구조 (목표)
|
|
```
|
|
ItemMasterDataManagement/
|
|
├── hooks/
|
|
│ ├── index.ts
|
|
│ ├── usePageManagement.ts
|
|
│ ├── useSectionManagement.ts
|
|
│ ├── useFieldManagement.ts
|
|
│ ├── useMasterFieldManagement.ts
|
|
│ ├── useTemplateManagement.ts
|
|
│ ├── useAttributeManagement.ts
|
|
│ └── useTabManagement.ts
|
|
├── tabs/
|
|
├── dialogs/
|
|
├── components/
|
|
├── utils/
|
|
├── types.ts
|
|
└── index.tsx (메인 컴포넌트, ~200줄 목표)
|
|
```
|
|
|
|
---
|
|
|
|
## 관련 파일
|
|
|
|
### 프론트엔드
|
|
- `src/components/items/ItemMasterDataManagement.tsx` - 메인 컴포넌트 (리팩토링 대상)
|
|
- `src/components/items/ItemMasterDataManagement/hooks/index.ts` - 훅 export
|
|
- `src/components/items/ItemMasterDataManagement/hooks/usePageManagement.ts` - 페이지 관리 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useSectionManagement.ts` - 섹션 관리 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useFieldManagement.ts` - 필드 관리 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useMasterFieldManagement.ts` - 마스터 필드 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useTemplateManagement.ts` - 템플릿 관리 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useAttributeManagement.ts` - 속성 관리 훅
|
|
- `src/components/items/ItemMasterDataManagement/hooks/useTabManagement.ts` - 탭 관리 훅
|
|
- `src/contexts/ItemMasterContext.tsx` - Context Provider
|
|
|
|
### 참조 문서
|
|
- `claudedocs/item-master/[NEXT-2025-11-26] item-master-api-pending-tasks.md` - API 연동 작업 체크리스트 |