- Remove 75 orphaned files: bypass API (models, DTOs, repositories, base classes, SQL schema), screening (models, DTOs, repositories), and CodeGenerationResult DTO - Replace favicon with navy version - Rename app title from "S&P Data Platform" to "S&P Collector" - Fix vite base path to match Spring Boot context-path (/snp-collector) - Rewrite CLAUDE.md with accurate architecture documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
100 lines
3.8 KiB
Markdown
100 lines
3.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## 프로젝트 개요
|
|
|
|
S&P Maritime API에서 선박/항만/사건 데이터를 수집하여 PostgreSQL에 저장하는 배치 시스템. React 기반 관리 UI 포함.
|
|
|
|
## 빌드 & 실행
|
|
|
|
```bash
|
|
# Java 버전 설정
|
|
sdk use java 17.0.18-amzn
|
|
|
|
# 프론트엔드 빌드 (src/main/resources/static/으로 출력)
|
|
cd frontend && npm install && npm run build && cd ..
|
|
|
|
# 백엔드 빌드 (프론트 빌드 후 실행)
|
|
mvn clean package -DskipTests -Dskip.npm -Dskip.installnodenpm
|
|
|
|
# 로컬 실행
|
|
mvn spring-boot:run
|
|
|
|
# 테스트
|
|
mvn test
|
|
|
|
# 프론트엔드 개발 서버 (localhost:5173, API는 8041로 프록시)
|
|
cd frontend && npm run dev
|
|
```
|
|
|
|
## 서버 설정
|
|
|
|
- 포트: 8041, Context Path: `/snp-collector`
|
|
- Swagger UI: `http://localhost:8041/snp-collector/swagger-ui/index.html`
|
|
- 프론트엔드 vite base: `/snp-collector/` (context-path와 일치해야 함)
|
|
- 프론트엔드 빌드 출력: `frontend/` → `src/main/resources/static/` (emptyOutDir: true)
|
|
|
|
## 배치 Job 아키텍처
|
|
|
|
### 베이스 클래스 계층 (`common/batch/`)
|
|
|
|
```
|
|
BaseJobConfig<I, O> # 단일 Step chunk-oriented Job
|
|
└── BaseMultiStepJobConfig<I, O> # 다중 Step Job (createJobFlow() 오버라이드)
|
|
└── BasePartitionedJobConfig<I, O> # 파티셔닝 병렬 처리 Job
|
|
```
|
|
|
|
- **BaseApiReader<T>**: WebClient 기반 Maritime API 호출. GET/POST 지원. BatchApiLog 자동 기록.
|
|
- **BaseProcessor<I, O>**: DTO→Entity 변환. `processItem()` 구현.
|
|
- **BaseWriter<T>**: `writeItems()` 구현. BaseJdbcRepository의 saveAll() 사용 (기존 ID 조회 → insert/update 분리 → PreparedStatement 배치).
|
|
- **BaseEntity**: 공통 감사 필드 (createdAt, updatedAt, jobExecutionId).
|
|
|
|
### 새 Job 추가 패턴
|
|
|
|
각 Job은 `jobs/batch/{도메인}/` 하위에 config, dto, entity, reader, processor, writer, repository 구성:
|
|
1. `*JobConfig` extends BaseJobConfig (또는 BaseMultiStepJobConfig/BasePartitionedJobConfig)
|
|
2. `*Reader` extends BaseApiReader — `fetchDataFromApi()` 또는 `fetchNextBatch()` 구현
|
|
3. `*Processor` extends BaseProcessor — `processItem()` 구현
|
|
4. `*Writer` extends BaseWriter — `writeItems()` 구현
|
|
5. `*Repository` extends BaseJdbcRepository — SQL insert/update 구현
|
|
|
|
### Job 실행 흐름
|
|
|
|
1. **스케줄**: Quartz JDBC Store → `QuartzBatchJob` → `QuartzJobService` → Spring Batch Job 실행
|
|
2. **수동 실행**: `BatchController.POST /api/batch/jobs/{jobName}/execute`
|
|
3. **재수집**: 실패 레코드 자동 재시도 (`AutoRetryJobExecutionListener`, 최대 3회)
|
|
4. **스케줄 초기화**: `SchedulerInitializer`가 앱 시작 시 DB의 `JobScheduleEntity`를 Quartz에 등록
|
|
|
|
## 주요 API 경로 (/api/batch)
|
|
|
|
| 메서드 | 경로 | 설명 |
|
|
|--------|------|------|
|
|
| POST | /jobs/{jobName}/execute | 배치 작업 실행 |
|
|
| GET | /jobs | 작업 목록 |
|
|
| GET | /jobs/{jobName}/executions | 실행 이력 |
|
|
| GET | /executions/{id}/detail | 실행 상세 (Step 포함) |
|
|
| POST | /executions/{id}/stop | 실행 중지 |
|
|
| GET/POST | /schedules | 스케줄 관리 (CRUD) |
|
|
| GET | /dashboard | 대시보드 |
|
|
| GET | /timeline | 타임라인 |
|
|
|
|
## 프론트엔드
|
|
|
|
- React 19 + TypeScript + Vite + Tailwind CSS
|
|
- 라우팅: React Router (basename `/snp-collector`)
|
|
- 페이지: Dashboard, Jobs, Executions, ExecutionDetail, Recollects, RecollectDetail, Schedules, Timeline
|
|
- API 클라이언트: `frontend/src/api/batchApi.ts`
|
|
- 전역 상태: ToastContext, ThemeContext
|
|
|
|
## Lint/Format
|
|
|
|
- 백엔드: 별도 lint 도구 미설정 (checkstyle, spotless 없음). IDE 기본 포매터 사용.
|
|
- 프론트엔드: `cd frontend && npm run lint` (ESLint)
|
|
|
|
## 배포
|
|
|
|
- Gitea Actions (`.gitea/workflows/deploy.yml`)
|
|
- Maven Docker 이미지 (maven:3.9-eclipse-temurin-17)
|
|
- 빌드 산출물: `/deploy/snp-batch/app.jar`
|