refactor: 모노레포 구조로 전환 (frontend/ + backend/ + database/)

Phase 1: 모노레포 디렉토리 구조 구축

- 기존 React 프로젝트를 frontend/ 디렉토리로 이동 (git mv)
- backend/ 디렉토리 생성 (Phase 2에서 Spring Boot 초기화)
- database/migration/ 디렉토리 생성 (Phase 2에서 Flyway 마이그레이션)
- 루트 .gitignore에 frontend/, backend/ 경로 반영
- 루트 CLAUDE.md를 모노레포 가이드로 갱신
- Makefile 추가 (dev/build/lint 통합 명령)
- frontend/vite.config.ts에 /api → :8080 백엔드 proxy 설정
- .githooks/pre-commit을 모노레포 구조에 맞게 갱신
  (frontend/ 변경 시 frontend/ 내부에서 검증)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
htlee 2026-04-07 08:47:24 +09:00
부모 1eccbd7a72
커밋 e6319a571c
156개의 변경된 파일241개의 추가작업 그리고 104개의 파일을 삭제

파일 보기

@ -1,54 +1,73 @@
#!/bin/bash #!/bin/bash
#============================================================================== #==============================================================================
# pre-commit hook (React TypeScript) # pre-commit hook (Monorepo: frontend + backend)
# TypeScript 컴파일 + 린트 검증 — 실패 시 커밋 차단 # 변경된 영역만 선택적으로 검증
#============================================================================== #==============================================================================
echo "pre-commit: TypeScript 타입 체크 중..." # 스테이징된 파일 목록
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
# npm 확인 # frontend 변경 확인
if ! command -v npx &>/dev/null; then FRONTEND_CHANGED=$(echo "$STAGED" | grep -E '^frontend/' || true)
echo "경고: npx가 설치되지 않았습니다. 검증을 건너뜁니다."
exit 0 # backend 변경 확인
BACKEND_CHANGED=$(echo "$STAGED" | grep -E '^backend/' || true)
# === Frontend 검증 ===
if [ -n "$FRONTEND_CHANGED" ] && [ -d "frontend" ]; then
echo "pre-commit: frontend TypeScript 타입 체크 중..."
if ! command -v npx &>/dev/null; then
echo "경고: npx가 설치되지 않았습니다. 검증을 건너뜁니다."
elif [ ! -d "frontend/node_modules" ]; then
echo "경고: frontend/node_modules가 없습니다. 'cd frontend && npm install' 후 다시 시도하세요."
exit 1
else
(cd frontend && npx tsc --noEmit --pretty 2>&1)
TSC_RESULT=$?
if [ $TSC_RESULT -ne 0 ]; then
echo ""
echo "╔══════════════════════════════════════════════════════════╗"
echo "║ TypeScript 타입 에러! 커밋이 차단되었습니다. ║"
echo "╚══════════════════════════════════════════════════════════╝"
exit 1
fi
echo "pre-commit: 타입 체크 성공"
# ESLint
if [ -f "frontend/eslint.config.js" ] || [ -f "frontend/eslint.config.mjs" ]; then
echo "pre-commit: frontend ESLint 검증 중..."
(cd frontend && npx eslint src/ --quiet 2>&1)
LINT_RESULT=$?
if [ $LINT_RESULT -ne 0 ]; then
echo ""
echo "╔══════════════════════════════════════════════════════════╗"
echo "║ ESLint 에러! 커밋이 차단되었습니다. ║"
echo "║ 'cd frontend && npm run lint:fix'로 자동 수정 시도. ║"
echo "╚══════════════════════════════════════════════════════════╝"
exit 1
fi
echo "pre-commit: ESLint 통과"
fi
fi
fi fi
# node_modules 확인 # === Backend 검증 ===
if [ ! -d "node_modules" ]; then if [ -n "$BACKEND_CHANGED" ] && [ -d "backend" ] && [ -f "backend/pom.xml" ]; then
echo "경고: node_modules가 없습니다. 'npm install' 실행 후 다시 시도하세요." echo "pre-commit: backend 컴파일 체크 중..."
exit 1 (cd backend && ./mvnw compile -q 2>&1)
fi MVN_RESULT=$?
# TypeScript 타입 체크 if [ $MVN_RESULT -ne 0 ]; then
npx tsc --noEmit --pretty 2>&1
TSC_RESULT=$?
if [ $TSC_RESULT -ne 0 ]; then
echo ""
echo "╔══════════════════════════════════════════════════════════╗"
echo "║ TypeScript 타입 에러! 커밋이 차단되었습니다. ║"
echo "║ 타입 에러를 수정한 후 다시 커밋해주세요. ║"
echo "╚══════════════════════════════════════════════════════════╝"
echo ""
exit 1
fi
echo "pre-commit: 타입 체크 성공"
# ESLint 검증 (설정 파일이 있는 경우만)
if [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ] || [ -f ".eslintrc.cjs" ] || [ -f "eslint.config.js" ] || [ -f "eslint.config.mjs" ]; then
echo "pre-commit: ESLint 검증 중..."
npx eslint src/ --ext .ts,.tsx --quiet 2>&1
LINT_RESULT=$?
if [ $LINT_RESULT -ne 0 ]; then
echo "" echo ""
echo "╔══════════════════════════════════════════════════════════╗" echo "╔══════════════════════════════════════════════════════════╗"
echo "║ ESLint 에러! 커밋이 차단되었습니다. ║" echo "║ Backend 컴파일 에러! 커밋이 차단되었습니다. ║"
echo "║ 'npm run lint -- --fix'로 자동 수정을 시도해보세요. ║"
echo "╚══════════════════════════════════════════════════════════╝" echo "╚══════════════════════════════════════════════════════════╝"
echo ""
exit 1 exit 1
fi fi
echo "pre-commit: backend 컴파일 성공"
echo "pre-commit: ESLint 통과"
fi fi
exit 0

