# MES 모듈 통합 흐름 분석 계획

> **작성일**: 2025-01-09
> **목적**: 견적 → 수주 → 작업지시 + 공정관리 모듈 간 연동 상태 점검 및 문제점 분석
> **기준 문서**: `docs/dev_plans/process-management-plan.md`, `docs/dev_plans/order-management-plan.md`, `docs/dev_plans/work-order-plan.md`
> **상태**: ✅ 분석 완료 + 개선 방향 **재결정됨** (2025-01-09 추가 분석)

---

## 📍 현재 진행 상태

| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | 공정 관리 페이지 확인 + 개념 명확화 |
| **다음 작업** | WorkOrder `process_type` → `process_id` FK 변경 구현 |
| **진행률** | 7/7 (100%) |
| **마지막 업데이트** | 2025-01-09 |

### ✅ 결정된 개선 방향 (재결정)

| 결정 사항 | 내용 |
|----------|------|
| **WorkOrder.process_type** | `process_type` (varchar) → `process_id` (FK) **변경** |
| **Process.process_type** | 공정 구분 → `common_codes`에서 관리 |
| **개념 정리** | 공정명(WorkOrder) ≠ 공정구분(Process) 명확히 구분 |

---

## 1. 개요

### 1.1 배경
MES 시스템의 핵심 모듈인 공정관리, 수주관리, 작업지시가 개별적으로 개발 완료되었으나,
모듈 간 통합 흐름이 제대로 설계되었는지 검증이 필요합니다.

### 1.2 분석 목표
```
┌─────────────────────────────────────────────────────────────────┐
│  🎯 분석 목표                                                    │
├─────────────────────────────────────────────────────────────────┤
│  1. 모듈 간 데이터 흐름 검증                                      │
│  2. API 연동 상태 점검                                           │
│  3. 프론트엔드 연동 상태 점검                                     │
│  4. 설계 문제점 및 개선 방안 도출                                  │
└─────────────────────────────────────────────────────────────────┘
```

---

## 2. 분석 대상

### 2.1 모듈 구성

| 모듈 | 역할 | API 상태 | Frontend 상태 |
|------|------|:--------:|:------------:|
| **견적관리 (Quote)** | 견적서 작성 및 수주 변환 | ✅ 완료 | ✅ 완료 |
| **수주관리 (Order)** | 견적→수주 변환, 생산지시 생성 | ✅ 완료 | ✅ 완료 |
| **작업지시 (WorkOrder)** | 실제 생산 작업 관리 | ✅ 완료 | ✅ 완료 |
| **공정관리 (Process)** | 공정 템플릿 및 품목 분류 규칙 관리 | ✅ 완료 | ✅ 완료 |

### 2.2 기대 데이터 흐름

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   견적관리    │     │   수주관리    │     │   작업지시    │     │   공정관리    │
│   (Quote)    │ ──→ │   (Order)    │ ──→ │ (WorkOrder)  │  ?  │  (Process)   │
└──────────────┘     └──────────────┘     └──────────────┘     └──────────────┘
       │                    │                    │                    │
       ▼                    ▼                    ▼                    ▼
 - 견적서 작성        - 수주 확정           - 작업 상태 관리      - 공정 템플릿
 - 품목/단가 구성     - 생산지시 생성       - 담당자 배정         - 품목 분류 규칙
 - 고객 승인         - 납기 관리          - 공정별 진행         - 작업 단계 정의
