# WACE 화면 시스템 - DB 스키마 & 컴포넌트 설정 전체 레퍼런스

> **최종 업데이트**: 2026-03-16
> **용도**: AI 챗봇이 화면 생성 시 참조하는 DB 스키마, 컴포넌트 전체 설정 사전
> **관련 문서**: `v2-component-usage-guide.md` (SQL 템플릿, 실행 예시)

---

## 1. 시스템 아키텍처

### 렌더링 파이프라인

```
[DB] screen_definitions + screen_layouts_v2
  → [Backend API] GET /api/screens/:screenId
  → [layoutV2Converter] V2 JSON → Legacy 변환 (기본값 + overrides 병합)
  → [ResponsiveGridRenderer] → DynamicComponentRenderer
  → [ComponentRegistry] → 실제 React 컴포넌트
```

### 테이블 관계도

```
비즈니스 테이블 ←── table_labels (라벨)
                ←── table_type_columns (컬럼 타입, company_code='*')
                ←── column_labels (한글 라벨)

screen_definitions ←── screen_layouts_v2 (layout_data JSON)
menu_info (메뉴 트리, menu_url → /screen/{screen_code})

[선택] dataflow_diagrams (비즈니스 로직)
[선택] numbering_rules + numbering_rule_parts (채번)
[선택] table_column_category_values (카테고리)
```

---

## 2. DB 테이블 스키마

### 2.1 비즈니스 테이블 필수 구조

> **[최우선 규칙] 비즈니스 테이블에 NOT NULL / UNIQUE 제약조건 절대 금지!**
>
> 멀티테넌시 환경에서 회사별로 필수값/유니크 규칙이 다를 수 있으므로,
> 제약조건은 DB 레벨이 아닌 **`table_type_columns`의 메타데이터(`is_nullable`, `is_unique`)로 논리적 제어**한다.
> DB에 직접 NOT NULL/UNIQUE/CHECK/FOREIGN KEY를 걸면 멀티테넌시가 깨진다.
>
> **허용**: `id` PRIMARY KEY, `DEFAULT` 값만 DB 레벨 설정
> **금지**: 비즈니스 컬럼에 `NOT NULL`, `UNIQUE`, `CHECK`, `FOREIGN KEY`

```sql
CREATE TABLE "{테이블명}" (
  "id" varchar(500) PRIMARY KEY DEFAULT gen_random_uuid()::text,
  "created_date" timestamp DEFAULT now(),
  "updated_date" timestamp DEFAULT now(),
  "writer" varchar(500) DEFAULT NULL,
  "company_code" varchar(500),
  -- 모든 비즈니스 컬럼은 varchar(500), NOT NULL/UNIQUE 제약조건 금지
);
```

### 2.2 table_labels

| 컬럼 | 타입 | 설명 |
|------|------|------|
| table_name | varchar PK | 테이블명 |
| table_label | varchar | 한글 라벨 |
| description | text | 설명 |
| use_log_table | varchar(1) | 'Y'/'N' |

### 2.3 table_type_columns

| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | serial PK | 자동 증가 |
| table_name | varchar | UNIQUE(+column_name+company_code) |
| column_name | varchar | 컬럼명 |
| company_code | varchar | `'*'` = 전체 공통 |
| input_type | varchar | text/number/date/code/entity/select/checkbox/radio/textarea/category/numbering |
| detail_settings | text | JSON (code/entity/select 상세) |
| is_nullable | varchar | `'Y'`/`'N'` (논리적 필수값 제어) |
| display_order | integer | -5~-1: 기본, 0~: 비즈니스 |
| column_label | varchar | 컬럼 한글 라벨 |
| description | text | 컬럼 설명 |
| is_visible | boolean | 화면 표시 여부 (기본 true) |
| code_category | varchar | input_type=code일 때 코드 카테고리 |
| code_value | varchar | 코드 값 |
| reference_table | varchar | input_type=entity일 때 참조 테이블 |
| reference_column | varchar | 참조 컬럼 |
| display_column | varchar | 참조 표시 컬럼 |
| is_unique | varchar | `'Y'`/`'N'` (논리적 유니크 제어) |
| category_ref | varchar | 카테고리 참조 |

### 2.4 screen_definitions

| 컬럼 | 타입 | 설명 |
|------|------|------|
| screen_id | serial PK | 자동 증가 |
| screen_name | varchar NOT NULL | 화면명 |
| screen_code | varchar | **조건부 UNIQUE** (`WHERE is_active <> 'D'`) |
| table_name | varchar | 메인 테이블명 |
| company_code | varchar NOT NULL | 회사 코드 |
| description | text | 화면 설명 |
| is_active | char(1) | `'Y'`/`'N'`/`'D'` (D=삭제) |
| layout_metadata | jsonb | 레이아웃 메타데이터 |
| created_date | timestamp | 생성일시 |
| created_by | varchar | 생성자 |
| updated_date | timestamp | 수정일시 |
| updated_by | varchar | 수정자 |
| deleted_date | timestamp | 삭제일시 |
| deleted_by | varchar | 삭제자 |
| delete_reason | text | 삭제 사유 |
| db_source_type | varchar | `'internal'` (기본) / `'external'` |
| db_connection_id | integer | 외부 DB 연결 ID |
| data_source_type | varchar | `'database'` (기본) / `'rest_api'` |
| rest_api_connection_id | integer | REST API 연결 ID |
| rest_api_endpoint | varchar | REST API 엔드포인트 |
| rest_api_json_path | varchar | JSON 응답 경로 (기본 `'data'`) |
| source_screen_id | integer | 원본 화면 ID (복사본일 때) |

> **screen_code UNIQUE 주의**: `is_active = 'D'`(삭제)인 화면은 UNIQUE 대상에서 제외된다. 삭제된 화면과 같은 코드로 새 화면을 만들 수 있지만, 활성 상태(`'Y'`/`'N'`)에서는 중복 불가.

### 2.5 screen_layouts_v2

| 컬럼 | 타입 | 설명 |
|------|------|------|
| layout_id | serial PK | 자동 증가 |
| screen_id | integer FK | UNIQUE(+company_code+layer_id) |
| company_code | varchar NOT NULL | 회사 코드 |
| layout_data | jsonb NOT NULL | 전체 레이아웃 JSON (기본 `'{}'`) |
| created_at | timestamptz | 생성일시 |
| updated_at | timestamptz | 수정일시 |
| layer_id | integer | 1=기본 레이어 (기본값 1) |
| layer_name | varchar | 레이어명 (기본 `'기본 레이어'`) |
| condition_config | jsonb | 레이어 조건부 표시 설정 |

