# 품목 등록 동적 페이지 재구현

## 작업 일자: 2025-12-02

## 문서 버전
| 버전 | 날짜 | 작성자 | 내용 |
|------|------|--------|------|
| 1.0 | 2025-12-02 | Claude | 롤백 후 재구현 시작 |
| 1.1 | 2025-12-02 | Claude | Phase 1-8 완료 |

---

## 배경

- 이전 작업에서 DynamicItemForm 구현이 디자인 누락으로 롤백됨
- 기존 ItemForm (목업 데이터 기반)의 디자인을 100% 유지하면서 동적 렌더링 구현 필요

---

## 핵심 원칙

1. **디자인 100% 동일**: 기존 ItemForm과 완벽히 동일한 UI/UX
2. **밸리데이션 동일**: 에러 메시지 위치, 스타일 동일
3. **버튼/아이콘 동일**: 모든 버튼, 아이콘 위치 및 스타일 동일
4. **화면 등장 순서 동일**: 섹션 표시 순서, 조건부 렌더링 동일
5. **동적 구성**: 품목기준관리 API 기반으로 필드/섹션 동적 생성

---

## 체크리스트

### Phase 1: 현재 상태 분석
- [x] 기존 ItemForm 디자인 완전 분석
  - [x] 품목 유형 선택 UI
  - [x] 기본 정보 섹션 레이아웃
  - [x] BOM 섹션 레이아웃
  - [x] 전개도 섹션 레이아웃
  - [x] 버튼 위치 및 스타일
  - [x] 밸리데이션 에러 표시 방식
- [x] 품목관리 API 응답 구조 확인 (init, pages.getStructure)

### Phase 2: DynamicItemForm 폴더 생성
- [x] 기본 폴더 구조 생성
  ```
  src/components/items/DynamicItemForm/
  ├── index.tsx
  ├── types.ts
  ├── hooks/
  │   ├── index.ts
  │   ├── useFormStructure.ts
  │   └── useDynamicFormState.ts
  └── fields/
      ├── index.ts
      ├── TextField.tsx
      ├── DropdownField.tsx
      ├── NumberField.tsx
      ├── DateField.tsx
      ├── TextareaField.tsx
      ├── CheckboxField.tsx
      └── DynamicFieldRenderer.tsx
  ```

### Phase 3: 타입 정의
- [x] `types.ts` - 동적 폼 관련 타입 정의
- [x] API 응답 타입과 프론트엔드 타입 매핑
- [x] SimpleUnitOption 타입 추가

### Phase 4: 훅 구현
- [x] `useFormStructure.ts` - API에서 폼 구조 로드
- [x] `useDynamicFormState.ts` - 동적 상태 관리

### Phase 5: 필드 컴포넌트 구현 (디자인 100% 동일)
- [x] `TextField.tsx` - 기존 Input 스타일 동일
- [x] `DropdownField.tsx` - 기존 Select 스타일 동일
- [x] `NumberField.tsx` - 기존 숫자 입력 스타일 동일
- [x] `DateField.tsx` - 기존 날짜 선택 스타일 동일
- [x] `TextareaField.tsx` - 기존 텍스트영역 스타일 동일
- [x] `CheckboxField.tsx` - 기존 체크박스 스타일 동일
- [x] `DynamicFieldRenderer.tsx` - 필드 타입별 렌더러

### Phase 6: 메인 폼 컴포넌트
- [x] `index.tsx` - 메인 동적 폼 컴포넌트
  - [x] 기존 ItemForm과 동일한 레이아웃
  - [x] 동일한 헤더 스타일 (FormHeader 인라인)
  - [x] 동일한 ValidationAlert 스타일
  - [x] 동일한 섹션 Card 스타일
  - [x] 동일한 버튼 배치

### Phase 7: 기존 ItemForm 주석처리 및 전환
- [x] `/items/create/page.tsx` - DynamicItemForm으로 전환
- [x] 기존 ItemForm import 주석처리
- [x] 전환 테스트 준비

### Phase 8: API 연동
- [x] POST /api/proxy/items 연동 구현
- [x] 품목 등록 후 목록 페이지 이동
- [x] 에러 처리

### Phase 9: 테스트
- [x] TypeScript 빌드 검증 완료 (DynamicItemForm 에러 없음)
- [ ] 품목 유형별 등록 테스트 (FG, PT, RM, SM, CS)
- [ ] 밸리데이션 테스트
- [ ] API 연동 테스트
- [ ] 품목 목록에 등록된 데이터 표시 확인

---

## 테스트 가이드

### 사전 조건
1. 백엔드 서버 실행 (sam-api)
2. 프론트엔드 개발 서버 실행 (`npm run dev`)
3. 품목기준관리에서 페이지/섹션/필드 설정 완료

