Files
sam-react-prod/claudedocs/item-master/[PLAN-2025-12-24] hook-extraction-plan.md
byeongcheolryu a823ae0777 refactor: 품목기준관리 설정 페이지 훅/컴포넌트 분리
- Phase 1: 신규 훅 4개 생성
  - useInitialDataLoading.ts (초기 데이터 로딩)
  - useImportManagement.ts (섹션/필드 Import)
  - useReorderManagement.ts (드래그앤드롭 순서 변경)
  - useDeleteManagement.ts (삭제/언링크 핸들러)
- Phase 2: UI 컴포넌트 2개 생성
  - AttributeTabContent.tsx (속성 탭 콘텐츠)
  - ItemMasterDialogs.tsx (다이얼로그 통합)
- 메인 컴포넌트 1,799줄 → ~1,478줄 (약 320줄 감소)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 14:35:29 +09:00

7.1 KiB

ItemMasterDataManagement 훅 분리 계획서

날짜: 2025-12-24 대상 파일: src/components/items/ItemMasterDataManagement.tsx (1,799줄) 목표: ~500줄로 축소


현재 구조 분석

파일 구성

구간 줄 수 내용
Import 1-61 React, UI, 다이얼로그, 훅 import
상수 63-91 ITEM_TYPE_OPTIONS, INPUT_TYPE_OPTIONS
Context 구조분해 94-124 useItemMaster에서 20+개 함수/상태
훅 초기화 127-286 7개 훅 + 150+개 상태 구조분해
useMemo 298-372 sectionsAsTemplates 변환
useState/useEffect 374-504 로딩, 에러, 모바일, Import 상태
핸들러 519-743 Import, Clone, Delete, Reorder
UI 렌더링 746-1799 Tabs + 13개 다이얼로그

기존 훅 (7개)

src/components/items/ItemMasterDataManagement/hooks/
├── usePageManagement.ts      - 페이지 CRUD
├── useSectionManagement.ts   - 섹션 CRUD
├── useFieldManagement.ts     - 필드 CRUD
├── useMasterFieldManagement.ts - 마스터 필드 CRUD
├── useTemplateManagement.ts  - 템플릿 관리
├── useAttributeManagement.ts - 속성 관리
└── useTabManagement.ts       - 탭 관리

분리 계획

Phase 1: 신규 훅 생성 (4개)

1. useInitialDataLoading (~100줄 분리)

분리 대상:

  • 초기 데이터 로딩 useEffect (387-492줄)
  • 로딩/에러 상태 (isInitialLoading, error)
  • transformers 호출 로직

반환값:

{
  isInitialLoading: boolean;
  error: string | null;
  reload: () => Promise<void>;
}

2. useImportManagement (~80줄 분리)

분리 대상:

  • Import 다이얼로그 상태 (512-516줄)
  • handleImportSection (519-530줄)
  • handleImportField (540-559줄)
  • handleCloneSection (562-570줄)

반환값:

{
  // 상태
  isImportSectionDialogOpen, setIsImportSectionDialogOpen,
  isImportFieldDialogOpen, setIsImportFieldDialogOpen,
  selectedImportSectionId, setSelectedImportSectionId,
  selectedImportFieldId, setSelectedImportFieldId,
  importFieldTargetSectionId, setImportFieldTargetSectionId,
  // 핸들러
  handleImportSection,
  handleImportField,
  handleCloneSection,
}

3. useReorderManagement (~60줄 분리)

분리 대상:

  • moveSection (650-668줄)
  • moveField (672-702줄)

반환값:

{
  moveSection: (dragIndex: number, hoverIndex: number) => Promise<void>;
  moveField: (sectionId: number, dragFieldId: number, hoverFieldId: number) => Promise<void>;
}

4. useDeleteManagement (~50줄 분리)

분리 대상:

  • handleDeletePageWithTracking (582-588줄)
  • handleDeleteSectionWithTracking (591-597줄)
  • handleUnlinkFieldWithTracking (601-609줄)
  • handleResetAllData (705-743줄)

반환값:

{
  handleDeletePage: (pageId: number) => void;
  handleDeleteSection: (pageId: number, sectionId: number) => void;
  handleUnlinkField: (pageId: string, sectionId: string, fieldId: string) => Promise<void>;
  handleResetAllData: () => void;
}

Phase 2: UI 컴포넌트 분리 (2개)

1. AttributeTabContent (~400줄 분리)

