Files
sam-react-prod/scripts/verify-module-separation.sh
유병철 4b8ca09ea5 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/)
2026-03-18 15:41:23 +09:00

98 lines
2.8 KiB
Bash
Executable File

#!/bin/bash
# ===================================================================
# Module Separation Verification Script
#
# 공통 ERP → 테넌트 모듈 간 금지된 정적 import를 검사합니다.
# Phase 0에서 해소한 의존성이 다시 발생하지 않도록 CI에서 실행 가능.
#
# 사용법: bash scripts/verify-module-separation.sh
# 종료코드: 0 = 통과, 1 = 위반 발견
# ===================================================================
set -euo pipefail
echo "================================================="
echo " Module Separation Verification"
echo "================================================="
echo ""
# 테넌트 전용 경로 패턴 (from 'xxx' 또는 from "xxx" 형태로 검색)
TENANT_PATHS=(
"@/components/production/"
"@/components/quality/"
"@/components/business/construction/"
"@/components/vehicle-management/"
)
# 공통 ERP 소스 디렉토리 (테넌트 페이지 제외)
COMMON_DIRS=(
"src/components/approval"
"src/components/accounting"
"src/components/auth"
"src/components/atoms"
"src/components/board"
"src/components/business/CEODashboard"
"src/components/business/DashboardSwitcher.tsx"
"src/components/clients"
"src/components/common"
"src/components/customer-center"
"src/components/document-system"
"src/components/hr"
"src/components/items"
"src/components/layout"
"src/components/material"
"src/components/molecules"
"src/components/organisms"
"src/components/orders"
"src/components/outbound"
"src/components/pricing"
"src/components/providers"
"src/components/reports"
"src/components/settings"
"src/components/stocks"
"src/components/templates"
"src/components/ui"
"src/lib"
"src/hooks"
"src/stores"
"src/contexts"
)
VIOLATIONS=0
for dir in "${COMMON_DIRS[@]}"; do
# 디렉토리/파일이 없으면 스킵
[ -e "$dir" ] || continue
for tenant_path in "${TENANT_PATHS[@]}"; do
# 정적 import 검색 (dynamic import는 허용)
found=$(grep -rn "from ['\"]${tenant_path}" "$dir" \
--include="*.ts" --include="*.tsx" 2>/dev/null \
| grep -v "dynamic(" \
| grep -v "// MODULE_SEPARATION_OK" \
|| true)
if [ -n "$found" ]; then
echo "VIOLATION: $dir$tenant_path"
echo "$found"
echo ""
VIOLATIONS=$((VIOLATIONS + 1))
fi
done
done
echo "================================================="
if [ $VIOLATIONS -eq 0 ]; then
echo " PASSED: No forbidden imports found."
exit 0
else
echo " FAILED: Found $VIOLATIONS forbidden import(s)."
echo ""
echo " 해결 방법:"
echo " - dynamic import (next/dynamic)로 교체"
echo " - @/lib/api/ 또는 @/interfaces/로 타입 이동"
echo " - @/components/document-system/으로 공유 모달 이동"
echo " - 불가피한 경우 // MODULE_SEPARATION_OK 주석 추가"
exit 1
fi