docs: 개발 계획 및 변경 이력 문서 추가

- 작업지시 계획 문서 업데이트
- MES 통합 분석, 서버 컴포넌트 감사 계획 추가
- 수주관리, 인수인계서 API 연동 변경 이력 추가
- sub/ 하위 계획 문서들 추가 (카테고리, 계약, 품목, 단가 등)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-15 08:54:31 +09:00
parent 37d8ce9cc2
commit 7b18ee1b10
14 changed files with 2478 additions and 21 deletions

View File

@@ -0,0 +1,94 @@
# 변경 내용 요약
**날짜:** 2025-01-08
**작업자:** Claude Code
**이슈:** Order Management API Phase 1.1
## 📋 변경 개요
수주관리(Order Management) API의 기본 CRUD 및 상태 관리 기능을 구현했습니다.
WorkOrderService/Controller 패턴을 참고하여 SAM API 규칙을 준수하는 OrderService와 OrderController를 생성했습니다.
## 📁 수정/추가된 파일
### 신규 생성 (7개)
- `app/Services/OrderService.php` - 수주 비즈니스 로직 서비스
- `app/Http/Controllers/Api/V1/OrderController.php` - 수주 API 컨트롤러
- `app/Http/Requests/Order/StoreOrderRequest.php` - 생성 요청 검증
- `app/Http/Requests/Order/UpdateOrderRequest.php` - 수정 요청 검증
- `app/Http/Requests/Order/UpdateOrderStatusRequest.php` - 상태 변경 요청 검증
- `app/Swagger/v1/OrderApi.php` - Swagger API 문서
### 수정 (5개)
- `routes/api.php` - OrderController import 및 라우트 추가
- `lang/ko/message.php` - 수주 관련 메시지 키 추가
- `lang/en/message.php` - 수주 관련 메시지 키 추가
- `lang/ko/error.php` - 수주 에러 메시지 키 추가
- `lang/en/error.php` - 수주 에러 메시지 키 추가
## 🔧 상세 변경 사항
### 1. OrderService
**기능:**
- `index()` - 목록 조회 (검색/필터링/페이징)
- `stats()` - 통계 조회 (상태별 건수/금액)
- `show()` - 단건 조회
- `store()` - 생성 (수주번호 자동생성)
- `update()` - 수정 (완료/취소 상태 수정 불가)
- `destroy()` - 삭제 (진행중/완료 상태 삭제 불가)
- `updateStatus()` - 상태 변경 (전환 규칙 검증)
**내부 메서드:**
- `validateStatusTransition()` - 상태 전환 규칙 검증
- `calculateItemAmounts()` - 품목 금액 계산 (공급가, 세액, 합계)
- `generateOrderNo()` - 수주번호 자동 생성 (ORD{YYYYMMDD}{0001})
### 2. OrderController
**엔드포인트:**
- `GET /api/v1/orders` - 목록 조회
- `GET /api/v1/orders/stats` - 통계 조회
- `POST /api/v1/orders` - 생성
- `GET /api/v1/orders/{id}` - 단건 조회
- `PUT /api/v1/orders/{id}` - 수정
- `DELETE /api/v1/orders/{id}` - 삭제
- `PATCH /api/v1/orders/{id}/status` - 상태 변경
### 3. FormRequest 클래스
**StoreOrderRequest:**
- 주문유형, 카테고리, 거래처 정보, 금액, 배송, 품목 배열 검증
**UpdateOrderRequest:**
- Store와 유사하나 order_no 제외 (수정 불가)
**UpdateOrderStatusRequest:**
- status 필드만 검증 (Rule::in 사용)
### 4. 상태 전환 규칙
```
DRAFT → CONFIRMED, CANCELLED
CONFIRMED → IN_PROGRESS, CANCELLED
IN_PROGRESS → COMPLETED, CANCELLED
COMPLETED → (변경 불가)
CANCELLED → DRAFT (복구 가능)
```
### 5. Swagger 문서
**스키마:**
- Order, OrderItem, OrderPagination, OrderStats
- OrderCreateRequest, OrderUpdateRequest, OrderItemRequest, OrderStatusRequest
## ✅ 검증 완료 항목
- [x] Pint 코드 스타일 검사 (6개 파일 자동 수정)
- [x] Swagger 문서 생성 (`php artisan l5-swagger:generate`)
- [x] Service-First 아키텍처 준수
- [x] FormRequest 검증 패턴 사용
- [x] i18n 메시지 키 사용
- [x] Multi-tenancy (BelongsToTenant) 지원
- [x] 감사 로그 컬럼 (created_by, updated_by, deleted_by)
## ⚠️ 배포 시 주의사항
- Order 모델은 기존에 이미 존재함 (마이그레이션 불필요)
- Swagger UI에서 API 테스트 가능: http://api.sam.kr/api-docs/index.html
## 🔗 관련 문서
- 계획 문서: `docs/plans/order-management-plan.md`
- 참고 패턴: `app/Services/WorkOrderService.php`, `app/Http/Controllers/Api/V1/WorkOrderController.php`

View File

@@ -0,0 +1,81 @@
# 변경 내용 요약
**날짜:** 2026-01-09
**작업자:** Claude Code
**이슈:** Phase 1.2 인수인계보고서관리 Frontend API 연동
## 📋 변경 개요
인수인계보고서관리(Handover Report) Frontend의 actions.ts를 Mock 데이터에서 실제 API 연동으로 변환했습니다.
## 📁 수정된 파일
| 파일 | 변경 내용 |
|------|----------|
| `react/src/components/business/construction/handover-report/actions.ts` | Mock → API 완전 변환 |
| `docs/plans/sub/handover-report-plan.md` | 진행 상태 업데이트 |
## 🔧 상세 변경 사항
### 1. actions.ts 완전 재작성 (499줄)
**제거된 코드:**
- `MOCK_REPORTS` 배열 (7개 목업 데이터)
- `MOCK_REPORT_DETAILS` 객체 (상세 목업 데이터)
- 모든 목업 기반 로직
**추가된 코드:**
#### 헬퍼 함수
```typescript
// API 요청 헬퍼 (쿠키 기반 인증)
async function apiRequest<T>(endpoint, options): Promise<ApiResult<T>>
// 타입 변환 함수들
function transformHandoverReport(apiData): HandoverReport
function transformHandoverReportDetail(apiData): HandoverReportDetail
function transformToApiRequest(data): Record<string, unknown>
```
#### API 연동 함수
| 함수명 | HTTP Method | Endpoint | 용도 |
|--------|-------------|----------|------|
| `getHandoverReportList` | GET | `/construction/handover-reports` | 목록 조회 |
| `getHandoverReportStats` | GET | `/construction/handover-reports/stats` | 통계 조회 |
| `getHandoverReportDetail` | GET | `/construction/handover-reports/{id}` | 상세 조회 |
| `createHandoverReport` | POST | `/construction/handover-reports` | 등록 (신규) |
| `updateHandoverReport` | PUT | `/construction/handover-reports/{id}` | 수정 |
| `deleteHandoverReport` | DELETE | `/construction/handover-reports/{id}` | 삭제 |
| `deleteHandoverReports` | DELETE | `/construction/handover-reports/bulk` | 일괄 삭제 |
#### 타입 변환 매핑
- `snake_case` (API) ↔ `camelCase` (Frontend)
- 중첩 객체 처리: `managers`, `items`, `external_equipment_cost`
- null 안전 처리 및 기본값 설정
### 2. handover-report-plan.md 업데이트
- 상태: ⏳ 대기 → 🔄 진행중
- Frontend 작업 상태 갱신
- 마지막 업데이트 날짜 변경
## ✅ 검증 결과
- [x] TypeScript 타입 검사: 오류 없음
- [x] ESLint 검사: 오류 없음
- [x] 타입 정합성: types.ts와 완전 일치
## ⚠️ 알려진 이슈 (별도 작업 필요)
`HandoverReportListClient.tsx`에 기존 타입 불일치 존재:
- `partnerId` - HandoverReport 타입에 없음
- `contractManagerId` - HandoverReport 타입에 없음
- `constructionPMId` - HandoverReport 타입에 없음
→ 이번 작업 범위 외, 별도 수정 필요
## 🔗 관련 문서
- [상위 계획](../plans/construction-api-integration-plan.md)
- [세부 계획](../plans/sub/handover-report-plan.md)
- [API 백엔드](../../api/app/Services/Construction/HandoverReportService.php)