```

---

## 3. 분석 결과

### 3.0 ✅ 견적관리 → 수주관리 연동 (정상 작동)

**API 연동 구현**:
```
POST /api/v1/orders/from-quote/{quoteId}
→ Order 생성 + Quote 상태 변경 (finalized → converted)
```

**연결 관계**:
| 항목 | 내용 |
|------|------|
| FK 연결 | `orders.quote_id` → `quotes.id` |
| 상태 연동 | Quote `finalized` 시에만 수주 변환 가능 |
| 중복 방지 | 동일 Quote에 대해 중복 변환 불가 |

**Quote 상태 흐름**:
```
draft → sent → approved → finalized → converted
(임시저장) (발송) (승인)    (확정)      (수주변환)
```

**API 핵심 로직** (`api/app/Services/OrderService.php`):
```php
public function createFromQuote(int $quoteId): Order
{
    $quote = Quote::findOrFail($quoteId);

    // 변환 가능 상태 검증 (finalized만 가능)
    if ($quote->status !== Quote::STATUS_FINALIZED) {
        throw new BadRequestHttpException(__('error.quote.must_be_finalized'));
    }

    // 중복 변환 방지
    $existingOrder = Order::where('quote_id', $quoteId)->first();
    if ($existingOrder) {
        throw new BadRequestHttpException(__('error.order.already_exists_from_quote'));
    }

    // Order 생성 + Quote 품목 자동 복사
    $order = Order::create([
        'quote_id' => $quote->id,
        'client_id' => $quote->client_id,
        'status_code' => Order::STATUS_DRAFT,
        // ... 견적 정보 복사
    ]);

    // Quote 상태 변경
    $quote->status = Quote::STATUS_CONVERTED;
    $quote->save();

    return $order;
}
```

**프론트엔드 구현**:
```typescript
// react/src/components/orders/actions.ts
export async function createOrderFromQuote(
  quoteId: string | number
): Promise<OrderApiResponse>

// react/src/components/quotes/QuotationSelectDialog.tsx
// 견적 선택 → 수주 변환 UI 컴포넌트
```

**데이터 변환**:
| Quote 필드 | Order 필드 | 변환 방식 |
|-----------|-----------|----------|
| `id` | `quote_id` (FK) | 참조 |
| `client_id` | `client_id` | 복사 |
| `project_name` | `project_name` | 복사 |
| `quote_items` | `order_items` | 품목 복사 |
| `product_category` | - | 참조용 |

**평가**: ✅ **정상 구현됨** - FK 관계, 상태 연동, 중복 방지 모두 정상

---

### 3.1 ✅ 수주관리 → 작업지시 연동 (정상 작동)

**API 연동 구현**:
```
POST /api/v1/orders/{id}/production-order
→ WorkOrder 생성 + Order 상태 변경 (CONFIRMED → IN_PROGRESS)
```

**연결 관계**:
| 항목 | 내용 |
|------|------|
| FK 연결 | `work_orders.sales_order_id` → `orders.id` |
| 상태 연동 | Order CONFIRMED 시에만 생산지시 가능 |
| 중복 방지 | 동일 Order에 대해 중복 생성 불가 |

**프론트엔드 구현**:
```typescript
// react/src/components/orders/actions.ts
export async function createProductionOrder(
  orderId: string,
  data?: CreateProductionOrderData
): Promise<ProductionOrderResult>

// CreateProductionOrderData 타입
interface CreateProductionOrderData {
  processType?: 'screen' | 'slat' | 'bending';
  priority?: 'urgent' | 'high' | 'normal' | 'low';
  assigneeId?: number;
  teamId?: number;
  scheduledDate?: string;
  memo?: string;
}
```

**평가**: ✅ **정상 구현됨**

---

### 3.2 🔴 공정관리 → 작업지시 연동 (설계 문제 발견 → 해결 방향 결정)

#### 3.2.0 ✅ 개념 명확화 (2025-01-09 추가 분석)

**공정 관리 페이지 확인** (`/master-data/process-management`):

| 공정코드 | 공정명 | 구분 | 담당부서 | 상태 |
|---------|-------|------|---------|------|
| P-001 | 슬랫 | 생산 | 경영본부 | 사용중 |
| P-002 | 스크린 | 생산 | 개발팀 | 사용중 |

**핵심 발견**:
```
┌─────────────────────────────────────────────────────────────────┐
│  💡 개념 정리                                                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  WorkOrder.process_type = "공정명" (스크린, 슬랫, 절곡)           │
│  → 공정 관리 테이블(processes)에서 등록된 공정                    │
│  → 하드코딩 ❌ → 공정 테이블 FK로 연결해야 함 ✅                   │
│                                                                  │
│  Process.process_type = "공정 구분" (생산, 검사, 포장, 조립)      │
│  → 공정의 분류/카테고리                                          │
│  → common_codes에서 관리해야 함 ✅                                │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

**최종 정리**:

