# 페이지 빌더 (Page Builder) 구현 문서

> **작성일**: 2026-01-22
> **상태**: 개발 중 (테스트 버전)
> **경로**: `/dev/page-builder`
> **Git 상태**: `.gitignore`에 등록되어 버전 관리 제외 (테스트용)

---

## 1. 개요

### 1.1 목적
품목기준관리(Item Master Data Management)의 폼 구조를 **시각적으로(WYSIWYG)** 편집할 수 있는 Framer 스타일의 페이지 빌더입니다.

### 1.2 핵심 기능
- 드래그 앤 드롭으로 섹션/필드 배치
- 실시간 미리보기 (데스크탑/태블릿/모바일)
- **API 연동**: 품목기준관리 API와 동기화
- 조건부 표시 설정 (필드 값에 따른 섹션/필드 표시/숨김)
- Undo/Redo 지원
- JSON 내보내기/가져오기

### 1.3 접근 방법
```
URL: http://localhost:3000/dev/page-builder
```

---

## 2. 파일 구조

```
src/app/[locale]/(protected)/dev/page-builder/
├── page.tsx                    # 페이지 진입점
├── PageBuilderClient.tsx       # 메인 클라이언트 컴포넌트
├── PLAN.md                     # 초기 기획 문서
│
├── components/
│   ├── index.ts                # 컴포넌트 배럴 export
│   ├── ComponentPalette.tsx    # 좌측 컴포넌트 팔레트 (섹션/필드 드래그)
│   ├── BuilderCanvas.tsx       # 중앙 캔버스 (드롭 영역, 미리보기)
│   ├── PropertyPanel.tsx       # 우측 속성 패널 (섹션/필드 편집)
│   ├── PageSelector.tsx        # 페이지 목록 관리
│   └── ConditionEditor.tsx     # 조건부 표시 설정 UI
│
├── hooks/
│   ├── usePageBuilder.ts       # 섹션/필드 CRUD, 선택 상태 관리
│   ├── usePageManager.ts       # 페이지 CRUD, API 연동, 저장/로드
│   ├── useHistory.ts           # Undo/Redo 히스토리 관리
│   └── useItemMasterSync.ts    # (미사용) 초기 API 동기화 시도
│
├── types/
│   ├── index.ts                # 타입 배럴 export
│   ├── builder.types.ts        # BuilderPage, BuilderSection, BuilderField 등
│   └── constants.ts            # 필드 타입, 섹션 타입 옵션 상수
│
└── utils/
    ├── index.ts                # 유틸 배럴 export
    └── transformers.ts         # API ↔ Builder 타입 변환 함수
```

---

## 3. 핵심 타입 정의

### 3.1 BuilderPage
```typescript
interface BuilderPage {
  id: string;
  name: string;           // 페이지 이름 (예: "소모품 등록")
  itemType: ItemType;     // 품목 유형 (FG, PT, SM, RM, CS)
  sections: BuilderSection[];
  createdAt: string;
  updatedAt: string;
}
```

### 3.2 BuilderSection
```typescript
interface BuilderSection {
  id: string;
  title: string;
  description?: string;
  sectionType: SectionType;   // BASIC, BOM, CERTIFICATION 등
  columns: 1 | 2 | 3;         // 레이아웃 열 수
  isCollapsible?: boolean;
  isDefaultOpen?: boolean;
  fields: BuilderField[];
  displayCondition?: DisplayCondition;  // 조건부 표시
  order: number;
}
```

### 3.3 BuilderField
```typescript
interface BuilderField {
  id: string;
  name: string;               // 필드 라벨
  fieldKey: string;           // API 키 (예: "item_name")
  inputType: FieldInputType;  // textbox, number, dropdown 등
  required: boolean;
  placeholder?: string;
  defaultValue?: string;
  options?: DropdownOption[]; // 드롭다운용
  colSpan?: 1 | 2 | 3;
  description?: string;
  displayCondition?: DisplayCondition;
  validationRules?: ValidationRule[];
  order: number;
}
```

### 3.4 DisplayCondition (조건부 표시)
```typescript
interface DisplayCondition {
  enabled: boolean;
  logic: 'AND' | 'OR';
  conditions: FieldCondition[];
}

interface FieldCondition {
  fieldKey: string;
  operator: 'equals' | 'not_equals' | 'contains' | 'not_contains';
  expectedValue: string;
}
```

---

## 4. API 연동

### 4.1 사용하는 API
품목기준관리와 **동일한 API** 사용:
```typescript
// src/lib/api/item-master.ts
itemMasterApi.init()                        // 전체 페이지/섹션/필드 조회
itemMasterApi.sections.create(pageId, data) // 섹션 생성
itemMasterApi.sections.update(id, data)     // 섹션 수정
itemMasterApi.sections.delete(id)           // 섹션 삭제
itemMasterApi.fields.create(sectionId, data)// 필드 생성
itemMasterApi.fields.update(id, data)       // 필드 수정
itemMasterApi.fields.delete(id)             // 필드 삭제
```

### 4.2 API 모드 토글
- **API 모드 ON**: 백엔드 API에서 데이터 로드/저장
- **API 모드 OFF**: localStorage에서 로드/저장 (오프라인 테스트용)
- 설정은 localStorage에 저장되어 새로고침 후에도 유지

### 4.3 동기화 로직 (usePageManager.ts)
```typescript
const syncPageToAPI = async (page: BuilderPage) => {
  // 1. 원본 데이터와 현재 데이터 비교
  // 2. 삭제된 섹션/필드 → API DELETE 호출
  // 3. 새로 추가된 섹션/필드 → API CREATE 호출
  // 4. 수정된 섹션/필드 → API UPDATE 호출
  // 5. 완료 후 API에서 최신 데이터 다시 로드
};
```