### 2.6 menu_info

| 컬럼 | 타입 | 설명 |
|------|------|------|
| objid | numeric PK | BIGINT 고유값 |
| menu_type | numeric | 0=화면, 1=폴더 |
| parent_obj_id | numeric | 부모 메뉴 objid |
| menu_name_kor | varchar | 메뉴명 (한글) |
| menu_name_eng | varchar | 메뉴명 (영문) |
| seq | numeric | 정렬 순서 |
| menu_url | varchar | `/screen/{screen_code}` |
| menu_desc | varchar | 메뉴 설명 |
| writer | varchar | 작성자 |
| regdate | timestamp | 등록일시 |
| status | varchar | 상태 (`'active'` 등) |
| company_code | varchar | 회사 코드 (기본 `'*'`) |
| screen_code | varchar | 연결 화면 코드 |
| system_name | varchar | 시스템명 |
| lang_key | varchar | 다국어 키 |
| lang_key_desc | varchar | 다국어 설명 키 |
| menu_code | varchar | 메뉴 코드 |
| source_menu_objid | bigint | 원본 메뉴 objid (복사본일 때) |
| screen_group_id | integer | 화면 그룹 ID |
| menu_icon | varchar | 메뉴 아이콘 |

---

## 3. 컴포넌트 전체 설정 레퍼런스 (32개)

> 아래 설정은 layout_data JSON의 각 컴포넌트 `overrides` 안에 들어가는 값이다.
> 기본값과 다른 부분만 overrides에 지정하면 된다.

---

### 3.1 v2-table-list (데이터 테이블)

**용도**: DB 테이블 데이터를 테이블/카드 형태로 조회/편집. 가장 핵심적인 컴포넌트.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| tableName | string | - | 조회할 DB 테이블명 |
| selectedTable | string | - | tableName 별칭 |
| displayMode | `"table"\|"card"` | `"table"` | 테이블 모드 또는 카드 모드 |
| autoLoad | boolean | `true` | 화면 로드 시 자동으로 데이터 조회 |
| isReadOnly | boolean | false | 읽기 전용 (편집 불가) |
| columns | ColumnConfig[] | `[]` | 표시할 컬럼 설정 배열 |
| title | string | - | 테이블 상단 제목 |
| showHeader | boolean | `true` | 테이블 헤더 행 표시 |
| showFooter | boolean | `true` | 테이블 푸터 표시 |
| height | string | `"auto"` | 높이 모드 (`"auto"`, `"fixed"`, `"viewport"`) |
| fixedHeight | number | - | height="fixed"일 때 고정 높이(px) |
| autoWidth | boolean | `true` | 컬럼 너비 자동 계산 |
| stickyHeader | boolean | `false` | 스크롤 시 헤더 고정 |

**checkbox (체크박스 설정)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| enabled | boolean | `true` | 체크박스 사용 여부 |
| multiple | boolean | `true` | 다중 선택 허용 |
| position | `"left"\|"right"` | `"left"` | 체크박스 위치 |
| selectAll | boolean | `true` | 전체 선택 버튼 표시 |

**pagination (페이지네이션)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| enabled | boolean | `true` | 페이지네이션 사용 |
| pageSize | number | `20` | 한 페이지당 행 수 |
| showSizeSelector | boolean | `true` | 페이지 크기 변경 드롭다운 |
| showPageInfo | boolean | `true` | "1-20 / 100건" 같은 정보 표시 |
| pageSizeOptions | number[] | `[10,20,50,100]` | 선택 가능한 페이지 크기 |

**horizontalScroll (가로 스크롤)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| enabled | boolean | `true` | 가로 스크롤 사용 |
| maxVisibleColumns | number | `8` | 스크롤 없이 보이는 최대 컬럼 수 |
| minColumnWidth | number | `100` | 컬럼 최소 너비(px) |
| maxColumnWidth | number | `300` | 컬럼 최대 너비(px) |

**tableStyle (스타일)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| theme | string | `"default"` | 테마 (`default`/`striped`/`bordered`/`minimal`) |
| headerStyle | string | `"default"` | 헤더 스타일 (`default`/`dark`/`light`) |
| rowHeight | string | `"normal"` | 행 높이 (`compact`/`normal`/`comfortable`) |
| alternateRows | boolean | `true` | 짝수/홀수 행 색상 교차 |
| hoverEffect | boolean | `true` | 마우스 호버 시 행 강조 |
| borderStyle | string | `"light"` | 테두리 (`none`/`light`/`heavy`) |

**toolbar (툴바 버튼)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| showEditMode | boolean | `false` | 즉시저장/배치저장 모드 전환 버튼 |
| showExcel | boolean | `false` | Excel 내보내기 버튼 |
| showPdf | boolean | `false` | PDF 내보내기 버튼 |
| showSearch | boolean | `false` | 테이블 내 검색 |
| showRefresh | boolean | `false` | 상단 새로고침 버튼 |
| showPaginationRefresh | boolean | `true` | 하단 새로고침 버튼 |

**filter (필터)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| enabled | boolean | `true` | 필터 기능 사용 |
| filters | array | `[]` | 사전 정의 필터 목록 |

**ColumnConfig (columns 배열 요소)**:

| 설정 | 타입 | 설명 |
|------|------|------|
| columnName | string | DB 컬럼명 |
| displayName | string | 화면 표시명 |
| visible | boolean | 표시 여부 |
| sortable | boolean | 정렬 가능 여부 |
| searchable | boolean | 검색 가능 여부 |
| editable | boolean | 인라인 편집 가능 여부 |
| width | number | 컬럼 너비(px) |
| align | `"left"\|"center"\|"right"` | 텍스트 정렬 |
| format | string | 포맷 (`text`/`number`/`date`/`currency`/`boolean`) |
| hidden | boolean | 숨김 (데이터는 로드하되 표시 안 함) |
| fixed | `"left"\|"right"\|false` | 컬럼 고정 위치 |
| thousandSeparator | boolean | 숫자 천 단위 콤마 |
| isEntityJoin | boolean | 엔티티 조인 사용 여부 |
| entityJoinInfo | object | 조인 정보 (`sourceTable`, `sourceColumn`, `referenceTable`, `joinAlias`) |