| 구분 | 필드명 | 실제 의미 | 현재 상태 | 올바른 상태 |
|------|--------|----------|----------|------------|
| **WorkOrder** | `process_type` | 공정명 | 하드코딩 (screen/slat/bending) | **공정 테이블 FK** |
| **Process** | `process_type` | 공정 구분 | 하드코딩 (생산/검사/포장/조립) | common_codes |

---

#### 3.2.1 process_type 불일치 문제 (기존 분석)

| 구분 | 공정관리 (Process) | 작업지시 (WorkOrder) |
|------|:------------------:|:-------------------:|
| **필드명** | `process_type` | `process_type` |
| **값 (Frontend)** | '생산', '검사', '포장', '조립' | 'screen', 'slat', 'bending' |
| **값 개수** | 4개 (한글) | 3개 (영문) |
| **실제 의미** | 공정 **구분** (카테고리) | 공정 **명** (공정 테이블 데이터) |

**문제점**:
- 동일한 필드명(`process_type`)을 사용하지만 **완전히 다른 의미**
- WorkOrder는 **공정 테이블을 참조해야 하는데** 하드코딩되어 있음
- **FK 관계가 없음** - Process 테이블과 WorkOrder 테이블 연결 없음

#### 3.2.2 코드 증거

**공정관리 타입** (`react/src/types/process.ts`):
```typescript
export type ProcessType = '생산' | '검사' | '포장' | '조립';
```

**작업지시 타입** (`react/src/components/production/WorkOrders/types.ts`):
```typescript
export type ProcessType = 'screen' | 'slat' | 'bending';

export const PROCESS_TYPE_LABELS: Record<ProcessType, string> = {
  screen: '스크린',
  slat: '슬랫',
  bending: '절곡',
};
```

**API 모델** (`api/app/Models/Production/WorkOrder.php`):
```php
const PROCESS_SCREEN = 'screen';
const PROCESS_SLAT = 'slat';
const PROCESS_BENDING = 'bending';
```

#### 3.2.3 영향도 분석

| 기능 | 현재 상태 | 문제점 |
|------|----------|--------|
| 공정 선택 | WorkOrder 생성 시 하드코딩된 3개 옵션만 사용 | Process 테이블 활용 안됨 |
| 분류 규칙 | Process에만 존재 | WorkOrder에서 품목 자동 분류 불가 |
| 작업 단계 | Process와 WorkOrder 각각 별도 정의 | 데이터 중복 |
| 메타데이터 | Process에 풍부한 정보 (인원, 설비, 템플릿) | WorkOrder에서 미활용 |

---

### 3.3 🟡 공정관리 → 수주관리 연동 (연결 없음)

**현재 상태**:
- Process와 Order 간 직접적인 연결 관계 없음
- 이는 **의도된 설계**로 보임 (공정은 생산 단계에서 적용)

---

## 4. 문제점 요약

### 4.1 핵심 문제: process_type 이중 정의

```
┌─────────────────────────────────────────────────────────────────┐
│  🔴 핵심 문제                                                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  공정관리(Process)와 작업지시(WorkOrder)가                        │
│  동일한 필드명(process_type)을 사용하지만                         │
│  완전히 다른 값 체계와 목적을 가지고 있음                          │
│                                                                  │
│  ┌─────────────┐          ┌─────────────┐                       │
│  │   Process   │    ❌    │  WorkOrder  │                       │
│  │ (생산/검사)  │ ─────── │ (screen/slat) │                      │
│  └─────────────┘  연결없음  └─────────────┘                       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 4.2 문제 유형 분류

| # | 문제 | 심각도 | 영향 |
|---|------|:------:|------|
| 1 | process_type 값 체계 불일치 | 🔴 높음 | 데이터 일관성, 확장성 |
| 2 | Process ↔ WorkOrder FK 부재 | 🔴 높음 | 메타데이터 활용 불가 |
| 3 | 공정 정보 중복 정의 | 🟡 중간 | 유지보수 복잡성 |
| 4 | 새 공정 추가 시 코드 수정 필요 | 🟡 중간 | 확장성 제한 |

---

## 5. 해결 방안 (검토 필요)

### 5.1 Option A: 현행 유지 (의도된 분리)

**전제**: 공정관리와 작업지시가 **서로 다른 도메인**임을 인정

```
공정관리 (Process)          작업지시 (WorkOrder)
─────────────────          ─────────────────
목적: 품목 분류 자동화       목적: 실제 생산 작업 관리
대상: 모든 품목 유형         대상: 특화 제조품 (스크린/슬랫/절곡)
사용자: 품질/물류팀          사용자: 생산팀
```

**장점**:
- 현재 코드 변경 불필요
- 각 도메인의 독립성 유지

**단점**:
- `process_type` 필드명 혼란 지속
- 공정 메타데이터 재활용 불가

**권장 조치**:
- WorkOrder의 `process_type`을 `manufacturing_type` 또는 `product_line`으로 **리네이밍**
- 문서에 두 개념의 차이 명확히 기술

---

### 5.2 Option B: 통합 연결 (FK 추가)

**전제**: 공정관리가 작업지시의 **상위 템플릿** 역할을 해야 함

```
Process (공정 템플릿)
    │
    │ process_id (FK)
    ▼