View File

@@ -0,0 +1,525 @@
# MES 모듈 통합 흐름 분석 계획
> **작성일**: 2025-01-09
> **목적**: 견적 → 수주 → 작업지시 + 공정관리 모듈 간 연동 상태 점검 및 문제점 분석
> **기준 문서**: `docs/plans/process-management-plan.md`, `docs/plans/order-management-plan.md`, `docs/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/plans/process-management-plan.md`
- **수주관리 계획**: `docs/plans/order-management-plan.md`
- **작업지시 계획**: `docs/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 스킬로 생성되었습니다.*

View File

@@ -0,0 +1,397 @@
# 공정관리 (Process Management) API 연동 계획
> **작성일**: 2025-01-08
> **목적**: 공정관리 기능 검증 및 테스트
> **상태**: ✅ 검증 완료
---
## 📍 현재 진행 상태
| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | Phase 3: 개별 품목 연결 기능 (process_items) |
| **다음 작업** | 완료 (Phase 2는 선택사항) |
| **진행률** | 5/5 (100%) - Phase 1 + Phase 3 완료 |
| **마지막 업데이트** | 2026-01-08 |
---
## 1. 개요
### 1.1 기능 설명
공정관리는 MES 시스템의 기초 데이터로, 생산 공정을 정의하고 관리하는 기능입니다.
작업지시 생성 시 공정 유형(process_type)으로 연결되며, 자동 분류 규칙을 통해 품목별 공정 배정을 자동화합니다.
### 1.2 현재 구현 상태 분석
#### API (Laravel) - ✅ 완료
| 구성요소 | 파일 경로 | 상태 |
|---------|----------|:----:|
| Model | `api/app/Models/Process.php` | ✅ |
| Model | `api/app/Models/ProcessClassificationRule.php` | ✅ |
| Model | `api/app/Models/ProcessItem.php` | ✅ (Phase 3) |
| Migration | `api/database/migrations/2026_01_08_180607_create_process_items_table.php` | ✅ |
| Service | `api/app/Services/ProcessService.php` | ✅ |
| Controller | `api/app/Http/Controllers/V1/ProcessController.php` | ✅ |
| FormRequest | `api/app/Http/Requests/V1/Process/StoreProcessRequest.php` | ✅ |
| FormRequest | `api/app/Http/Requests/V1/Process/UpdateProcessRequest.php` | ✅ |
| Swagger | `api/app/Swagger/v1/ProcessApi.php` | ✅ |
| Route | `/api/v1/processes` | ✅ |
#### Frontend (React/Next.js) - ✅ API 연동 완료
| 구성요소 | 파일 경로 | 상태 |
|---------|----------|:----:|
| 목록 페이지 | `react/src/app/[locale]/(protected)/master-data/process-management/page.tsx` | ✅ |
| 등록 페이지 | `react/src/app/[locale]/(protected)/master-data/process-management/new/page.tsx` | ✅ |
| 상세 페이지 | `react/src/app/[locale]/(protected)/master-data/process-management/[id]/page.tsx` | ✅ |
| 수정 페이지 | `react/src/app/[locale]/(protected)/master-data/process-management/[id]/edit/page.tsx` | ✅ |
| 목록 컴포넌트 | `react/src/components/process-management/ProcessListClient.tsx` | ✅ |
| 폼 컴포넌트 | `react/src/components/process-management/ProcessForm.tsx` | ✅ |
| 상세 컴포넌트 | `react/src/components/process-management/ProcessDetail.tsx` | ✅ |
| 규칙 모달 | `react/src/components/process-management/RuleModal.tsx` | ✅ |
| **actions.ts** | `react/src/components/process-management/actions.ts` | ✅ |
### 1.3 관련 URL
| 화면 | URL | 설명 |
|------|-----|------|
| 공정목록 | `/master-data/process-management` | 토글 기능 포함 |
| 공정등록 | `/master-data/process-management/new` | 모달 - 규칙추가 |
| 공정상세 | `/master-data/process-management/{id}` | 상세 정보 |
| 공정수정 | `/master-data/process-management/{id}/edit` | 수정 폼 |
### 1.4 연관관계
```
┌─────────────────┐ process_type ┌─────────────────┐
│ Process │ ───────────────────────│ WorkOrder │
│ (공정관리) │ screen/slat/bending │ (작업지시) │
└─────────────────┘ └─────────────────┘
├── classificationRules (패턴 규칙)
│ ▼
│ ┌─────────────────────────┐
│ │ ProcessClassificationRule│
│ │ (자동 분류 규칙) │
│ └─────────────────────────┘
└── processItems (개별 품목) ← Phase 3
┌─────────────────────────┐ ┌─────────────────┐
│ ProcessItem │────────│ Item │
│ (공정-품목 연결) │ │ (품목) │
└─────────────────────────┘ └─────────────────┘
```
---
## 2. API 엔드포인트
### 2.1 REST API (구현 완료)
| Method | Endpoint | 설명 | 상태 |
|--------|----------|------|:----:|
| GET | `/api/v1/processes` | 공정 목록 조회 (검색/페이징) | ✅ |
| GET | `/api/v1/processes/{id}` | 공정 상세 조회 | ✅ |
| POST | `/api/v1/processes` | 공정 생성 | ✅ |
| PUT | `/api/v1/processes/{id}` | 공정 수정 | ✅ |
| DELETE | `/api/v1/processes/{id}` | 공정 삭제 | ✅ |
| DELETE | `/api/v1/processes` | 공정 일괄 삭제 | ✅ |
| PATCH | `/api/v1/processes/{id}/toggle` | 공정 상태 토글 | ✅ |
| GET | `/api/v1/processes/options` | 드롭다운용 옵션 목록 | ✅ |
| GET | `/api/v1/processes/stats` | 공정 통계 | ✅ |
### 2.2 actions.ts 구현 함수 (완료)
```typescript
// 목록/조회
getProcessList(params) // 목록 조회
getProcessById(id) // 상세 조회
getProcessOptions() // 드롭다운 옵션
getProcessStats() // 통계 조회
// CRUD
createProcess(data) // 생성
updateProcess(id, data) // 수정
deleteProcess(id) // 삭제
deleteProcesses(ids) // 일괄 삭제
toggleProcessActive(id) // 상태 토글
// 보조
getDepartmentOptions() // 부서 옵션 (분류 규칙용)
getItemList(params) // 품목 목록 (분류 규칙용)
```
---
## 3. 데이터 스키마
### 3.1 Process (공정)
```typescript
interface Process {
id: string;
processCode: string; // P-001, P-002
processName: string; // 공정명
description?: string; // 공정 설명
processType: '생산' | '검사' | '포장' | '조립';
department: string; // 담당 부서
workLogTemplate?: string; // 작업일지 양식
classificationRules: ClassificationRule[];
requiredWorkers: number; // 필요 작업자 수
equipmentInfo?: string; // 설비 정보
workSteps: string[]; // 작업 단계
note?: string;
status: '사용중' | '미사용';
createdAt: string;
updatedAt: string;
}
```
### 3.2 ClassificationRule (자동 분류 규칙)
```typescript
interface ClassificationRule {
id: string;
registrationType: 'pattern' | 'individual'; // 패턴 규칙 vs 개별 품목
ruleType: '품목코드' | '품목명' | '품목구분';
matchingType: 'startsWith' | 'endsWith' | 'contains' | 'equals';
conditionValue: string;
priority: number;
description?: string;
isActive: boolean;
createdAt: string;
}
```
### 3.3 ProcessItem (공정-품목 연결) - Phase 3 추가
```typescript
// API 응답 스키마
interface ApiProcessItem {
id: number;
process_id: number;
item_id: number;
priority: number;
is_active: boolean;
item?: {
id: number;
code: string;
name: string;
};
}
// DB 테이블: process_items
// - id (PK)
// - process_id (FK → processes)
// - item_id (FK → items)
// - priority (정렬 순서)
// - is_active (사용 여부)
// - created_at, updated_at
```
### 3.4 API 요청/응답 변환
#### 요청 (Frontend → API)
```typescript
// 패턴 규칙과 개별 품목 분리
{
classification_rules: [ // 패턴 규칙만
{ rule_type, matching_type, condition_value, ... }
],
item_ids: [123, 456, 789] // 개별 품목 ID 배열
}
```
#### 응답 (API → Frontend)
```typescript
// process_items를 individual 규칙으로 변환
{
classification_rules: [...], // 패턴 규칙
process_items: [ // 개별 품목 연결
{ id, process_id, item_id, priority, is_active, item: {...} }
]
}
```
---
## 4. 작업 범위
### Phase 1: 검증 및 테스트 (완료 - 2026-01-08)
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1.1 | 목록 조회 테스트 | ✅ | 검색, 탭 필터 정상 |
| 1.2 | 등록 기능 테스트 | ✅ | 정상 (담당부서는 DB 데이터 의존) |
| 1.3 | 수정 기능 테스트 | ✅ | 필요인원 변경/저장 정상 |
| 1.4 | 삭제 기능 테스트 | ⏭️ | 데이터 보존으로 생략 |
| 1.5 | 토글 기능 테스트 | ✅ | 사용중↔미사용 전환 정상 |
### 📋 참고사항
- **담당부서 드롭다운**: departments 테이블 데이터에 의존. 데이터 없으면 빈 드롭다운 (정상 동작)
### Phase 2: 개선 사항 (선택)
| # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 2.1 | 공정 순서 드래그앤드롭 | ⏭️ | 후순위 |
| 2.2 | 작업 지침서 PDF 업로드 | ⏭️ | 후순위 |
| 2.3 | 공정 흐름도 시각화 | ⏭️ | 후순위 |
### Phase 3: 개별 품목 연결 기능 (완료 - 2026-01-08)
#### 배경
- 기존 분류 규칙에서 400개 이상의 품목 코드를 `,` 구분자로 저장 시도
- `condition_value` VARCHAR(255) 필드 초과 → API 422 에러 발생
- 해결: 개별 품목은 별도 테이블(`process_items`)로 관계형 저장
#### 완료 작업
| # | 작업 항목 | 상태 | 파일/위치 |
|---|----------|:----:|----------|
| 3.1 | ProcessItem 모델 생성 | ✅ | `api/app/Models/ProcessItem.php` |
| 3.2 | process_items 마이그레이션 | ✅ | `api/database/migrations/2026_01_08_180607_*` |
| 3.3 | Process 모델 관계 추가 | ✅ | `processItems()` HasMany |
| 3.4 | ProcessService 수정 | ✅ | `syncProcessItems()` 메서드 추가 |
| 3.5 | Validation 업데이트 | ✅ | `item_ids` 배열 검증 추가 |
| 3.6 | Swagger 문서 업데이트 | ✅ | `ProcessItem` 스키마 추가 |
| 3.7 | Frontend actions.ts 수정 | ✅ | 요청/응답 변환 로직 |
#### 핵심 변경 사항
**API 측 (Laravel)**
```php
// ProcessService.php
private function syncProcessItems(Process $process, array $itemIds): void
{
$process->processItems()->delete();
foreach ($itemIds as $index => $itemId) {
ProcessItem::create([
'process_id' => $process->id,
'item_id' => $itemId,
'priority' => $index,
'is_active' => true,
]);
}
}
```
**Frontend 측 (Next.js)**
```typescript
// actions.ts
// 패턴 규칙과 개별 품목 분리
const patternRules = data.classificationRules.filter(
(rule) => rule.registrationType === 'pattern'
);
const individualRules = data.classificationRules.filter(
(rule) => rule.registrationType === 'individual'
);
// item_ids 추출
const itemIds = individualRules.flatMap((rule) =>
rule.conditionValue.split(',').map((id) => parseInt(id.trim(), 10))
);
```
---
## 5. 주요 기능 상세
### 5.1 토글 기능
- 목록에서 각 공정의 사용/미사용 상태를 토글
- `PATCH /api/v1/processes/{id}/toggle` 호출
- 미사용 공정은 작업지시 생성 시 선택 불가
### 5.2 규칙 추가 (모달)
- 자동 분류 규칙을 통해 품목별 공정 자동 배정
- 우선순위(priority)에 따라 규칙 적용 순서 결정
- include/exclude로 포함/제외 규칙 설정
### 5.3 양식 보기 (모달)
- 작업일지 템플릿 미리보기
- HTML/마크다운 형식 지원
---
## 6. 의존성
### 6.1 필수 선행 작업
- **없음** (기초 데이터)
### 6.2 후속 연동
- **작업지시 (WorkOrder)**: 공정 유형 선택 (process_type: screen/slat/bending)
- **품목관리 (Item)**: 자동 분류 규칙 적용
---
## 7. 검증 방법
### 7.1 테스트 체크리스트
| 기능 | 테스트 항목 | 예상 결과 |
|------|-----------|----------|
| 목록 조회 | 페이지 로드 | 공정 목록 표시 |
| 검색 | "생산" 검색 | 필터링된 결과 |
| 탭 필터 | "사용중" 탭 클릭 | 사용중 공정만 표시 |
| 등록 | 새 공정 등록 | 목록에 추가됨 |
| 수정 | 공정명 변경 | 변경 반영됨 |
| 삭제 | 공정 삭제 | 목록에서 제거됨 |
| 토글 | 상태 토글 | 사용중↔미사용 전환 |
| 규칙 추가 | 분류 규칙 추가 | 규칙 저장됨 |
### 7.2 API 테스트
```bash
# 목록 조회
curl -X GET "http://api.sam.kr/api/v1/processes" -H "X-Api-Key: ..."
# 상세 조회
curl -X GET "http://api.sam.kr/api/v1/processes/1" -H "X-Api-Key: ..."
# 통계 조회
curl -X GET "http://api.sam.kr/api/v1/processes/stats" -H "X-Api-Key: ..."
# 토글
curl -X PATCH "http://api.sam.kr/api/v1/processes/1/toggle" -H "X-Api-Key: ..."
```
---
## 8. 참고 사항
### 8.1 공정 유형 (process_type)
현재 작업지시에서 사용하는 공정 유형:
- `screen`: 스크린 공정
- `slat`: 슬랫 공정
- `bending`: 절곡 공정
### 8.2 Process vs WorkOrder.process_type
- `Process` 모델: 공정의 메타데이터 (이름, 설명, 규칙 등)
- `WorkOrder.process_type`: 실제 작업지시에 적용된 공정 유형
- 향후 FK 연결로 확장성 확보 가능
---
## 9. 참고 문서
- **빠른 시작**: `docs/quickstart/quick-start.md`
- **API 규칙**: `docs/standards/api-rules.md`
- **품질 체크리스트**: `docs/standards/quality-checklist.md`
### 참고 코드
- **Controller**: `api/app/Http/Controllers/V1/ProcessController.php`
- **Service**: `api/app/Services/ProcessService.php`
- **actions.ts**: `react/src/components/process-management/actions.ts`
---
## 10. 자기완결성 점검
| # | 검증 항목 | 상태 | 비고 |
|---|----------|:----:|------|
| 1 | 작업 목적이 명확한가? | ✅ | 검증 및 테스트 |
| 2 | 성공 기준이 정의되어 있는가? | ✅ | 섹션 7 참조 |
| 3 | 작업 범위가 구체적인가? | ✅ | Phase 1 테스트 항목 |
| 4 | 의존성이 명시되어 있는가? | ✅ | 선행 작업 없음 |
| 5 | 참고 파일 경로가 정확한가? | ✅ | 모든 경로 검증됨 |
| 6 | 단계별 절차가 실행 가능한가? | ✅ | 테스트 체크리스트 제공 |
| 7 | 검증 방법이 명시되어 있는가? | ✅ | curl + 체크리스트 |
| 8 | 모호한 표현이 없는가? | ✅ | 구체적 경로 명시 |
---
*이 문서는 독립 세션에서 바로 작업 시작 가능하도록 설계되었습니다.*

View File

@@ -0,0 +1,147 @@
# React 서버 컴포넌트 점검 계획
> **작성일**: 2025-01-09
> **목적**: push하지 않은 작업분 중 서버 컴포넌트를 클라이언트 컴포넌트로 변경
> **상태**: ✅ 점검 완료 - 수정 불필요
---
## 📍 점검 결과 요약
| 항목 | 내용 |
|------|------|
| **점검 대상** | push하지 않은 커밋 (origin/master..HEAD) |
| **커밋 수** | 20개 |
| **점검 파일 수** | 31개 (tsx/ts 파일) |
| **서버 컴포넌트 발견** | 0개 |
| **수정 필요** | ❌ 없음 |
---
## 1. 점검 배경
### 1.1 정책
- 프론트엔드 정책: **서버 컴포넌트 사용 금지**
- 모든 컴포넌트는 **클라이언트 컴포넌트**로 작성해야 함
- `'use client'` 지시어 필수
### 1.2 점검 범위
- **대상**: react 폴더의 push하지 않은 작업분
- **제외**: 이미 push된 커밋 (프론트엔드에서 수정 중)
---
## 2. 점검 대상 파일
### 2.1 변경된 TSX 파일 (16개)
| # | 파일 | 'use client' | 상태 |
|---|------|:------------:|:----:|
| 1 | `src/app/[locale]/(protected)/sales/order-management-sales/[id]/edit/page.tsx` | ✅ | 정상 |
| 2 | `src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx` | ✅ | 정상 |
| 3 | `src/app/[locale]/(protected)/sales/order-management-sales/[id]/production-order/page.tsx` | ✅ | 정상 |
| 4 | `src/app/[locale]/(protected)/sales/order-management-sales/new/page.tsx` | ✅ | 정상 |
| 5 | `src/app/[locale]/(protected)/sales/order-management-sales/page.tsx` | ✅ | 정상 |
| 6 | `src/components/approval/DocumentCreate/ApprovalLineSection.tsx` | ✅ | 정상 |
| 7 | `src/components/approval/DocumentCreate/ReferenceSection.tsx` | ✅ | 정상 |
| 8 | `src/components/hr/EmployeeManagement/EmployeeForm.tsx` | ✅ | 정상 |
| 9 | `src/components/orders/OrderRegistration.tsx` | ✅ | 정상 |
| 10 | `src/components/orders/QuotationSelectDialog.tsx` | ✅ | 정상 |
| 11 | `src/components/process-management/ProcessDetail.tsx` | ✅ | 정상 |
| 12 | `src/components/process-management/RuleModal.tsx` | ✅ | 정상 |
| 13 | `src/components/production/WorkOrders/SalesOrderSelectModal.tsx` | ✅ | 정상 |
| 14 | `src/components/production/WorkOrders/WorkOrderCreate.tsx` | ✅ | 정상 |
| 15 | `src/components/production/WorkOrders/WorkOrderDetail.tsx` | ✅ | 정상 |
| 16 | `src/components/production/WorkOrders/WorkOrderList.tsx` | ✅ | 정상 |
### 2.2 변경된 TS 파일 (15개) - 검토 불필요
TS 파일은 컴포넌트가 아닌 유틸리티/타입/액션 파일로 서버 컴포넌트 대상 아님:
- `src/components/business/construction/*/actions.ts` (6개)
- `src/components/orders/actions.ts`
- `src/components/orders/index.ts`
- `src/components/process-management/actions.ts`
- `src/components/production/WorkOrders/actions.ts`
- `src/components/production/WorkOrders/types.ts`
- `src/lib/api/common-codes.ts`
- `src/lib/api/index.ts`
- `src/types/process.ts`
- `src/components/business/construction/site-management/types.ts`
---
## 3. Push하지 않은 커밋 목록
```
311ddd9 docs: Phase D~K 마이그레이션 완료 상태 반영 (95%)
6615f39 feat(order-management): Mock → API 연동 및 common-codes 유틸리티 추가
d472b77 fix(approval): 결재선/참조 Select 값 변경 불가 버그 수정
5fa20c8 feat(item-management): Mock → API 연동 완료
749f0ce feat: 거래처관리 API 연동 (Phase 2.2)
273d570 feat(시공사): 2.1 현장관리 - Frontend API 연동
78e193c refactor(work-orders): process_type을 process_id FK로 변환
9d30555 feat(시공사): 1.2 인수인계보고서 - Frontend API 연동
d15a203 feat(work-orders): 다중 담당자 UI 구현
8172226 Merge remote-tracking branch 'origin/master'
668cde3 Merge remote-tracking branch 'origin/master'
c651e7b feat(WEB): 수주관리 Phase 3 완료 - 고급 기능 구현
2d7809b feat: [시공관리] 계약관리 Frontend API 연동
12b4259 refactor(work-orders): 코드 리뷰 기반 프론트엔드 개선
fde8726 feat(WEB): 수주관리 Phase 2 타입 정의 확장 및 공정관리 개별 품목 표시 수정
ba36c0e feat: 공정 관리 Frontend actions 업데이트
d797868 fix(WEB): 공정관리 개별 품목 저장 안되는 버그 수정
3d2dea6 feat: 수주 관리 Phase 3 - Frontend API 연동
6632943 Merge remote-tracking branch 'origin/master'
288871c feat(WEB): 직원 관리 폼 직급/부서/직책 Select 드롭다운 연동
572ffe8 feat(orders): Phase 2 - Frontend API 연동 완료
```
---
## 4. 점검 결론
### 4.1 결과
**✅ 모든 TSX 파일에 'use client' 지시어가 있음**
push하지 않은 작업분에서 서버 컴포넌트가 발견되지 않았습니다.
모든 컴포넌트가 클라이언트 컴포넌트 정책을 준수하고 있습니다.
### 4.2 수정 필요 항목
**없음**
---
## 5. 향후 권장사항
### 5.1 새 파일 생성 시 체크리스트
```
□ TSX 파일 첫 줄에 'use client' 지시어 추가
□ page.tsx 파일도 예외 없이 'use client' 필수
□ layout.tsx 파일도 필요시 'use client' 추가
```
### 5.2 코드 리뷰 시 확인
- PR 리뷰 시 새 TSX 파일의 'use client' 지시어 확인
- async 컴포넌트 패턴 지양 (useEffect, React Query 등 사용)
### 5.3 린트 규칙 고려
향후 ESLint 커스텀 룰 추가 검토:
```javascript
// .eslintrc.js 예시
rules: {
'react/enforce-use-client': 'error' // 커스텀 룰
}
```
---
## 6. 변경 이력
| 날짜 | 항목 | 변경 내용 |
|------|------|----------|
| 2025-01-09 | 문서 생성 | 서버 컴포넌트 점검 완료, 수정 불필요 확인 |
---
*이 문서는 /sc:plan 스킬로 생성되었습니다.*

View File

@@ -0,0 +1,149 @@
# 카테고리관리 (Categories) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
> **API 상태**: ✅ 기존 API 존재
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/base-info/categories/
│ └── page.tsx
└── components/business/construction/category-management/
├── CategoryManagementClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 mockCategories:**
```typescript
let mockCategories: Category[] = [
{ id: '1', name: '슬라이드 OPEN 사이즈', order: 1, isDefault: true },
{ id: '2', name: '모터', order: 2, isDefault: true },
{ id: '3', name: '공정자재', order: 3, isDefault: true },
{ id: '4', name: '철물', order: 4, isDefault: true },
];
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getCategories` | 카테고리 목록 조회 | ✅ Mock |
| `createCategory` | 카테고리 생성 | ✅ Mock |
| `updateCategory` | 카테고리 수정 | ✅ Mock |
| `deleteCategory` | 카테고리 삭제 | ✅ Mock |
| `reorderCategories` | 카테고리 순서 변경 | ✅ Mock |
---
## 2. 기존 API 분석
### 2.1 기존 엔드포인트 (api/routes/api.php line 835-880)
```php
Route::prefix('construction/categories')->group(function () {
Route::get('/', [CategoryController::class, 'index']);
Route::get('/tree', [CategoryController::class, 'tree']);
Route::post('/', [CategoryController::class, 'store']);
Route::post('/reorder', [CategoryController::class, 'reorder']);
Route::get('/{category}', [CategoryController::class, 'show']);
Route::put('/{category}', [CategoryController::class, 'update']);
Route::patch('/{category}/toggle', [CategoryController::class, 'toggle']);
Route::post('/{category}/move', [CategoryController::class, 'move']);
Route::delete('/{category}', [CategoryController::class, 'destroy']);
// 필드 관리
Route::get('/{category}/fields', [CategoryController::class, 'fields']);
Route::post('/{category}/fields', [CategoryController::class, 'storeField']);
Route::put('/{category}/fields/{field}', [CategoryController::class, 'updateField']);
Route::delete('/{category}/fields/{field}', [CategoryController::class, 'destroyField']);
Route::post('/{category}/fields/reorder', [CategoryController::class, 'reorderFields']);
// 템플릿 관리
Route::get('/{category}/templates', [CategoryController::class, 'templates']);
Route::post('/{category}/templates', [CategoryController::class, 'storeTemplate']);
// 변경 로그
Route::get('/{category}/logs', [CategoryController::class, 'logs']);
});
```
### 2.2 API-컴포넌트 매핑
| 컴포넌트 함수 | API 엔드포인트 | 매핑 상태 |
|--------------|---------------|:--------:|
| `getCategories` | `GET /construction/categories` | ✅ 매핑 가능 |
| `createCategory` | `POST /construction/categories` | ✅ 매핑 가능 |
| `updateCategory` | `PUT /construction/categories/{id}` | ✅ 매핑 가능 |
| `deleteCategory` | `DELETE /construction/categories/{id}` | ✅ 매핑 가능 |
| `reorderCategories` | `POST /construction/categories/reorder` | ✅ 매핑 가능 |
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | 기존 API 응답 형식 확인 | ⏳ | |
| 2 | 프론트 타입과 정합성 확인 | ⏳ | |
| 3 | 필요시 API 수정 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Category 타입 (현재)
```typescript
interface Category {
id: string;
name: string;
order: number;
isDefault: boolean;
}
```
### 4.2 API 응답 타입 (확인 필요)
```typescript
// API 응답과 프론트 타입 매칭 필요
interface CategoryResponse {
id: number | string;
name: string;
order: number;
is_default: boolean; // snake_case → camelCase 변환 필요
parent_id?: number;
// 추가 필드 확인 필요
}
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

171
plans/sub/contract-plan.md Normal file
View File

@@ -0,0 +1,171 @@
# 계약관리 (Contract) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/project/contract/
│ └── page.tsx
└── components/business/construction/contract/
├── ContractListClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 MOCK_CONTRACTS:**
```typescript
const MOCK_CONTRACTS: Contract[] = [
{
id: '1',
contractNumber: 'CON-2025-0001',
title: '강남 오피스텔 신축공사 계약',
partnerId: '1',
partnerName: '대우건설',
contractManagerId: 'M1',
contractManagerName: '김영수',
constructionPmId: 'PM1',
constructionPmName: '이철수',
startDate: '2025-01-01',
endDate: '2025-12-31',
amount: 5000000000,
status: 'active',
stage: 'construction',
createdAt: '2024-12-01T00:00:00Z',
updatedAt: '2025-01-01T00:00:00Z',
},
// ... 총 9개 계약
];
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getContractList` | 계약 목록 조회 | ✅ Mock |
| `getContractStats` | 계약 통계 조회 | ✅ Mock |
| `getContractStageCounts` | 단계별 카운트 | ✅ Mock |
| `getContract` | 계약 상세 조회 | ✅ Mock |
| `deleteContract` | 계약 삭제 | ✅ Mock |
| `deleteContracts` | 계약 일괄 삭제 | ✅ Mock |
| `getContractDetail` | 계약 상세 (확장) | ✅ Mock |
| `updateContract` | 계약 수정 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트
| Method | Endpoint | 용도 |
|--------|----------|------|
| GET | `/api/construction/contracts` | 목록 조회 |
| GET | `/api/construction/contracts/stats` | 통계 조회 |
| GET | `/api/construction/contracts/stage-counts` | 단계별 카운트 |
| GET | `/api/construction/contracts/{id}` | 상세 조회 |
| POST | `/api/construction/contracts` | 등록 |
| PUT | `/api/construction/contracts/{id}` | 수정 |
| DELETE | `/api/construction/contracts/{id}` | 삭제 |
| DELETE | `/api/construction/contracts/bulk` | 일괄 삭제 |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetContractListParams {
page?: number;
size?: number;
startDate?: string;
endDate?: string;
partnerId?: string;
contractManagerId?: string;
constructionPmId?: string;
status?: ContractStatus;
stage?: ContractStage;
search?: string;
}
```
**목록 조회 Response:**
```typescript
interface ContractListResponse {
items: Contract[];
totalCount: number;
page: number;
size: number;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | ContractController 생성 | ⏳ | |
| 2 | ContractService 생성 | ⏳ | |
| 3 | ContractFormRequest 생성 | ⏳ | |
| 4 | Contract 모델 확인/수정 | ⏳ | |
| 5 | routes/api.php 등록 | ⏳ | |
| 6 | Swagger 문서 작성 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Contract 타입
```typescript
interface Contract {
id: string;
contractNumber: string;
title: string;
partnerId: string;
partnerName: string;
contractManagerId: string;
contractManagerName: string;
constructionPmId: string;
constructionPmName: string;
startDate: string;
endDate: string;
amount: number;
status: ContractStatus;
stage: ContractStage;
createdAt: string;
updatedAt: string;
}
type ContractStatus = 'active' | 'completed' | 'suspended' | 'terminated';
type ContractStage = 'contract' | 'pre_construction' | 'construction' | 'completion' | 'warranty';
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

View File

@@ -0,0 +1,154 @@
# 인수인계보고서관리 (Handover Report) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ✅ 완료
> **마지막 업데이트**: 2026-01-09
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/project/contract/handover-report/
│ └── page.tsx
└── components/business/construction/handover-report/
├── HandoverReportListClient.tsx
├── HandoverReportDetailForm.tsx
├── actions.ts
├── types.ts
├── index.ts
└── modals/
├── HandoverReportDocumentModal.tsx
└── index.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 MOCK_REPORTS:**
```typescript
const MOCK_REPORTS: HandoverReport[] = [
{
id: '1',
reportNumber: '123123',
partnerName: '통신공사',
siteName: '서울역사 통신공사',
// ... 총 7개 보고서
},
];
const MOCK_REPORT_DETAILS: Record<string, HandoverReportDetail> = {
'1': { ... },
'2': { ... },
};
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getHandoverReportList` | 보고서 목록 조회 | ✅ Mock |
| `getHandoverReportStats` | 보고서 통계 조회 | ✅ Mock |
| `deleteHandoverReport` | 보고서 삭제 | ✅ Mock |
| `deleteHandoverReports` | 보고서 일괄 삭제 | ✅ Mock |
| `getHandoverReportDetail` | 보고서 상세 조회 | ✅ Mock |
| `updateHandoverReport` | 보고서 수정 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트 (실제 구현됨)
| Method | Endpoint | 용도 | 상태 |
|--------|----------|------|:----:|
| GET | `/api/v1/construction/handover-reports` | 목록 조회 | ✅ |
| GET | `/api/v1/construction/handover-reports/stats` | 통계 조회 | ✅ |
| GET | `/api/v1/construction/handover-reports/{id}` | 상세 조회 | ✅ |
| POST | `/api/v1/construction/handover-reports` | 등록 | ✅ |
| PUT | `/api/v1/construction/handover-reports/{id}` | 수정 | ✅ |
| DELETE | `/api/v1/construction/handover-reports/{id}` | 삭제 | ✅ |
| DELETE | `/api/v1/construction/handover-reports/bulk` | 일괄 삭제 | ✅ |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetHandoverReportListParams {
page?: number;
size?: number;
startDate?: string;
endDate?: string;
contractId?: string;
partnerId?: string;
status?: HandoverReportStatus;
search?: string;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API) ✅ 완료
| # | 작업 | 상태 | 파일 |
|---|------|:----:|------|
| 1 | HandoverReportController 생성 | ✅ | `api/app/Http/Controllers/Api/V1/Construction/HandoverReportController.php` |
| 2 | HandoverReportService 생성 | ✅ | `api/app/Services/Construction/HandoverReportService.php` |
| 3 | HandoverReportFormRequest 생성 | ✅ | `api/app/Http/Requests/Construction/HandoverReport*.php` |
| 4 | HandoverReport 모델 생성 | ✅ | `api/app/Models/Construction/HandoverReport*.php` |
| 5 | routes/api.php 등록 | ✅ | 라인 438-446 |
| 6 | Migrations 생성 | ✅ | 3개 테이블 (reports, managers, items) |
### 3.2 Frontend (React) ✅ 완료
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ✅ | 7개 함수 완료 (create 추가) |
| 2 | API 클라이언트 연동 | ✅ | apiRequest 헬퍼 구현 |
| 3 | 에러 핸들링 추가 | ✅ | try-catch + 에러 메시지 |
| 4 | types.ts 정합성 확인 | ✅ | 타입 검사 통과 |
---
## 4. 타입 정의
### 4.1 HandoverReport 타입 (현재 types.ts)
```typescript
interface HandoverReport {
id: string;
reportNumber: string;
partnerName: string;
siteName: string;
contractManagerName: string;
constructionPMName: string | null;
totalSites: number;
contractAmount: number;
contractStartDate: string;
contractEndDate: string;
status: HandoverReportStatus;
contractId: string;
createdAt: string;
updatedAt: string;
}
type HandoverReportStatus = 'pending' | 'completed';
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
| 2026-01-09 | Backend 완료 확인, Frontend 작업 시작 | ✅ |
| 2026-01-09 | Frontend actions.ts API 연동 완료 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

144
plans/sub/items-plan.md Normal file
View File

@@ -0,0 +1,144 @@
# 품목관리 (Items) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/base-info/items/
│ └── page.tsx
└── components/business/construction/item-management/
├── ItemManagementClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 Mock 함수:**
```typescript
// getItemList에서 Mock 품목 데이터 생성
// 품목: 품목코드, 품목명, 카테고리, 규격, 단위, 단가 등
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getItemList` | 품목 목록 조회 | ✅ Mock |
| `getItemStats` | 품목 통계 조회 | ✅ Mock |
| `deleteItem` | 품목 삭제 | ✅ Mock |
| `deleteItems` | 품목 일괄 삭제 | ✅ Mock |
| `getCategoryOptions` | 카테고리 옵션 조회 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트
| Method | Endpoint | 용도 |
|--------|----------|------|
| GET | `/api/construction/items` | 목록 조회 |
| GET | `/api/construction/items/stats` | 통계 조회 |
| GET | `/api/construction/items/{id}` | 상세 조회 |
| POST | `/api/construction/items` | 등록 |
| PUT | `/api/construction/items/{id}` | 수정 |
| DELETE | `/api/construction/items/{id}` | 삭제 |
| DELETE | `/api/construction/items/bulk` | 일괄 삭제 |
| POST | `/api/construction/items/import` | 엑셀 일괄 등록 |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetItemListParams {
page?: number;
size?: number;
categoryId?: string;
status?: ItemStatus;
search?: string;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | ItemController 생성 | ⏳ | 시공사용 |
| 2 | ItemService 생성 | ⏳ | |
| 3 | ItemFormRequest 생성 | ⏳ | |
| 4 | Item 모델 확인/수정 | ⏳ | |
| 5 | routes/api.php 등록 | ⏳ | |
| 6 | Swagger 문서 작성 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Item 타입
```typescript
interface Item {
id: string;
itemCode: string;
itemName: string;
categoryId: string;
categoryName: string;
specification?: string;
unit: string;
unitPrice: number;
status: ItemStatus;
description?: string;
createdAt: string;
updatedAt: string;
}
type ItemStatus = 'active' | 'inactive' | 'discontinued';
```
### 4.2 ItemStats 타입
```typescript
interface ItemStats {
total: number;
active: number;
inactive: number;
byCategory: {
categoryId: string;
categoryName: string;
count: number;
}[];
}
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

View File

@@ -0,0 +1,153 @@
# 발주관리 (Order Management) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/order-management/
│ └── page.tsx
└── components/business/construction/order-management/
├── OrderManagementClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 generateMockOrders:**
```typescript
function generateMockOrders(count: number): Order[] {
// 50개의 Mock 발주 데이터 생성
// 결정론적 Mock 데이터 (index 기반 선택)
const partners = ['삼성물산', '현대건설', '대우건설', ...];
const sites = ['강남 오피스텔', '송파 주상복합', ...];
const statuses = ['pending', 'approved', 'in_progress', 'completed', 'cancelled'];
}
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getOrderList` | 발주 목록 조회 | ✅ Mock |
| `getOrderStats` | 발주 통계 조회 | ✅ Mock |
| `deleteOrder` | 발주 삭제 | ✅ Mock |
| `deleteOrders` | 발주 일괄 삭제 | ✅ Mock |
| `updateOrderStatus` | 발주 상태 변경 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트
| Method | Endpoint | 용도 |
|--------|----------|------|
| GET | `/api/construction/orders` | 목록 조회 |
| GET | `/api/construction/orders/stats` | 통계 조회 |
| GET | `/api/construction/orders/{id}` | 상세 조회 |
| POST | `/api/construction/orders` | 등록 |
| PUT | `/api/construction/orders/{id}` | 수정 |
| PATCH | `/api/construction/orders/{id}/status` | 상태 변경 |
| DELETE | `/api/construction/orders/{id}` | 삭제 |
| DELETE | `/api/construction/orders/bulk` | 일괄 삭제 |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetOrderListParams {
page?: number;
size?: number;
startDate?: string;
endDate?: string;
siteId?: string;
partnerId?: string;
status?: OrderStatus;
search?: string;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | OrderController 생성 | ⏳ | |
| 2 | OrderService 생성 | ⏳ | |
| 3 | OrderFormRequest 생성 | ⏳ | |
| 4 | Order 모델 생성 | ⏳ | |
| 5 | routes/api.php 등록 | ⏳ | |
| 6 | Swagger 문서 작성 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Order 타입
```typescript
interface Order {
id: string;
orderNumber: string;
siteId: string;
siteName: string;
partnerId: string;
partnerName: string;
title: string;
description?: string;
totalAmount: number;
status: OrderStatus;
orderDate: string;
deliveryDate?: string;
createdAt: string;
updatedAt: string;
}
type OrderStatus = 'pending' | 'approved' | 'in_progress' | 'completed' | 'cancelled';
```
### 4.2 OrderStats 타입
```typescript
interface OrderStats {
total: number;
pending: number;
approved: number;
inProgress: number;
completed: number;
cancelled: number;
totalAmount: number;
}
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

141
plans/sub/pricing-plan.md Normal file
View File

@@ -0,0 +1,141 @@
# 단가관리 (Pricing) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
> **API 상태**: ✅ 기존 API 존재
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/base-info/pricing/
│ └── page.tsx
└── components/business/construction/pricing-management/
├── PricingListClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 Mock 함수:**
```typescript
// getPricingList에서 Mock 단가 데이터 생성
// 단가: 품목별 단가, 버전 관리, 적용일 등
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getPricingList` | 단가 목록 조회 | ✅ Mock |
| `getPricingStats` | 단가 통계 조회 | ✅ Mock |
| `deletePricing` | 단가 삭제 | ✅ Mock |
| `deletePricings` | 단가 일괄 삭제 | ✅ Mock |
---
## 2. 기존 API 분석
### 2.1 기존 엔드포인트 (api/routes/api.php line 946-955)
```php
Route::prefix('construction/pricing')->group(function () {
Route::get('/', [PricingController::class, 'index']);
Route::get('/cost', [PricingController::class, 'cost']);
Route::get('/by-items', [PricingController::class, 'byItems']);
Route::post('/', [PricingController::class, 'store']);
Route::get('/{pricing}', [PricingController::class, 'show']);
Route::put('/{pricing}', [PricingController::class, 'update']);
Route::delete('/{pricing}', [PricingController::class, 'destroy']);
Route::post('/{pricing}/finalize', [PricingController::class, 'finalize']);
Route::get('/{pricing}/revisions', [PricingController::class, 'revisions']);
});
```
### 2.2 API-컴포넌트 매핑
| 컴포넌트 함수 | API 엔드포인트 | 매핑 상태 |
|--------------|---------------|:--------:|
| `getPricingList` | `GET /construction/pricing` | ✅ 매핑 가능 |
| `getPricingStats` | 없음 | ⚠️ 추가 필요 |
| `deletePricing` | `DELETE /construction/pricing/{id}` | ✅ 매핑 가능 |
| `deletePricings` | 없음 | ⚠️ bulk 추가 필요 |
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | stats 엔드포인트 추가 | ⏳ | |
| 2 | bulk delete 엔드포인트 추가 | ⏳ | |
| 3 | 프론트 타입과 정합성 확인 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Pricing 타입
```typescript
interface Pricing {
id: string;
itemId: string;
itemName: string;
itemCode: string;
categoryId: string;
categoryName: string;
unitPrice: number;
laborCost: number;
materialCost: number;
totalPrice: number;
effectiveDate: string;
expirationDate?: string;
version: number;
status: PricingStatus;
createdAt: string;
updatedAt: string;
}
type PricingStatus = 'draft' | 'active' | 'expired' | 'finalized';
```
### 4.2 PricingStats 타입
```typescript
interface PricingStats {
total: number;
active: number;
expired: number;
draft: number;
averagePrice: number;
}
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

View File

@@ -0,0 +1,148 @@
# 현장관리 (Site Management) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/site-management/
│ └── page.tsx
└── components/business/construction/site-management/
├── SiteManagementListClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 MOCK_SITES:**
```typescript
const MOCK_SITES: Site[] = [
{
id: '1',
siteCode: '123123',
partnerId: '1',
partnerName: '회사명',
siteName: '현장명',
address: '-',
status: 'unregistered',
createdAt: '2025-09-01T00:00:00Z',
updatedAt: '2025-09-01T00:00:00Z',
},
// ... 총 7개 현장
];
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getSiteList` | 현장 목록 조회 | ✅ Mock |
| `getSiteStats` | 현장 통계 조회 | ✅ Mock |
| `deleteSite` | 현장 삭제 | ✅ Mock |
| `deleteSites` | 현장 일괄 삭제 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트
| Method | Endpoint | 용도 |
|--------|----------|------|
| GET | `/api/construction/sites` | 목록 조회 |
| GET | `/api/construction/sites/stats` | 통계 조회 |
| GET | `/api/construction/sites/{id}` | 상세 조회 |
| POST | `/api/construction/sites` | 등록 |
| PUT | `/api/construction/sites/{id}` | 수정 |
| DELETE | `/api/construction/sites/{id}` | 삭제 |
| DELETE | `/api/construction/sites/bulk` | 일괄 삭제 |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetSiteListParams {
page?: number;
size?: number;
startDate?: string;
endDate?: string;
partnerId?: string;
status?: SiteStatus;
search?: string;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | SiteController 확인/수정 | ⏳ | 이미 import 존재 |
| 2 | SiteService 생성 | ⏳ | |
| 3 | SiteFormRequest 생성 | ⏳ | |
| 4 | Site 모델 확인/수정 | ⏳ | |
| 5 | routes/api.php 등록 | ⏳ | |
| 6 | Swagger 문서 작성 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 Site 타입
```typescript
interface Site {
id: string;
siteCode: string;
partnerId: string;
partnerName: string;
siteName: string;
address: string;
status: SiteStatus;
createdAt: string;
updatedAt: string;
}
type SiteStatus = 'active' | 'suspended' | 'unregistered' | 'pending';
```
### 4.2 SiteStats 타입
```typescript
interface SiteStats {
total: number;
construction: number;
unregistered: number;
}
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

View File

@@ -0,0 +1,138 @@
# 구조검토관리 (Structure Review) API 연동 계획
> **작성일**: 2026-01-08
> **상위 문서**: [construction-api-integration-plan.md](../construction-api-integration-plan.md)
> **상태**: ⏳ 대기
---
## 1. 컴포넌트 분석
### 1.1 파일 위치
```
react/src/
├── app/[locale]/(protected)/construction/order/structure-review/
│ └── page.tsx
└── components/business/construction/structure-review/
├── StructureReviewListClient.tsx
├── actions.ts
└── types.ts
```
### 1.2 현재 Mock 데이터
**actions.ts 내 Mock 함수:**
```typescript
// getStructureReviewList에서 Mock 데이터 생성
// 검토 상태: pending, in_review, approved, rejected
// 검토 유형: structural, electrical, mechanical, fire_safety
```
### 1.3 현재 함수 목록
| 함수명 | 용도 | Mock 상태 |
|--------|------|:--------:|
| `getStructureReviewList` | 구조검토 목록 조회 | ✅ Mock |
| `getStructureReviewStats` | 구조검토 통계 조회 | ✅ Mock |
| `deleteStructureReview` | 구조검토 삭제 | ✅ Mock |
| `deleteStructureReviews` | 구조검토 일괄 삭제 | ✅ Mock |
| `updateStructureReviewStatus` | 상태 변경 | ✅ Mock |
---
## 2. API 설계
### 2.1 엔드포인트
| Method | Endpoint | 용도 |
|--------|----------|------|
| GET | `/api/construction/structure-reviews` | 목록 조회 |
| GET | `/api/construction/structure-reviews/stats` | 통계 조회 |
| GET | `/api/construction/structure-reviews/{id}` | 상세 조회 |
| POST | `/api/construction/structure-reviews` | 등록 |
| PUT | `/api/construction/structure-reviews/{id}` | 수정 |
| PATCH | `/api/construction/structure-reviews/{id}/status` | 상태 변경 |
| DELETE | `/api/construction/structure-reviews/{id}` | 삭제 |
| DELETE | `/api/construction/structure-reviews/bulk` | 일괄 삭제 |
### 2.2 요청/응답 스키마
**목록 조회 Request:**
```typescript
interface GetStructureReviewListParams {
page?: number;
size?: number;
startDate?: string;
endDate?: string;
siteId?: string;
partnerId?: string;
reviewType?: ReviewType;
status?: ReviewStatus;
search?: string;
}
```
---
## 3. 작업 항목
### 3.1 Backend (API)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | StructureReviewController 생성 | ⏳ | |
| 2 | StructureReviewService 생성 | ⏳ | |
| 3 | StructureReviewFormRequest 생성 | ⏳ | |
| 4 | StructureReview 모델 생성 | ⏳ | |
| 5 | routes/api.php 등록 | ⏳ | |
| 6 | Swagger 문서 작성 | ⏳ | |
### 3.2 Frontend (React)
| # | 작업 | 상태 | 비고 |
|---|------|:----:|------|
| 1 | actions.ts Mock → API 변환 | ⏳ | |
| 2 | API 클라이언트 연동 | ⏳ | |
| 3 | 에러 핸들링 추가 | ⏳ | |
| 4 | types.ts 정합성 확인 | ⏳ | |
---
## 4. 타입 정의
### 4.1 StructureReview 타입
```typescript
interface StructureReview {
id: string;
reviewNumber: string;
siteId: string;
siteName: string;
partnerId: string;
partnerName: string;
reviewType: ReviewType;
title: string;
description?: string;
reviewerName?: string;
reviewDate?: string;
status: ReviewStatus;
comments?: string;
createdAt: string;
updatedAt: string;
}
type ReviewType = 'structural' | 'electrical' | 'mechanical' | 'fire_safety';
type ReviewStatus = 'pending' | 'in_review' | 'approved' | 'rejected';
```
---
## 5. 변경 이력
| 날짜 | 작업 | 상태 |
|------|------|------|
| 2026-01-08 | 문서 초안 작성 | ✅ |
---
*상위 문서: [construction-api-integration-plan.md](../construction-api-integration-plan.md)*

View File

@@ -2,7 +2,7 @@
> **작성일**: 2025-01-08 > **작성일**: 2025-01-08
> **목적**: 작업지시 기능 검증 및 테스트 > **목적**: 작업지시 기능 검증 및 테스트
> **상태**: ✅ API 연동 완료 (검증만 필요) > **상태**: ✅ 전체 테스트 완료 (2025-01-11)
--- ---
@@ -10,10 +10,10 @@
| 항목 | 내용 | | 항목 | 내용 |
|------|------| |------|------|
| **마지막 완료 작업** | API 연동 완료 확인 (2025-12-26) | | **마지막 완료 작업** | 전체 기능 테스트 완료 (2025-01-11) |
| **다음 작업** | 기능 검증 및 테스트 | | **다음 작업** | 운영 준비 |
| **진행률** | 4/5 (80%) | | **진행률** | 5/5 (100%) |
| **마지막 업데이트** | 2025-01-08 | | **마지막 업데이트** | 2025-01-11 |
--- ---
@@ -190,33 +190,48 @@ const BENDING_STEPS = ['가이드레일 제작', '케이스 제작', '하단마
## 4. 작업 범위 ## 4. 작업 범위
### Phase 1: 검증 및 테스트 (현재) ### Phase 1: 검증 및 테스트 ✅ 완료 (2025-01-11)
| # | 작업 항목 | 상태 | 비고 | | # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------| |---|----------|:----:|------|
| 1.1 | 목록 조회 테스트 | | 필터링/검색/페이징 | | 1.1 | 목록 조회 테스트 | | 필터링/검색/페이징 정상 |
| 1.2 | 등록 기능 테스트 | | 수주 선택 모달 | | 1.2 | 등록 기능 테스트 | | 수주 선택 모달 동작 확인 |
| 1.3 | 상세 조회 테스트 | | 상세 정보 표시 | | 1.3 | 상세 조회 테스트 | | 버그 수정 완료 (site_name 컬럼 수정) |
| 1.4 | 상태 변경 테스트 | | 상태 흐름 검증 | | 1.4 | 상태 변경 테스트 | | 전체 상태 전이 검증 완료 |
| 1.5 | 담당자 배정 테스트 | | 배정 모달 동작 | | 1.5 | 담당자 배정 테스트 | | 배정 시 상태 자동 전이 확인 |
### Phase 2: 공정별 기능 테스트 **Phase 1 테스트 상세:**
- **버그 수정**: WorkOrderService.php:119 - `project_name``site_name` (Order 모델에 맞춤)
- **상태 전이**: pending ⇄ waiting ⇄ in_progress ⇄ completed ⇄ shipped 모두 정상
- **담당자 배정**: 배정 시 unassigned → pending 자동 전이 확인
### Phase 2: 공정별 기능 테스트 ✅ 완료 (2025-01-11)
| # | 작업 항목 | 상태 | 비고 | | # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------| |---|----------|:----:|------|
| 2.1 | 스크린 공정 작업 단계 | | 5단계 | | 2.1 | 스크린 공정 작업지시 | | process_id=2 생성 확인 |
| 2.2 | 슬랫 공정 작업 단계 | | 5단계 | | 2.2 | 슬랫 공정 작업지시 | | process_id=1 생성 확인 |
| 2.3 | 절곡 공정 작업 단계 | | 4단계 | | 2.3 | 공정별 필터링 | | forProcess(), forProcessName() 정상 |
| 2.4 | 절곡 상세 토글 | | 개별 항목 토글 | | 2.4 | 작업지시 품목 관리 | | WorkOrderItem CRUD 확인 |
### Phase 3: 이슈 및 연동 **Phase 2 테스트 상세:**
- **공정 목록**: 슬랫(P-001), 스크린(P-002) 활성화 확인
- **공정별 필터**: `forProcess(1)`, `forProcessName('슬랫')` 정상 동작
- **품목 관리**: 작업지시별 품목 추가/조회 정상
### Phase 3: 이슈 및 연동 ✅ 완료 (2025-01-11)
| # | 작업 항목 | 상태 | 비고 | | # | 작업 항목 | 상태 | 비고 |
|---|----------|:----:|------| |---|----------|:----:|------|
| 3.1 | 이슈 등록 기능 | | | | 3.1 | 이슈 등록 기능 | | 이슈 생성 정상 |
| 3.2 | 이슈 해결 기능 | | | | 3.2 | 이슈 해결 기능 | | 해결 상태/시간 저장 확인 |
| 3.3 | 수주 연동 확인 | | Order API 필요 | | 3.3 | 수주 연동 확인 | | salesOrder 관계 정상 |
| 3.4 | 작업실적 연동 | ⏭️ | 후순위 | | 3.4 | 작업실적 연동 | ⏭️ | 후순위 (별도 기능) |
**Phase 3 테스트 상세:**
- **이슈 관리**: 등록(open) → 해결(resolved) 전체 흐름 정상
- **open_issues_count**: 미해결 이슈 카운트 속성 정상
- **수주 연동**: WorkOrder.salesOrder 관계를 통한 수주 정보 조회 정상
--- ---