**cardConfig (displayMode="card"일 때)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| idColumn | string | `"id"` | ID 컬럼 |
| titleColumn | string | `"name"` | 카드 제목 컬럼 |
| subtitleColumn | string | - | 부제목 컬럼 |
| descriptionColumn | string | - | 설명 컬럼 |
| imageColumn | string | - | 이미지 URL 컬럼 |
| cardsPerRow | number | `3` | 행당 카드 수 |
| cardSpacing | number | `16` | 카드 간격(px) |
| showActions | boolean | `true` | 카드 액션 버튼 표시 |

---

### 3.2 v2-split-panel-layout (마스터-디테일 분할)

**용도**: 좌측 마스터 테이블 선택 → 우측 디테일 테이블 연동. 가장 복잡한 컴포넌트.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| splitRatio | number | `30` | 좌측 패널 비율(0~100) |
| resizable | boolean | `true` | 사용자가 분할선 드래그로 비율 변경 가능 |
| minLeftWidth | number | `200` | 좌측 최소 너비(px) |
| minRightWidth | number | `300` | 우측 최소 너비(px) |
| autoLoad | boolean | `true` | 화면 로드 시 자동 데이터 조회 |
| syncSelection | boolean | `true` | 좌측 선택 시 우측 자동 갱신 |

**leftPanel / rightPanel 공통 설정**:

| 설정 | 타입 | 설명 |
|------|------|------|
| title | string | 패널 제목 |
| tableName | string | DB 테이블명 |
| displayMode | `"list"\|"table"\|"custom"` | `list`: 리스트, `table`: 테이블, `custom`: 자유 배치 |
| columns | array | 컬럼 설정 (`name`, `label`, `width`, `sortable`, `align`, `isEntityJoin`, `joinInfo`) |
| showSearch | boolean | 패널 내 검색 바 표시 |
| showAdd | boolean | 추가 버튼 표시 |
| showEdit | boolean | 수정 버튼 표시 |
| showDelete | boolean | 삭제 버튼 표시 |
| addButton | object | `{ enabled, mode("auto"/"modal"), modalScreenId }` |
| editButton | object | `{ enabled, mode("auto"/"modal"), modalScreenId, buttonLabel }` |
| deleteButton | object | `{ enabled, buttonLabel, confirmMessage }` |
| addModalColumns | array | 추가 모달 전용 컬럼 (`name`, `label`, `required`) |
| dataFilter | object | `{ enabled, filters, matchType("all"/"any") }` |
| tableConfig | object | `{ showCheckbox, showRowNumber, rowHeight, headerHeight, striped, bordered, hoverable, stickyHeader }` |
| components | array | displayMode="custom"일 때 내부 컴포넌트 배열 |

**rightPanel 전용 설정**:

| 설정 | 타입 | 설명 |
|------|------|------|
| relation | object | 마스터-디테일 연결 관계 |
| relation.type | `"detail"\|"join"` | detail: FK 관계, join: 테이블 JOIN |
| relation.leftColumn | string | 좌측(마스터) 연결 컬럼 (보통 `"id"`) |
| relation.rightColumn | string | 우측(디테일) 연결 컬럼 (FK) |
| relation.foreignKey | string | FK 컬럼명 (rightColumn과 동일) |
| relation.keys | array | 복합키 `[{ leftColumn, rightColumn }]` |
| additionalTabs | array | 우측 패널에 탭 추가 (각 탭은 rightPanel과 동일 구조 + `tabId`, `label`) |
| addConfig | object | `{ targetTable, autoFillColumns, leftPanelColumn, targetColumn }` |
| deduplication | object | `{ enabled, groupByColumn, keepStrategy, sortColumn }` |
| summaryColumnCount | number | 요약 표시 컬럼 수 |

---

### 3.3 v2-table-search-widget (검색 바)

**용도**: 테이블 상단에 배치하여 검색/필터 기능 제공. 대상 테이블 컬럼을 자동 감지.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| autoSelectFirstTable | boolean | `true` | 화면 내 첫 번째 테이블 자동 연결 |
| showTableSelector | boolean | `true` | 테이블 선택 드롭다운 표시 |
| title | string | `"테이블 검색"` | 검색 바 제목 |
| filterMode | `"dynamic"\|"preset"` | `"dynamic"` | dynamic: 자동 필터, preset: 고정 필터 |
| presetFilters | array | `[]` | 고정 필터 목록 (`{ columnName, columnLabel, filterType, width }`) |
| targetPanelPosition | `"left"\|"right"\|"auto"` | `"left"` | split-panel에서 대상 패널 위치 |

---

### 3.4 v2-input (텍스트/숫자 입력)

**용도**: 텍스트, 숫자, 비밀번호, textarea, 슬라이더, 컬러, 버튼 등 단일 값 입력.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| inputType | string | `"text"` | 입력 유형: `text`/`number`/`password`/`slider`/`color`/`button`/`textarea` |
| format | string | `"none"` | 포맷 검증: `none`/`email`/`tel`/`url`/`currency`/`biz_no` |
| placeholder | string | `""` | 입력 힌트 텍스트 |
| required | boolean | `false` | 필수 입력 표시 |
| readonly | boolean | `false` | 읽기 전용 |
| disabled | boolean | `false` | 비활성화 |
| maxLength | number | - | 최대 입력 글자 수 |
| minLength | number | - | 최소 입력 글자 수 |
| pattern | string | - | 정규식 패턴 검증 |
| showCounter | boolean | `false` | 글자 수 카운터 표시 |
| min | number | - | 최소값 (number/slider) |
| max | number | - | 최대값 (number/slider) |
| step | number | - | 증감 단위 (number/slider) |
| buttonText | string | - | 버튼 텍스트 (inputType=button) |
| tableName | string | - | 바인딩 테이블명 |
| columnName | string | - | 바인딩 컬럼명 |

---

### 3.5 v2-select (선택)

