# CLAUDE.md 이 파일은 Java-Service-Tree-Framework-Engine-Fire 모듈을 claude code와 연동해서 개발하기 위한 가이드 문서이다. ## 시작하기 전에 @/docs/a-rms.md 파일을 읽고 왜 arms가 존재하는 지, arms의 msa 아키텍처에서 이 모듈이 어떤 역할을 하는 지 파악한다. ## 프로젝트 개요 Java21을 사용하는 Engine-Fire 모듈은 암스 요구사항과 ALM 이슈를 OpenSearch를 통해 수집하고 집계하는 어플리케이션이다. ## Spring Module ### spring-boot-starter-web - 모든 REST API는 Spring MVC 기반(@RestController)으로 구현한다. - 요청/응답은 DTO/VO 규칙을 따른다. ### spring-boot-starter-aop - 로깅, 트랜잭션, 공통 처리 로직은 AOP로 분리한다. ### spring-webflux - 비동기·논블로킹(Asynchronous & Non-blocking) 방식의 웹 애플리케이션을 만든다. - Jira 외부 API 호출의 I/O 효율 + rate limit 대응 재시도를 위해 WebFlux를 사용한다. ### spring-cloud-starter-openfeign - A-RMS의 모듈 간 통신은 Feign Client를 사용한다. - RestTemplate, WebClient 직접 호출은 사용하지 않는다. ### springdoc-openapi-starter-webmvc-ui - 모든 API는 Swagger(springdoc)를 통해 문서화한다. ## Dependency ### org.projectlombok:lombok - DTO와 VO의 보일러플레이트 코드를 줄이고, 깔끔한 생성자 주입을 돕는다. ## 디렉토리 구조 ``` src/ ├── main/ │ └── java/ │ ├── api/ # API들을 정의 │ ├── config/ # Configuration Bean들을 정의 │ └── egovframework.javaservice.esframework # es 프레임워크를 정의 ``` ---- ## API 개발 패턴 가이드 ### 1. 코드를 짜기 전에 - @/docs/almIssueEntity.md를 읽고 기본적인 이슈 엔티티 정보를 분석한다. - @/rules/auto-code.md를 읽고 먼저 API 템플릿 구조를 생성한 후, 비즈니스 로직을 구현한다. > 프롬프트 예시) 신규 도메인 kpi에 대해서 api 셋트를 신규 생성해줘. - @/rules/business-pattern.md를 읽고 이에 위반하는 코드는 작성하지 않는다. --- ### 2. 구현 규칙 #### 2.1 DTO / VO - DTO는 요청(Request) 전용으로 사용한다. - VO는 응답(Response) 전용으로 사용한다. - Record 타입은 사용하지 않는다. #### 2.2 의존성 주입 - 클래스 간 의존성 주입은 생성자 주입을 사용한다. - Lombok의 @AllArgsConstructor를 사용한다. --- ### 3. 서비스 구현 & 쿼리 작성 ### Multi-field Query Strategy #### 1. 필드 타입 명시 * 멀티 필드 사용 시 **항상 필드 타입을 명시한다** * `field.keyword` * `field.text` * 필드 이름만 단독으로 사용하지 않는다 #### 2. 선택 기준 * 정확 일치 / 필터 / 집계 → `field.keyword` * 유사도 / 자연어 검색 → `field.text` #### 3. 금지 규칙 * 의도 없이 필드 타입 생략 금지 * 요구사항과 맞지 않는 타입 선택 금지 * 쿼리 필드 상수화 금지 * 쿼리 필드는 항상 리터럴로 직접 작성한다 --- ### includeFields 규칙 #### 1. 매핑 기준 * `includeFields` 작성 전 반드시 `@/docs/AlmIssueEntity.md`의 Index Mapping을 확인한다 * 매핑에 정의된 정확한 필드 경로만 사용한다 * 매핑에 없는 필드는 사용하지 않는다 #### 2. 필드 경로 * 중첩 필드는 점 표기법으로 작성한다 * 예: `priority.priority_name` #### 3. 멀티 필드 * 멀티 필드 사용 시 **서브필드를 반드시 명시한다** * `field.keyword` * `field.text` * 필드 타입을 생략하지 않는다 --- ### fieldAlias 규칙 * `.valueByName()`, `.countByName()`를 사용하지 않으면 `mainFieldAlias()`, `subFieldAlias()`를 추가하지 않는다