### 테스트 항목

#### 1. 품목 등록 페이지 접근
```
URL: http://localhost:3000/items/create
```
- [ ] 페이지 로딩 시 "폼 구조를 불러오는 중..." 표시
- [ ] 품목 유형 선택 전 안내 메시지 표시

#### 2. 품목 유형 선택
- [ ] FG (완제품) 선택 시 해당 폼 구조 로드
- [ ] PT (부품) 선택 시 해당 폼 구조 로드
- [ ] RM (원자재) 선택 시 해당 폼 구조 로드
- [ ] SM (부자재) 선택 시 해당 폼 구조 로드
- [ ] CS (소모품) 선택 시 해당 폼 구조 로드

#### 3. 필드 렌더링
- [ ] 텍스트 필드 정상 렌더링
- [ ] 숫자 필드 정상 렌더링
- [ ] 드롭다운 필드 정상 렌더링 (단위 옵션 포함)
- [ ] 체크박스 필드 정상 렌더링
- [ ] 날짜 필드 정상 렌더링
- [ ] 텍스트영역 필드 정상 렌더링

#### 4. 밸리데이션
- [ ] 필수 필드 빈값 시 에러 메시지 표시
- [ ] ValidationAlert에 에러 목록 표시
- [ ] 에러 필드에 빨간 테두리 표시

#### 5. API 연동
- [ ] 저장 버튼 클릭 시 POST /api/proxy/items 호출
- [ ] 저장 성공 시 /items 페이지로 이동
- [ ] 저장 실패 시 에러 메시지 표시

#### 6. 디자인 검증
- [ ] 기존 ItemForm과 레이아웃 동일
- [ ] 헤더 스타일 동일 (아이콘, 버튼 위치)
- [ ] 섹션 Card 스타일 동일
- [ ] 필드 라벨/에러 스타일 동일

---

## 생성된 파일

### DynamicItemForm 컴포넌트
- `src/components/items/DynamicItemForm/index.tsx` - 메인 폼 (388줄)
- `src/components/items/DynamicItemForm/types.ts` - 타입 정의
- `src/components/items/DynamicItemForm/hooks/index.ts` - 훅 export
- `src/components/items/DynamicItemForm/hooks/useFormStructure.ts` - 폼 구조 로드
- `src/components/items/DynamicItemForm/hooks/useDynamicFormState.ts` - 상태 관리
- `src/components/items/DynamicItemForm/fields/index.ts` - 필드 export
- `src/components/items/DynamicItemForm/fields/TextField.tsx`
- `src/components/items/DynamicItemForm/fields/NumberField.tsx`
- `src/components/items/DynamicItemForm/fields/DropdownField.tsx`
- `src/components/items/DynamicItemForm/fields/CheckboxField.tsx`
- `src/components/items/DynamicItemForm/fields/DateField.tsx`
- `src/components/items/DynamicItemForm/fields/TextareaField.tsx`
- `src/components/items/DynamicItemForm/fields/DynamicFieldRenderer.tsx`

### 수정된 파일
- `src/app/[locale]/(protected)/items/create/page.tsx` - DynamicItemForm 사용으로 변경

---

## API 흐름

```
1. useFormStructure(itemType)
   └─> itemMasterApi.init()
       └─> /api/proxy/item-master/init
           └─> pages, sections, fields, unitOptions 반환

2. itemMasterApi.pages.getStructure(pageId)
   └─> /api/proxy/item-master/pages/{id}/structure
       └─> page, sections, directFields 반환

3. 품목 등록
   └─> POST /api/proxy/items
       └─> body: DynamicFormData
```

---

## 디자인 매칭 요소

### 레이아웃
- `form` > `space-y-6`
- `Card` > `CardHeader` > `CardTitle` > `CardContent`
- `grid grid-cols-1 md:grid-cols-2 gap-4`

### 필드 스타일
- Label with required marker: `<span className="text-red-500"> *</span>`
- Error state: `className={error ? 'border-red-500' : ''}`
- Error message: `<p className="text-xs text-red-500 mt-1">{error}</p>`
- Helper text: `<p className="text-xs text-muted-foreground mt-1">* ...</p>`

### 버튼 스타일
- Cancel: `variant="outline" size="sm"`
- Submit: `size="sm" disabled={!selectedItemType || isSubmitting}`
- Icons: `X`, `Save` from lucide-react

---

## 변경 이력

| 날짜 | 작업 내용 |
|------|----------|
| 2025-12-02 | 문서 생성, Phase 1 시작 |
| 2025-12-02 | Phase 1-8 완료: DynamicItemForm 전체 구현 |