**용도**: 드롭다운, 콤보박스, 라디오, 체크박스, 태그, 토글 등 선택형 입력.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| mode | string | `"dropdown"` | 선택 모드: `dropdown`/`combobox`/`radio`/`check`/`tag`/`tagbox`/`toggle`/`swap` |
| source | string | `"distinct"` | 데이터 소스: `static`/`code`/`db`/`api`/`entity`/`category`/`distinct`/`select` |
| options | array | `[]` | source=static일 때 옵션 목록 `[{ label, value }]` |
| codeGroup | string | - | source=code일 때 코드 그룹 |
| codeCategory | string | - | source=code일 때 코드 카테고리 |
| table | string | - | source=db일 때 테이블명 |
| valueColumn | string | - | source=db일 때 값 컬럼 |
| labelColumn | string | - | source=db일 때 표시 컬럼 |
| entityTable | string | - | source=entity일 때 엔티티 테이블 |
| entityValueField | string | - | source=entity일 때 값 필드 |
| entityLabelField | string | - | source=entity일 때 표시 필드 |
| searchable | boolean | `true` | 검색 가능 (combobox에서 기본 활성) |
| multiple | boolean | `false` | 다중 선택 허용 |
| maxSelect | number | - | 최대 선택 수 |
| allowClear | boolean | - | 선택 해제 허용 |
| placeholder | string | `"선택하세요"` | 힌트 텍스트 |
| required | boolean | `false` | 필수 선택 |
| readonly | boolean | `false` | 읽기 전용 |
| disabled | boolean | `false` | 비활성화 |
| cascading | object | - | 연쇄 선택 (상위 select 값에 따라 하위 옵션 변경) |
| hierarchical | boolean | - | 계층 구조 (부모-자식 관계) |
| parentField | string | - | 부모 필드명 |

---

### 3.6 v2-date (날짜)

**용도**: 날짜, 시간, 날짜시간, 날짜범위, 월, 연도 입력.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dateType | string | `"date"` | 날짜 유형: `date`/`datetime`/`time`/`daterange`/`month`/`year` |
| format | string | `"YYYY-MM-DD"` | 표시/저장 형식 |
| placeholder | string | `"날짜 선택"` | 힌트 텍스트 |
| required | boolean | `false` | 필수 입력 |
| readonly | boolean | `false` | 읽기 전용 |
| disabled | boolean | `false` | 비활성화 |
| showTime | boolean | `false` | 시간 선택 표시 (datetime) |
| use24Hours | boolean | `true` | 24시간 형식 |
| range | boolean | - | 범위 선택 (시작~종료) |
| minDate | string | - | 선택 가능 최소 날짜 (ISO 8601) |
| maxDate | string | - | 선택 가능 최대 날짜 |
| showToday | boolean | - | 오늘 버튼 표시 |

---

### 3.7 v2-button-primary (액션 버튼)

**용도**: 저장, 삭제, 조회, 커스텀 등 액션 버튼. 제어관리(dataflow)와 연결 가능.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| text | string | `"저장"` | 버튼 텍스트 |
| actionType | string | `"button"` | 버튼 타입: `button`/`submit`/`reset` |
| variant | string | `"primary"` | 스타일: `primary`/`secondary`/`danger` |
| size | string | `"md"` | 크기: `sm`/`md`/`lg` |
| disabled | boolean | `false` | 비활성화 |
| action | object | - | 액션 설정 |
| action.type | string | `"save"` | 액션 유형: `save`/`delete`/`edit`/`copy`/`navigate`/`modal`/`control`/`custom` |
| action.successMessage | string | `"저장되었습니다."` | 성공 시 토스트 메시지 |
| action.errorMessage | string | `"오류가 발생했습니다."` | 실패 시 토스트 메시지 |
| webTypeConfig | object | - | 제어관리 연결 설정 |
| webTypeConfig.enableDataflowControl | boolean | - | 제어관리 활성화 |
| webTypeConfig.dataflowConfig | object | - | 제어관리 설정 |
| webTypeConfig.dataflowConfig.controlMode | string | - | `"relationship"`/`"flow"`/`"none"` |
| webTypeConfig.dataflowConfig.relationshipConfig | object | - | `{ relationshipId, executionTiming("before"/"after"/"replace") }` |
| webTypeConfig.dataflowConfig.flowConfig | object | - | `{ flowId, executionTiming }` |

---

### 3.8 v2-table-grouped (그룹화 테이블)

**용도**: 특정 컬럼 기준으로 데이터를 그룹화. 그룹별 접기/펼치기, 집계 표시.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| selectedTable | string | `""` | DB 테이블명 |
| columns | array | `[]` | 컬럼 설정 (v2-table-list와 동일) |
| showCheckbox | boolean | `false` | 체크박스 표시 |
| checkboxMode | `"single"\|"multi"` | `"multi"` | 체크박스 모드 |
| isReadOnly | boolean | `false` | 읽기 전용 |
| rowClickable | boolean | `true` | 행 클릭 가능 |
| showExpandAllButton | boolean | `true` | 전체 펼치기/접기 버튼 |
| groupHeaderStyle | string | `"default"` | 그룹 헤더 스타일 (`default`/`compact`/`card`) |
| emptyMessage | string | `"데이터가 없습니다."` | 빈 데이터 메시지 |
| height | string\|number | `"auto"` | 높이 |
| maxHeight | number | `600` | 최대 높이(px) |
| pagination.enabled | boolean | `false` | 페이지네이션 사용 |
| pagination.pageSize | number | `10` | 페이지 크기 |

**groupConfig (그룹화 설정)**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| groupByColumn | string | `""` | **필수**. 그룹화 기준 컬럼 |
| groupLabelFormat | string | `"{value}"` | 그룹 라벨 포맷 |
| defaultExpanded | boolean | `true` | 초기 펼침 여부 |
| sortDirection | `"asc"\|"desc"` | `"asc"` | 그룹 정렬 방향 |
| summary.showCount | boolean | `true` | 그룹별 건수 표시 |
| summary.sumColumns | string[] | `[]` | 합계 표시할 컬럼 목록 |
| summary.avgColumns | string[] | - | 평균 표시 컬럼 |
| summary.maxColumns | string[] | - | 최대값 표시 컬럼 |
| summary.minColumns | string[] | - | 최소값 표시 컬럼 |

---

### 3.9 v2-pivot-grid (피벗 분석)

**용도**: 다차원 데이터 분석. 행/열/데이터/필터 영역에 필드를 배치하여 집계.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| fields | array | `[]` | **필수**. 피벗 필드 배열 |
| dataSource | object | - | 데이터 소스 (`type`, `tableName`, `joinConfigs`, `filterConditions`) |
| allowSortingBySummary | boolean | - | 집계값 기준 정렬 허용 |
| allowFiltering | boolean | - | 필터링 허용 |
| allowExpandAll | boolean | - | 전체 확장/축소 허용 |
| wordWrapEnabled | boolean | - | 텍스트 줄바꿈 |
| height | string\|number | - | 높이 |
| totals.showRowGrandTotals | boolean | - | 행 총합계 표시 |
| totals.showColumnGrandTotals | boolean | - | 열 총합계 표시 |
| chart.enabled | boolean | - | 차트 연동 표시 |
| chart.type | string | - | 차트 타입 (`bar`/`line`/`area`/`pie`/`stackedBar`) |