WorkOrder (작업지시)
```

**필요 변경**:
1. `work_orders` 테이블에 `process_id` FK 추가
2. Process 모델에 제조 공정 유형 추가 (screen, slat, bending)
3. WorkOrder 생성 시 Process 선택 UI 추가
4. 공정별 메타데이터 (작업단계, 인원, 설비) 자동 적용

**장점**:
- 데이터 일관성 확보
- 공정 메타데이터 재활용
- 새 공정 추가 시 코드 수정 불필요

**단점**:
- DB 마이그레이션 필요
- 기존 데이터 마이그레이션 필요
- API 및 프론트엔드 수정 필요

---

### 5.3 Option C: 하이브리드 (권장)

**전제**: 점진적 통합으로 위험 최소화

**Phase 1**: 명명 정리 (즉시)
- WorkOrder의 `process_type` → `manufacturing_type` 리네이밍
- 문서 정리 및 팀 공유

**Phase 2**: 연결 준비 (중기)
- Process 모델에 `is_manufacturing` 플래그 추가
- 제조 전용 공정 구분 (screen, slat, bending)

**Phase 3**: 통합 (장기)
- WorkOrder에 `process_id` FK 추가 (optional)
- 메타데이터 연동 구현

---

## 6. 컨펌 결과 (✅ 결정 완료 → 재결정)

| # | 항목 | ~~이전 결정~~ | **최종 결정** | 결정일 |
|---|------|-------------|--------------|--------|
| 1 | **설계 방향** | ~~Option C (하이브리드)~~ | **Option B** (FK 추가) | 2025-01-09 |
| 2 | **필드 변경** | ~~리네이밍만~~ | **FK로 변경** | 2025-01-09 |
| 3 | **FK 추가 여부** | ~~❌ 불필요~~ | **✅ 필요** - 공정 테이블 FK | 2025-01-09 |
| 4 | **도메인 연결** | ~~독립 도메인~~ | **Process → WorkOrder 연결** | 2025-01-09 |

### 6.0 재결정 사유

```
┌─────────────────────────────────────────────────────────────────┐
│  💡 핵심 발견 (공정 관리 페이지 확인)                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  WorkOrder.process_type 값 (screen, slat, bending)이            │
│  실제로는 공정 관리 페이지에서 등록된 "공정명"임을 확인             │
│                                                                  │
│  /master-data/process-management 등록 현황:                      │
│  - P-001: 슬랫 (slat)                                           │
│  - P-002: 스크린 (screen)                                       │
│                                                                  │
│  ∴ 하드코딩된 값이 아닌 공정 테이블 FK로 연결해야 함               │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

### 6.1 다음 작업 (FK 추가 구현)

```
WorkOrder `process_type` (varchar) → `process_id` (FK) 변경 작업 범위:

1. DB 마이그레이션
   - work_orders.process_type (varchar) 제거
   - work_orders.process_id (FK) 추가 → processes.id 참조
   - 기존 데이터 마이그레이션 (screen→P-002, slat→P-001, bending→신규등록)

2. API 수정
   - api/app/Models/Production/WorkOrder.php
     - PROCESS_* 상수 제거
     - process_type 필드 → process_id FK 필드
     - process() BelongsTo 관계 추가
   - api/app/Services/OrderService.php (생산지시 생성 로직)
   - api/app/Services/WorkOrderService.php (비즈니스 로직)
   - 관련 FormRequest, Resource 클래스

3. Frontend 수정
   - react/src/components/production/WorkOrders/types.ts
     - ProcessType enum 제거
     - process_id: number 필드 추가
     - process 관계 데이터 타입 추가
   - 관련 컴포넌트 (actions.ts, components)
     - 공정 선택 드롭다운 → API에서 공정 목록 조회
```

