Files
sam-docs/dev/dev_plans/bending-management/README.md
강영보 220ab78041 docs: [bending] 절곡품 전용 테이블 분리 완료 문서
- README: bending_items 266건 + bending_models 62건 DB 검증 완료
- README: 하장바 검색 문제 해결 (10건 정상)
- README: bending_data JSON 통합, bending_item_mappings DROP
- README: LOT 코드 체계, 테이블 관계도, 레거시 대응표 갱신
- step1: 데이터분석 업데이트
- step5: canvas 그리기 추가
- .gitattributes CRLF→LF 정규화
2026-03-19 20:04:17 +09:00

765 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 절곡품 관리 기능 개발 계획서
> **시작일**: 2026-03-16
> **위치**: MNG 생산관리 > 절곡품 관리 (신규 메뉴)
> **목표**: 경동기업(5130) 수준의 절곡품 마스터 관리 + 전개도 데이터 + 이미지 관리
> **원칙**: 기존 BendingInfoBuilder/PrefixResolver 보존, **전용 테이블 분리 방식**
> **최종수정**: 2026-03-19 (테이블 분리 완료, 데이터 이관 완료)
---
## 배경
SAM은 절곡품의 "계산과 조합"(BendingInfoBuilder/PrefixResolver)은 잘 되어 있지만,
"관리와 시각화"가 빠져 있다. 경동기업(5130) `guiderail/list.php` 수준의 관리 화면을 MNG에 구현한다.
**갭 분석**: `docs/dev/dev_plans/bending-parts-analysis.md` 참조
---
## ⚠️ 아키텍처 변경: items → 전용 테이블 분리 (2026-03-19)
### 변경 결정 배경
기존에는 `items` 테이블(`item_category='BENDING'`)에 `options` JSON으로 절곡 속성을 저장했으나,
다음 문제로 **전용 테이블 분리**로 방향 전환:
| 문제 | 설명 |
|------|------|
| **검색 불가** | 레거시 5130에서 "하장바" 검색 시 5건+ 나오지만 MNG2 기초관리에서 0건 |
| **options 누락** | BD-LEGACY-* 210건 중 상당수가 `options.item_name` 미채워짐 → 검색 불가 |
| **JSON 비정규화** | 20+개 절곡 속성이 options JSON 안에 있어 인덱싱/검색/정렬 불가 |
| **코드 체계 불일치** | BD-LEGACY-*, BD-{품명}-* 혼재, LOT 코드 체계 적용 불가 |
| **스키마 불명확** | options 키가 코드에만 정의(OPTION_KEYS), DB 레벨 제약 없음 |
### 하장바 검색 문제 — ✅ 해결됨
```
[레거시 5130] chandj.bending WHERE item_name LIKE '%하장바%'
→ 13건 (삭제 3건 제외 = 유효 10건)
[이전 MNG2 — items 방식] items WHERE item_category='BENDING' AND name LIKE '%하장바%'
→ 2건만 (options.item_name 누락 → 검색 불가)
[현재 MNG2 — bending_items 전용 테이블] bending_items WHERE item_name LIKE '%하장바%'
→ 10건 ✅ (정규 컬럼 item_name에 인덱스, chandj 유효건과 일치)
[해결 방법]
테이블 분리(bending_items) + bending:clean-reimport로 chandj.bending 직접 이관
→ item_name이 정규 컬럼으로 승격되어 검색 정상 동작
```
### 새 테이블 구조: `bending_items`
```sql
CREATE TABLE bending_items (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
tenant_id BIGINT UNSIGNED NOT NULL,
-- 코드 체계 (LOT 코드 = 제품Code + 종류Code + YYMMDD)
code VARCHAR(50) NOT NULL, -- LOT: {제품}{종류}{YYMMDD} (예: CP260319 = 케이스 점검구)
legacy_code VARCHAR(50) NULL, -- 이전 BD-LEGACY-* / BD-{품명}-* 코드
legacy_bending_id INT UNSIGNED NULL, -- chandj.bending.id 참조
-- 기본 정보 (기존 options에서 정규 컬럼으로 승격)
item_name VARCHAR(100) NOT NULL, -- 품명 (검색 가능!)
item_sep VARCHAR(20) NULL, -- 대분류: 스크린/철재
item_bending VARCHAR(50) NULL, -- 중분류: 가이드레일/케이스/하단마감재/...
material VARCHAR(50) NULL, -- 재질: SUS 1.2T / EGI 1.55T
item_spec VARCHAR(100) NULL, -- 규격: 120*70
model_name VARCHAR(50) NULL, -- 소속 모델: KSS01
model_UA VARCHAR(20) NULL, -- 인정여부: 인정/비인정
-- 절곡 전용 속성
rail_width DECIMAL(10,2) NULL, -- 레일폭
exit_direction VARCHAR(20) NULL, -- 출구방향 (케이스 전용)
box_width DECIMAL(10,2) NULL, -- 박스폭 (케이스 전용)
box_height DECIMAL(10,2) NULL, -- 박스높이 (케이스 전용)
front_bottom DECIMAL(10,2) NULL, -- 전면밑 (케이스 전용)
inspection_door VARCHAR(20) NULL, -- 점검구 (케이스 전용)
-- 메타 (비정형 속성만 — 검색/필터 대상 아닌 것)
options JSON NULL, -- memo, author, search_keyword, modified_by 등
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_by BIGINT UNSIGNED NULL,
updated_by BIGINT UNSIGNED NULL,
deleted_by BIGINT UNSIGNED NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
-- 인덱스
INDEX idx_tenant (tenant_id),
INDEX idx_item_name (item_name),
INDEX idx_item_sep (item_sep),
INDEX idx_item_bending (item_bending),
INDEX idx_material (material),
INDEX idx_model_name (model_name),
INDEX idx_code (code),
INDEX idx_legacy_code (legacy_code),
UNIQUE KEY uk_tenant_code (tenant_id, code, deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 전개도 데이터: `bending_items.bending_data` (JSON 컬럼)
> **변경 이력**: 초기 설계는 별도 `bending_data` 테이블이었으나, JSON 통합으로 최종 결정.
> 마이그레이션 `100007_move_bending_data_back_to_json`으로 `bending_data` 테이블 DROP 완료.
```json
// bending_items.bending_data JSON 구조
[
{ "no": 1, "input": 10, "rate": "", "sum": 10, "color": true, "aAngle": false },
{ "no": 2, "input": 11, "rate": "", "sum": 21, "color": false, "aAngle": false },
{ "no": 3, "input": 110, "rate": "-1", "sum": 130, "color": false, "aAngle": false }
]
```
### 테이블 관계도 (최종)
```
┌──────────────────────────┐ ┌──────────────────────┐
│ bending_items (266건) │ │ bending_models (62건) │
│ ──────────────────────── │ │ ──────────────────── │
│ 기초관리 마스터 │ │ 가이드레일/케이스/ │
│ 품명/재질/규격 (정규컬럼) │◄···│ 하단마감재 모델 │
│ bending_data: JSON (내장) │ │ components JSON │
│ code: RM260319 등 │ │ (sam_item_id 참조) │
└──────────┬───────────────┘ └──────────────────────┘
│ 코드 매핑 (FK 없음)
│ code 앞 2자리로 items.code 패턴 매칭
┌──────────────────────┐
│ items (기존 무변경) │
│ ──────────────────── │
│ BD-{PREFIX}-{LENGTH} │
│ 재고/BOM/작업지시서 │
│ BendingInfoBuilder │
└──────────────────────┘
```
### items 테이블과의 관계 — FK 없음, 코드 매핑
```
┌──────────────────────────┐ ┌──────────────────────────┐
│ bending_items (신규) │ │ items (기존 유지) │
│ ──────────────────────── │ │ ──────────────────────── │
│ 기초관리 마스터 전용 │ 코드 │ BD-{prod}{spec}-{length} │
│ 품명/재질/규격 정규 컬럼 │ ·····→ │ 재고/BOM/작업지시서 연결 │
│ 전개도 데이터 │ 매핑 │ item_category='BENDING' │
│ code: CP260319 등 │ │ 재고관리용 (무변경) │
│ bending_item_mappings 흡수│ │ │
└──────────────────────────┘ └──────────────────────────┘
연결 방식: FK 없음
- 재고 조회 필요 시: code 앞 2자리(제품+종류)로 items.code 패턴 매칭
- items 테이블의 재고/BOM 기능은 완전히 독립 유지
- BendingInfoBuilder는 items 테이블 계속 참조 (무변경)
- bending_item_mappings 테이블 → 제거 (code에 흡수)
```
### 영향도 분석 — 변경 / 무변경 구분
| 컴포넌트 | 변경 여부 | 설명 |
|----------|----------|------|
| `bending_items` 테이블 | **신규 생성** | 전용 테이블 + mappings 흡수 |
| `bending_item_mappings` 테이블 | **제거** | bending_items에 컬럼 흡수 |
| `BendingItemService` | **수정** | Item::where(BENDING) → BendingItem 모델 |
| `BendingItemResource` | **수정** | getOption() → 정규 컬럼 직접 참조 |
| `BendingItemController` (API) | 최소 수정 | 서비스만 바뀜, 라우트 동일 |
| `BendingItemMapping` 모델 | **제거** | |
| `BendingBaseController` (MNG) | 무변경 | API 클라이언트, URL 동일 |
| `BendingProductController` (MNG) | 무변경 | API 클라이언트 |
| `BendingInfoBuilder` | **무변경** | items 테이블 기반 (재고/BOM용) |
| `Migrate5130BendingStock` | **무변경** | items 테이블 재고 생성용 |
| `ValidateBendingItems` | **무변경** | items의 BD-* 재고 검증용 |
| `files` (이미지) | **수정** | fileable_type='BendingItem' |
| `work_order_items` | 무변경 | items.id 참조 유지 |
### 수정 대상 파일 및 완료 상태 (2026-03-19)
```
[API 프로젝트] /home/kkk/sam/api/
✅ 기초관리 (bending_items):
app/Models/BendingItem.php ← Eloquent (bending_data JSON, files)
app/Services/BendingItemService.php ← BendingItem 모델, JSON 직접 저장
app/Services/BendingCodeService.php ← BendingItem 조회 (LOT 코드)
app/Http/Resources/Api/V1/BendingItemResource.php ← 정규 컬럼 + bending_data JSON + 수치 int 캐스팅
app/Http/Requests/Api/V1/BendingItemStoreRequest.php ← unique → bending_items
app/Swagger/v1/BendingItemApi.php ← Swagger 스키마
✅ 절곡품 모델 (bending_models):
app/Models/BendingModel.php ← Eloquent (components JSON, files)
app/Services/GuiderailModelService.php ← BendingModel + component 이미지 자동 복사
app/Http/Resources/Api/V1/GuiderailModelResource.php ← 정규 컬럼 + 수치 int 캐스팅
✅ 파일 처리:
app/Http/Controllers/Api/V1/ItemsFileController.php ← items → bending_items → bending_models 폴백
✅ 이관 커맨드:
app/Console/Commands/BendingCleanReimport.php ← 기초관리 클린 재이관 + 이미지 (1커맨드)
app/Console/Commands/BendingModelImport.php ← 모델 이관 + 조립도 JSON 업로드 + component 이미지 복사 (1커맨드)
✅ 마이그레이션:
2026_03_19_100000_create_bending_items_table.php
2026_03_19_100001~100003 (bending_data 테이블 → JSON 통합 과정)
2026_03_19_100004_drop_bending_item_mappings_table.php
2026_03_19_100005_add_length_columns_to_bending_items.php
2026_03_19_100006_create_bending_models_table.php
2026_03_19_100007_move_bending_data_back_to_json.php
✅ 제거:
app/Models/Production/BendingItemMapping.php ← 삭제됨
app/Models/BendingDataRow.php ← 삭제됨 (JSON 통합)
bending_item_mappings 테이블 ← DROP
bending_data 테이블 ← DROP (JSON 통합)
무변경:
app/Http/Controllers/Api/V1/BendingItemController.php ← 서비스 주입 (변경 불필요)
app/Http/Controllers/Api/V1/GuiderailModelController.php ← 서비스 주입
app/Services/Production/BendingInfoBuilder.php ← items 직접 사용 (재고/BOM)
app/Console/Commands/Migrate5130BendingStock.php ← items 재고용
app/Console/Commands/ValidateBendingItems.php ← items 재고 검증용
```
### 전체 복원 커맨드
```bash
# Step 1: 기초관리 (265건 + bending_data JSON + 이미지 265건)
php artisan bending:clean-reimport --legacy-img-path=/tmp/bending_img
# Step 2: 절곡품 모델 (61건 + 조립도 61건 + 부품이미지 276건 + sam_item_id)
php artisan bending:model-import --legacy-path=/tmp/legacy_5130
# 사전 준비 (docker 컨테이너에 레거시 파일 복사):
docker cp /home/kkk/sam/5130/bending/img docker-api-1:/tmp/bending_img
docker compose exec -T api mkdir -p /tmp/legacy_5130
docker cp /home/kkk/sam/5130/guiderail docker-api-1:/tmp/legacy_5130/guiderail
docker cp /home/kkk/sam/5130/shutterbox docker-api-1:/tmp/legacy_5130/shutterbox
docker cp /home/kkk/sam/5130/bottombar docker-api-1:/tmp/legacy_5130/bottombar
```
### 데이터 현황 (2026-03-19 DB 검증 완료)
| 테이블 | 건수 | 소스 | 상태 |
|--------|------|------|------|
| bending_items | **266건** | chandj.bending 직접 (bending_data JSON 포함) | ✅ 이관 완료 |
| bending_models | **62건** | chandj guiderail 21 + shutterbox 30 + bottombar 11 | ✅ 이관 완료 |
| bending_item_mappings | 0건 | **DROP 완료** | ✅ 제거됨 |
| items (BENDING) | 215건 | 기존 재고/BOM용 — **무변경 유지** | ✅ 독립 |
| 파일 (R2 업로드) | 예정 건수 | 현재 | 비고 |
|------------------|----------|------|------|
| bending_item / bending_diagram | 266건 | ⬜ 미업로드 | `bending:clean-reimport --legacy-img-path` 필요 |
| bending_model / assembly_image | 62건 | ⬜ 미업로드 | `bending:model-import --legacy-path` 필요 |
| bending_model / component_image | ~280건 | ⬜ 미업로드 | 부품별 독립 복사본 (스냅샷) |
| 레거시 대비 | chandj | bending_models | 상태 |
|-------------|--------|----------------|------|
| 가이드레일 | 20건 | 21건 | ✅ |
| 케이스 | 30건 | 30건 | ✅ |
| 하단마감재(스크린) | 8건 | 8건 | ✅ |
| 하단마감재(철재) | 3건 | 3건 | ✅ |
| 검색 검증 | 이전(items) | 현재(bending_items) | 상태 |
|----------|------------|-------------------|------|
| 하장바 | 2건 | **10건** (chandj 유효건 일치) | ✅ 해결 |
> **이미지 업로드 안내**: 레거시 이미지 파일을 docker 컨테이너에 복사 후 artisan 커맨드 실행 필요 (위 "전체 복원 커맨드" 참조)
### 이미지 스냅샷 정책
```
기초관리 이미지 수정 → 모델 component에 영향 없음 (독립 복사본)
구조:
bending_items → files (bending_diagram) ← 원본 (수정 가능)
bending_models → components[].image_file_id ← 복사본 (독립)
→ files (assembly_image) ← 조립도 (별도)
신규 부품 추가 시:
API(GuiderailModelService)에서 image_file_id 자동 복사 예정
MNG2 editPartOriginal() → sam_item_id로 기초관리 편집 페이지 연결
```
### LOT 코드 체계
```
형식: {제품Code}{종류Code}{YYMMDD}
유니크: (tenant_id, code, length_code, deleted_at)
예시:
RS260319 + length_code=30 → 가이드레일(벽면) SUS마감 3000mm
CF260319 → 케이스 전면부
BS260319 + length_code=40 → 하단마감재(스크린) SUS 4000mm
변환 완료: BD-PREFIX-LEN 112건 → LOT 코드
미변환: BD-한글 58건, BD-LEGACY 40건 (legacy_code 유지, 향후 변환)
```
### LOT 코드 체계 (레거시 형태 유지)
```
형식: {제품Code}{종류Code}{YYMMDD}
예시:
RM260319 → 가이드레일(벽면형) 본체, 2026-03-19
RS260319 → 가이드레일(벽면형) SUS마감재, 2026-03-19
CF260319 → 케이스 전면부, 2026-03-19
BS260319 → 하단마감재(스크린) SUS, 2026-03-19
```
**LOT 코드 테이블 (정본)**:
| 제품 | 제품Code | 종류명 | 종류Code |
|------|----------|--------|----------|
| 가이드레일(벽면형) | R | 본체 | M |
| | | 본체(철재) | T |
| | | C형 | C |
| | | D형 | D |
| | | SUS 마감재 | S |
| 가이드레일(측면형) | S | 본체디딤 | M |
| | | 본체(철재) | T |
| | | C형 | C |
| | | D형 | D |
| | | SUS 마감재1 | S |
| | | SUS 마감재2 | U |
| 케이스 | C | 전면부 | F |
| | | 점검구 | P |
| | | 린텔부 | L |
| | | 후면코너부 | B |
| 하단마감재(스크린) | B | SUS | S |
| | | EGI | E |
| 하단마감재(철재) | T | SUS | S |
| | | EGI | E |
| L-Bar | L | 스크린용 | A |
| 연기차단재 | G | 화이바원단(W50) | I |
| | | 화이바원단(W80) | I |
### 데이터 현황 (2026-03-19 DB 검증 완료)
| 항목 | 건수 | 비고 |
|------|------|------|
| **bending_items** (전용 테이블) | **266건** | ✅ 전건 bending_data JSON 포함 |
| **bending_models** (전용 테이블) | **62건** | ✅ guiderail 21 + shutterbox 30 + bottombar 11 |
| items BENDING (기존, 무변경) | 215건 | 재고/BOM용 독립 유지 |
| bending_item_mappings | **DROP 완료** | bending_items.code에 흡수 |
| 하장바 (bending_items) | **10건** | ✅ chandj 유효건과 일치 |
| 이미지 (R2) | **미업로드** | 레거시 파일 docker 복사 후 커맨드 실행 필요 |
---
## MNG 현재 구조
### 생산관리 메뉴 (sidebar-static.blade.php)
```
생산 관리 (production-group)
├─ 품목기준 필드 관리 ✅ (구현됨)
├─ 견적수식 관리 ✅ (구현됨)
├─ 제품 관리 (준비중)
├─ 자재 관리 (준비중)
├─ BOM 관리 (준비중)
├─ 카테고리 관리 (준비중)
└─ 절곡품 관리 ← 🆕 추가 대상
├─ 기초관리 (개별 부품 CRUD)
└─ 절곡품 (모델별 조합 관리)
```
### 기존 절곡 관련 코드 (MNG)
| 파일 | 역할 | 변경 여부 |
|------|------|----------|
| `views/documents/partials/bending-worklog.blade.php` | 절곡 작업일지 렌더링 | 무변경 |
| `views/documents/partials/bending-inspection-data.blade.php` | 절곡 중간검사 | 무변경 |
---
## 작업 순서 및 진행 상태
```
Step 1 (DB분석) → Step 2 (API) → Step 3 (MNG 화면) → Step 4 (React 연동)
✅ 완료 ✅ 완료 ✅ 완료 (샘플용) ⬜ 미착수
테이블 분리: ✅ 완료 (bending_items + bending_models 전용 테이블)
데이터 이관: ✅ 완료 (266건 기초관리 + 62건 모델)
이미지 업로드: ⬜ 미완료 (레거시 파일 docker 복사 후 커맨드 실행 필요)
```
| 문서 | 내용 | 상태 |
|------|------|:---:|
| `step1-데이터분석.md` | 레거시 매핑 + options 확장 | ✅ 완료 |
| `step2-API.md` | API 엔드포인트 + 컨트롤러 설계 | ✅ 완료 |
| `step3-MNG화면.md` | Blade 뷰 + HTMX + 메뉴 등록 | ✅ 완료 |
| `step4-React연동.md` | React 운영 화면 구현 | ⬜ 미착수 |
| `legacy-guiderail-analysis.md` | 레거시 guiderail 모듈 상세 분석 | ✅ 완료 |
### 완료된 작업 (2026-03-16~19)
**Step 1 완료 (DB 분석 + 테이블 분리):**
- `bending_items` 전용 테이블 생성 — 정규 컬럼 승격 (item_name, item_sep, material 등 인덱스)
- `bending_models` 전용 테이블 생성 — 가이드레일/케이스/하단마감재 3개 타입 통합
- `bending_data` 테이블 → JSON 통합 → `bending_items.bending_data` 컬럼
- `bending_item_mappings` 테이블 DROP — `bending_items.code`에 흡수
- `bending:clean-reimport` — chandj.bending 266건 직접 이관 (bending_data JSON 포함)
- `bending:model-import` — chandj guiderail 21 + shutterbox 30 + bottombar 11 = 62건 이관
- ~~`bending:fill-options`~~ / ~~`bending:import-legacy`~~ — 구 items 방식 커맨드 (대체됨)
**Step 2 완료 (API):**
- `BendingItemController` — CRUD + filters + pagination (6 엔드포인트)
- `GuiderailModelController` — CRUD + filters (6 엔드포인트, 3개 카테고리 통합)
- `BendingItemResource` / `GuiderailModelResource` — API 응답 포맷 (정규 컬럼 직접 참조)
- `FormRequest` — Index/Store/Update 유효성 검증
- `ApiKeyMiddleware` — bending/guiderail/files 화이트리스트
**Step 3 완료 (MNG 샘플용):**
- 기초관리: 목록(13컬럼) + 폼(기본정보12필드 + 케이스전용5필드 + 절곡테이블 + 이미지업로드)
- 절곡품: 가이드레일/케이스/하단마감재 별도 메뉴 + 타입별 헤더 분기
- 절곡품 폼: 부품 추가(기초관리 검색 모달) + 삭제 + 수량/품명/재질 편집 + 절곡테이블 inline 편집
- 작업지시서: 레거시 포맷 인쇄 페이지 (`/print`)
- 파일: FileViewController (API R2 프록시) + 이미지 업로드/표시
- DB 메뉴: 기초관리 + 절곡품 + 케이스 + 하단마감재 (4개)
**미완료:**
- ⬜ 이미지 R2 업로드 — 레거시 파일 docker 복사 후 커맨드 재실행 필요
- ⬜ Step 4 React 연동 — 미착수
---
## 참조 문서
| 문서 | 경로 | 용도 |
|------|------|------|
| 갭 분석 | `dev_plans/bending-parts-analysis.md` | 요구사항 기준 |
| API 규칙 | `standards/api-rules.md` | API 네이밍/응답 |
| options 정책 | `standards/options-column-policy.md` | JSON 컬럼 설계 |
| 품목 정책 | `rules/item-policy.md` | BD 코드 체계 |
| Phase 2 | `dev_plans/integrated-phase-2.md` | 절곡 설계 |
| Phase 3 | `dev_plans/integrated-phase-3.md` | 절곡 검사 |
## 프로토타입
| 위치 | 설명 |
|------|------|
| `SAM/work/절곡/index.html` | 사이드바 + iframe 전체 구조 |
| `SAM/work/절곡/base.html` | 기초관리 목록 (참고용) |
| `SAM/work/절곡/base-form.html` | 등록/수정 폼 + 절곡 테이블 (참고용) |
| `SAM/work/절곡/products.html` | 절곡품 탭 목록 (참고용) |
| `SAM/work/절곡/product-form.html` | 절곡품 등록/수정 (참고용) |
# 절곡품 관리 — 전체 흐름도
---
## 1. 시스템 전체 구조
```
┌─────────────────────────────────────────────────────────────────────┐
│ SAM 절곡품 관리 시스템 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MNG │ │ API │ │ React │ │
│ │ (샘플용) │────→│ (핵심) │←────│ (운영용) │ │
│ │ Blade │ │ Laravel │ │ Next.js │ │
│ └──────────┘ └─────┬────┘ └──────────┘ │
│ │ │
│ ┌─────────────┐ │
│ │ samdb │ │
│ │bending_items│ ← 기초관리 마스터 (전용, bending_data JSON 포함) │
│ │bending_models│ ← 절곡품 모델 (가이드레일/케이스/하단마감재) │
│ │ items │ ← 재고/BOM용 (기존 무변경) │
│ │ files │ ← bending_diagram 이미지 │
│ └─────────────┘ │
│ │ │
│ ┌────┴────┐ │
│ │ R2 │ ← Cloudflare (이미지 저장) │
│ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
---
## 2. 데이터 구조 (2계층 — 전용 테이블 + JSON)
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ [1계층] 기초관리 — 개별 부품 (bending_items 전용 테이블) │
│ ══════════════════════════════════════════════ │
│ │
│ bending_items (266건) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ id: 100 │ │
│ │ code: RM260319 ← LOT 코드 (제품+종류+날짜)│ │
│ │ legacy_code: BD-LEGACY-042 ← 이전 코드 보존 │ │
│ │ item_name: "마감재" ← 정규 컬럼 (인덱스) │ │
│ │ item_sep: "스크린" ← 정규 컬럼 (인덱스) │ │
│ │ item_bending: "가이드레일" ← 정규 컬럼 (인덱스) │ │
│ │ material: "SUS 1.2T" ← 정규 컬럼 (인덱스) │ │
│ │ model_name: "KSS01" ← 정규 컬럼 │ │
│ │ model_UA: "인정" ← 정규 컬럼 │ │
│ │ item_spec: "120*70" ← 정규 컬럼 │ │
│ │ rail_width: 70 ← 정규 컬럼 │ │
│ │ + 케이스전용: exit_direction, box_width... 정규 │ │
│ │ bending_data: JSON 배열 ← 전개도 데이터 (내장) │ │
│ │ [{no:1, input:10, rate:"", sum:10, color:true}, │ │
│ │ {no:2, input:11, rate:"", sum:21, color:false}, │ │
│ │ {no:3, input:110, rate:"-1", sum:130}, ...] │ │
│ └──────────────────────────────────────────────────┘ │
│ ↑ 266건 (전건 bending_data JSON 포함) │
│ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │
│ [2계층] 절곡품 — 모델별 부품 조합 │
│ ════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 가이드레일 모델: KSS01 벽면형 SUS마감 │ │
│ │ │ │
│ │ components (부품 조합): │ │
│ │ ┌─────┬───────────┬──────────┬────┬────────┐ │ │
│ │ │순서 │ 부품명 │ 재질 │수량│전개폭합│ │ │
│ │ ├─────┼───────────┼──────────┼────┼────────┤ │ │
│ │ │ 1 │ 마감재 │ SUS 1.2T│ 2 │ 203 │ ──→ item:100│
│ │ │ 2 │ 본체 │ EGI 1.55│ 1 │ 296 │ ──→ item:101│
│ │ │ 3 │ 벽면형-C │ EGI 1.55│ 1 │ 144 │ ──→ item:102│
│ │ │ 4 │ 벽면형-D │ EGI 1.55│ 1 │ 144 │ ──→ item:103│
│ │ └─────┴───────────┴──────────┴────┴────────┘ │ │
│ │ │ │
│ │ 재질별 폭합: SUS 1.2T → 406 | EGI 1.55T → 398 │ │
│ └────────────────────────────────────────────────────────┘ │
│ ↑ 가이드레일 21건 + 케이스 30건 + 하단마감재 11건 = 62건 │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## 3. 3가지 타입 비교
```
┌─────────────────┬─────────────────┬─────────────────┐
│ 가이드레일 │ 케이스 │ 하단마감재 │
├─────────────────┼─────────────────┼─────────────────┤
│ │ │ │
│ 모델: KSS01 │ 모델: ❌ 없음 │ 모델: KSS01 │
│ 마감: SUS/EGI │ 마감: ❌ 없음 │ 마감: SUS/EGI │
│ 형상: 벽면/측면 │ 형상: ❌ 없음 │ 형상: ❌ 없음 │
│ 대분류: 스크린/철재│ 대분류: ❌ │ 대분류: 스크린/철재│
│ 인정: 인정/비인정 │ 인정: ❌ │ 인정: 인정/비인정 │
│ │ │ │
│ 규격: 120×70 │ 규격: 650×550 │ 규격: 60×40 │
│ 레일폭: 70 │ 전면밑: 50 │ │
│ │ 레일폭: 75 │ │
│ │ 점검구: 후면 │ │
│ │ │ │
│ 파트: 3~5개 │ 파트: 5개 │ 파트: 1개 │
│ ┌─────────────┐│ ┌─────────────┐│ ┌─────────────┐│
│ │본체상부 ││ │상부덮개 ││ │하단마감 ││
│ │본체하부 ││ │전면 ││ │(단일 파트) ││
│ │마감재 ││ │점검구 ││ └─────────────┘│
│ │(+C형,D형) ││ │린텔 ││ │
│ └─────────────┘│ │후면코너 ││ │
│ │ └─────────────┘│ │
├─────────────────┼─────────────────┼─────────────────┤
│ 재질별 폭합 │ 재질별 폭합 │ 재질별 폭합 │
│ SUS: 406 │ EGI: 2652 │ SUS: 193 │
│ EGI: 398 │ │ │
└─────────────────┴─────────────────┴─────────────────┘
```
---
## 4. 전개도 테이블 구조 (1개 부품)
```
레거시 5130 화면과 동일한 구조:
┌────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 번호 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 입력 │ 10 │ 11 │ 110 │ 30 │ 15 │ 15 │ 15 │ ← 치수 입력
│ │[색상]│ │ │ │ │[색상]│ │ ← 파란 배경
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 연신율 │ │ │ -1 │ -1 │ -1 │ │ │ ← 절곡 방향
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│연신율후 │ 10 │ 11 │ 109 │ 29 │ 14 │ 15 │ 15 │ ← input + rate
│ │ │ │(-1) │(-1) │(-1) │ │ │ (rate=-1 → -1mm)
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 합계 │ 10 │ 21 │ 130 │ 159 │ 173 │ 188 │ 203 │ ← 보정후 누적합
│ │[색상]│ │ │ │ │[색상]│ │ ← 노란 배경
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 음영 │ ■■ │ │ │ │ │ ■■ │ │ ← 색상 마킹
├────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ A각 │ │ │ │ A각 │ │ │ │ ← A각 표시
└────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
연신율 보정 규칙:
rate = "" → 보정 없음 (input 그대로)
rate = "-1" → input - 1mm (하향 절곡)
rate = "1" → input + 1mm (상향 절곡)
합계 = 보정후 값의 누적합
폭합계 = 마지막 합계값 (이 예시: 203)
```
---
## 5. JSON 저장 구조 (options.bendingData)
```
레거시 (별도 배열 5개) SAM (객체 배열 1개)
──────────────────── ────────────────────
inputList: [10,11,110...] bendingData: [
bendingrateList: ["","","-1"...] { no:1, input:10, rate:"",
sumList: [10,21,130...] sum:10, color:true, aAngle:false },
colorList: [true,false,false...] { no:2, input:11, rate:"",
AList: [false,false,false...] sum:21, color:false, aAngle:false },
{ no:3, input:110, rate:"-1",
→ 5개 배열 동기화 필요 sum:130, color:false, aAngle:false },
→ 열 추가/삭제 시 5개 다 조작 ...
]
→ 1개 배열만 관리
→ 열 추가 = 객체 1개 push
```
---
## 6. 화면 흐름도
```
┌──────────────────────────────────────────────────────────────┐
│ MNG │
│ │
│ 생산 관리 │
│ ├─ 품목기준 필드 관리 │
│ ├─ 견적수식 관리 │
│ └─ 🆕 절곡품 관리 │
│ ├─ 기초관리 ─────────────────┐ │
│ └─ 절곡품 ──────────────┐ │ │
│ │ │ │
└─────────────────────────────┼────┼───────────────────────────┘
│ │
┌───────────────────┘ └───────────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ 절곡품 목록 │ │ 기초관리 목록 │
│ │ │ │
│ [가이드레일] [케이스] │ │ 265건 테이블 │
│ [하단마감재] │ │ 필터: 대분류/인정/ │
│ │ │ 그룹/품명/검색 │
│ 필터 + 테이블 │ │ │
│ │ │ 행 클릭 ──→ 상세 │
│ 행 클릭 ──→ 상세 │ │ [+등록] ──→ 등록 │
│ [+등록] ──→ 등록 │ └───────────┬──────────┘
└───────────┬──────────┘ │
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ 절곡품 등록/수정 │ │ 기초관리 등록/수정 │
│ │ │ │
│ ┌──────────┬───────┐ │ │ ┌──────────┬───────┐ │
│ │ 기본정보 │ 이미지 │ │ │ │ 기본정보 │ 이미지 │ │
│ │ (타입별) │ 업로드 │ │ │ │ 대분류 │ 업로드 │ │
│ ├──────────┤ 검색어 │ │ │ │ 그룹/품명 │ 검색어 │ │
│ │ 파트 탭 │ │ │ │ │ 재질/규격 │ │ │
│ │ [1][2][3] │ │ │ │ ├──────────┤ │ │
│ │ │ │ │ │ │ 절곡 테이블│ │ │
│ │ 절곡테이블│ │ │ │ │ (단일) │ │ │
│ │ (파트별) │ │ │ │ ├──────────┤ │ │
│ ├──────────┤ │ │ │ │ 재질별폭합│ │ │
│ │ 재질별폭합│ │ │ │ └──────────┴───────┘ │
│ └──────────┴───────┘ │ └──────────────────────┘
└──────────────────────┘
```
---
## 7. API 엔드포인트 흐름
```
MNG / React
├── GET /api/v1/bending-items ← 기초관리 목록
├── GET /api/v1/bending-items/filters ← 필터 옵션
├── GET /api/v1/bending-items/{id} ← 상세
├── POST /api/v1/bending-items ← 등록
├── PUT /api/v1/bending-items/{id} ← 수정
├── DELETE /api/v1/bending-items/{id} ← 삭제
├── GET /api/v1/guiderail-models ← 절곡품 모델 목록
├── GET /api/v1/guiderail-models/{id} ← 모델 상세 (부품조합)
├── POST /api/v1/guiderail-models ← 모델 등록
├── PUT /api/v1/guiderail-models/{id} ← 모델 수정
├── DELETE /api/v1/guiderail-models/{id} ← 모델 삭제
├── POST /api/v1/items/{id}/files ← 이미지 업로드 (기존)
├── GET /api/v1/items/{id}/files ← 이미지 목록 (기존)
└── GET /api/v1/files/{id}/view ← 이미지 표시 (기존)
※ 이미지는 기존 ItemsFileController 재사용
※ field_key: 'bending_diagram'
```
---
## 8. 작업 순서
```
Step 1 Step 2 Step 3 Step 4
데이터 분석 API 구현 MNG 화면 React 화면
━━━━━━━━ ━━━━━━━━ ━━━━━━━━ ━━━━━━━━
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│레거시 265건│ │Controller│ │기초관리 │ │견적 이미지│
│SAM 170건 │──→ │Service │──→ │ 목록/등록 │──→ │GuiderailP│
│매핑 테이블 │ │FormReq │ │절곡품 │ │review │
│ │ │Resource │ │ 목록/등록 │ │ │
│options 확장│ │ │ │ │ │절곡품 │
│artisan cmd│ │이미지: │ │메뉴 등록 │ │관리 화면 │
│ │ │기존 재사용│ │(tinker) │ │(본 화면) │
│회귀 테스트 │ │ │ │ │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
API 프로젝트 API 프로젝트 MNG 프로젝트 React 프로젝트
(샘플 확인용) (운영용)
```
---
## 9. 레거시 → SAM 대응표
```
레거시 (5130) SAM (테이블 분리 완료)
━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━
chandj.bending (265건) → bending_items (266건, 전용 테이블, 정규 컬럼)
chandj.bending.전개도 배열 → bending_items.bending_data (JSON 컬럼, 내장)
chandj.guiderail (20건) → bending_models (62건, guiderail+shutterbox+bottombar)
guiderail/list.php → MNG /bending/products (절곡품 목록)
bending CRUD → MNG /bending/base (기초관리)
put_guiderail_image.php → 기존 FileController (R2) — ⬜ 이미지 업로드 미완료
fetch_guiderail_detail.php → React GuiderailPreview
drawingTool.js (Canvas) → 2차 구현 (1차는 이미지 업로드만)
inputList[] (별도 배열 5개) → bending_data JSON [{no, input, rate, sum, color, aAngle}]
items (BENDING) + options → items 유지 (재고/BOM용, BendingInfoBuilder 무변경)
bending_item_mappings → DROP 완료 (bending_items.code에 흡수)
```
---
## 10. 레거시 guiderail 모듈 상세 분석
> 별도 문서로 분리: [`legacy-guiderail-analysis.md`](./legacy-guiderail-analysis.md)
>
> 포함 내용: 파일 구성(21개), DB 스키마(guiderail/bending), CRUD 흐름,
> 전개도 생성, 구성요소(벽면형/측면형), 검색/필터, guidebook