**fields 배열 요소**:

| 설정 | 타입 | 설명 |
|------|------|------|
| field | string | DB 컬럼명 |
| caption | string | 표시 라벨 |
| area | `"row"\|"column"\|"data"\|"filter"` | **필수**. 배치 영역 |
| summaryType | string | area=data일 때: `sum`/`count`/`avg`/`min`/`max`/`countDistinct` |
| groupInterval | string | 날짜 그룹화: `year`/`quarter`/`month`/`week`/`day` |
| sortBy | string | 정렬 기준: `value`/`caption` |
| sortOrder | string | 정렬 방향: `asc`/`desc`/`none` |

---

### 3.10 v2-card-display (카드 뷰)

**용도**: 테이블 데이터를 카드 형태로 표시. 이미지+제목+설명 구조.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSource | string | `"table"` | 데이터 소스: `table`/`static` |
| tableName | string | - | DB 테이블명 |
| cardsPerRow | number | `3` | 행당 카드 수 (1~6) |
| cardSpacing | number | `16` | 카드 간격(px) |
| columnMapping | object | `{}` | 필드 매핑 (`title`, `subtitle`, `description`, `image`, `status`) |
| cardStyle.showTitle | boolean | `true` | 제목 표시 |
| cardStyle.showSubtitle | boolean | `true` | 부제목 표시 |
| cardStyle.showDescription | boolean | `true` | 설명 표시 |
| cardStyle.showImage | boolean | `false` | 이미지 표시 |
| cardStyle.showActions | boolean | `true` | 액션 버튼 표시 |

---

### 3.11 v2-timeline-scheduler (간트차트/타임라인)

**용도**: 시간축 기반 일정/계획 시각화. 드래그/리사이즈로 일정 편집. 품목별 그룹 뷰, 자동 스케줄 생성, 반제품 계획 연동 지원.

**기본 설정**:

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| selectedTable | string | - | 스케줄 데이터 테이블 |
| customTableName | string | - | selectedTable 대신 사용 (useCustomTable=true 시) |
| useCustomTable | boolean | `false` | customTableName 사용 여부 |
| resourceTable | string | `"equipment_mng"` | 리소스(설비/작업자) 테이블 |
| scheduleType | string | `"PRODUCTION"` | 스케줄 유형: `PRODUCTION`/`MAINTENANCE`/`SHIPPING`/`WORK_ASSIGN` |
| viewMode | string | - | 뷰 모드: `"itemGrouped"` (품목별 카드 그룹) / 미설정 시 리소스 기반 |
| defaultZoomLevel | string | `"day"` | 초기 줌: `day`/`week`/`month` |
| editable | boolean | `true` | 편집 가능 |
| draggable | boolean | `true` | 드래그 이동 허용 |
| resizable | boolean | `true` | 기간 리사이즈 허용 |
| rowHeight | number | `50` | 행 높이(px) |
| headerHeight | number | `60` | 헤더 높이(px) |
| resourceColumnWidth | number | `150` | 리소스 컬럼 너비(px) |
| showConflicts | boolean | `true` | 시간 겹침 충돌 표시 |
| showProgress | boolean | `true` | 진행률 바 표시 |
| showTodayLine | boolean | `true` | 오늘 날짜 표시선 |
| showToolbar | boolean | `true` | 상단 툴바 표시 |
| showLegend | boolean | `true` | 범례(상태 색상 안내) 표시 |
| showNavigation | boolean | `true` | 날짜 네비게이션 버튼 표시 |
| showZoomControls | boolean | `true` | 줌 컨트롤 버튼 표시 |
| showAddButton | boolean | `true` | 추가 버튼 |
| height | number | `500` | 높이(px) |
| maxHeight | number | - | 최대 높이(px) |

**fieldMapping (필수)**:

| 설정 | 기본값 | 설명 |
|------|--------|------|
| id | `"schedule_id"` | 스케줄 PK 필드 |
| resourceId | `"resource_id"` | 리소스 FK 필드 |
| title | `"schedule_name"` | 제목 필드 |
| startDate | `"start_date"` | 시작일 필드 |
| endDate | `"end_date"` | 종료일 필드 |
| status | - | 상태 필드 |
| progress | - | 진행률 필드 (0~100) |

**resourceFieldMapping**:

| 설정 | 기본값 | 설명 |
|------|--------|------|
| id | `"equipment_code"` | 리소스 PK |
| name | `"equipment_name"` | 리소스 표시명 |
| group | - | 리소스 그룹 |

**statusColors (상태별 색상)**:

| 상태 | 기본 색상 |
|------|----------|
| planned | `"#3b82f6"` (파랑) |
| in_progress | `"#10b981"` (초록) |
| completed | `"#6b7280"` (회색) |
| delayed | `"#ef4444"` (빨강) |
| cancelled | `"#9ca3af"` (연회색) |

**staticFilters (정적 필터)** - DB 조회 시 항상 적용되는 WHERE 조건:

| 설정 | 타입 | 설명 |
|------|------|------|
| product_type | string | `"완제품"` 또는 `"반제품"` 등 고정 필터 |
| status | string | 상태값 필터 |
| (임의 컬럼) | string | 해당 컬럼으로 필터링 |

```json
"staticFilters": {
  "product_type": "완제품"
}
```

**linkedFilter (연결 필터)** - 다른 컴포넌트(주로 테이블)의 선택 이벤트와 연동:

| 설정 | 타입 | 설명 |
|------|------|------|
| sourceField | string | 소스 컴포넌트(좌측 테이블)의 필터 기준 컬럼 |
| targetField | string | 타임라인 스케줄 데이터에서 매칭할 컬럼 |
| sourceTableName | string | 이벤트 발신 테이블명 (이벤트 필터용) |
| sourceComponentId | string | 이벤트 발신 컴포넌트 ID (선택) |
| emptyMessage | string | 선택 전 빈 상태 메시지 |
| showEmptyWhenNoSelection | boolean | 선택 전 빈 상태 표시 여부 |

