# 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`