---

## 7. 참고 문서

- **공정관리 계획**: `docs/dev_plans/process-management-plan.md`
- **수주관리 계획**: `docs/dev_plans/order-management-plan.md`
- **작업지시 계획**: `docs/dev_plans/work-order-plan.md`
- **시스템 아키텍처**: `docs/architecture/system-overview.md`
- **품질 체크리스트**: `docs/standards/quality-checklist.md`

---

## 8. 분석 파일 참조

### 8.1 API 레이어
| 파일 | 역할 |
|------|------|
| `api/app/Http/Controllers/Api/V1/QuoteController.php` | 견적 CRUD |
| `api/app/Http/Controllers/Api/V1/OrderController.php` | 수주 CRUD + 생산지시 생성 |
| `api/app/Http/Controllers/V1/ProcessController.php` | 공정 CRUD |
| `api/app/Http/Controllers/Api/V1/WorkOrderController.php` | 작업지시 CRUD |
| `api/app/Services/QuoteService.php` | 견적 비즈니스 로직 |
| `api/app/Services/OrderService.php` | 견적→수주 변환, 수주→작업지시 연동 |
| `api/app/Services/WorkOrderService.php` | 작업지시 비즈니스 로직 |

### 8.2 모델 레이어
| 파일 | 핵심 필드 |
|------|----------|
| `api/app/Models/Quote/Quote.php` | `status` (draft/sent/approved/finalized/converted), `product_category` |
| `api/app/Models/Order.php` | `status_code`, `quote_id` (FK) |
| `api/app/Models/Process.php` | `process_type` (생산/검사/포장/조립) |
| `api/app/Models/Production/WorkOrder.php` | `process_type` (screen/slat/bending), `sales_order_id` (FK) |

### 8.3 프론트엔드 레이어
| 파일 | 역할 |
|------|------|
| `react/src/components/quotes/types.ts` | Quote 타입 정의 |
| `react/src/components/quotes/QuotationSelectDialog.tsx` | 견적 선택 UI |
| `react/src/types/process.ts` | Process 타입 정의 |
| `react/src/components/production/WorkOrders/types.ts` | WorkOrder 타입 정의 |
| `react/src/components/orders/actions.ts` | Order API 호출 + 생산지시 생성 + 견적변환 |
| `react/src/components/process-management/actions.ts` | Process API 호출 |
| `react/src/components/production/WorkOrders/actions.ts` | WorkOrder API 호출 |

---

## 9. 변경 이력

| 날짜 | 항목 | 변경 내용 | 파일 | 승인 |
|------|------|----------|------|------|
| 2025-01-09 | 문서 생성 | MES 통합 흐름 분석 완료 | - | - |
| 2025-01-09 | 견적 분석 추가 | Quote → Order 연동 분석 (섹션 3.0) | - | - |
| 2025-01-09 | 결정 반영 | Option C 선택, 리네이밍 진행, FK 미추가 결정 | - | ✅ |
| 2025-01-09 | **재결정** | 공정 관리 페이지 확인 후 **Option B (FK 추가)로 변경** | - | ✅ |

### 9.1 재결정 상세

**재결정 배경**:
- 공정 관리 페이지(`/master-data/process-management`) 실제 확인
- `screen`, `slat`, `bending` 값이 공정명(Process Name)임을 확인
- P-001: 슬랫, P-002: 스크린 등록 확인

**이전 결정 → 최종 결정**:
| 항목 | 이전 | 최종 |
|------|------|------|
| 설계 방향 | Option C (하이브리드) | **Option B (FK 추가)** |
| 필드 처리 | 리네이밍만 | **FK로 변경** |
| FK 추가 | 불필요 | **필요** |
| 도메인 관계 | 독립 | **연결** |

---

*이 문서는 /plan 스킬로 생성되었습니다.*