```json
"linkedFilter": {
  "sourceField": "part_code",
  "targetField": "item_code",
  "sourceTableName": "sales_order_mng",
  "emptyMessage": "좌측 수주 목록에서 품목을 선택하세요",
  "showEmptyWhenNoSelection": true
}
```

> **linkedFilter 동작 원리**: v2EventBus의 `TABLE_SELECTION_CHANGE` 이벤트를 구독.
> 좌측 테이블에서 행을 선택하면 해당 행의 `sourceField` 값을 수집하여,
> 타임라인 데이터 중 `targetField`가 일치하는 스케줄만 클라이언트 측에서 필터링 표시.
> `staticFilters`는 서버 측 조회, `linkedFilter`는 클라이언트 측 필터링.

**viewMode: "itemGrouped" (품목별 그룹 뷰)**:

리소스(설비) 기반 간트차트 대신, 품목(item_code)별로 카드를 그룹화하여 표시하는 모드.
각 카드 안에 해당 품목의 스케줄 바가 미니 타임라인으로 표시됨.

설정 시 `viewMode: "itemGrouped"`만 추가하면 됨. 툴바에 자동으로:
- 날짜 네비게이션 (이전/오늘/다음)
- 줌 컨트롤
- 새로고침 버튼
- (완제품 탭일 때) **완제품 계획 생성** / **반제품 계획 생성** 버튼

**자동 스케줄 생성 (내장 기능)**:

`viewMode: "itemGrouped"` + `staticFilters.product_type === "완제품"` 일 때 자동 활성화.

- **완제품 계획 생성**: linkedFilter로 선택된 수주 품목 기반, 미리보기 다이얼로그 → 확인 후 생성
  - API: `POST /production/generate-schedule/preview` → `POST /production/generate-schedule`
- **반제품 계획 생성**: 현재 타임라인의 완제품 스케줄 기반, BOM 소요량으로 반제품 계획 미리보기 → 확인 후 생성
  - API: `POST /production/generate-semi-schedule/preview` → `POST /production/generate-semi-schedule`

> **중요**: 반제품 전용 타임라인에는 `linkedFilter`를 걸지 않는다.
> 반제품 item_code가 수주 품목 코드와 다르므로 매칭 불가.
> `staticFilters: { product_type: "반제품" }`만 설정하여 전체 반제품 계획을 표시.

---

### 3.12 v2-tabs-widget (탭)

**용도**: 탭 전환. 각 탭 내부에 컴포넌트 배치 가능.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| tabs | array | `[{id:"tab-1",label:"탭1",...}]` | 탭 배열 |
| defaultTab | string | `"tab-1"` | 기본 활성 탭 ID |
| orientation | string | `"horizontal"` | 탭 방향: `horizontal`/`vertical` |
| variant | string | `"default"` | 스타일: `default`/`pills`/`underline` |
| allowCloseable | boolean | `false` | 탭 닫기 버튼 표시 |
| persistSelection | boolean | `false` | 탭 선택 상태 localStorage 저장 |

**tabs 배열 요소**: `{ id, label, order, disabled, icon, components[] }`
**components 요소**: `{ id, componentType, label, position, size, componentConfig }`

---

### 3.13 v2-aggregation-widget (집계 카드)

**용도**: 합계, 평균, 개수 등 집계값을 카드 형태로 표시.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSourceType | string | `"table"` | 데이터 소스: `table`/`component`/`selection` |
| tableName | string | - | 테이블명 |
| items | array | `[]` | 집계 항목 배열 |
| layout | string | `"horizontal"` | 배치: `horizontal`/`vertical` |
| showLabels | boolean | `true` | 라벨 표시 |
| showIcons | boolean | `true` | 아이콘 표시 |
| gap | string | `"16px"` | 항목 간격 |
| autoRefresh | boolean | `false` | 자동 새로고침 |
| refreshOnFormChange | boolean | `true` | 폼 변경 시 새로고침 |

**items 요소**: `{ id, columnName, columnLabel, type("sum"/"avg"/"count"/"max"/"min"), format, decimalPlaces, prefix, suffix }`

---

### 3.14 v2-status-count (상태별 건수)

**용도**: 상태별 건수를 카드 형태로 표시. 대시보드/현황 화면용.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| title | string | `"상태 현황"` | 제목 |
| tableName | string | `""` | 대상 테이블 |
| statusColumn | string | `"status"` | 상태 컬럼명 |
| relationColumn | string | `""` | 관계 컬럼 (필터용) |
| items | array | - | 상태 항목 `[{ value, label, color }]` |
| showTotal | boolean | - | 합계 표시 |
| cardSize | string | `"md"` | 카드 크기: `sm`/`md`/`lg` |

---

### 3.15 v2-text-display (텍스트 표시)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| text | string | `"텍스트를 입력하세요"` | 표시 텍스트 |
| fontSize | string | `"14px"` | 폰트 크기 |
| fontWeight | string | `"normal"` | 폰트 굵기 |
| color | string | `"#212121"` | 텍스트 색상 |
| textAlign | string | `"left"` | 정렬: `left`/`center`/`right` |
| backgroundColor | string | - | 배경색 |
| padding | string | - | 패딩 |

---

### 3.16 v2-numbering-rule (자동 채번)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| ruleConfig | object | - | 채번 규칙 설정 |
| maxRules | number | `6` | 최대 파트 수 |
| readonly | boolean | `false` | 읽기 전용 |
| showPreview | boolean | `true` | 미리보기 표시 |
| showRuleList | boolean | `true` | 규칙 목록 표시 |
| cardLayout | string | `"vertical"` | 레이아웃: `vertical`/`horizontal` |

---

### 3.17 v2-file-upload (파일 업로드)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| placeholder | string | `"파일을 선택하세요"` | 힌트 텍스트 |
| multiple | boolean | `true` | 다중 업로드 |
| accept | string | `"*/*"` | 허용 파일 형식 (예: `"image/*"`, `".pdf,.xlsx"`) |
| maxSize | number | `10485760` | 최대 파일 크기(bytes, 기본 10MB) |
| maxFiles | number | - | 최대 파일 수 |
| showPreview | boolean | - | 미리보기 표시 |
| showFileList | boolean | - | 파일 목록 표시 |
| allowDelete | boolean | - | 삭제 허용 |
| allowDownload | boolean | - | 다운로드 허용 |

---