24
.gitignore vendored
파일 보기

@ -1,8 +1,11 @@
# === Build === # === Build ===
dist/ frontend/dist/
build/ frontend/build/
backend/target/
backend/build/
# === Dependencies === # === Dependencies ===
frontend/node_modules/
node_modules/ node_modules/
# === IDE === # === IDE ===
@ -27,12 +30,15 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# === Test === # === Test ===
coverage/ frontend/coverage/
backend/coverage/
# === Cache === # === Cache ===
.eslintcache frontend/.eslintcache
.prettiercache frontend/.prettiercache
*.tsbuildinfo frontend/*.tsbuildinfo
frontend/.vite/
.vite/
# === Code Review Graph (로컬 전용) === # === Code Review Graph (로컬 전용) ===
.code-review-graph/ .code-review-graph/
@ -55,3 +61,9 @@ coverage/
.claude/skills/version/ .claude/skills/version/
.claude/skills/fix-issue/ .claude/skills/fix-issue/
.claude/scripts/ .claude/scripts/
# === Backend (Spring Boot) ===
backend/.mvn/wrapper/maven-wrapper.jar
backend/.gradle/
backend/HELP.md
backend/*.log

118
CLAUDE.md
파일 보기

@ -1,74 +1,76 @@
# KCG AI Monitoring # KCG AI Monitoring (모노레포)
해양경찰청 AI 기반 불법어선 탐지 및 단속 지원 플랫폼 해양경찰청 AI 기반 불법어선 탐지 및 단속 지원 플랫폼
## 기술 스택 ## 모노레포 구조
- **프레임워크**: React 19 + TypeScript 5.9 ```
- **빌드**: Vite 8 kcg-ai-monitoring/
- **스타일**: Tailwind CSS 4 + CVA (class-variance-authority) ├── frontend/ # React 19 + TypeScript + Vite (UI)
- **지도**: MapLibre GL 5 + deck.gl 9 ├── backend/ # Spring Boot 3.x + Java 21 (자체 인증/권한/감사 + 분석 프록시)
- **차트**: ECharts 6 ├── database/ # PostgreSQL 마이그레이션 (Flyway)
- **상태관리**: Zustand 5 │ └── migration/
- **다국어**: i18next (ko/en, 10개 네임스페이스) ├── docs/ # 프로젝트 문서 (SFR, 아키텍처)
- **라우팅**: React Router 7 ├── .claude/ # Claude Code 워크플로우
- **린트**: ESLint 10 (flat config) ├── .githooks/ # Git hooks (commit-msg, pre-commit, post-checkout)
└── Makefile # 통합 dev/build 명령
```
## 시스템 구성
```
[Frontend Vite :5173] ──→ [Backend Spring :8080] ──┬→ [Iran Backend :8080] (분석 데이터 read)
│ └→ [Prediction FastAPI :8001]
└→ [PostgreSQL kcgaidb] (자체 인증/권한/감사/의사결정)
```
- **자체 백엔드**: 인증/권한/감사로그/관리자 + 운영자 의사결정 (확정/제외/학습)
- **iran 백엔드 프록시**: 분석 결과 read-only 참조 (vessel_analysis, group_polygons, correlations)
- **신규 DB (kcgaidb)**: 자체 생산 데이터만 저장, prediction 분석 테이블은 미복사
## 명령어 ## 명령어
```bash ```bash
npm run dev # 개발 서버 (Vite) make install # 의존성 설치
npm run build # 프로덕션 빌드 make dev # 프론트 + 백엔드 동시 실행
npm run lint # ESLint 검사 make dev-frontend # 프론트만
npm run lint:fix # ESLint 자동 수정 make dev-backend # 백엔드만
npm run format # Prettier 포맷팅 make build # 전체 빌드
npm run format:check # 포맷팅 검사 make lint # 프론트 lint
make format # 프론트 prettier
``` ```
## 디렉토리 구조 ## 기술 스택
``` ### Frontend (`frontend/`)
src/ - React 19, TypeScript 5.9, Vite 8
├── app/ # 라우터, 인증, 레이아웃 - Tailwind CSS 4 + CVA
├── features/ # 13개 도메인 모듈 (31+ 페이지) - MapLibre GL 5 + deck.gl 9 (지도)
│ ├── admin/ # 관리자 - ECharts 6 (차트)
│ ├── ai-operations/ # AI 작전 - Zustand 5 (상태관리)
│ ├── auth/ # 인증 - i18next (ko/en)
│ ├── dashboard/ # 대시보드 - React Router 7
│ ├── detection/ # 탐지 - ESLint 10 + Prettier
│ ├── enforcement/ # 단속
│ ├── field-ops/ # 현장작전
│ ├── monitoring/ # 모니터링
│ ├── patrol/ # 순찰
│ ├── risk-assessment/# 위험평가
│ ├── statistics/ # 통계
│ ├── surveillance/ # 감시
│ └── vessel/ # 선박
├── lib/ # 공유 라이브러리
│ ├── charts/ # ECharts 래퍼 + 프리셋
│ ├── i18n/ # i18next 설정 + 로케일
│ ├── map/ # MapLibre + deck.gl 통합
│ └── theme/ # 디자인 토큰 + CVA 변형
├── data/mock/ # 7개 목 데이터 모듈
├── stores/ # Zustand 스토어 (8개)
├── services/ # API 서비스 샘플
├── shared/ # 공유 UI 컴포넌트
└── styles/ # CSS (Dark/Light 테마)
```
## Path Alias ### Backend (`backend/`) — Phase 2에서 초기화
- Spring Boot 3.x + Java 21
- Spring Security + JWT
- PostgreSQL + Flyway
- Caffeine (권한 캐싱)
- 트리 기반 RBAC (wing 패턴)
| Alias | 경로 | ### Database (`kcgaidb`)
|-------|------| - PostgreSQL
| `@/` | `src/` | - 사용자: `kcg-app`
| `@lib/` | `src/lib/` | - 스키마: `kcg`
| `@shared/` | `src/shared/` |
| `@features/` | `src/features/` | ## 권한 체계
| `@data/` | `src/data/` |
| `@stores/` | `src/stores/` | 좌측 탭(메뉴) = 권한 그룹, 내부 패널/액션 = 자식 자원, CRUD 단위 개별 제어.
상세는 `.claude/plans/vast-tinkering-knuth.md` 참조.
## 팀 컨벤션 ## 팀 컨벤션
- 팀 규칙`.claude/rules/` 참조 - 팀 규칙: `.claude/rules/`
- 커밋: Conventional Commits (한국어), `.githooks/commit-msg` 검증 - 커밋: Conventional Commits (한국어), `.githooks/commit-msg` 검증
- Git Hooks: `.githooks/` (core.hooksPath 설정됨) - pre-commit: `frontend/` 디렉토리 기준 TypeScript + ESLint 검증

47
Makefile Normal file
파일 보기

@ -0,0 +1,47 @@
.PHONY: help install dev dev-frontend dev-backend build build-frontend build-backend lint format test clean
help:
@echo "사용 가능한 명령:"
@echo " make install - 프론트엔드 의존성 설치"
@echo " make dev - 프론트엔드 + 백엔드 동시 실행"
@echo " make dev-frontend - 프론트엔드 dev 서버만 실행 (Vite)"
@echo " make dev-backend - 백엔드 dev 서버만 실행 (Spring Boot)"
@echo " make build - 프론트엔드 + 백엔드 빌드"
@echo " make build-frontend - 프론트엔드 빌드"
@echo " make build-backend - 백엔드 빌드"
@echo " make lint - 프론트엔드 lint 검사"
@echo " make format - 프론트엔드 prettier 포맷팅"
@echo " make clean - 빌드 산출물 삭제"
install:
cd frontend && npm install
@if [ -f backend/pom.xml ]; then cd backend && ./mvnw dependency:resolve || true; fi
dev-frontend:
cd frontend && npm run dev
dev-backend:
@if [ -f backend/pom.xml ]; then cd backend && ./mvnw spring-boot:run -Dspring-boot.run.profiles=local; \
else echo "백엔드가 아직 초기화되지 않았습니다 (Phase 2에서 추가)"; fi
dev:
@$(MAKE) -j2 dev-frontend dev-backend
build-frontend:
cd frontend && npm run build
build-backend:
@if [ -f backend/pom.xml ]; then cd backend && ./mvnw clean package -DskipTests; \
else echo "백엔드가 아직 초기화되지 않았습니다 (Phase 2에서 추가)"; fi
build: build-frontend build-backend
lint:
cd frontend && npm run lint
format:
cd frontend && npm run format
clean:
rm -rf frontend/dist frontend/node_modules/.vite
@if [ -f backend/pom.xml ]; then cd backend && ./mvnw clean; fi

18
backend/README.md Normal file
파일 보기

@ -0,0 +1,18 @@
# Backend (Spring Boot)
Phase 2에서 초기화 예정.
## 계획된 구성
- Spring Boot 3.x + Java 21
- PostgreSQL + Flyway
- Spring Security + JWT
- Caffeine 캐시
- 트리 기반 RBAC 권한 체계 (wing 패턴)
## 책임
- 자체 인증/권한/감사로그
- 운영자 의사결정 (모선 확정/제외/학습)
- iran 백엔드 분석 데이터 프록시
- 관리자 화면 API
상세 설계: `.claude/plans/vast-tinkering-knuth.md`

파일 보기

@ -0,0 +1,30 @@
# Database Migrations
PostgreSQL 마이그레이션 (Flyway 형식).
## DB 정보
- DB Name: `kcgaidb`
- User: `kcg-app`
- Schema: `kcg`
## 마이그레이션 파일 (Phase 2에서 작성)
| 파일 | 내용 |
|---|---|
| `V001__auth_init.sql` | 사용자, 조직, 역할, 로그인 이력 |
| `V002__perm_tree.sql` | 권한 트리 + 권한 매트릭스 |
| `V003__perm_seed.sql` | 초기 역할 + 트리 노드 시드 |
| `V004__access_logs.sql` | 감사로그, 접근 이력 |
| `V005__parent_workflow.sql` | 모선 워크플로우 (운영자 결정/제외/학습 세션) |
## 실행 방법
```bash
# DB 생성 (1회)
psql -U postgres -c "CREATE DATABASE kcgaidb;"
psql -U postgres -c "CREATE USER \"kcg-app\" WITH PASSWORD 'Kcg2026ai';"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE kcgaidb TO \"kcg-app\";"
# 마이그레이션은 backend Spring Boot가 기동 시 자동 실행 (Flyway)
cd backend && ./mvnw spring-boot:run
```

Some files were not shown because too many files have changed in this diff Show More