signal-batch/CLAUDE.md
htlee a98fdcbdc9 chore: 팀 워크플로우 v1.2.0 초기 구성 (java-maven)
- .claude/rules: team-policy, git-workflow, code-style, naming, testing
- .claude/skills: init-project, sync-team-workflow, create-mr, fix-issue
- .claude/scripts: on-pre-compact, on-post-compact, on-commit (v1.2.0)
- .claude/settings.json: 팀 표준 권한 allow/deny + script hooks
- .githooks: commit-msg, pre-commit (mvn compile), post-checkout
- .mvn/settings.xml: Nexus 미러 설정
- .editorconfig: 팀 표준 포맷
- CLAUDE.md: 팀 규칙 참조 섹션 추가
- .gitignore: !.claude/ negation 추가 (글로벌 gitignore override)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:52:38 +09:00

200 lines
7.2 KiB
Markdown

# Signal Batch - Vessel Signal Batch Aggregation System
## 빌드 및 실행
```bash
# 빌드 (Maven)
mvn clean package -DskipTests
# 프로파일별 실행
java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=prod
java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=prod-mpr
java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=dev
java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=local
java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=query
```
## 프로젝트 개요
- **설명**: 선박 항적(Track) 실시간 수집 및 배치 집계 시스템
- **Java**: 17
- **Spring Boot**: 3.2.5
- **DB**: PostgreSQL + PostGIS
- **빌드도구**: Maven (pom.xml)
## 프로파일 구성
| 프로파일 | 용도 | 배치 | DataSource | 포트 |
|---------|------|-----|-----------|------|
| **prod** | 운영환경 | 활성화 | 3개 분리 | 18090 |
| **prod-mpr** | 운영환경(MPR) | 활성화 | 3개 분리 | 18090 |
| **dev** | 개발환경 | 활성화 | 3개 분리 | 18090 |
| **local** | 로컬개발 | 비활성화 | 단일 | 8090 |
| **query** | 조회전용 | 비활성화 | 단일 | 8090 |
## 핵심 패키지 구조
```
gc.mda.signal_batch/
├── batch/ # 배치 처리 (Job, Processor, Reader, Writer)
│ ├── job/ # Job 설정 및 스케줄러
│ ├── reader/ # ItemReader (파티션, 메모리)
│ ├── processor/ # ItemProcessor (항적 변환, 비정상 검출)
│ ├── writer/ # ItemWriter (Bulk Insert, Upsert)
│ └── listener/ # 배치 리스너
├── domain/
│ ├── gis/ # GIS API (해구, 구역, 타일)
│ ├── vessel/ # 선박 항적/위치 조회, 필터링
│ ├── track/ # 비정상 항적 검출 API
│ ├── passage/ # 순차 영역 통과 조회
│ ├── ship/ # 선박 이미지 API
│ └── debug/ # 디버그 API
├── global/
│ ├── config/ # DataSource, WebSocket, Batch 설정
│ ├── util/ # 공통 유틸리티
│ ├── websocket/ # WebSocket STOMP 스트리밍
│ └── tool/ # 배치 진단 도구
├── migration/ # 데이터 마이그레이션
└── monitoring/ # 모니터링, 메트릭, 성능 최적화
```
## DataSource 구성 (3개)
1. **CollectDataSource**: 원본 신호 수집 (읽기 전용)
2. **QueryDataSource**: 집계 데이터 조회/쓰기
3. **BatchDataSource**: Spring Batch 메타데이터
설정 클래스:
- `DevDataSourceConfig.java` (dev)
- `ProdDataSourceConfig.java` (prod/prod-mpr)
- `LocalDataSourceConfig.java` (local)
- `QueryDataSourceConfig.java` (query)
## 주요 API 엔드포인트
### REST API V1 (WKT 응답)
| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | `/api/v1/haegu/boundaries` | 해구 경계 |
| GET | `/api/v1/haegu/vessel-stats` | 해구별 선박 통계 |
| GET | `/api/v1/tracks/haegu/{no}` | 해구별 항적 |
| GET | `/api/v1/tracks/area/{areaId}` | 영역별 항적 |
| POST | `/api/v1/tracks/vessels` | 선박별 항적 조회 (일괄) |
| GET | `/api/v1/vessels/recent-positions` | 최근 위치 업데이트 선박 |
### REST API V2 (JSON/CompactVesselTrack)
| 메서드 | 경로 | 설명 |
|--------|------|------|
| POST | `/api/v2/tracks/vessels` | 선박별 항적 (JSON 배열 응답) |
| GET | `/api/v2/tracks/haegu/{no}` | 해구별 항적 (JSON) |
### 비정상 항적 API
| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | `/api/v1/abnormal-tracks/recent` | 최근 비정상 항적 |
| GET | `/api/v1/abnormal-tracks/vessel/{sigSrcCd}/{targetId}` | 특정 선박 비정상 이력 |
| GET | `/api/v1/abnormal-tracks/statistics` | 비정상 통계 |
| POST | `/api/v1/abnormal-tracks/detect` | 사용자 정의 기준 검출 |
### 기타 API
| 메서드 | 경로 | 설명 |
|--------|------|------|
| POST | `/api/v1/passages/sequential` | 순차 구역 통과 조회 |
| GET | `/api/v1/shipimg/{imo}` | 선박 이미지 조회 |
| GET | `/api/v1/tiles/{z}/{x}/{y}` | 타일 집계 데이터 |
### WebSocket (STOMP)
- **엔드포인트**: `/ws-tracks` (네이티브), `/ws-tracks` + SockJS
- **쿼리 요청**: `/app/tracks/query`
- **쿼리 취소**: `/app/tracks/cancel/{queryId}`
- **응답 수신**: `/user/queue/tracks/response`
- **청크 데이터**: `/user/queue/tracks/chunk`
- **상태 업데이트**: `/user/queue/tracks/status`
## 배치 Job
| Job | Cron | 지연 | 역할 |
|-----|------|-----|------|
| **incremental** | 매 5분 (3,8,13...) | 3분 | 수집 DB → 위치 집계 |
| **track** | 매 5분 (4,9,14...) | 4분 | 위치 → 항적(LineStringM) 변환 |
| **hourly** | 매시 10분 | - | 5분 → 시간 집계, 비정상 검출 |
| **daily** | 매일 01:00 | - | 시간 → 일 집계, 비정상 검출 |
### 배치 처리 흐름
```
CollectDB (신호)
→ incremental Job (5분 버킷 집계)
→ track Job (LineStringM 항적 생성)
→ hourly Job (시간 병합 + 비정상 검출)
→ daily Job (일 병합 + 비정상 검출)
```
## 코드 스타일
- Lombok 사용 (@Data, @Builder, @Slf4j)
- JdbcTemplate 직접 사용 (JPA 미사용)
- PostGIS 공간 쿼리 활용
- 청크 기반 배치 처리 (기본 10,000건)
- UPSERT/Bulk Insert 최적화
## 주요 DTO
- `CompactVesselTrack`: WebSocket/REST V2 응답 (geometry[], timestamps[], speeds[], nationalCode, shipKindCode)
- `TrackResponse`: REST V1 응답 (WKT 기반)
- `VesselTracksRequest`: 항적 조회 요청
- `AbnormalTrackResponse`: 비정상 항적 응답
- `SequentialPassageRequest/Response`: 순차 통과 조회
## 최근 작업 이력
### 2026-01-20
- V2 REST API 추가 (WebSocket 응답 호환)
- `GisControllerV2.java`, `GisServiceV2.java`
- CompactVesselTrack 확장: nationalCode, shipKindCode, integrationTargetId 추가
- WebSocket 청크 스트리밍 구현 (`ChunkedTrackStreamingService`)
- 선박 최신 위치 캐시 갱신 스케줄러 추가
- DateTime 파싱 유연화 (`FlexibleLocalDateTimeDeserializer`)
- Swagger 9개 API 그룹 체계화
## 주의사항
- 빌드: `mvn` 사용 (Gradle 아님)
- 프로파일별 DataSource 설정이 다름
- WebSocket은 STOMP 프로토콜 사용
- LineStringM 형식: `LINESTRING M(lon lat unixTimestamp, ...)`
- 비정상 항적 검출: 시간/일 집계 시 자동 수행
## 성능 설정 (prod)
```yaml
batch:
chunk-size: 10000
partition-size: 12
fetch-size: 200000
bulk-insert:
batch-size: 10000
parallel-threads: 8
cache:
latest-position:
ttl-minutes: 60
max-size: 60000
abnormal-detection:
5min-speed-threshold: 500 knots
hourly-daily-speed-limit: 500 knots
```
## Swagger 문서
- **접근**: `http://localhost:{port}/swagger-ui.html`
- **API 그룹**: 항적조회, 비정상항적, 타일, 선박이미지, 성능최적화, 관리자, 모니터링, 마이그레이션, 디버그
## 팀 규칙
- 코드 스타일: `.claude/rules/code-style.md` 참조
- 네이밍 규칙: `.claude/rules/naming.md` 참조
- 테스트 규칙: `.claude/rules/testing.md` 참조
- Git 워크플로우: `.claude/rules/git-workflow.md` 참조
- 팀 정책: `.claude/rules/team-policy.md` 참조