### 3.18 v2-section-card (그룹 컨테이너 - 테두리)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| title | string | `"섹션 제목"` | 제목 |
| description | string | `""` | 설명 |
| showHeader | boolean | `true` | 헤더 표시 |
| padding | string | `"md"` | 패딩: `none`/`sm`/`md`/`lg` |
| backgroundColor | string | `"default"` | 배경: `default`/`muted`/`transparent` |
| borderStyle | string | `"solid"` | 테두리: `solid`/`dashed`/`none` |
| collapsible | boolean | `false` | 접기/펼치기 가능 |
| defaultOpen | boolean | `true` | 기본 펼침 |

---

### 3.19 v2-section-paper (그룹 컨테이너 - 배경색)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| backgroundColor | string | `"default"` | 배경: `default`/`muted`/`accent`/`primary`/`custom` |
| customColor | string | - | custom일 때 색상 |
| showBorder | boolean | `false` | 테두리 표시 |
| padding | string | `"md"` | 패딩: `none`/`sm`/`md`/`lg` |
| roundedCorners | string | `"md"` | 모서리: `none`/`sm`/`md`/`lg` |
| shadow | string | `"none"` | 그림자: `none`/`sm`/`md` |

---

### 3.20 v2-divider-line (구분선)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| orientation | string | - | 방향 (가로/세로) |
| thickness | number | - | 두께 |

---

### 3.21 v2-split-line (캔버스 분할선)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| resizable | boolean | `true` | 드래그 리사이즈 허용 |
| lineColor | string | `"#e2e8f0"` | 분할선 색상 |
| lineWidth | number | `4` | 분할선 두께(px) |

---

### 3.22 v2-repeat-container (반복 렌더링)

**용도**: 데이터 수만큼 내부 컴포넌트를 반복 렌더링. 카드 리스트 등에 사용.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSourceType | string | `"manual"` | 소스: `table-list`/`v2-repeater`/`externalData`/`manual` |
| dataSourceComponentId | string | - | 연결할 컴포넌트 ID |
| tableName | string | - | 테이블명 |
| layout | string | `"vertical"` | 배치: `vertical`/`horizontal`/`grid` |
| gridColumns | number | `2` | grid일 때 컬럼 수 |
| gap | string | `"16px"` | 아이템 간격 |
| showBorder | boolean | `true` | 카드 테두리 |
| showShadow | boolean | `false` | 카드 그림자 |
| borderRadius | string | `"8px"` | 모서리 둥글기 |
| backgroundColor | string | `"#ffffff"` | 배경색 |
| padding | string | `"16px"` | 패딩 |
| showItemTitle | boolean | `false` | 아이템 제목 표시 |
| itemTitleTemplate | string | `""` | 제목 템플릿 (예: `"{order_no} - {item}"`) |
| emptyMessage | string | `"데이터가 없습니다"` | 빈 상태 메시지 |
| clickable | boolean | `false` | 클릭 가능 |
| selectionMode | string | `"single"` | 선택 모드: `single`/`multiple` |
| usePaging | boolean | `false` | 페이징 사용 |
| pageSize | number | `10` | 페이지 크기 |

---

### 3.23 v2-repeater (반복 데이터 관리)

**용도**: 인라인/모달 모드로 반복 데이터(주문 상세 등) 관리. 행 추가/삭제/편집.

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| renderMode | string | `"inline"` | 모드: `inline` (인라인 편집) / `modal` (모달로 선택 추가) |
| mainTableName | string | - | 저장 대상 테이블 |
| foreignKeyColumn | string | - | 마스터 연결 FK 컬럼 |
| foreignKeySourceColumn | string | - | 마스터 PK 컬럼 |
| columns | array | `[]` | 컬럼 설정 |
| dataSource.tableName | string | - | 데이터 테이블 |
| dataSource.foreignKey | string | - | FK 컬럼 |
| dataSource.sourceTable | string | - | 모달용 소스 테이블 |
| modal.size | string | `"md"` | 모달 크기: `sm`/`md`/`lg`/`xl`/`full` |
| modal.title | string | - | 모달 제목 |
| modal.searchFields | string[] | - | 검색 필드 |
| features.showAddButton | boolean | `true` | 추가 버튼 |
| features.showDeleteButton | boolean | `true` | 삭제 버튼 |
| features.inlineEdit | boolean | `false` | 인라인 편집 |
| features.showRowNumber | boolean | `false` | 행 번호 표시 |
| calculationRules | array | - | 자동 계산 규칙 (예: 수량*단가=금액) |

---

### 3.24 v2-approval-step (결재 스테퍼)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| targetTable | string | `""` | 결재 대상 테이블 |
| targetRecordIdField | string | `""` | 레코드 ID 필드 |
| displayMode | string | `"horizontal"` | 표시 방향: `horizontal`/`vertical` |
| showComment | boolean | `true` | 결재 코멘트 표시 |
| showTimestamp | boolean | `true` | 결재 시간 표시 |
| showDept | boolean | `true` | 부서 표시 |
| compact | boolean | `false` | 컴팩트 모드 |

---

### 3.25 v2-bom-tree (BOM 트리)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| detailTable | string | `"bom_detail"` | BOM 디테일 테이블 |
| foreignKey | string | `"bom_id"` | BOM 마스터 FK |
| parentKey | string | `"parent_detail_id"` | 트리 부모 키 (자기참조) |

---

### 3.26 v2-bom-item-editor (BOM 편집)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| detailTable | string | `"bom_detail"` | BOM 디테일 테이블 |
| sourceTable | string | `"item_info"` | 품목 소스 테이블 |
| foreignKey | string | `"bom_id"` | BOM 마스터 FK |
| parentKey | string | `"parent_detail_id"` | 트리 부모 키 |
| itemCodeField | string | `"item_number"` | 품목 코드 필드 |
| itemNameField | string | `"item_name"` | 품목명 필드 |
| itemTypeField | string | `"type"` | 품목 유형 필드 |
| itemUnitField | string | `"unit"` | 품목 단위 필드 |

---

### 3.27 v2-category-manager (카테고리 관리)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| tableName | string | - | 대상 테이블 |
| columnName | string | - | 카테고리 컬럼 |
| menuObjid | number | - | 연결 메뉴 OBJID |
| viewMode | string | `"tree"` | 뷰 모드: `tree`/`list` |
| showViewModeToggle | boolean | `true` | 뷰 모드 토글 표시 |
| defaultExpandLevel | number | `1` | 기본 트리 펼침 레벨 |
| showInactiveItems | boolean | `false` | 비활성 항목 표시 |
| leftPanelWidth | number | `15` | 좌측 패널 너비 |