분리 대상:

  • 속성 탭 내용 (807-1331줄)
  • 단위/재질/표면처리 반복 UI 통합

Props:

interface AttributeTabContentProps {
  activeAttributeTab: string;
  attributeSubTabs: AttributeSubTab[];
  unitOptions: UnitOption[];
  materialOptions: MaterialOption[];
  surfaceTreatmentOptions: SurfaceTreatmentOption[];
  customAttributeOptions: Record<string, Option[]>;
  attributeColumns: Record<string, Column[]>;
  itemMasterFields: ItemMasterField[];
  // 핸들러들...
}

2. ItemMasterDialogs (~280줄 분리)

분리 대상:

  • 13개 다이얼로그 렌더링 (1442-1797줄)

Props:

interface ItemMasterDialogsProps {
  // 모든 다이얼로그 관련 props
}

Phase 3: 코드 정리

  1. 래퍼 함수 제거 (~30줄)

    • handleAddSectionWrapper 등을 훅 내부로 이동
    • selectedPage를 훅 파라미터로 전달
  2. unused 변수 정리

    • _mounted, _isLoading 등 제거
  3. Import 최적화

    • 사용하지 않는 import 제거

예상 결과

줄 수 변화

항목 현재 분리 후
Import 61 40
상수 28 28
훅 사용 160 60
useMemo 75 75
상태/Effect 130 20
핸들러 225 30
UI 렌더링 1,053 300
합계 1,799 ~550

새 파일 구조

src/components/items/ItemMasterDataManagement/
├── ItemMasterDataManagement.tsx  ← ~550줄 (메인)
├── hooks/
│   ├── index.ts
│   ├── usePageManagement.ts      (기존)
│   ├── useSectionManagement.ts   (기존)
│   ├── useFieldManagement.ts     (기존)
│   ├── useMasterFieldManagement.ts (기존)
│   ├── useTemplateManagement.ts  (기존)
│   ├── useAttributeManagement.ts (기존)
│   ├── useTabManagement.ts       (기존)
│   ├── useInitialDataLoading.ts  ← NEW
│   ├── useImportManagement.ts    ← NEW
│   ├── useReorderManagement.ts   ← NEW
│   └── useDeleteManagement.ts    ← NEW
├── components/
│   ├── AttributeTabContent.tsx   ← NEW
│   └── ItemMasterDialogs.tsx     ← NEW
├── dialogs/ (기존 13개)
├── tabs/ (기존 4개)
├── services/ (기존 6개)
└── utils/ (기존 1개)

작업 순서

Step 1: useInitialDataLoading 훅 생성

  • 훅 파일 생성
  • 로딩/에러 상태 이동
  • useEffect 이동
  • 메인 컴포넌트에서 사용

Step 2: useImportManagement 훅 생성

  • 훅 파일 생성
  • Import 상태 이동
  • 핸들러 이동
  • 메인 컴포넌트에서 사용

Step 3: useReorderManagement 훅 생성

  • 훅 파일 생성
  • moveSection, moveField 이동
  • 메인 컴포넌트에서 사용

Step 4: useDeleteManagement 훅 생성

  • 훅 파일 생성
  • Delete/Unlink 핸들러 이동
  • 메인 컴포넌트에서 사용

Step 5: AttributeTabContent 컴포넌트 분리

  • 컴포넌트 파일 생성
  • 속성 탭 UI 이동
  • 반복 코드 통합

Step 6: ItemMasterDialogs 컴포넌트 분리

  • 컴포넌트 파일 생성
  • 13개 다이얼로그 이동

Step 7: 정리 및 테스트

  • 래퍼 함수 정리
  • unused 코드 제거
  • 빌드 확인
  • 수동 테스트

리스크 및 주의사항

  1. Context 의존성: 훅들이 useItemMaster Context에 의존

    • 해결: 필요한 함수만 훅 파라미터로 전달
  2. 상태 공유: 여러 훅에서 동일 상태 사용

    • 해결: 공통 상태는 메인 컴포넌트에서 관리
  3. 타입 호환성: 기존 훅의 setter 타입 문제

    • 해결: as any 임시 사용 또는 타입 수정
  4. 테스트: 페이지 기능이 많아 수동 테스트 필요

    • 해결: 체크리스트 작성하여 순차 테스트

다음 단계

  1. 이 계획서 확인 후 작업 시작
  2. Step 1부터 순차 진행
  3. 각 Step 완료 후 빌드 확인
  4. 최종 수동 테스트