400 lines
14 KiB
Markdown
400 lines
14 KiB
Markdown
|
|
# V2 마이그레이션 학습노트 (DDD1542 전용)
|
||
|
|
|
||
|
|
> **목적**: 마이그레이션 작업 전 완벽한 이해를 위한 개인 학습노트
|
||
|
|
> **작성일**: 2026-02-03
|
||
|
|
> **절대 규칙**: 모르면 물어보기, 추측 금지
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. 가장 중요한 핵심 (이전 신하가 실패한 이유)
|
||
|
|
|
||
|
|
### 1.1 "component" vs "v2-input" 차이
|
||
|
|
|
||
|
|
```
|
||
|
|
[잘못된 상태] [올바른 상태]
|
||
|
|
┌──────────────────┐ ┌──────────────────┐
|
||
|
|
│ component │ │ v2-input │
|
||
|
|
│ 업체코드 │ │ 업체코드 │
|
||
|
|
│ "자동 생성됩니다" │ │ "자동 생성됩니다" │
|
||
|
|
└──────────────────┘ └──────────────────┘
|
||
|
|
↑ ↑
|
||
|
|
테이블-컬럼 연결 없음 table_name + column_name 연결됨
|
||
|
|
```
|
||
|
|
|
||
|
|
**핵심**: 컬럼을 왼쪽 패널에서 **드래그**해야 올바른 연결이 생성됨
|
||
|
|
|
||
|
|
### 1.2 올바른 컴포넌트 생성 방법
|
||
|
|
|
||
|
|
```
|
||
|
|
[왼쪽 패널: 테이블 컬럼 목록]
|
||
|
|
운송업체 (8개)
|
||
|
|
├── 업체코드 [numbering] ─드래그→ 화면 캔버스 → v2-numbering-rule (또는 v2-input)
|
||
|
|
├── 업체명 [text] ─드래그→ 화면 캔버스 → v2-input
|
||
|
|
├── 유형 [category] ─드래그→ 화면 캔버스 → v2-select
|
||
|
|
├── 연락처 [text] ─드래그→ 화면 캔버스 → v2-input
|
||
|
|
└── ...
|
||
|
|
```
|
||
|
|
|
||
|
|
### 1.3 input_type → V2 컴포넌트 매핑
|
||
|
|
|
||
|
|
| table_type_columns.input_type | V2 컴포넌트 | 연동 테이블 |
|
||
|
|
|-------------------------------|-------------|-------------|
|
||
|
|
| text | v2-input | - |
|
||
|
|
| number | v2-input (type=number) | - |
|
||
|
|
| date | v2-date | - |
|
||
|
|
| category | v2-select | category_values |
|
||
|
|
| numbering | v2-numbering-rule 또는 v2-input | numbering_rules |
|
||
|
|
| entity | v2-entity-search | 엔티티 조인 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. V1 vs V2 구조 차이
|
||
|
|
|
||
|
|
### 2.1 테이블 구조
|
||
|
|
|
||
|
|
```
|
||
|
|
V1 (본서버: screen_layouts) V2 (개발서버: screen_layouts_v2)
|
||
|
|
──────────────────────────────────────────────────────────────────
|
||
|
|
- 컴포넌트별 1개 레코드 - 화면당 1개 레코드
|
||
|
|
- properties JSONB - layout_data JSONB
|
||
|
|
- component_type VARCHAR - url (컴포넌트 경로)
|
||
|
|
- menu_objid 기반 채번/카테고리 - table_name + column_name 기반
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 V2 layout_data 구조
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"version": "2.0",
|
||
|
|
"components": [
|
||
|
|
{
|
||
|
|
"id": "comp_xxx",
|
||
|
|
"url": "@/lib/registry/components/v2-table-list",
|
||
|
|
"position": { "x": 0, "y": 0 },
|
||
|
|
"size": { "width": 100, "height": 50 },
|
||
|
|
"displayOrder": 0,
|
||
|
|
"overrides": {
|
||
|
|
"tableName": "inspection_standard",
|
||
|
|
"columns": ["id", "name", "status"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"updatedAt": "2026-02-03T12:00:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.3 컴포넌트 URL 매핑
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const V1_TO_V2_URL_MAPPING = {
|
||
|
|
'table-list': '@/lib/registry/components/v2-table-list',
|
||
|
|
'button-primary': '@/lib/registry/components/v2-button-primary',
|
||
|
|
'text-input': '@/lib/registry/components/v2-input',
|
||
|
|
'select-basic': '@/lib/registry/components/v2-select',
|
||
|
|
'date-input': '@/lib/registry/components/v2-date',
|
||
|
|
'entity-search-input': '@/lib/registry/components/v2-entity-search',
|
||
|
|
'category-manager': '@/lib/registry/components/v2-category-manager',
|
||
|
|
'numbering-rule': '@/lib/registry/components/v2-numbering-rule',
|
||
|
|
'tabs-widget': '@/lib/registry/components/v2-tabs-widget',
|
||
|
|
'split-panel-layout': '@/lib/registry/components/v2-split-panel-layout',
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 데이터 타입 관리 (V2)
|
||
|
|
|
||
|
|
### 3.1 핵심 테이블 관계
|
||
|
|
|
||
|
|
```
|
||
|
|
table_type_columns (컬럼 타입 정의)
|
||
|
|
├── input_type = 'category' → category_values (table_name + column_name)
|
||
|
|
├── input_type = 'numbering' → numbering_rules (detail_settings.numberingRuleId)
|
||
|
|
├── input_type = 'entity' → 엔티티 조인
|
||
|
|
└── input_type = 'text', 'number', 'date', etc.
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.2 category_values 조회 쿼리
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 특정 테이블.컬럼의 카테고리 값 조회
|
||
|
|
SELECT value_id, value_code, value_label, parent_value_id, depth
|
||
|
|
FROM category_values
|
||
|
|
WHERE table_name = '테이블명'
|
||
|
|
AND column_name = '컬럼명'
|
||
|
|
AND company_code = 'COMPANY_7'
|
||
|
|
ORDER BY value_order;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.3 numbering_rules 연결 방식
|
||
|
|
|
||
|
|
```json
|
||
|
|
// table_type_columns.detail_settings
|
||
|
|
{
|
||
|
|
"numberingRuleId": "rule-xxx"
|
||
|
|
}
|
||
|
|
|
||
|
|
// numbering_rules에서 해당 rule 조회
|
||
|
|
SELECT * FROM numbering_rules WHERE rule_id = 'rule-xxx';
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. V2 컴포넌트 목록 (23개)
|
||
|
|
|
||
|
|
### 4.1 입력 컴포넌트
|
||
|
|
|
||
|
|
| ID | 이름 | 용도 |
|
||
|
|
|----|------|------|
|
||
|
|
| v2-input | 입력 | 텍스트, 숫자, 비밀번호, 이메일 |
|
||
|
|
| v2-select | 선택 | 드롭다운, 라디오, 체크박스 |
|
||
|
|
| v2-date | 날짜 | 날짜, 시간, 날짜범위 |
|
||
|
|
|
||
|
|
### 4.2 표시 컴포넌트
|
||
|
|
|
||
|
|
| ID | 이름 | 용도 |
|
||
|
|
|----|------|------|
|
||
|
|
| v2-text-display | 텍스트 표시 | 라벨, 제목 |
|
||
|
|
| v2-card-display | 카드 디스플레이 | 카드 형태 데이터 |
|
||
|
|
| v2-aggregation-widget | 집계 위젯 | 합계, 평균, 개수 |
|
||
|
|
|
||
|
|
### 4.3 테이블/데이터 컴포넌트
|
||
|
|
|
||
|
|
| ID | 이름 | 용도 |
|
||
|
|
|----|------|------|
|
||
|
|
| v2-table-list | 테이블 리스트 | 데이터 그리드 |
|
||
|
|
| v2-table-search-widget | 검색 필터 | 테이블 검색 |
|
||
|
|
| v2-pivot-grid | 피벗 그리드 | 다차원 분석 |
|
||
|
|
| v2-table-grouped | 그룹화 테이블 | 그룹별 접기/펼치기 |
|
||
|
|
|
||
|
|
### 4.4 레이아웃 컴포넌트
|
||
|
|
|
||
|
|
| ID | 이름 | 용도 |
|
||
|
|
|----|------|------|
|
||
|
|
| v2-split-panel-layout | 분할 패널 | 마스터-디테일 |
|
||
|
|
| v2-tabs-widget | 탭 위젯 | 탭 전환 |
|
||
|
|
| v2-section-card | 섹션 카드 | 제목+테두리 그룹 |
|
||
|
|
| v2-section-paper | 섹션 페이퍼 | 배경색 그룹 |
|
||
|
|
| v2-divider-line | 구분선 | 영역 구분 |
|
||
|
|
| v2-repeat-container | 리피터 컨테이너 | 데이터 반복 |
|
||
|
|
| v2-unified-repeater | 통합 리피터 | 인라인/모달/버튼 |
|
||
|
|
|
||
|
|
### 4.5 액션/특수 컴포넌트
|
||
|
|
|
||
|
|
| ID | 이름 | 용도 |
|
||
|
|
|----|------|------|
|
||
|
|
| v2-button-primary | 기본 버튼 | 저장, 삭제 등 |
|
||
|
|
| v2-numbering-rule | 채번 규칙 | 자동 코드 생성 |
|
||
|
|
| v2-category-manager | 카테고리 관리자 | 카테고리 관리 |
|
||
|
|
| v2-location-swap-selector | 위치 교환 | 위치 선택 |
|
||
|
|
| v2-rack-structure | 랙 구조 | 창고 랙 시각화 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 화면 패턴 (5가지)
|
||
|
|
|
||
|
|
### 5.1 패턴 A: 기본 마스터 화면
|
||
|
|
|
||
|
|
```
|
||
|
|
사용 조건: 단일 테이블 CRUD
|
||
|
|
|
||
|
|
┌─────────────────────────────────────────────────┐
|
||
|
|
│ v2-table-search-widget │
|
||
|
|
├─────────────────────────────────────────────────┤
|
||
|
|
│ v2-table-list │
|
||
|
|
│ [신규] [삭제] v2-button-primary │
|
||
|
|
└─────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5.2 패턴 B: 마스터-디테일 화면
|
||
|
|
|
||
|
|
```
|
||
|
|
사용 조건: 마스터 선택 → 디테일 표시
|
||
|
|
|
||
|
|
┌──────────────────┬──────────────────────────────┐
|
||
|
|
│ 마스터 리스트 │ 디테일 리스트 │
|
||
|
|
│ v2-table-list │ v2-table-list │
|
||
|
|
│ │ (relation: foreignKey) │
|
||
|
|
└──────────────────┴──────────────────────────────┘
|
||
|
|
v2-split-panel-layout
|
||
|
|
```
|
||
|
|
|
||
|
|
**필수 설정:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"leftPanel": { "tableName": "master_table" },
|
||
|
|
"rightPanel": {
|
||
|
|
"tableName": "detail_table",
|
||
|
|
"relation": { "type": "detail", "foreignKey": "master_id" }
|
||
|
|
},
|
||
|
|
"splitRatio": 30
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5.3 패턴 C: 마스터-디테일 + 탭
|
||
|
|
|
||
|
|
```
|
||
|
|
┌──────────────────┬──────────────────────────────┐
|
||
|
|
│ 마스터 리스트 │ v2-tabs-widget │
|
||
|
|
│ v2-table-list │ ├─ 탭1: v2-table-list │
|
||
|
|
│ │ ├─ 탭2: v2-table-list │
|
||
|
|
│ │ └─ 탭3: 폼 컴포넌트들 │
|
||
|
|
└──────────────────┴──────────────────────────────┘
|
||
|
|
v2-split-panel-layout
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. 모달 처리 방식 변경
|
||
|
|
|
||
|
|
### 6.1 V1 (본서버)
|
||
|
|
|
||
|
|
```
|
||
|
|
화면 A (screen_id: 142) - 검사장비관리
|
||
|
|
└── 버튼 클릭 → 화면 B (screen_id: 143) - 검사장비 등록모달 (별도 screen_id)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6.2 V2 (개발서버)
|
||
|
|
|
||
|
|
```
|
||
|
|
화면 A (screen_id: 142) - 검사장비관리
|
||
|
|
└── layout_data.components[] 내에 v2-dialog-form 또는 overlay 포함
|
||
|
|
```
|
||
|
|
|
||
|
|
**핵심**: V2에서는 모달을 별도 화면이 아닌, 부모 화면의 컴포넌트로 통합
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. 마이그레이션 절차 (Step by Step)
|
||
|
|
|
||
|
|
### Step 1: 사전 분석
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 본서버 화면 목록 확인
|
||
|
|
SELECT sd.screen_id, sd.screen_code, sd.screen_name, sd.table_name,
|
||
|
|
COUNT(sl.layout_id) as component_count
|
||
|
|
FROM screen_definitions sd
|
||
|
|
LEFT JOIN screen_layouts sl ON sd.screen_id = sl.screen_id
|
||
|
|
WHERE sd.screen_code LIKE 'COMPANY_7_%'
|
||
|
|
GROUP BY sd.screen_id, sd.screen_code, sd.screen_name, sd.table_name;
|
||
|
|
|
||
|
|
-- 개발서버 V2 현황 확인
|
||
|
|
SELECT sd.screen_id, sd.screen_code, sd.screen_name,
|
||
|
|
sv2.layout_data IS NOT NULL as has_v2_layout
|
||
|
|
FROM screen_definitions sd
|
||
|
|
LEFT JOIN screen_layouts_v2 sv2 ON sd.screen_id = sv2.screen_id
|
||
|
|
WHERE sd.company_code = 'COMPANY_7';
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 2: table_type_columns 확인
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- 해당 테이블의 컬럼 타입 확인
|
||
|
|
SELECT column_name, column_label, input_type, detail_settings
|
||
|
|
FROM table_type_columns
|
||
|
|
WHERE table_name = '대상테이블명'
|
||
|
|
AND company_code = 'COMPANY_7';
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 3: V2 layout_data 생성
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"version": "2.0",
|
||
|
|
"components": [
|
||
|
|
{
|
||
|
|
"id": "생성된ID",
|
||
|
|
"url": "@/lib/registry/components/v2-컴포넌트타입",
|
||
|
|
"position": { "x": 0, "y": 0 },
|
||
|
|
"size": { "width": 100, "height": 50 },
|
||
|
|
"displayOrder": 0,
|
||
|
|
"overrides": {
|
||
|
|
"tableName": "테이블명",
|
||
|
|
"fieldName": "컬럼명"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"migratedFrom": "V1",
|
||
|
|
"migratedAt": "2026-02-03T00:00:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 4: screen_layouts_v2 INSERT
|
||
|
|
|
||
|
|
```sql
|
||
|
|
INSERT INTO screen_layouts_v2 (screen_id, company_code, layout_data)
|
||
|
|
VALUES ($1, $2, $3::jsonb)
|
||
|
|
ON CONFLICT (screen_id, company_code)
|
||
|
|
DO UPDATE SET layout_data = $3::jsonb, updated_at = NOW();
|
||
|
|
```
|
||
|
|
|
||
|
|
### Step 5: 검증
|
||
|
|
|
||
|
|
- [ ] 화면 렌더링 확인 (component가 아닌 v2-xxx로 표시되는지)
|
||
|
|
- [ ] 컴포넌트별 테이블-컬럼 연결 확인
|
||
|
|
- [ ] 카테고리 드롭다운 동작 확인
|
||
|
|
- [ ] 채번 규칙 동작 확인
|
||
|
|
- [ ] 저장/수정/삭제 테스트
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. 품질관리 메뉴 마이그레이션 현황
|
||
|
|
|
||
|
|
| 본서버 코드 | 화면명 | 테이블 | 상태 | 비고 |
|
||
|
|
|-------------|--------|--------|------|------|
|
||
|
|
| COMPANY_7_126 | 검사정보 관리 | inspection_standard | ✅ V2 존재 | 컴포넌트 검증 필요 |
|
||
|
|
| COMPANY_7_127 | 품목옵션 설정 | - | ✅ V2 존재 | v2-category-manager |
|
||
|
|
| COMPANY_7_138 | 카테고리 설정 | inspection_standard | ❌ 누락 | table_name 기반 |
|
||
|
|
| COMPANY_7_139 | 코드 설정 | inspection_standard | ❌ 누락 | table_name 기반 |
|
||
|
|
| COMPANY_7_142 | 검사장비 관리 | inspection_equipment_mng | ❌ 누락 | 모달 통합 |
|
||
|
|
| COMPANY_7_143 | 검사장비 등록모달 | inspection_equipment_mng | ❌ 누락 | → 142 통합 |
|
||
|
|
| COMPANY_7_144 | 불량기준 정보 | defect_standard_mng | ❌ 누락 | 모달 통합 |
|
||
|
|
| COMPANY_7_145 | 불량기준 등록모달 | defect_standard_mng | ❌ 누락 | → 144 통합 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. 관련 코드 파일 경로
|
||
|
|
|
||
|
|
| 항목 | 경로 |
|
||
|
|
|------|------|
|
||
|
|
| V2 컴포넌트 폴더 | `frontend/lib/registry/components/v2-xxx/` |
|
||
|
|
| 컴포넌트 등록 | `frontend/lib/registry/components/index.ts` |
|
||
|
|
| 카테고리 서비스 | `backend-node/src/services/categoryTreeService.ts` |
|
||
|
|
| 채번 서비스 | `backend-node/src/services/numberingRuleService.ts` |
|
||
|
|
| 엔티티 조인 API | `frontend/lib/api/entityJoin.ts` |
|
||
|
|
| 폼 호환성 훅 | `frontend/hooks/useFormCompatibility.ts` |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 10. 절대 하지 말 것
|
||
|
|
|
||
|
|
1. ❌ **테이블-컬럼 연결 없이 컴포넌트 배치** → "component"로 표시됨
|
||
|
|
2. ❌ **menu_objid 기반 카테고리/채번 사용** → V2는 table_name + column_name 기반
|
||
|
|
3. ❌ **모달을 별도 screen_id로 생성** → V2는 부모 화면에 통합
|
||
|
|
4. ❌ **V1 컴포넌트 타입 사용** → 반드시 v2- 접두사 컴포넌트 사용
|
||
|
|
5. ❌ **company_code 필터링 누락** → 멀티테넌시 필수
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 11. 모르면 확인할 곳
|
||
|
|
|
||
|
|
1. **컴포넌트 구조**: `docs/V2_컴포넌트_분석_가이드.md`
|
||
|
|
2. **화면 개발 표준**: `docs/screen-implementation-guide/화면개발_표준_가이드.md`
|
||
|
|
3. **마이그레이션 절차**: `docs/DDD1542/본서버_개발서버_마이그레이션_상세가이드.md`
|
||
|
|
4. **탑실 디자인 명세**: `/Users/gbpark/Downloads/화면개발 8/`
|
||
|
|
5. **실제 코드**: 위 경로의 소스 파일들
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 12. 왕의 훈계
|
||
|
|
|
||
|
|
> **"항상 애매한 거는 md파일 보거나 물어볼 것. 코드에는 전부 정답이 있음. 만약 모른다면 너 잘못. 실수해도 너 잘못."**
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 변경 이력
|
||
|
|
|
||
|
|
| 날짜 | 작성자 | 내용 |
|
||
|
|
|------|--------|------|
|
||
|
|
| 2026-02-03 | DDD1542 | 초안 작성 (문서 4개 정독 후) |
|