---

### 3.28 v2-media (미디어)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| mediaType | string | `"file"` | 미디어 타입: `file`/`image`/`video`/`audio` |
| multiple | boolean | `false` | 다중 업로드 |
| preview | boolean | `true` | 미리보기 |
| maxSize | number | `10` | 최대 크기(MB) |
| accept | string | `"*/*"` | 허용 형식 |
| showFileList | boolean | `true` | 파일 목록 |
| dragDrop | boolean | `true` | 드래그앤드롭 |

---

### 3.29 v2-location-swap-selector (위치 교환)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSource.type | string | `"static"` | 소스: `static`/`table`/`code` |
| dataSource.tableName | string | - | 장소 테이블 |
| dataSource.valueField | string | `"location_code"` | 값 필드 |
| dataSource.labelField | string | `"location_name"` | 표시 필드 |
| dataSource.staticOptions | array | - | 정적 옵션 `[{value, label}]` |
| departureField | string | `"departure"` | 출발지 저장 필드 |
| destinationField | string | `"destination"` | 도착지 저장 필드 |
| departureLabel | string | `"출발지"` | 출발지 라벨 |
| destinationLabel | string | `"도착지"` | 도착지 라벨 |
| showSwapButton | boolean | `true` | 교환 버튼 표시 |
| variant | string | `"card"` | UI: `card`/`inline`/`minimal` |

---

### 3.30 v2-rack-structure (창고 랙)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| maxConditions | number | `10` | 최대 조건 수 |
| maxRows | number | `99` | 최대 열 수 |
| maxLevels | number | `20` | 최대 단 수 |
| codePattern | string | `"{warehouseCode}-{floor}{zone}-{row:02d}-{level}"` | 위치 코드 패턴 |
| namePattern | string | `"{zone}구역-{row:02d}열-{level}단"` | 위치 이름 패턴 |
| showTemplates | boolean | `true` | 템플릿 표시 |
| showPreview | boolean | `true` | 미리보기 |
| showStatistics | boolean | `true` | 통계 카드 |
| readonly | boolean | `false` | 읽기 전용 |

---

### 3.31 v2-process-work-standard (공정 작업기준)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSource.itemTable | string | `"item_info"` | 품목 테이블 |
| dataSource.routingVersionTable | string | `"item_routing_version"` | 라우팅 버전 테이블 |
| dataSource.routingDetailTable | string | `"item_routing_detail"` | 라우팅 디테일 테이블 |
| dataSource.processTable | string | `"process_mng"` | 공정 테이블 |
| splitRatio | number | `30` | 좌우 분할 비율 |
| leftPanelTitle | string | `"품목 및 공정 선택"` | 좌측 패널 제목 |
| readonly | boolean | `false` | 읽기 전용 |
| itemListMode | string | `"all"` | 품목 모드: `all`/`registered` |

---

### 3.32 v2-item-routing (품목 라우팅)

| 설정 | 타입 | 기본값 | 설명 |
|------|------|--------|------|
| dataSource.itemTable | string | `"item_info"` | 품목 테이블 |
| dataSource.routingVersionTable | string | `"item_routing_version"` | 라우팅 버전 테이블 |
| dataSource.routingDetailTable | string | `"item_routing_detail"` | 라우팅 디테일 테이블 |
| dataSource.processTable | string | `"process_mng"` | 공정 테이블 |
| splitRatio | number | `40` | 좌우 분할 비율 |
| leftPanelTitle | string | `"품목 목록"` | 좌측 제목 |
| rightPanelTitle | string | `"공정 순서"` | 우측 제목 |
| readonly | boolean | `false` | 읽기 전용 |
| autoSelectFirstVersion | boolean | `true` | 첫 버전 자동 선택 |
| itemListMode | string | `"all"` | 품목 모드: `all`/`registered` |

---

## 4. 패턴 의사결정 트리

```
Q1. 좌측 마스터 + 우측 탭(타임라인/테이블) 복합 구성?
    → 패턴 F → v2-split-panel-layout(custom) + v2-tabs-widget + v2-timeline-scheduler
Q2. 시간축 기반 일정/간트차트?
    ├ 품목별 카드 그룹 뷰? → 패턴 E-2 → v2-timeline-scheduler(viewMode:itemGrouped)
    └ 리소스(설비) 기반? → 패턴 E → v2-timeline-scheduler
Q3. 다차원 피벗 분석? → v2-pivot-grid
Q4. 그룹별 접기/펼치기? → v2-table-grouped
Q5. 카드 형태 표시? → v2-card-display
Q6. 마스터-디테일?
    ├ 우측 멀티 탭? → v2-split-panel-layout + additionalTabs
    └ 단일 디테일? → v2-split-panel-layout
Q7. 단일 테이블? → v2-table-search-widget + v2-table-list
```

### 패턴 요약표

| 패턴 | 대표 화면 | 핵심 컴포넌트 |
|------|----------|-------------|
| A | 거래처관리 | v2-table-search-widget + v2-table-list |
| B | 수주관리 | v2-split-panel-layout |
| C | 수주관리(멀티탭) | v2-split-panel-layout + additionalTabs |
| D | 재고현황 | v2-table-grouped |
| E | 설비 작업일정 | v2-timeline-scheduler (리소스 기반) |
| E-2 | 품목별 타임라인 | v2-timeline-scheduler (viewMode: itemGrouped) |
| F | 생산계획 | split(custom) + tabs + timeline |

---

## 5. 관계(relation) 레퍼런스

| 관계 유형 | 설정 |
|----------|------|
| 단순 FK | `{ type:"detail", leftColumn:"id", rightColumn:"{FK}", foreignKey:"{FK}" }` |
| 복합 키 | `{ type:"detail", keys:[{ leftColumn:"a", rightColumn:"b" }] }` |
| JOIN | `{ type:"join", leftColumn:"{col}", rightColumn:"{col}" }` |

## 6. 엔티티 조인

FK 컬럼에 참조 테이블의 이름을 표시:

**table_type_columns**: `input_type='entity'`, `detail_settings='{"referenceTable":"X","referenceColumn":"id","displayColumn":"name"}'`

**layout_data columns**: `{ name:"fk_col", isEntityJoin:true, joinInfo:{ sourceTable:"A", sourceColumn:"fk_col", referenceTable:"X", joinAlias:"name" } }`
