fix: [build] TS 에러 6건 수정 (수주 status 타입, 출하 cancelled 누락)

- page.tsx: draft→order_registered, in_progress→production_ordered (OrderStatus 타입 일치)
- actions.ts: ApiOrderStats에 in_production, produced optional 필드 추가
- ShipmentDetail.tsx: STATUS_TRANSITIONS에 cancelled 추가
- ShipmentList.tsx: colorMap에 cancelled 추가
This commit is contained in:
유병철
2026-03-18 15:50:55 +09:00
parent 4b8ca09ea5
commit 341f2b3e3f
5 changed files with 88 additions and 3 deletions

View File

@@ -5,6 +5,87 @@
---
## 0. 왜 산업군별 모듈 분리가 필요한가 (협의 필요)
### 현재 상황: 하나의 ERP, 다른 업종의 고객사
SAM ERP는 **하나의 코드베이스**로 여러 회사(테넌트)에 서비스를 제공합니다.
그런데 고객사마다 업종이 다릅니다:
```
경동 → 셔터 제조업 (MES) → 생산관리, 품질관리, 차량관리가 필요
주일 → 건설업 → 시공관리, 차량관리가 필요
A사 → 유통/서비스업 → 공통 ERP(회계/인사/영업)만 필요
```
현재는 **모든 테넌트에게 모든 메뉴가 보입니다.**
경동 직원에게 시공관리 메뉴가 보이고, 주일 직원에게 생산관리 메뉴가 보입니다.
→ 사용하지 않는 메뉴가 노출되어 혼란을 주고, 대시보드에도 불필요한 섹션이 나타남.
### 제안: 업종(industry) 기반 모듈 ON/OFF
```
┌─────────────────────────────────────────────────┐
│ SAM ERP (공통) │
│ 회계 · 인사 · 영업 · 결재 · 게시판 · 설정 │
├──────────┬──────────┬───────────┬───────────────┤
│ 생산관리 │ 품질관리 │ 시공관리 │ 차량관리 │
│ (MES) │ │ (건설) │ (선택) │
├──────────┴──────────┼───────────┤ │
│ 셔터 MES 업종 │ 건설 업종 │ │
│ (경동) │ (주일) │ │
└─────────────────────┴───────────┴───────────────┘
```
- **공통 모듈**: 모든 테넌트가 사용 (회계, 인사, 영업 등)
- **업종 모듈**: 테넌트의 업종에 따라 자동으로 켜짐/꺼짐
- **선택 모듈**: 업종과 관계없이 개별 선택 가능 (차량관리 등)
### 협의가 필요한 부분
이 구조로 가려면 다음 사항의 합의가 필요합니다:
#### 1) 업종 분류 체계
현재 프론트엔드에 하드코딩된 매핑:
| 업종 코드 | 의미 | 활성 모듈 |
|-----------|------|-----------|
| `shutter_mes` | 셔터 제조 (MES) | 생산관리 + 품질관리 + 차량관리 |
| `construction` | 건설업 | 시공관리 + 차량관리 |
**Q. 이 분류가 맞는지? 추가할 업종이 있는지?**
예: 일반 제조업, 도소매업, 서비스업 등
#### 2) 모듈 경계
현재 정의된 모듈 단위:
| 모듈 | 포함 기능 | 비고 |
|------|----------|------|
| 공통 ERP | 대시보드, 회계, 인사, 영업, 결재, 게시판, 설정 등 | 항상 ON |
| 생산관리 | 생산지시, 작업지시, 작업일보 | 경동 전용 |
| 품질관리 | 설비점검, 수리요청, 검사 | 경동 전용 |
| 시공관리 | 프로젝트, 계약, 기성, 시공일보 | 주일 전용 |
| 차량관리 | 차량등록, 운행일지, 지게차 | 선택적 |
**Q. 모듈 단위 범위가 적절한지? 분리/통합이 필요한 모듈이 있는지?**
#### 3) 활성화 방식
| 방식 | 장점 | 단점 |
|------|------|------|
| **A. 업종 자동** (현재) | 간단, 실수 방지 | 유연성 낮음 |
| **B. 모듈 개별 선택** (향후) | 유연함 | 관리 복잡 |
| **C. 업종 기본값 + 개별 재정의** | 균형 | 구현 복잡도 중간 |
**Q. 어떤 방식을 채택할 것인지?**
현재 프론트엔드는 A 방식으로 구현, B/C로 확장 가능하도록 설계됨.
#### 4) 적용 시점과 범위
- 백엔드에서 `tenant.options.industry` 값만 세팅하면 즉시 동작
- 값을 안 넣으면 기존과 100% 동일 (부작용 제로)
- **Q. 언제부터, 어떤 테넌트부터 적용할 것인지?**
---
## 1. 개요
### 목표
@@ -197,7 +278,7 @@ function MyComponent() {
| Phase 0 | 크로스 모듈 의존성 해소 | `a99c3b39` | ✅ 완료 |
| Phase 1 | 모듈 레지스트리 + 라우트 가드 | `0a65609e` | ✅ 완료 |
| Phase 2 | CEO 대시보드 모듈 디커플링 | `46501214` | ✅ 완료 |
| Phase 3 | 물리적 분리 (경계 마커, 검증, 가드, 문서) | (미커밋) | ✅ 완료 |
| Phase 3 | 물리적 분리 (경계 마커, 검증, 가드, 문서) | `4b8ca09e` | ✅ 완료 |
---

View File

@@ -299,12 +299,12 @@ function OrderListContent() {
// 수주: 생산에 넘어가지 않은 건 (DRAFT + CONFIRMED)
const orderCount = orders.filter(
(o) => o.status === "draft" || o.status === "order_registered" || o.status === "order_confirmed"
(o) => o.status === "order_registered" || o.status === "order_confirmed"
).length;
// 생산: 생산지시대기 + 생산중 (IN_PROGRESS + IN_PRODUCTION)
const productionCount = orders.filter(
(o) => o.status === "in_progress" || o.status === "in_production"
(o) => o.status === "production_ordered" || o.status === "in_production"
).length;
// 출하: 출하대기 ~ 출고중 (PRODUCED + SHIPPING)

View File

@@ -212,6 +212,8 @@ interface ApiOrderStats {
draft: number;
confirmed: number;
in_progress: number;
in_production?: number;
produced?: number;
completed: number;
cancelled: number;
total_amount: number;

View File

@@ -85,6 +85,7 @@ const STATUS_TRANSITIONS: Record<ShipmentStatus, ShipmentStatus | null> = {
ready: 'shipping',
shipping: 'completed',
completed: null,
cancelled: null,
};
export function ShipmentDetail({ id }: ShipmentDetailProps) {

View File

@@ -129,6 +129,7 @@ export function ShipmentList() {
ready: 'yellow',
shipping: 'blue',
completed: 'green',
cancelled: 'red',
};
return {