kcg-ai-monitoring/backend/README.md
htlee b37e18d952 docs: prediction-analysis 신규 + 루트/SFR 문서 drift 해소
- docs/prediction-analysis.md 신설 — opus 4.7 독립 리뷰 기반 prediction 구조/방향 심층 분석
  (9개 섹션: 아키텍처·5분 사이클·17 알고리즘·4대 도메인 커버리지·6축 구조 평가·개선 제안 P1~P4·임계값 전수표)
- AGENTS.md / README.md — V001~V016→V030, Python 3.9→3.11+, 14→17 알고리즘 모듈
- docs/architecture.md — /gear-collision 라우트 추가 (26→27 보호 경로)
- docs/sfr-traceability.md — V029→V030, 48→51 테이블, SFR-10 에 GEAR_IDENTITY_COLLISION 추가
- docs/sfr-user-guide.md — 어구 정체성 충돌 페이지 섹션 신설
- docs/system-flow-guide.md — 노드 수 102→115, V030 manifest 미반영 경고
- backend/README.md — "Phase 2 예정" 상태 → 실제 운영 구성 + PR #79 hotfix 요구사항 전면 재작성
2026-04-17 11:20:53 +09:00

89 lines
4.4 KiB
Markdown
Raw Blame 히스토리

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Backend (Spring Boot)
운영 배포 중 — rocky-211 `:18080` (`kcg-ai-backend` systemd).
## 구성
- **Runtime**: Spring Boot 3.5.7 + Java 21
- **DB**: PostgreSQL (kcgaidb) + Flyway V001~V030 (51 테이블)
- **Auth**: Spring Security + JWT 쿠키 + BCrypt
- **Cache**: Caffeine (권한 트리 10분 TTL)
- **Permission**: 트리 기반 RBAC (47 리소스 × 5 operation)
- **HTTP client**: `RestClient` + 명시적 `@Bean` 주입 (`predictionRestClient`, `signalBatchRestClient`)
## 책임
- 자체 인증/권한/감사 로그 + 관리자 API
- 운영자 의사결정 (모선 확정·제외·학습, 어구 정체성 충돌 분류)
- prediction 분석 결과 조회 (`/api/analysis/*`) + 이벤트 허브 (`/api/events`, `/api/alerts`)
- prediction 실시간 상태 프록시 (`/api/prediction/*`)
## 빌드 · 배포
```bash
# 로컬 실행
./mvnw spring-boot:run
# 프로덕션 빌드
./mvnw clean package -DskipTests
# → target/kcg-ai-backend-*.jar
# 운영 배포 (수동)
scp target/kcg-ai-backend-*.jar rocky-211:/opt/kcg-ai-backend/
ssh rocky-211 "sudo systemctl restart kcg-ai-backend"
```
## 필수 컴파일 설정 (PR #79 hotfix)
Spring 6.1 의 parameter-level `@Qualifier` 주입이 동작하려면 두 가지가 **필수**:
1. **`pom.xml`** — `maven-compiler-plugin``default-compile``default-testCompile` 양쪽 execution 에
`<parameters>true</parameters>` 설정. 파라미터 이름을 바이트코드에 보존해야 `@Qualifier` resolve 가 가능.
2. **`src/main/java/lombok.config`** — `lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier`
설정. Lombok `@RequiredArgsConstructor` 가 필드의 `@Qualifier` 를 생성자 파라미터에 복사해야 Spring 이 인식.
둘 중 하나라도 누락되면 `PredictionProxyController` 같은 다중 `RestClient` bean 주입 컨트롤러가 기동 시점에
`NoUniqueBeanDefinitionException` 으로 크래시 루프에 빠진다. 로컬에서 `./mvnw spring-boot:run` 실패는
운영 restart 시 동일하게 재현되므로 **MR 범위 밖이어도 우선 해결**.
## 주요 패키지 구조
```
src/main/java/gc/mda/kcg/
├── config/ # RestClientConfig, SecurityConfig, OpenApi, CorsConfig, CaffeineConfig 등
├── auth/ # LoginController, JWT, 비밀번호 정책
├── permission/ # 트리 RBAC, @RequirePermission AOP, 캐시
├── audit/ # @Auditable AOP, AuditLogService, AccessLogFilter
├── domain/
│ ├── analysis/ # VesselAnalysisController, GearCollisionController (V030), PredictionProxyController 등
│ ├── fleet/ # ParentInferenceWorkflowController, FleetService
│ ├── event/ # EventController, AlertController
│ ├── enforcement/ # EnforcementController, EnforcementPlanController
│ ├── master/ # MasterDataController (CodeMaster, GearTypeMaster, VesselPermit 등)
│ ├── admin/ # AdminLogController, AdminStatsController, UserManagementController
│ └── stats/ # StatsController (KPI 집계)
└── Application.java
```
모든 컨트롤러는 `controller → service → repository` 계층을 준수하며, 쓰기 액션은
`@RequirePermission` + `@Auditable` 로 권한·감사 일관 적용.
## Flyway 마이그레이션
- 경로: [src/main/resources/db/migration/V001__*.sql ~ V030__gear_identity_collision.sql](src/main/resources/db/migration/)
- 최신: **V030** (2026-04-17) — `gear_identity_collisions` 테이블 + `detection:gear-collision` 권한 트리
- Flyway 자동 적용: Spring Boot 기동 시점
## 디렉토리 밖 의존성
- **prediction → kcgaidb**: prediction 이 직접 write. backend 는 HTTP 호출 없이 DB 조회로만 연동
- **signal-batch**: `http://192.168.1.18:18090/signal-batch` (정적정보 보강, `signalBatchRestClient` 주입)
- **prediction (FastAPI)**: `http://redis-211:18092` (실시간 상태/채팅 프록시 전용)
## 운영 체크리스트
1. 빌드 성공 → local `./mvnw spring-boot:run` 기동 확인 → curl `/api/auth/me` 200 확인
2. scp 배포 → `systemctl restart kcg-ai-backend``journalctl -u kcg-ai-backend -n 100`
3. 응답 확인: `curl -k https://kcg-ai-monitoring.gc-si.dev/api/analysis/vessels?hours=1`
4. Flyway 에러 시: `backend.application` 로그에서 `Migration ... failed` 확인