test: Verify pre-commit hook formatting check
This commit is contained in:
212
CLAUDE.md
Normal file
212
CLAUDE.md
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
**kamco-change-detection-api** is a Spring Boot 3.5.7 application using Java 21 and PostgreSQL for KAMCO's change detection system. The project handles geospatial data with JTS/GeoJSON integration and uses QueryDSL for type-safe database queries.
|
||||||
|
|
||||||
|
## Build & Run Commands
|
||||||
|
|
||||||
|
### Build
|
||||||
|
```bash
|
||||||
|
# Full build with tests
|
||||||
|
./gradlew build
|
||||||
|
|
||||||
|
# Build without tests (Jenkins CI uses this)
|
||||||
|
./gradlew clean build -x test
|
||||||
|
|
||||||
|
# Build JAR (creates ROOT.jar)
|
||||||
|
./gradlew bootJar
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Application
|
||||||
|
```bash
|
||||||
|
# Run with local profile (default)
|
||||||
|
./gradlew bootRun
|
||||||
|
|
||||||
|
# Run with specific profile
|
||||||
|
./gradlew bootRun --args='--spring.profiles.active=dev'
|
||||||
|
# or
|
||||||
|
java -jar build/libs/ROOT.jar --spring.profiles.active=dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
./gradlew test
|
||||||
|
|
||||||
|
# Run specific test class
|
||||||
|
./gradlew test --tests com.kamco.cd.kamcoback.KamcoBackApplicationTests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Technology Stack
|
||||||
|
- **Framework**: Spring Boot 3.5.7
|
||||||
|
- **Language**: Java 21
|
||||||
|
- **Database**: PostgreSQL
|
||||||
|
- **Connection Pool**: HikariCP
|
||||||
|
- **ORM**: Spring Data JPA + Hibernate
|
||||||
|
- **Query DSL**: QueryDSL 5.0.0 (Jakarta)
|
||||||
|
- **Geospatial**: JTS (Java Topology Suite) with GeoJSON serialization
|
||||||
|
- **Build Tool**: Gradle
|
||||||
|
- **Monitoring**: Spring Boot Actuator
|
||||||
|
|
||||||
|
### Configuration Profiles
|
||||||
|
|
||||||
|
The application uses **profile-based configuration** with three environments:
|
||||||
|
|
||||||
|
| Profile | File | Purpose | Active Profiles |
|
||||||
|
|---------|------|---------|----------------|
|
||||||
|
| `local` | application.yml | Local development | default |
|
||||||
|
| `dev` | application-dev.yml | Development server | `--spring.profiles.active=dev` |
|
||||||
|
| `prod` | application.yml | Production server | `--spring.profiles.active=prod` |
|
||||||
|
|
||||||
|
**CRITICAL**: Profile names must match configuration exactly:
|
||||||
|
- ✅ Use `dev` (not `develop`)
|
||||||
|
- ✅ Use `prod` (not `production`)
|
||||||
|
- ✅ Use `local` (default, not `localhost`)
|
||||||
|
|
||||||
|
### Geospatial Data Handling
|
||||||
|
|
||||||
|
The application has **custom Jackson serializers/deserializers** for JTS Geometry types:
|
||||||
|
|
||||||
|
**Location**: `com.kamco.cd.kamcoback.common.utils.geometry`
|
||||||
|
|
||||||
|
- `GeometrySerializer`: Converts JTS Geometry → GeoJSON with **16-digit precision** (increased from default 8 digits)
|
||||||
|
- `GeometryDeserializer`: Converts GeoJSON → JTS Geometry types (Point, Polygon, Geometry)
|
||||||
|
|
||||||
|
**Registered for types**: `Geometry`, `Point`, `Polygon`
|
||||||
|
|
||||||
|
**Configuration**: `WebConfig.java` configures ObjectMapper bean with custom module
|
||||||
|
|
||||||
|
**Usage in entities**: Use JTS geometry types directly in JPA entities:
|
||||||
|
```java
|
||||||
|
@Column(columnDefinition = "geometry(Point,4326)")
|
||||||
|
private Point location;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "geometry(Polygon,4326)")
|
||||||
|
private Polygon boundary;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database Configuration
|
||||||
|
|
||||||
|
**HikariCP Connection Pool** is configured per profile:
|
||||||
|
|
||||||
|
| Setting | Local | Dev | Prod |
|
||||||
|
|---------|-------|-----|------|
|
||||||
|
| Min Idle | 10 | 5 | N/A |
|
||||||
|
| Max Pool Size | 50 | 20 | N/A |
|
||||||
|
| Connection Timeout | 20s | Default | Default |
|
||||||
|
| Idle Timeout | 5min | Default | Default |
|
||||||
|
| Max Lifetime | 30min | Default | Default |
|
||||||
|
|
||||||
|
**JPA/Hibernate Settings**:
|
||||||
|
- DDL Auto: `validate` (schema changes require manual migration)
|
||||||
|
- JDBC Batch Size: 50
|
||||||
|
- Default Batch Fetch Size: 100 (N+1 query prevention)
|
||||||
|
- Show SQL: `true` in dev, configurable per profile
|
||||||
|
|
||||||
|
**Startup Logging**: `StartupLogger.java` displays full configuration on startup including active profiles, database connection, pool settings, and JPA configuration.
|
||||||
|
|
||||||
|
### QueryDSL Setup
|
||||||
|
|
||||||
|
**Dependencies** (build.gradle):
|
||||||
|
- Implementation: `querydsl-jpa:5.0.0:jakarta`
|
||||||
|
- Annotation Processor: `querydsl-apt:5.0.0:jakarta`
|
||||||
|
|
||||||
|
**Q-Class Generation**: Q-classes are generated via annotation processors for Jakarta Persistence entities.
|
||||||
|
|
||||||
|
**Pattern** (from TODO): Future repositories should follow `CustomRepository` + `CustomRepositoryImpl` pattern for complex queries.
|
||||||
|
|
||||||
|
### Actuator Monitoring
|
||||||
|
|
||||||
|
**Endpoints** configured at `/monitor` base path:
|
||||||
|
- `/monitor/health` - Health checks with readiness/liveness probes
|
||||||
|
- JMX endpoints excluded for security
|
||||||
|
|
||||||
|
**Health Probes**: Enabled for Kubernetes-style readiness and liveness checks.
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
**Standard**: Google Java Style Guide with project-specific modifications
|
||||||
|
|
||||||
|
**Key Rules**:
|
||||||
|
- **Indentation**: 2 spaces (not tabs)
|
||||||
|
- **Line Length**: 100 characters max
|
||||||
|
- **Line Endings**: LF (Unix-style)
|
||||||
|
- **Charset**: UTF-8
|
||||||
|
- **Trailing Whitespace**: Removed
|
||||||
|
- **Final Newline**: Required
|
||||||
|
|
||||||
|
**Style XML**: `intellij-java-google-style.xml` (IntelliJ IDEA code style configuration)
|
||||||
|
|
||||||
|
### Automated Code Formatting
|
||||||
|
|
||||||
|
**Spotless Gradle Plugin**: Automatically enforces Google Java Format
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check formatting
|
||||||
|
./gradlew spotlessCheck
|
||||||
|
|
||||||
|
# Apply formatting
|
||||||
|
./gradlew spotlessApply
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pre-commit Hook**: Automatically checks formatting before each commit
|
||||||
|
- Location: `.git/hooks/pre-commit`
|
||||||
|
- Runs `spotlessCheck` before allowing commits
|
||||||
|
- If formatting fails, run `./gradlew spotlessApply` to fix
|
||||||
|
|
||||||
|
**IntelliJ Setup**: See `CODE_STYLE_SETUP.md` for detailed instructions on:
|
||||||
|
- Importing code style XML
|
||||||
|
- Enabling format-on-save
|
||||||
|
- Configuring Actions on Save
|
||||||
|
|
||||||
|
**Important**: The project uses **spaces** (not tabs) for indentation, with 2-space indent size.
|
||||||
|
|
||||||
|
## Package Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
com.kamco.cd.kamcoback
|
||||||
|
├── KamcoBackApplication.java # Main application entry point
|
||||||
|
├── config/
|
||||||
|
│ ├── WebConfig.java # Jackson ObjectMapper + Geometry serializers
|
||||||
|
│ └── StartupLogger.java # Application startup diagnostics
|
||||||
|
└── common/
|
||||||
|
├── api/ # API DTOs
|
||||||
|
└── utils/
|
||||||
|
└── geometry/ # GeoJSON serialization utilities
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Notes
|
||||||
|
|
||||||
|
### Current State (Early Stage)
|
||||||
|
The project is in initial setup phase. From `common/README.md`, planned but not yet implemented:
|
||||||
|
- QueryDSL custom/impl repository pattern
|
||||||
|
- Common code management system
|
||||||
|
- Redis caching layer
|
||||||
|
|
||||||
|
### When Adding New Features
|
||||||
|
1. **Entities with Geometry**: Use JTS types directly; serialization is handled automatically
|
||||||
|
2. **Repository Queries**: Use QueryDSL for type-safe queries (Q-classes auto-generated)
|
||||||
|
3. **Configuration**: Add profile-specific settings in appropriate application-{profile}.yml
|
||||||
|
4. **Database Changes**: DDL is set to `validate`; schema changes need manual migration
|
||||||
|
|
||||||
|
### Profile Activation Troubleshooting
|
||||||
|
If you see "Failed to configure a DataSource", check:
|
||||||
|
1. Profile name matches configuration file exactly (`dev`, `prod`, or `local`)
|
||||||
|
2. DataSource URL, username, password are set in profile configuration
|
||||||
|
3. PostgreSQL JDBC driver is on classpath (runtimeOnly dependency)
|
||||||
|
|
||||||
|
### Testing Geometry Serialization
|
||||||
|
Use the configured ObjectMapper bean for JSON operations. Manual ObjectMapper creation will miss custom geometry serializers.
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
**Jenkins Pipeline**: `Jenkinsfile-dev`
|
||||||
|
- Branch: `develop`
|
||||||
|
- Build: `./gradlew clean build -x test`
|
||||||
|
- JDK: Java 21
|
||||||
|
- Artifact: `ROOT.jar`
|
||||||
115
CODE_STYLE_SETUP.md
Normal file
115
CODE_STYLE_SETUP.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# Code Style 설정 가이드
|
||||||
|
|
||||||
|
이 문서는 프로젝트에서 Google Java Style을 자동으로 적용하기 위한 설정 가이드입니다.
|
||||||
|
|
||||||
|
## 자동 포맷팅 구성
|
||||||
|
|
||||||
|
### 1. 커밋 시점 자동 체크 (Git Pre-commit Hook)
|
||||||
|
|
||||||
|
커밋 전에 자동으로 코드 스타일을 체크하고, 문제가 있으면 커밋을 막습니다.
|
||||||
|
|
||||||
|
**설정 완료:** `.git/hooks/pre-commit` 파일이 자동으로 실행됩니다.
|
||||||
|
|
||||||
|
**동작 방식:**
|
||||||
|
- 커밋 시도 시 `./gradlew spotlessCheck` 자동 실행
|
||||||
|
- 포맷팅 오류가 있으면 커밋 차단 및 안내 메시지 출력
|
||||||
|
- 포맷팅이 올바르면 커밋 허용
|
||||||
|
|
||||||
|
**포맷팅 오류 발생 시:**
|
||||||
|
```bash
|
||||||
|
# 자동 포맷팅 적용
|
||||||
|
./gradlew spotlessApply
|
||||||
|
|
||||||
|
# 변경사항 추가 후 다시 커밋
|
||||||
|
git add .
|
||||||
|
git commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. IntelliJ IDEA 저장 시점 자동 포맷팅
|
||||||
|
|
||||||
|
#### 방법 1: Code Style 설정 임포트 (권장)
|
||||||
|
|
||||||
|
1. **IntelliJ IDEA 열기**
|
||||||
|
2. **Settings/Preferences** (Mac: `⌘,` / Windows: `Ctrl+Alt+S`)
|
||||||
|
3. **Editor > Code Style > Java**
|
||||||
|
4. **⚙️ (톱니바퀴)** 클릭 > **Import Scheme > IntelliJ IDEA code style XML**
|
||||||
|
5. 프로젝트 루트의 `intellij-java-google-style.xml` 파일 선택
|
||||||
|
6. **OK** 클릭
|
||||||
|
|
||||||
|
#### 방법 2: 저장 시 자동 포맷팅 활성화
|
||||||
|
|
||||||
|
**Option A: Actions on Save 설정**
|
||||||
|
|
||||||
|
1. **Settings/Preferences** > **Tools > Actions on Save**
|
||||||
|
2. 다음 옵션들을 활성화:
|
||||||
|
- ✅ **Reformat code**
|
||||||
|
- ✅ **Optimize imports**
|
||||||
|
- ✅ **Rearrange code** (선택사항)
|
||||||
|
3. **Changed lines** 또는 **Whole file** 선택
|
||||||
|
4. **OK** 클릭
|
||||||
|
|
||||||
|
**Option B: Save Actions Plugin 사용 (더 많은 옵션)**
|
||||||
|
|
||||||
|
1. **Settings/Preferences** > **Plugins**
|
||||||
|
2. **Marketplace**에서 "Save Actions" 검색 및 설치
|
||||||
|
3. **Settings/Preferences** > **Other Settings > Save Actions**
|
||||||
|
4. 다음 옵션 활성화:
|
||||||
|
- ✅ **Activate save actions on save**
|
||||||
|
- ✅ **Reformat file**
|
||||||
|
- ✅ **Optimize imports**
|
||||||
|
- ✅ **Rearrange fields and methods** (선택사항)
|
||||||
|
|
||||||
|
### 3. Gradle Spotless Plugin 수동 실행
|
||||||
|
|
||||||
|
#### 코드 포맷팅 체크
|
||||||
|
```bash
|
||||||
|
# 포맷팅 문제 확인만 (수정하지 않음)
|
||||||
|
./gradlew spotlessCheck
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 코드 자동 포맷팅
|
||||||
|
```bash
|
||||||
|
# 모든 Java 파일 자동 포맷팅 적용
|
||||||
|
./gradlew spotlessApply
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 빌드 시 자동 체크
|
||||||
|
```bash
|
||||||
|
# 빌드 전에 자동으로 spotlessCheck 실행됨
|
||||||
|
./gradlew build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 코드 스타일 규칙
|
||||||
|
|
||||||
|
프로젝트는 **Google Java Style Guide** 기반으로 다음 규칙을 따릅니다:
|
||||||
|
|
||||||
|
- **Indentation**: 2 spaces (탭 아님)
|
||||||
|
- **Line Length**: 100 characters
|
||||||
|
- **Line Endings**: LF (Unix-style)
|
||||||
|
- **Charset**: UTF-8
|
||||||
|
- **Import Order**: Static imports → 빈 줄 → Regular imports
|
||||||
|
- **Braces**: 모든 if, for, while, do 문에 중괄호 필수
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
### Pre-commit hook이 실행되지 않는 경우
|
||||||
|
```bash
|
||||||
|
# 실행 권한 확인 및 부여
|
||||||
|
chmod +x .git/hooks/pre-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spotless 플러그인이 동작하지 않는 경우
|
||||||
|
```bash
|
||||||
|
# Gradle 의존성 다시 다운로드
|
||||||
|
./gradlew clean build --refresh-dependencies
|
||||||
|
```
|
||||||
|
|
||||||
|
### IntelliJ 포맷팅이 다르게 적용되는 경우
|
||||||
|
1. `intellij-java-google-style.xml` 다시 임포트
|
||||||
|
2. **File > Invalidate Caches** > **Invalidate and Restart**
|
||||||
|
|
||||||
|
## 추가 정보
|
||||||
|
|
||||||
|
- **Google Java Style Guide**: https://google.github.io/styleguide/javaguide.html
|
||||||
|
- **Spotless Plugin**: https://github.com/diffplug/spotless
|
||||||
|
- **IntelliJ Code Style**: https://www.jetbrains.com/help/idea/code-style.html
|
||||||
20
build.gradle
20
build.gradle
@@ -2,6 +2,7 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.5.7'
|
id 'org.springframework.boot' version '3.5.7'
|
||||||
id 'io.spring.dependency-management' version '1.1.7'
|
id 'io.spring.dependency-management' version '1.1.7'
|
||||||
|
id 'com.diffplug.spotless' version '6.25.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'com.kamco.cd'
|
group = 'com.kamco.cd'
|
||||||
@@ -58,3 +59,22 @@ tasks.named('test') {
|
|||||||
bootJar {
|
bootJar {
|
||||||
archiveFileName = 'ROOT.jar'
|
archiveFileName = 'ROOT.jar'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Spotless configuration for code formatting
|
||||||
|
spotless {
|
||||||
|
java {
|
||||||
|
target 'src/**/*.java'
|
||||||
|
googleJavaFormat('1.19.2').aosp().reflowLongStrings()
|
||||||
|
indentWithSpaces(2)
|
||||||
|
trimTrailingWhitespace()
|
||||||
|
endWithNewline()
|
||||||
|
importOrder()
|
||||||
|
removeUnusedImports()
|
||||||
|
formatAnnotations()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run spotlessCheck before build
|
||||||
|
tasks.named('build') {
|
||||||
|
dependsOn 'spotlessCheck'
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.kamco.cd.kamcoback.common.api;
|
||||||
|
|
||||||
|
public class HelloApiController {
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.kamco.cd.kamcoback.common.service;
|
||||||
|
|
||||||
|
public class HelloService {
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.kamco.cd.kamcoback.config.api;
|
||||||
|
|
||||||
|
public class ApiResponseDto {
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.kamco.cd.kamcoback.config.api;
|
||||||
|
|
||||||
|
public interface EnumType {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user