### 4.4 타입 변환 (transformers.ts)
```typescript
// API → Builder 변환
transformPagesToBuilder(apiData): BuilderPage[]

// Builder → API 변환
transformSectionToAPI(section): APISectionCreateData
transformFieldToAPI(field): APIFieldCreateData

// ID 구분 (API ID는 숫자, 로컬 ID는 문자열)
isApiId(id: string): boolean  // "123" → true, "section_abc123" → false
```

---

## 5. 주요 컴포넌트 설명

### 5.1 PageBuilderClient.tsx
메인 컴포넌트로 전체 레이아웃 구성:
- 상단: 툴바 (미리보기 모드, Undo/Redo, 저장 버튼들)
- 좌측: PageSelector + ComponentPalette
- 중앙: BuilderCanvas
- 우측: PropertyPanel

주요 상태:
```typescript
const [isAPIMode, setIsAPIMode] = useState(true);     // API 모드
const [previewMode, setPreviewMode] = useState<'desktop' | 'tablet' | 'mobile'>('desktop');
```

### 5.2 PageSelector.tsx
페이지 목록 관리:
- 페이지 선택/생성/삭제/복제/이름변경
- 호버 시 액션 버튼 표시 (배경색 포함으로 긴 제목도 가리지 않음)

### 5.3 BuilderCanvas.tsx
드래그 앤 드롭 캔버스:
- 섹션 드롭 → 새 섹션 추가
- 필드 드롭 → 해당 섹션에 필드 추가
- 요소 클릭 → 선택 (PropertyPanel에서 편집)

### 5.4 PropertyPanel.tsx
선택된 요소의 속성 편집:
- 섹션: 제목, 설명, 타입, 열 수, 접기 설정, 조건부 표시
- 필드: 이름, 키, 타입, 필수여부, 옵션, 조건부 표시

### 5.5 ConditionEditor.tsx
조건부 표시 설정 UI:
- 다른 필드 값에 따라 현재 섹션/필드 표시/숨김
- AND/OR 논리 연산 지원
- 여러 조건 추가 가능

---

## 6. 사용 방법

### 6.1 기본 워크플로우
1. `/dev/page-builder` 접속
2. **API 모드 ON** 확인 (우측 상단 토글)
3. 좌측에서 페이지 선택 (소모품, 원자재 등)
4. 컴포넌트 팔레트에서 섹션/필드를 캔버스로 드래그
5. 캔버스에서 요소 클릭 → 우측 패널에서 속성 편집
6. **"API 저장"** 버튼 클릭 → 백엔드에 저장
7. 품목기준관리 페이지에서 변경사항 확인

### 6.2 저장 버튼 종류
| 버튼 | 기능 |
|------|------|
| API 저장 (초록색) | 현재 페이지를 백엔드 API에 저장 |
| 현재 페이지 저장 (JSON) | 현재 페이지를 JSON 파일로 다운로드 |
| 전체 저장 | 모든 페이지를 JSON 파일로 다운로드 |
| 가져오기 | JSON 파일에서 페이지 데이터 로드 |

### 6.3 Undo/Redo
- **실행 취소**: 마지막 작업 취소
- **다시 실행**: 취소한 작업 복원
- 히스토리는 세션 동안만 유지

---

## 7. 테스트 완료 항목

### 7.1 API 연동 테스트 (2026-01-22)
| 테스트 | 결과 |
|--------|------|
| 페이지 빌더에서 섹션 제목 수정 | ✅ "기본정보" → "기본정보 (빌더테스트)" |
| API 저장 버튼 클릭 | ✅ `PUT /api/proxy/item-master/sections/92` (200 OK) |
| 품목기준관리 페이지 반영 확인 | ✅ 변경된 제목 표시 확인 |

### 7.2 UI 수정 (2026-01-22)
- 페이지 목록 호버 버튼에 배경색 추가 (긴 제목 가림 방지)

---

## 8. 알려진 이슈 / TODO

### 8.1 현재 이슈
- [ ] 새 섹션/필드 생성 후 order 값 자동 계산 필요
- [ ] BOM 섹션 타입 특수 처리 (자재명세표)
- [ ] 드래그 앤 드롭 순서 변경 시 API order 업데이트

### 8.2 향후 개선 사항
- [ ] 실시간 미리보기에서 실제 폼 렌더링 (DynamicItemForm 연동)
- [ ] 필드 유효성 검사 규칙 편집 UI
- [ ] 섹션/필드 복사-붙여넣기
- [ ] 다중 선택 및 일괄 편집
- [ ] 변경사항 diff 뷰어

### 8.3 Git 관련
- 현재 `.gitignore`에 등록되어 있음: `src/app/**/dev/page-builder/`
- 정식 배포 시 gitignore에서 제거 필요

---

## 9. 관련 파일

### 9.1 품목기준관리 (연동 대상)
```
src/app/[locale]/(protected)/master-data/item-master-data-management/page.tsx
src/components/items/ItemMasterDataManagement/
src/lib/api/item-master.ts
```

### 9.2 동적 품목 폼 (렌더링 대상)
```
src/components/items/DynamicItemForm/
```

---

## 10. 참고 문서

- 초기 기획: `src/app/[locale]/(protected)/dev/page-builder/PLAN.md`
- API 문서: `claudedocs/api/item-master-api.md` (있다면)

---

*마지막 업데이트: 2026-01-22*
