2026-03-13 15:02:06 +09:00
# V2 컴포넌트 사용 가이드 (LLM/챗봇용)
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
> **최종 업데이트**: 2026-03-13
> **용도**: LLM 챗봇이 화면 개발 요청을 받았을 때, 어떤 컴포넌트를 어떤 설정으로 사용해야 하는지 판단하는 레퍼런스
> **버전**: 2.0.0
> **대상**: AI 에이전트, 챗봇, 화면 설계자
2026-01-30 14:13:44 +09:00
---
2026-03-13 15:02:06 +09:00
## 0. 핵심 규칙 (반드시 준수)
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
1. **사용자 업무 화면은 React 코드로 직접 만들지 않는다** → DB에 `screen_definitions` + `screen_layouts_v2` + `menu_info` INSERT로 구현
2. **모든 컴포넌트는 `v2-` 접두사** → `v2-` 없는 레거시 컴포넌트 사용 금지
3. **UI와 로직 분리** → UI는 `screen_layouts_v2` , 비즈니스 로직은 `dataflow_diagrams`
4. **멀티테넌시 필수** → 모든 테이블에 `company_code` 컬럼, 모든 쿼리에 `company_code` 필터링
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
---
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
## 1. 컴포넌트 전체 카탈로그 (32개)
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### 1.1 입력 컴포넌트
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-input
2026-02-24 10:15:25 +09:00
2026-03-13 15:02:06 +09:00
텍스트, 숫자, 비밀번호, textarea 등 모든 단일 값 입력을 처리하는 통합 입력 컴포넌트.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| inputType | string | 입력 유형 | `text` , `number` , `password` , `slider` , `color` , `button` , `textarea` |
| format | string | 포맷 검증 | `email` , `tel` , `url` , `currency` , `biz_no` |
| required | boolean | 필수 여부 | true/false |
| readonly | boolean | 읽기 전용 | true/false |
| maxLength | number | 최대 길이 | 숫자 |
| min / max | number | 숫자 범위 | 숫자 (inputType=number일 때) |
| step | number | 증감 단위 | 숫자 (inputType=number/slider일 때) |
| tableName | string | 바인딩 테이블 | DB 테이블명 |
| columnName | string | 바인딩 컬럼 | DB 컬럼명 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-select
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
드롭다운, 콤보박스, 라디오, 체크박스, 태그 등 선택형 입력 통합 컴포넌트.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| mode | string | 선택 모드 | `dropdown` , `combobox` , `radio` , `check` , `tag` , `tagbox` , `toggle` , `swap` |
| source | string | 데이터 소스 | `static` , `code` , `db` , `api` , `entity` , `category` , `distinct` , `select` |
| searchable | boolean | 검색 가능 | true/false (mode=combobox일 때 기본 true) |
| multiple | boolean | 다중 선택 | true/false |
| cascading | object | 연쇄 선택 | 상위 select 값에 따라 하위 옵션 변경 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**source 설명**:
- `static` : 고정 옵션 목록 (options 배열 직접 지정)
- `code` : code_info 테이블의 공통 코드
- `db` : 특정 테이블의 컬럼 값
- `entity` : 엔티티 조인 (다른 테이블 참조)
- `category` : v2-category-manager의 카테고리
- `distinct` : 테이블 컬럼의 DISTINCT 값
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-date
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
날짜, 시간, 날짜시간, 날짜범위, 월, 연도 입력.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| dateType | string | 날짜 유형 | `date` , `time` , `datetime` , `month` , `year` |
| format | string | 표시 형식 | `YYYY-MM-DD` , `HH:mm` , `YYYY-MM-DD HH:mm` 등 |
| range | boolean | 범위 선택 | true/false (시작~종료 날짜) |
| minDate / maxDate | string | 선택 가능 범위 | ISO 8601 날짜 |
| showToday | boolean | 오늘 버튼 | true/false |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-file-upload
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
파일/이미지 업로드. 다중 업로드, 미리보기 지원.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-media
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
이미지, 비디오, 오디오 등 미디어 표시/재생.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-location-swap-selector
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
출발지/도착지 선택 및 교환 (물류 화면용).
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-rack-structure
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
창고 랙 위치 일괄 생성 (열 범위, 단 수 설정).
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-process-work-standard
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
품목별 공정 작업기준(Pre-Work/In-Work/Post-Work) 관리. 라우팅과 연동.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-item-routing
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
품목별 라우팅 버전 및 공정 순서 관리 (3단계 계층: 품목 → 라우팅 버전 → 공정).
2026-01-30 14:13:44 +09:00
---
2026-03-13 15:02:06 +09:00
### 1.2 표시/데이터 컴포넌트
#### v2-table-list
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
가장 핵심 컴포넌트. DB 테이블 데이터를 조회/편집하는 테이블.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| selectedTable | string | **필수** . DB 테이블명 | 예: `"item_info"` |
| columns | array | 표시할 컬럼 설정 | `[{ columnName, displayName, visible, sortable, width, editable }]` |
| pagination | object | 페이지네이션 | `{ enabled: true, pageSize: 20, showSizeSelector: true }` |
| displayMode | string | 표시 모드 | `"table"` (기본) 또는 `"card"` |
| checkbox | object | 체크박스 | `{ enabled: true, multiple: true, position: "left", selectAll: true }` |
| horizontalScroll | object | 가로 스크롤 | `{ enabled: true, maxVisibleColumns: 8 }` |
| linkedFilters | array | 다른 컴포넌트와 연동 필터 | - |
| excludeFilter | object | 제외 필터 | - |
| autoLoad | boolean | 자동 데이터 로드 | true/false |
| stickyHeader | boolean | 헤더 고정 | true/false |
| toolbar | object | 툴바 (신규/삭제/엑셀 등) | - |
| tableStyle | object | 테이블 스타일 | `{ compact: true, striped: true }` |
**columns 배열 항목**:
```json
{
"columnName": "item_code",
"displayName": "품목코드",
"visible": true,
"sortable": true,
"width": 120,
"editable": false,
"inputType": "text",
"format": null,
"align": "left"
}
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
#### v2-table-grouped
v2-table-list 기반 확장. 특정 컬럼 기준으로 데이터를 그룹화하여 접기/펼치기 기능 제공.
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| selectedTable | string | **필수** . DB 테이블명 | - |
| groupConfig | object | **필수** . 그룹화 설정 | 아래 참조 |
| columns | array | 컬럼 설정 (v2-table-list와 동일) | - |
| showCheckbox | boolean | 체크박스 표시 | true/false |
**groupConfig 구조**:
```json
{
"groupByColumn": "category",
"groupLabelFormat": "{category_name} ({category_code})",
"summary": {
"sumColumns": ["quantity", "amount"],
"showCount": true
},
"defaultExpanded": true,
"nestedGroup": null
}
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
#### v2-table-search-widget
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
테이블 상단에 배치하는 검색/필터 바. 대상 테이블의 컬럼을 자동 감지하여 검색 필드 생성.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| autoSelectFirstTable | boolean | 첫 번째 테이블 자동 선택 | true/false |
| showTableSelector | boolean | 테이블 선택기 표시 | true/false |
| title | string | 검색 바 제목 | - |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-pivot-grid
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
다차원 피벗 테이블. 행/열/데이터/필터 영역으로 데이터 분석.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| fields | array | **필수** . 필드 정의 | 아래 참조 |
| dataSource | object | 데이터 소스 | `{ type: "table"/"api"/"static", joinConfigs, filterConditions }` |
**fields 배열 항목**:
```json
{
"dataField": "region",
"area": "row",
"caption": "지역"
}
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
area 값: `"row"` , `"column"` , `"data"` , `"filter"`
summaryType (area=data일 때): `"sum"` , `"avg"` , `"count"` , `"min"` , `"max"` , `"countDistinct"`
groupInterval (날짜 필드): `"year"` , `"quarter"` , `"month"` , `"week"` , `"day"`
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-text-display
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
라벨, 제목, 설명 텍스트 표시.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 |
|------|------|------|
| fontSize | string | 폰트 크기 |
| fontWeight | string | 폰트 두께 |
| color | string | 텍스트 색상 |
| textAlign | string | 정렬 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-card-display
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
테이블 데이터를 카드 형태로 표시.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| dataSource | string | 데이터 소스 | `"table"` , `"static"` , `"api"` |
| cardsPerRow | number | 행당 카드 수 | 1~6 |
| columnMapping | object | 필드 매핑 | `{ title, subtitle, description, image, status }` |
| cardStyle | object | 카드 스타일 | `{ imagePosition, imageSize }` |
#### v2-aggregation-widget
합계, 평균, 개수, 최대, 최소 등 집계 카드 표시.
| 설정 | 타입 | 설명 |
|------|------|------|
| items | array | 집계 항목 배열 (테이블, 컬럼, 집계함수) |
| filters | array | 필터 조건 |
| layout | string | 레이아웃 (horizontal/vertical) |
#### v2-status-count
상태별 건수를 카드 형태로 표시. 대시보드/현황 화면에 적합.
#### v2-numbering-rule
자동 코드/번호 채번. 접두사 + 날짜 + 순번 조합.
| 설정 | 타입 | 설명 |
|------|------|------|
| rule | string | 채번 규칙 |
| prefix | string | 접두사 |
| format | string | 포맷 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-category-manager
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
트리 기반 카테고리 관리 (3단계 계층). 카테고리 생성/수정/삭제/이동.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
---
### 1.3 레이아웃 컴포넌트
#### v2-split-panel-layout
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**가장 복잡하고 중요한 컴포넌트**. 마스터-디테일 좌우 분할 레이아웃.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| splitRatio | number | 좌측 비율 (0-100) | 기본 30 |
| resizable | boolean | 리사이즈 가능 | true/false |
| minLeftWidth | number | 좌측 최소 너비 | 기본 200 |
| minRightWidth | number | 우측 최소 너비 | 기본 300 |
| syncSelection | boolean | 선택 동기화 | true/false |
| autoLoad | boolean | 자동 로드 | true/false |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**leftPanel / rightPanel 구조**:
```json
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"leftPanel": {
"displayMode": "table",
"tableName": "master_table",
"columns": [],
"showSearch": true,
"showAdd": true,
"showEdit": true,
"showDelete": true,
"addButton": {
"enabled": true,
"mode": "auto",
"modalScreenId": ""
},
"editButton": {
"enabled": true,
"mode": "auto",
"modalScreenId": ""
},
"deleteButton": {
"enabled": true,
"buttonLabel": "삭제",
"confirmMessage": "삭제하시겠습니까?"
},
"addModalColumns": [],
"additionalTabs": [],
"dataFilter": {}
2026-02-24 10:15:25 +09:00
},
2026-03-13 15:02:06 +09:00
"rightPanel": {
"displayMode": "table",
"tableName": "detail_table",
"relation": {
"type": "detail",
"foreignKey": "master_id",
"leftColumn": "id",
"rightColumn": "master_id",
"keys": []
},
"addButton": { "enabled": true },
"editButton": { "enabled": true },
"deleteButton": { "enabled": true },
"additionalTabs": []
}
2026-01-30 14:13:44 +09:00
}
```
2026-03-13 15:02:06 +09:00
**displayMode 종류**:
- `"list"` : 리스트 형태 (제목, 부제목)
- `"table"` : 테이블 형태 (컬럼, 행)
- `"custom"` : 자유 배치 (components 배열로 내부 컴포넌트 배치)
**relation.type 종류**:
- `"join"` : 두 테이블 JOIN
- `"detail"` : 마스터 PK → 디테일 FK 관계
- `"custom"` : 커스텀 관계 (leftColumn, rightColumn 직접 지정)
**additionalTabs** (우측 패널에 멀티 탭 배치):
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
```json
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"additionalTabs": [
{
"id": "tab1",
"label": "기본정보",
"tableName": "detail_basic",
"relation": { "type": "detail", "foreignKey": "master_id" }
2026-02-24 10:15:25 +09:00
},
2026-03-13 15:02:06 +09:00
{
"id": "tab2",
"label": "이력",
"tableName": "detail_history",
"relation": { "type": "detail", "foreignKey": "master_id" }
2026-01-30 14:13:44 +09:00
}
2026-03-13 15:02:06 +09:00
]
2026-01-30 14:13:44 +09:00
}
```
2026-03-13 15:02:06 +09:00
#### v2-tabs-widget
탭 전환 레이아웃. 탭 내부에 컴포넌트를 배치할 수 있음.
2026-01-30 16:34:05 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| tabs | array | **필수** . 탭 배열 | `[{ id, label, order, disabled, components }]` |
| defaultTab | string | 기본 활성 탭 ID | - |
| orientation | string | 탭 방향 | `"horizontal"` , `"vertical"` |
| persistSelection | boolean | 선택 유지 | true/false |
2026-01-30 16:34:05 +09:00
2026-03-13 15:02:06 +09:00
**tabs 항목 구조**:
```json
2026-01-30 16:34:05 +09:00
{
2026-03-13 15:02:06 +09:00
"id": "tab-basic",
"label": "기본정보",
"order": 0,
"disabled": false,
"components": [
{
"id": "tbl-basic",
"componentType": "v2-table-list",
"label": "기본정보",
"position": { "x": 0, "y": 0 },
"size": { "width": 800, "height": 400 },
"componentConfig": { "selectedTable": "basic_info" }
}
]
2026-01-30 16:34:05 +09:00
}
```
2026-03-13 15:02:06 +09:00
#### v2-section-card
제목+테두리가 있는 그룹화 컨테이너. 폼 필드를 묶을 때 사용.
| 설정 | 타입 | 설명 |
|------|------|------|
| title | string | 섹션 제목 |
| collapsible | boolean | 접기/펼치기 가능 |
| padding | string | 내부 여백 |
#### v2-section-paper
배경색 기반 미니멀 그룹화 컨테이너.
#### v2-divider-line
영역 구분선 (가로/세로).
#### v2-split-line
캔버스 화면에서 좌우 영역을 분할하는 드래그 가능한 세로선. 디자이너 모드에서 사용.
#### v2-repeat-container
데이터 수만큼 내부 컴포넌트를 반복 렌더링.
2026-01-30 16:34:05 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| dataSourceType | string | 데이터 소스 | `"table"` , `"api"` , `"static"` |
| layout | string | 레이아웃 | `"vertical"` , `"horizontal"` , `"grid"` |
| gridColumns | number | 그리드 열 수 | 1~12 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-repeater
인라인/모달/버튼 모드로 반복 데이터를 관리하는 컴포넌트. 주문 상세, 항목 리스트 등.
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| mode | string | 동작 모드 | `"inline"` (인라인 편집), `"modal"` (모달 팝업), `"button"` (버튼 트리거) |
---
### 1.4 특수/비즈니스 컴포넌트
#### v2-button-primary
저장, 삭제, 조회 등 액션 버튼. 제어관리(dataflow)와 연결 가능.
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| text | string | 버튼 텍스트 | 예: `"저장"` , `"삭제"` |
| actionType | string | 액션 유형 | `"save"` , `"delete"` , `"search"` , `"custom"` |
| variant | string | 스타일 | `"default"` , `"outline"` , `"destructive"` , `"ghost"` |
**제어관리 연결** (webTypeConfig.dataflowConfig):
```json
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"webTypeConfig": {
"enableDataflowControl": true,
"dataflowConfig": {
"controlMode": "relationship",
"relationshipConfig": {
"relationshipId": "rel_001",
"relationshipName": "수주확정",
"executionTiming": "after"
}
}
}
2026-01-30 14:13:44 +09:00
}
```
2026-03-13 15:02:06 +09:00
executionTiming 값:
- `"before"` : 메인 액션 전에 제어 실행 (조건 체크용)
- `"after"` : 메인 액션 후에 제어 실행 (후처리용)
- `"replace"` : 메인 액션 대신 제어만 실행
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
#### v2-timeline-scheduler
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
간트차트형 일정/계획 시각화. 드래그/리사이즈로 일정 변경 가능.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
| 설정 | 타입 | 설명 | 값 |
|------|------|------|----|
| selectedTable | string | 스케줄 테이블명 | - |
| resourceTable | string | 리소스 테이블명 (설비/작업자) | - |
| fieldMapping | object | 필드 매핑 | `{ id, resourceId, title, startDate, endDate, status, progress }` |
| resourceFieldMapping | object | 리소스 필드 매핑 | `{ id, name, group }` |
| defaultZoomLevel | string | 초기 줌 | `"day"` , `"week"` , `"month"` |
| editable | boolean | 편집 가능 | true/false |
| allowDrag | boolean | 드래그 이동 허용 | true/false |
| allowResize | boolean | 리사이즈 허용 | true/false |
#### v2-approval-step
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
결재 단계 스테퍼 시각화. 결재 프로세스의 진행 상태를 단계별로 표시.
2026-02-24 10:15:25 +09:00
2026-03-13 15:02:06 +09:00
#### v2-bom-tree
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
BOM(Bill of Materials) 계층 트리 표시. 정전개(상위→하위)/역전개(하위→상위) 전환 가능.
#### v2-bom-item-editor
BOM 하위품목 트리 편집. 하위 부품 추가/수정/삭제/수량 변경 등.
2026-01-30 14:13:44 +09:00
---
2026-03-13 15:02:06 +09:00
## 2. 화면 패턴별 상세 구현 가이드
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### 2.1 패턴 A: 기본 마스터 (검색 + 테이블)
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**적용 조건**: 단일 테이블 CRUD. 마스터-디테일 관계 없음.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**layout_data 예시**:
```json
{
"version": "2.0",
"components": [
{
"id": "search_widget",
"url": "@/lib/registry/components/v2-table-search-widget",
"position": { "x": 0, "y": 0, "z": 1 },
"size": { "width": 1920, "height": 100 },
"displayOrder": 0,
"overrides": {
"label": "검색",
"autoSelectFirstTable": true
}
},
{
"id": "table_list",
"url": "@/lib/registry/components/v2-table-list",
"position": { "x": 0, "y": 120, "z": 1 },
"size": { "width": 1920, "height": 700 },
"displayOrder": 1,
"overrides": {
"label": "품목 목록",
"tableName": "item_info",
"columns": [
{ "columnName": "item_code", "displayName": "품목코드", "visible": true, "sortable": true, "width": 120 },
{ "columnName": "item_name", "displayName": "품목명", "visible": true, "sortable": true, "width": 200 },
{ "columnName": "item_type", "displayName": "품목유형", "visible": true, "width": 100 },
{ "columnName": "unit", "displayName": "단위", "visible": true, "width": 80 }
],
"pagination": { "enabled": true, "pageSize": 20 },
"checkbox": { "enabled": true, "multiple": true }
}
}
],
"gridSettings": { "columns": 12, "gap": 16, "padding": 16 },
"screenResolution": { "width": 1920, "height": 1080 }
}
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
### 2.2 패턴 B: 마스터-디테일 (좌우 분할)
**적용 조건**: 마스터 테이블 선택 시 연관 디테일 테이블 표시. 두 테이블 간 FK 관계 존재.
**layout_data 예시**:
```json
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"version": "2.0",
"components": [
{
"id": "split_panel",
"url": "@/lib/registry/components/v2-split-panel-layout",
"position": { "x": 0, "y": 0, "z": 1 },
"size": { "width": 1920, "height": 800 },
"displayOrder": 0,
"overrides": {
"label": "수주관리",
"splitRatio": 35,
"resizable": true,
"leftPanel": {
"displayMode": "table",
"tableName": "order_master",
"columns": [
{ "columnName": "order_no", "displayName": "수주번호", "visible": true, "width": 120 },
{ "columnName": "customer_name", "displayName": "거래처", "visible": true, "width": 150 },
{ "columnName": "order_date", "displayName": "수주일자", "visible": true, "width": 100 },
{ "columnName": "status", "displayName": "상태", "visible": true, "width": 80 }
],
"showSearch": true,
"showAdd": true,
"showDelete": true,
"addButton": { "enabled": true, "mode": "auto" },
"deleteButton": { "enabled": true, "confirmMessage": "삭제하시겠습니까?" }
},
"rightPanel": {
"displayMode": "table",
"tableName": "order_detail",
"relation": {
"type": "detail",
"foreignKey": "order_master_id",
"leftColumn": "id",
"rightColumn": "order_master_id"
},
"columns": [
{ "columnName": "item_code", "displayName": "품목코드", "visible": true, "width": 120 },
{ "columnName": "item_name", "displayName": "품목명", "visible": true, "width": 150 },
{ "columnName": "quantity", "displayName": "수량", "visible": true, "width": 80, "editable": true },
{ "columnName": "unit_price", "displayName": "단가", "visible": true, "width": 100, "editable": true }
],
"addButton": { "enabled": true },
"deleteButton": { "enabled": true }
}
}
}
],
"gridSettings": { "columns": 12, "gap": 16, "padding": 16 },
"screenResolution": { "width": 1920, "height": 1080 }
2026-01-30 14:13:44 +09:00
}
```
2026-03-13 15:02:06 +09:00
### 2.3 패턴 C: 마스터-디테일 + 탭
**적용 조건**: 마스터-디테일에서 우측에 여러 종류의 상세 정보를 탭으로 분리.
**차이점**: rightPanel에 `additionalTabs` 배열 추가.
```json
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"rightPanel": {
"displayMode": "table",
"tableName": "customer_basic",
"relation": {
"type": "detail",
"foreignKey": "customer_id"
},
"additionalTabs": [
{
"id": "tab-basic",
"label": "기본정보",
"tableName": "customer_basic",
"relation": { "type": "detail", "foreignKey": "customer_id" }
},
{
"id": "tab-history",
"label": "거래이력",
"tableName": "customer_history",
"relation": { "type": "detail", "foreignKey": "customer_id" }
},
{
"id": "tab-files",
"label": "첨부파일",
"tableName": "customer_files",
"relation": { "type": "detail", "foreignKey": "customer_id" }
}
]
}
2026-01-30 14:13:44 +09:00
}
```
2026-03-13 15:02:06 +09:00
---
## 3. 제어관리 (비즈니스 로직) 설정
### 3.1 개요
V2 컴포넌트는 **UI만 담당**한다. 버튼 클릭 시 실행되는 비즈니스 로직(INSERT/UPDATE/DELETE, 조건 체크, 외부 호출 등)은 `dataflow_diagrams` 테이블에서 별도 설정한다.
### 3.2 설정 위치
| 구분 | 저장 위치 | 용도 |
|------|----------|------|
| 버튼-제어 연결 | `screen_layouts_v2` → 컴포넌트 `webTypeConfig.dataflowConfig` | 어떤 버튼이 어떤 제어를 실행하는지 |
| 제어 정의 | `dataflow_diagrams` → `control` , `plan` JSONB | 조건, 액션, 필드 매핑 |
| 노드 플로우 | `node_flows` → `flow_data` JSONB | 복잡한 다단계 플로우 |
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### 3.3 실행 흐름
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
[버튼 클릭] v2-button-primary
│
▼
[설정 확인] webTypeConfig.dataflowConfig
│
├─ controlMode: "relationship" → dataflow_diagrams 실행
├─ controlMode: "flow" → node_flows 실행
└─ controlMode: "none" → 기본 액션만 실행
│
▼
[실행기] ImprovedButtonActionExecutor
│
├─ 1. Before 제어 (executionTiming = "before")
│ └─ 조건 체크 → 실패 시 중단
│
├─ 2. Main 액션 (executionTiming ≠ "replace"일 때)
│ └─ save / delete / update 실행
│
└─ 3. After 제어 (executionTiming = "after")
└─ 후처리 (이력 저장, 상태 변경, 외부 호출 등)
2026-01-30 14:13:44 +09:00
```
2026-03-13 15:02:06 +09:00
### 3.4 dataflow_diagrams 설정 예시
**시나리오**: 수주 목록에서 [확정] 버튼 클릭 → 상태를 '확정'으로 변경 + 이력 테이블에 기록
2026-01-30 14:13:44 +09:00
```json
{
2026-03-13 15:02:06 +09:00
"control": [
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"conditions": [
{ "field": "status", "operator": "=", "value": "대기", "dataType": "string" }
],
"triggerType": "update"
}
],
"plan": [
2026-01-30 14:13:44 +09:00
{
2026-03-13 15:02:06 +09:00
"actions": [
{
"actionType": "update",
"targetTable": "order_master",
"conditions": [
{ "field": "status", "operator": "=", "value": "대기" }
],
"fieldMappings": [
{ "targetField": "status", "defaultValue": "확정" }
]
},
{
"actionType": "insert",
"targetTable": "order_history",
"fieldMappings": [
{ "sourceField": "order_no", "targetField": "order_no" },
{ "sourceField": "customer_name", "targetField": "customer_name" },
{ "targetField": "action", "defaultValue": "확정" }
]
}
2026-01-30 14:13:44 +09:00
]
}
]
}
```
2026-03-13 15:02:06 +09:00
---
## 4. 화면 개발 체크리스트 (AI 에이전트용)
화면 개발 요청을 받았을 때 이 순서대로 확인한다.
### Step 1: 요구사항 분석
```
□ 어떤 테이블을 사용하는가? (메인 테이블, 디테일 테이블)
□ 테이블 간 관계는? (FK, 1:N, M:N)
□ 어떤 패턴인가? (A~G 중 선택, 의사결정 트리 참조)
□ 어떤 버튼이 필요한가? (저장, 삭제, 확정 등)
□ 비즈니스 로직이 있는가? (상태 변경, 이력 기록, 외부 호출 등)
```
### Step 2: DB 테이블 생성
```
□ 모든 컬럼 VARCHAR(500)
□ 기본 5개 컬럼 포함 (id, created_date, updated_date, writer, company_code)
□ table_labels, table_type_columns, column_labels 메타데이터 등록
□ company_code 인덱스 생성
```
### Step 3: screen_definitions INSERT
```sql
INSERT INTO screen_definitions (screen_name, screen_code, table_name, company_code, is_active)
VALUES ('화면명', '{company_code}_순번', '메인_테이블', '{company_code}', 'Y');
```
### Step 4: screen_layouts_v2 INSERT
```sql
INSERT INTO screen_layouts_v2 (screen_id, company_code, layer_id, layout_data)
VALUES ({screen_id}, '{company_code}', 1, '{패턴별 JSON}');
```
### Step 5: dataflow_diagrams INSERT (비즈니스 로직 필요 시)
2026-01-30 14:13:44 +09:00
```
□ 버튼별 액션 정의
2026-03-13 15:02:06 +09:00
□ 조건 설정 (어떤 상태일 때만 실행)
□ 필드 매핑 (소스→타겟)
□ 실행 타이밍 (before/after/replace)
```
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Step 6: menu_info INSERT
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
```sql
INSERT INTO menu_info (screen_id, menu_url, company_code, ...)
VALUES ({screen_id}, '/screen/{screen_code}', '{company_code}', ...);
```
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Step 7: 멀티테넌시 검증
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
```
□ 테이블에 company_code 컬럼 존재
□ 모든 SELECT에 company_code 필터링
□ INSERT에 company_code 포함
□ UPDATE/DELETE WHERE절에 company_code 포함
□ JOIN에 company_code 매칭
2026-01-30 14:13:44 +09:00
```
---
2026-03-13 15:02:06 +09:00
## 5. 자주 묻는 질문 (FAQ)
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Q: v2-table-list와 v2-table-grouped 중 어떤 걸 써야 하나?
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**A**: 데이터를 특정 컬럼 기준으로 묶어서 접기/펼치기가 필요하면 `v2-table-grouped` , 아니면 `v2-table-list` . 예를 들어 "카테고리별 품목 목록"은 `v2-table-grouped` , "품목 전체 목록"은 `v2-table-list` .
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Q: 마스터-디테일에서 탭을 사용하고 싶은데?
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**A**: `v2-split-panel-layout` 의 rightPanel에 `additionalTabs` 배열을 설정한다. 별도의 `v2-tabs-widget` 을 배치할 필요 없다.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Q: BOM 화면은 어떻게 만드나?
**A**: `v2-split-panel-layout` 의 좌측에 `v2-bom-tree` (또는 `v2-table-list` ), 우측에 `v2-bom-item-editor` 를 배치한다. 트리 컴포넌트가 자체적으로 정전개/역전개를 지원한다.
### Q: 버튼 클릭 시 특정 로직을 실행하고 싶은데?
**A**: `v2-button-primary` 의 `webTypeConfig.dataflowConfig` 에 제어관리를 연결한다. `dataflow_diagrams` 테이블에 실행할 액션(INSERT/UPDATE/DELETE)과 조건을 정의한다.
### Q: 검색 기능은 어떻게 추가하나?
**A**: `v2-table-search-widget` 을 `v2-table-list` 위에 배치한다. `autoSelectFirstTable: true` 로 설정하면 자동으로 화면의 첫 번째 테이블과 연동된다.
### Q: 파일 업로드는?
**A**: `v2-file-upload` 컴포넌트를 사용한다. 폼 내 배치하여 파일/이미지 업로드를 처리한다.
### Q: 결재 프로세스를 표시하고 싶은데?
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**A**: `v2-approval-step` 컴포넌트를 사용한다. 결재 단계를 스테퍼 형태로 시각화한다.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Q: 인라인 편집이 가능한가?
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**A**: `v2-table-list` 의 columns에서 `editable: true` 로 설정하면 해당 컬럼의 셀을 직접 편집할 수 있다. 단, 복잡한 편집은 모달 편집(`v2-split-panel-layout`의 editButton.mode = "modal")을 권장한다.
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
### Q: 화면에 집계(합계, 평균 등)를 표시하고 싶은데?
2026-01-30 14:13:44 +09:00
2026-03-13 15:02:06 +09:00
**A**: `v2-aggregation-widget` 을 사용하여 테이블 데이터의 합계, 평균, 개수 등을 카드 형태로 표시한다. 또는 `v2-status-count` 로 상태별 건수를 표시한다.
2026-01-30 14:13:44 +09:00
---
2026-03-13 15:02:06 +09:00
## 6. 컴포넌트 선택 빠른 참조표
| 요구사항 | 컴포넌트 |
|----------|----------|
| 데이터 목록 보기 | `v2-table-list` |
| 데이터 검색/필터 | `v2-table-search-widget` |
| 좌우 분할 (마스터-디테일) | `v2-split-panel-layout` |
| 그룹별 묶기 (접기/펼치기) | `v2-table-grouped` |
| 탭 전환 | `v2-tabs-widget` 또는 `v2-split-panel-layout` 의 additionalTabs |
| 카드 형태 보기 | `v2-card-display` |
| 피벗/집계 분석 | `v2-pivot-grid` |
| 간트차트/일정 | `v2-timeline-scheduler` |
| BOM 트리 | `v2-bom-tree` + `v2-bom-item-editor` |
| 텍스트 입력 | `v2-input` |
| 선택 (드롭다운 등) | `v2-select` |
| 날짜 입력 | `v2-date` |
| 파일 업로드 | `v2-file-upload` |
| 액션 버튼 | `v2-button-primary` |
| 자동 채번 | `v2-numbering-rule` |
| 카테고리 관리 | `v2-category-manager` |
| 결재 단계 표시 | `v2-approval-step` |
| 상태별 건수 | `v2-status-count` |
| 합계/평균 카드 | `v2-aggregation-widget` |
| 구분선 | `v2-divider-line` |
| 그룹 컨테이너 | `v2-section-card` 또는 `v2-section-paper` |
| 데이터 반복 | `v2-repeat-container` 또는 `v2-repeater` |
| 공정 작업기준 | `v2-process-work-standard` |
| 품목 라우팅 | `v2-item-routing` |
| 미디어 표시 | `v2-media` |
| 랙 구조 | `v2-rack-structure` |
| 위치 교환 | `v2-location-swap-selector` |