feat: [module] Phase 3 — 물리적 분리 (경계 마커, 검증 스크립트, 라우트 가드, 문서)
- MODULE.md 경계 마커 4개 (production, quality, construction, vehicle-management) - verify-module-separation.sh: Common→Tenant 금지 임포트 검증 스크립트 - 영업 생산지시 3개 페이지에 useModules 가드 추가 - MODULE_SEPARATION_OK 주석 마커 (공유 래퍼 허용) - tsconfig @modules/* path alias 추가 - CLAUDE.md 모듈 분리 아키텍처 섹션 추가 - 모듈 분리 가이드 문서 (claudedocs/architecture/)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { useModules } from "@/hooks/useModules";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
@@ -345,6 +346,24 @@ export default function ProductionOrderCreatePage() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const orderId = params.id as string;
|
||||
const { isEnabled, tenantIndustry } = useModules();
|
||||
|
||||
// 생산 모듈 비활성 시 접근 차단 (tenantIndustry 미설정 시 전부 허용)
|
||||
if (tenantIndustry && !isEnabled('production')) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="flex flex-col items-center justify-center min-h-[40vh]">
|
||||
<p className="text-muted-foreground">생산관리 모듈이 활성화되어 있지 않습니다.</p>
|
||||
<button
|
||||
className="mt-4 text-sm text-blue-600 hover:underline"
|
||||
onClick={() => router.push('/sales/order-management-sales')}
|
||||
>
|
||||
← 수주 목록으로
|
||||
</button>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRouter, useParams } from "next/navigation";
|
||||
import { useModules } from "@/hooks/useModules";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -194,6 +195,24 @@ export default function ProductionOrderDetailPage() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const orderId = params.id as string;
|
||||
const { isEnabled, tenantIndustry } = useModules();
|
||||
|
||||
// 생산 모듈 비활성 시 접근 차단 (tenantIndustry 미설정 시 전부 허용)
|
||||
if (tenantIndustry && !isEnabled('production')) {
|
||||
return (
|
||||
<PageLayout>
|
||||
<div className="flex flex-col items-center justify-center min-h-[40vh]">
|
||||
<p className="text-muted-foreground">생산관리 모듈이 활성화되어 있지 않습니다.</p>
|
||||
<button
|
||||
className="mt-4 text-sm text-blue-600 hover:underline"
|
||||
onClick={() => router.push('/sales/order-management-sales')}
|
||||
>
|
||||
← 수주 목록으로
|
||||
</button>
|
||||
</div>
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
const [detail, setDetail] = useState<ProductionOrderDetail | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import { useState, useCallback } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useModules } from "@/hooks/useModules";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -174,6 +175,23 @@ const TABLE_COLUMNS: TableColumn[] = [
|
||||
|
||||
export default function ProductionOrdersListPage() {
|
||||
const router = useRouter();
|
||||
const { isEnabled, tenantIndustry } = useModules();
|
||||
|
||||
// 생산 모듈 비활성 시 접근 차단 (tenantIndustry 미설정 시 전부 허용)
|
||||
if (tenantIndustry && !isEnabled('production')) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-[40vh]">
|
||||
<p className="text-muted-foreground">생산관리 모듈이 활성화되어 있지 않습니다.</p>
|
||||
<button
|
||||
className="mt-4 text-sm text-blue-600 hover:underline"
|
||||
onClick={() => router.push('/sales/order-management-sales')}
|
||||
>
|
||||
← 수주 목록으로
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const [stats, setStats] = useState<ProductionOrderStats>({
|
||||
total: 0,
|
||||
waiting: 0,
|
||||
|
||||
32
src/components/business/construction/MODULE.md
Normal file
32
src/components/business/construction/MODULE.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Construction Module (건설관리)
|
||||
|
||||
**Module ID**: `construction`
|
||||
**Tenant**: Juil (주일건설)
|
||||
**Route Prefixes**: `/construction`
|
||||
**Component Count**: 161 files
|
||||
|
||||
## Dependencies on Common ERP
|
||||
- `@/lib/api/*` — Server actions, API client
|
||||
- `@/components/ui/*` — UI primitives (shadcn/ui)
|
||||
- `@/components/templates/*` — IntegratedListTemplateV2 등
|
||||
- `@/components/organisms/*` — PageLayout, PageHeader
|
||||
- `@/hooks/*` — usePermission, useModules 등
|
||||
- `@/stores/authStore` — Tenant 정보
|
||||
- `@/components/common/*` — 공통 컴포넌트
|
||||
|
||||
## Exports to Common ERP
|
||||
**NONE** — 건설 모듈은 독립적으로 작동.
|
||||
|
||||
## Related Dashboard Sections
|
||||
- `construction` (시공 현황)
|
||||
|
||||
## Subdirectories
|
||||
- `bidding/` — 입찰 관리
|
||||
- `contract/` — 계약 관리
|
||||
- `estimates/` — 견적 관리
|
||||
- `progress-billing/` — 기성 관리
|
||||
- `site-management/` — 현장 관리
|
||||
- `labor-management/` — 노무 관리
|
||||
- `item-management/` — 자재 관리
|
||||
- `partners/` — 협력업체 관리
|
||||
- 기타 20개 하위 도메인
|
||||
25
src/components/production/MODULE.md
Normal file
25
src/components/production/MODULE.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Production Module (생산관리)
|
||||
|
||||
**Module ID**: `production`
|
||||
**Tenant**: Kyungdong (경동 셔터 MES)
|
||||
**Route Prefixes**: `/production`
|
||||
**Component Count**: 56 files
|
||||
|
||||
## Dependencies on Common ERP
|
||||
- `@/lib/api/*` — Server actions, API client
|
||||
- `@/components/ui/*` — UI primitives (shadcn/ui)
|
||||
- `@/components/templates/*` — IntegratedListTemplateV2 등
|
||||
- `@/components/organisms/*` — PageLayout, PageHeader
|
||||
- `@/hooks/*` — usePermission, useModules 등
|
||||
- `@/stores/authStore` — Tenant 정보
|
||||
- `@/stores/menuStore` — 사이드바 상태
|
||||
|
||||
## Exports to Common ERP
|
||||
**NONE** — Phase 0에서 모든 교차 참조 해소 완료.
|
||||
- 타입: `@/lib/api/production-orders/types.ts` (re-export)
|
||||
- 서버 액션: `@/lib/api/production-orders/actions.ts` (async wrapper)
|
||||
- 모달: `@/components/document-system/modals/` (dynamic import wrapper)
|
||||
|
||||
## Related Dashboard Sections
|
||||
- `production` (생산 현황)
|
||||
- `shipment` (출고 현황)
|
||||
21
src/components/quality/MODULE.md
Normal file
21
src/components/quality/MODULE.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Quality Module (품질관리)
|
||||
|
||||
**Module ID**: `quality`
|
||||
**Tenant**: Kyungdong (경동 셔터 MES)
|
||||
**Route Prefixes**: `/quality`
|
||||
**Component Count**: 35 files
|
||||
|
||||
## Dependencies on Common ERP
|
||||
- `@/lib/api/*` — Server actions, API client
|
||||
- `@/components/ui/*` — UI primitives (shadcn/ui)
|
||||
- `@/components/templates/*` — IntegratedListTemplateV2 등
|
||||
- `@/components/organisms/*` — PageLayout, PageHeader
|
||||
- `@/hooks/*` — usePermission, useModules 등
|
||||
- `@/stores/authStore` — Tenant 정보
|
||||
|
||||
## Exports to Common ERP
|
||||
**NONE** — Phase 0에서 교차 참조 해소 완료.
|
||||
- 모달: `@/components/document-system/modals/` (WorkLogModal — dynamic import)
|
||||
|
||||
## Related Dashboard Sections
|
||||
없음 (품질 대시보드 섹션은 아직 미구현)
|
||||
20
src/components/vehicle-management/MODULE.md
Normal file
20
src/components/vehicle-management/MODULE.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Vehicle Management Module (차량관리)
|
||||
|
||||
**Module ID**: `vehicle-management`
|
||||
**Tenant**: Optional (경동 + 주일 공통 선택)
|
||||
**Route Prefixes**: `/vehicle-management`, `/vehicle`
|
||||
**Component Count**: 13 files
|
||||
|
||||
## Dependencies on Common ERP
|
||||
- `@/lib/api/*` — Server actions, API client
|
||||
- `@/components/ui/*` — UI primitives (shadcn/ui)
|
||||
- `@/components/templates/*` — IntegratedListTemplateV2 등
|
||||
- `@/components/organisms/*` — PageLayout, PageHeader
|
||||
- `@/hooks/*` — usePermission, useModules 등
|
||||
- `@/stores/authStore` — Tenant 정보
|
||||
|
||||
## Exports to Common ERP
|
||||
**NONE**
|
||||
|
||||
## Related Dashboard Sections
|
||||
없음
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
getProductionOrders as _getProductionOrders,
|
||||
getProductionOrderStats as _getProductionOrderStats,
|
||||
getProductionOrderDetail as _getProductionOrderDetail,
|
||||
} from '@/components/production/ProductionOrders/actions';
|
||||
} from '@/components/production/ProductionOrders/actions'; // MODULE_SEPARATION_OK — 공유 액션 래퍼 (Phase 0)
|
||||
import type { ProductionOrderListParams } from './types';
|
||||
|
||||
export async function getProductionOrders(params: ProductionOrderListParams) {
|
||||
|
||||
@@ -19,4 +19,4 @@ export type {
|
||||
ApiProductionWorkOrder,
|
||||
ApiBomProcessGroup,
|
||||
ApiBomItem,
|
||||
} from '@/components/production/ProductionOrders/types';
|
||||
} from '@/components/production/ProductionOrders/types'; // MODULE_SEPARATION_OK — 공유 인터페이스 (Phase 0)
|
||||
|
||||
Reference in New Issue
Block a user