diff --git a/YARD_MANAGEMENT_3D_DATA_BINDING_REDESIGN.md b/YARD_MANAGEMENT_3D_DATA_BINDING_REDESIGN.md new file mode 100644 index 00000000..0b131635 --- /dev/null +++ b/YARD_MANAGEMENT_3D_DATA_BINDING_REDESIGN.md @@ -0,0 +1,426 @@ +# 야드 관리 3D - 데이터 바인딩 시스템 재설계 + +## 1. 개요 + +### 현재 방식의 문제점 + +- 고정된 임시 자재 마스터(`temp_material_master`) 테이블에 의존 +- 실제 외부 시스템의 자재 데이터와 연동 불가 +- 자재 목록이 제한적이고 유연성 부족 +- 사용자가 직접 데이터를 선택하거나 입력할 수 없음 + +### 새로운 방식의 목표 + +- 차트/리스트 위젯과 동일한 데이터 소스 선택 방식 적용 +- DB 커넥션 또는 REST API를 통해 실제 자재 데이터 연동 +- 사용자가 자재명, 수량 등을 직접 매핑 및 입력 가능 +- 설정되지 않은 요소는 뷰어에서 명확히 표시 + +--- + +## 2. 핵심 변경사항 + +### 2.1 요소(Element) 개념 도입 + +- 기존: 자재 목록에서 클릭 → 즉시 배치 +- 변경: [+ 요소 추가] 버튼 클릭 → 3D 캔버스에 즉시 빈 요소 배치 → 우측 패널이 데이터 바인딩 설정 화면으로 전환 + +### 2.2 데이터 소스 선택 + +- 현재 DB (내부 PostgreSQL) +- 외부 DB 커넥션 +- REST API + +### 2.3 데이터 매핑 + +- 자재명 필드 선택 (데이터 소스에서) +- 수량 필드 선택 (데이터 소스에서) +- 단위 직접 입력 (예: EA, BOX, KG 등) +- 색상 선택 + +--- + +## 3. 데이터베이스 스키마 변경 + +### 3.1 기존 테이블 수정: `yard_material_placement` + +```sql +-- 기존 컬럼 변경 +ALTER TABLE yard_material_placement + -- 기존 컬럼 제거 (외부 자재 ID 관련) + DROP COLUMN IF EXISTS external_material_id, + + -- 데이터 소스 정보 추가 + ADD COLUMN data_source_type VARCHAR(20), -- 'database', 'external_db', 'rest_api' + ADD COLUMN data_source_config JSONB, -- 데이터 소스 설정 + + -- 데이터 바인딩 정보 추가 + ADD COLUMN data_binding JSONB, -- 필드 매핑 정보 + + -- 자재 정보를 NULL 허용으로 변경 (설정 전에는 NULL) + ALTER COLUMN material_code DROP NOT NULL, + ALTER COLUMN material_name DROP NOT NULL, + ALTER COLUMN quantity DROP NOT NULL; +``` + +### 3.2 data_source_config 구조 + +```typescript +interface DataSourceConfig { + type: "database" | "external_db" | "rest_api"; + + // type === 'database' (현재 DB) + query?: string; + + // type === 'external_db' (외부 DB) + connectionId?: number; + query?: string; + + // type === 'rest_api' + url?: string; + method?: "GET" | "POST"; + headers?: Record; + queryParams?: Record; + body?: string; + dataPath?: string; // 응답에서 데이터 배열 경로 (예: "data.items") +} +``` + +### 3.3 data_binding 구조 + +```typescript +interface DataBinding { + // 데이터 소스의 특정 행 선택 + selectedRowIndex?: number; + + // 필드 매핑 (데이터 소스에서 선택) + materialNameField?: string; // 자재명이 들어있는 컬럼명 + quantityField?: string; // 수량이 들어있는 컬럼명 + + // 단위는 사용자가 직접 입력 + unit: string; // 예: "EA", "BOX", "KG", "M" 등 +} +``` + +--- + +## 4. UI/UX 설계 + +### 4.1 편집 모드 (YardEditor) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ [← 목록으로] 야드명: A구역 [저장] │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────┐ ┌──────────────────────────┐│ +│ │ │ │ ││ +│ │ │ │ [+ 요소 추가] ││ +│ │ │ │ ││ +│ │ 3D 캔버스 │ │ ┌────────────────────┐ ││ +│ │ │ │ │ □ 요소 1 │ ││ +│ │ │ │ │ 자재: 철판 A │ ││ +│ │ │ │ │ 수량: 50 EA │ ││ +│ │ │ │ │ [편집] [삭제] │ ││ +│ │ │ │ └────────────────────┘ ││ +│ │ │ │ ││ +│ │ │ │ ┌────────────────────┐ ││ +│ │ │ │ │ □ 요소 2 (미설정) │ ││ +│ │ │ │ │ 데이터 바인딩 │ ││ +│ │ │ │ │ 설정 필요 │ ││ +│ │ │ │ │ [설정] [삭제] │ ││ +│ │ │ │ └────────────────────┘ ││ +│ │ │ │ ││ +│ └───────────────────────────┘ └──────────────────────────┘│ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +#### 4.1.1 요소 목록 (우측 패널) + +- **[+ 요소 추가]** 버튼: 새 요소 생성 +- **요소 카드**: + - 설정 완료: 자재명, 수량 표시 + [편집] [삭제] 버튼 + - 미설정: "데이터 바인딩 설정 필요" + [설정] [삭제] 버튼 + +#### 4.1.2 요소 추가 흐름 + +``` +1. [+ 요소 추가] 클릭 + ↓ +2. 3D 캔버스의 기본 위치(0,0,0)에 회색 반투명 박스로 빈 요소 즉시 배치 + ↓ +3. 요소가 자동 선택됨 + ↓ +4. 우측 패널이 "데이터 바인딩 설정" 화면으로 자동 전환 + (요소 목록에서 [설정] 버튼을 클릭해도 동일한 화면) +``` + +### 4.2 데이터 바인딩 설정 패널 (우측) + +**[+ 요소 추가] 버튼 클릭 시 또는 [설정] 버튼 클릭 시 우측 패널이 아래와 같이 변경됩니다:** + +``` +┌──────────────────────────────────────┐ +│ 데이터 바인딩 설정 [← 목록]│ +├──────────────────────────────────────┤ +│ │ +│ ┌─ 1단계: 데이터 소스 선택 ─────────────────────────┐ │ +│ │ │ │ +│ │ ○ 현재 DB ○ 외부 DB ○ REST API │ │ +│ │ │ │ +│ │ [현재 DB 선택 시] │ │ +│ │ ┌────────────────────────────────────────────┐ │ │ +│ │ │ SELECT material_name, quantity, unit │ │ │ +│ │ │ FROM inventory │ │ │ +│ │ │ WHERE status = 'available' │ │ │ +│ │ └────────────────────────────────────────────┘ │ │ +│ │ [실행] 버튼 │ │ +│ │ │ │ +│ │ [외부 DB 선택 시] │ │ +│ │ - 외부 커넥션 선택 드롭다운 │ │ +│ │ - SQL 쿼리 입력 │ │ +│ │ - [실행] 버튼 │ │ +│ │ │ │ +│ │ [REST API 선택 시] │ │ +│ │ - URL 입력 │ │ +│ │ - Method 선택 (GET/POST) │ │ +│ │ - Headers, Query Params 설정 │ │ +│ │ - [실행] 버튼 │ │ +│ │ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─ 2단계: 쿼리 결과 및 필드 매핑 ──────────────────────┐ │ +│ │ │ │ +│ │ 쿼리 결과 (5행): │ │ +│ │ ┌────────────────────────────────────────────┐ │ │ +│ │ │ material_name │ quantity │ status │ │ │ +│ │ │ 철판 A │ 50 │ available │ ○ │ │ +│ │ │ 강관 파이프 │ 100 │ available │ ○ │ │ +│ │ │ 볼트 세트 │ 500 │ in_stock │ ○ │ │ +│ │ └────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ 필드 매핑: │ │ +│ │ 자재명: [material_name ▼] │ │ +│ │ 수량: [quantity ▼] │ │ +│ │ │ │ +│ │ 단위 입력: │ │ +│ │ 단위: [EA_____________] │ │ +│ │ (예: EA, BOX, KG, M, L 등) │ │ +│ │ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─ 3단계: 배치 설정 ──────────────────────────────────┐ │ +│ │ │ │ +│ │ 색상: [🎨 #3b82f6] │ │ +│ │ │ │ +│ │ 크기: │ │ +│ │ 너비: [5] 높이: [5] 깊이: [5] │ │ +│ │ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ [← 목록으로] [저장] │ +└──────────────────────────────────────┘ +``` + +**참고:** + +- [← 목록으로] 버튼: 요소 목록 화면으로 돌아갑니다 +- [저장] 버튼: 데이터 바인딩 설정을 저장하고 요소 목록 화면으로 돌아갑니다 +- 저장하지 않고 나가면 요소는 "미설정" 상태로 남습니다 + +### 4.3 뷰어 모드 (Yard3DViewer) + +#### 4.3.1 설정된 요소 + +- 정상적으로 3D 박스 렌더링 +- 클릭 시 자재명, 수량 정보 표시 + +#### 4.3.2 미설정 요소 + +``` +┌─────────────────────┐ +│ │ +│ ⚠️ │ +│ │ +│ 설정되지 않은 │ +│ 요소입니다 │ +│ │ +└─────────────────────┘ +``` + +- 반투명 회색 박스로 표시 +- 클릭 시 "데이터 바인딩이 설정되지 않았습니다" 메시지 + +--- + +## 5. 구현 단계 + +### Phase 1: 데이터베이스 스키마 변경 + +- [ ] `yard_material_placement` 테이블 수정 +- [ ] 마이그레이션 스크립트 작성 +- [ ] 기존 데이터 호환성 처리 + +### Phase 2: 백엔드 API 수정 + +- [ ] `YardLayoutService.ts` 수정 + - `addMaterialPlacement`: 데이터 소스/바인딩 정보 저장 + - `updatePlacement`: 데이터 바인딩 업데이트 + - `getPlacementsByLayoutId`: 새 필드 포함하여 조회 +- [ ] 데이터 소스 실행 로직 추가 + - DB 쿼리 실행 + - 외부 DB 쿼리 실행 + - REST API 호출 + +### Phase 3: 프론트엔드 타입 정의 + +- [ ] `types.ts`에 새로운 인터페이스 추가 + - `YardElementDataSource` + - `YardElementDataBinding` + - `YardPlacement` 업데이트 + +### Phase 4: 요소 추가 및 관리 + +- [ ] `YardEditor.tsx` 수정 + - [+ 요소 추가] 버튼 구현 + - 빈 요소 생성 로직 (즉시 3D 캔버스에 배치) + - 요소 추가 시 자동으로 해당 요소 선택 + - 우측 패널 상태 관리 (요소 목록 ↔ 데이터 바인딩 설정) + - 요소 목록 UI + - 설정/미설정 상태 구분 표시 + +### Phase 5: 데이터 바인딩 패널 + +- [ ] `YardElementConfigPanel.tsx` 생성 (우측 패널 컴포넌트) + - [← 목록으로] 버튼으로 요소 목록으로 복귀 + - 1단계: 데이터 소스 선택 (DatabaseConfig, ExternalDbConfig, RestApiConfig 재사용) + - 2단계: 쿼리 결과 테이블 + 행 선택 + 필드 매핑 + - 자재명 필드 선택 (드롭다운) + - 수량 필드 선택 (드롭다운) + - 단위 직접 입력 (Input) + - 3단계: 배치 설정 (색상, 크기) + - [저장] 버튼으로 설정 저장 및 목록으로 복귀 + +### Phase 6: 3D 캔버스 렌더링 수정 + +- [ ] `Yard3DCanvas.tsx` 수정 + - 설정된 요소: 기존 렌더링 + - 미설정 요소: 회색 반투명 박스 + 경고 아이콘 + +### Phase 7: 뷰어 모드 수정 + +- [ ] `Yard3DViewer.tsx` 수정 + - 미설정 요소 감지 + - 미설정 요소 클릭 시 안내 메시지 + +### Phase 8: 임시 테이블 제거 + +- [ ] `temp_material_master` 테이블 삭제 +- [ ] 관련 API 및 UI 코드 정리 + +--- + +## 6. 데이터 구조 예시 + +### 6.1 데이터 소스 + 필드 매핑 사용 + +```json +{ + "id": 1, + "yard_layout_id": 1, + "material_code": null, + "material_name": "철판 A타입", + "quantity": 50, + "unit": "EA", + "data_source_type": "database", + "data_source_config": { + "type": "database", + "query": "SELECT material_name, quantity FROM inventory WHERE material_id = 'MAT-001'" + }, + "data_binding": { + "selectedRowIndex": 0, + "materialNameField": "material_name", + "quantityField": "quantity", + "unit": "EA" + }, + "position_x": 10, + "position_y": 0, + "position_z": 10, + "size_x": 5, + "size_y": 5, + "size_z": 5, + "color": "#ef4444" +} +``` + +### 6.2 미설정 요소 + +```json +{ + "id": 3, + "yard_layout_id": 1, + "material_code": null, + "material_name": null, + "quantity": null, + "unit": null, + "data_source_type": null, + "data_source_config": null, + "data_binding": null, + "position_x": 30, + "position_y": 0, + "position_z": 30, + "size_x": 5, + "size_y": 5, + "size_z": 5, + "color": "#9ca3af" +} +``` + +--- + +## 7. 장점 + +1. **유연성**: 다양한 데이터 소스 지원 (내부 DB, 외부 DB, REST API) +2. **실시간성**: 실제 시스템의 자재 데이터와 연동 가능 +3. **일관성**: 차트/리스트 위젯과 동일한 데이터 소스 선택 방식 +4. **사용자 경험**: 데이터 매핑 방식 선택 가능 (자동/수동) +5. **확장성**: 새로운 데이터 소스 타입 추가 용이 +6. **명확성**: 미설정 요소를 시각적으로 구분 + +--- + +## 8. 마이그레이션 전략 + +### 8.1 기존 데이터 처리 + +- 기존 `temp_material_master` 기반 배치 데이터를 수동 입력 모드로 전환 +- `external_material_id` → `data_binding.mode = 'manual'`로 변환 + +### 8.2 단계적 전환 + +1. 새 스키마 적용 (기존 컬럼 유지) +2. 새 UI/로직 구현 및 테스트 +3. 기존 데이터 마이그레이션 +4. 임시 테이블 및 구 코드 제거 + +--- + +## 9. 기술 스택 + +- **백엔드**: PostgreSQL JSONB, Node.js/TypeScript +- **프론트엔드**: React, TypeScript, Shadcn UI +- **3D 렌더링**: React Three Fiber, Three.js +- **데이터 소스**: 기존 `DatabaseConfig`, `ExternalDbConfig`, `RestApiConfig` 컴포넌트 재사용 + +--- + +## 10. 예상 개발 기간 + +- Phase 1-2 (DB/백엔드): 1일 +- Phase 3-4 (프론트엔드 구조): 1일 +- Phase 5 (데이터 바인딩 모달): 2일 +- Phase 6-7 (3D 렌더링/뷰어): 1일 +- Phase 8 (정리 및 테스트): 0.5일 + +**총 예상 기간: 약 5.5일**