Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ reviews:
- Ensure proper use of ModelMapper for entity-DTO conversion
- Validate proper error handling and logging
- Check async operations if used
- Spring Cache is configured with NO expiry β€” this is intentional. Do not
suggest adding a TTL or time-based eviction. Cache is invalidated only on
write operations via @CacheEvict(allEntries = true).

- path: "src/main/java/**/repositories/**/*.java"
instructions: |
Expand Down Expand Up @@ -106,9 +109,10 @@ reviews:

- path: "src/test/resources/application.properties"
instructions: |
- Verify H2 in-memory database for tests
- Check test-specific configurations
- Ensure proper test isolation settings
- Verify in-memory SQLite for tests (jdbc:sqlite::memory:)
- Check test-specific SQLite configurations (dialect, driver, ddl-auto)
- Ensure Spring SQL init uses ddl.sql + dml.sql (not Flyway, which must be disabled)
- Ensure proper test isolation (server.port=0, spring.flyway.enabled=false)

- path: "src/main/resources/logback-spring.xml"
instructions: |
Expand Down Expand Up @@ -193,12 +197,14 @@ reviews:
If so, update the relevant sections of README.md to reflect the current state.
Do not rewrite sections unrelated to the changes.

## 3. .github/copilot-instructions.md
## 3. CLAUDE.md
If the PR introduces patterns, conventions, or architectural decisions that
should guide future AI-assisted contributions, add or update the relevant
instructions in .github/copilot-instructions.md.
instructions in CLAUDE.md.
Focus on things a developer (or AI assistant) unfamiliar with this specific
stack implementation should know before writing code here.
If the change is architecturally significant, also create or amend the
relevant ADR in docs/adr/.

- name: "enforce http error handling"
instructions: |
Expand Down Expand Up @@ -232,7 +238,7 @@ reviews:
title:
mode: warning
requirements: |
- Use Conventional Commits format (feat:, fix:, chore:, docs:, test:, refactor:)
- Use Conventional Commits format (feat:, fix:, chore:, docs:, test:, refactor:, ci:, perf:)
- Keep under 80 characters
- Be descriptive and specific
description:
Expand Down Expand Up @@ -355,7 +361,7 @@ knowledge_base:
code_guidelines:
enabled: true
filePatterns:
- ".github/copilot-instructions.md"
- "CLAUDE.md"
learnings:
scope: auto
issues:
Expand Down
148 changes: 0 additions & 148 deletions .github/copilot-instructions.md

This file was deleted.

8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ Release names follow the **historic football clubs** naming convention (A–Z):

### Changed

- Consolidate project documentation into `CLAUDE.md` as the single source of
truth; add Invariants and Architecture Decision Records sections; extend
Pre-commit Checks with ADR update requirement (#335)
- Remove `.github/copilot-instructions.md` (content merged into `CLAUDE.md`) (#335)
- Update `.coderabbit.yaml`: document intentional no-expiry cache behaviour in
services path instruction; point `knowledge_base.code_guidelines` and
`finishing_touches` sync-documentation check to `CLAUDE.md` (#335)

- Refactor `/pre-release` Phase 2: inline build and test steps directly
(`./mvnw clean install`, `docker compose build`) instead of delegating to
`/pre-commit`; move CodeRabbit review to run against the uncommitted CHANGELOG
Expand Down
162 changes: 161 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,166 @@
# CLAUDE.md

@.github/copilot-instructions.md
## Overview

REST API for managing football players built with Java and Spring Boot. Implements CRUD operations with a layered architecture, Spring Data JPA + SQLite, Bean Validation, Spring Cache, and Swagger documentation. Part of a cross-language comparison study (.NET, Go, Python, Rust, TypeScript).

## Tech Stack

- **Language**: Java 25 (LTS, required)
- **Framework**: Spring Boot 4.0.0 (Spring MVC)
- **ORM**: Spring Data JPA + Hibernate
- **Database**: SQLite (file-based runtime, in-memory for tests)
- **Build**: Maven 3 β€” always use `./mvnw` wrapper
- **Validation**: Bean Validation (JSR-380)
- **Caching**: Spring `@Cacheable` (simple in-memory, no expiry)
- **Mapping**: ModelMapper
- **Logging**: SLF4J
- **Testing**: JUnit 5 + AssertJ + MockMvc + Mockito
- **Coverage**: JaCoCo
- **API Docs**: SpringDoc OpenAPI 3 (Swagger)
- **Boilerplate**: Lombok
- **Containerization**: Docker

## Structure

```text
src/main/java/
β”œβ”€β”€ controllers/ β€” HTTP handlers; delegate to services, no business logic [HTTP layer]
β”œβ”€β”€ services/ β€” Business logic + @Cacheable caching [business layer]
β”œβ”€β”€ repositories/ β€” Spring Data JPA with derived queries [data layer]
β”œβ”€β”€ models/ β€” Player entity + DTOs
└── converters/ β€” JPA AttributeConverter for ISO-8601 date handling
src/main/resources/ β€” application.properties, Logback config
src/test/java/ β€” test classes mirroring main structure
src/test/resources/ β€” test config, schema (ddl.sql), seed data (dml.sql)
storage/ β€” SQLite database file (runtime)
```

**Layer rule**: `Controller β†’ Service β†’ Repository β†’ JPA`. Controllers must not access repositories directly. Business logic must not live in controllers.

## Coding Guidelines

- **Naming**: camelCase (methods/variables), PascalCase (classes), UPPER_SNAKE_CASE (constants)
- **Files**: class name matches file name
- **DI**: Constructor injection via Lombok `@RequiredArgsConstructor`; never field injection
- **Annotations**: `@RestController`, `@Service`, `@Repository`, `@Entity`, `@Data`/`@Builder`/`@AllArgsConstructor` (Lombok)
- **Transactions**: `@Transactional(readOnly = true)` on read service methods; `@Transactional` on writes
- **Errors**: `@ControllerAdvice` for global exception handling
- **Logging**: SLF4J only; never `System.out.println`
- **DTOs**: Never expose entities directly in controllers β€” always use DTOs
- **Tests**: BDD Given-When-Then naming (`givenX_whenY_thenZ`); AssertJ BDD style (`then(result).isNotNull()`); in-memory SQLite auto-clears after each test
- **Avoid**: field injection, `new` for Spring beans, missing `@Transactional`, exposing entities in controllers, hardcoded configuration

## Commands

### Quick Start

```bash
./mvnw spring-boot:run # port 9000
./mvnw clean test # run tests
./mvnw clean test jacoco:report # tests + coverage
open target/site/jacoco/index.html # view coverage report
docker compose up
docker compose down -v
```

### Pre-commit Checks

1. `./mvnw clean install` β€” must succeed
2. All tests pass
3. Check coverage at `target/site/jacoco/index.html`
4. No compilation warnings
5. Commit message follows Conventional Commits format (enforced by commitlint)
6. If this commit introduces or changes an architectural decision, update `CLAUDE.md` and create or amend the relevant ADR in `docs/adr/`.

### Commits

Format: `type(scope): description (#issue)` β€” max 80 chars
Types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf`
Example: `feat(api): add player stats endpoint (#42)`

## Agent Mode

### Proceed freely

- Route handlers and controller endpoints
- Service layer business logic
- Repository custom queries
- Unit and integration tests
- Exception handling in `@ControllerAdvice`
- Documentation updates, bug fixes, and refactoring
- Utility classes and helpers

### Ask before changing

- Database schema (entity fields, relationships)
- Dependencies (`pom.xml`)
- CI/CD configuration (`.github/workflows/`)
- Docker setup
- Application properties
- API contracts (breaking DTO changes)
- Caching strategy or TTL values
- Package structure

### Never modify

- `.java-version` (JDK 25 required)
- Maven wrapper scripts (`mvnw`, `mvnw.cmd`)
- Port configuration (9000/9001)
- Test database configuration (in-memory SQLite)
- Production configurations or deployment secrets

### Creating Issues

This project uses Spec-Driven Development (SDD): discuss in Plan mode first, create a GitHub Issue as the spec artifact, then implement. Always offer to draft an issue before writing code.

**Feature request** (`enhancement` label):
- **Problem**: the pain point being solved
- **Proposed Solution**: expected behavior and functionality
- **Suggested Approach** *(optional)*: implementation plan if known
- **Acceptance Criteria**: at minimum β€” behaves as proposed, tests added/updated, no regressions
- **References**: related issues, docs, or examples

**Bug report** (`bug` label):
- **Description**: clear summary of the bug
- **Steps to Reproduce**: numbered, minimal steps
- **Expected / Actual Behavior**: one section each
- **Environment**: runtime versions + OS
- **Additional Context**: logs, screenshots, stack traces
- **Possible Solution** *(optional)*: suggested fix or workaround

### Key workflows

**Add an endpoint**: Define DTO in `models/` with Bean Validation β†’ add service method in `services/` with `@Transactional` β†’ create controller endpoint with `@Operation` annotation β†’ add tests β†’ run `./mvnw clean test jacoco:report`.

**Modify schema**: Update `@Entity` in `models/Player.java` β†’ update DTOs if API changes β†’ manually update `storage/players-sqlite3.db` (preserve 26 players) β†’ update service, repository, and tests β†’ run `./mvnw clean test`.

**After completing work**: Suggest a branch name (e.g. `feat/add-player-stats`) and a commit message following Conventional Commits including co-author line:

```text
feat(scope): description (#issue)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
```

## Invariants (never change without explicit discussion)

- Port: 9000
- API contract: endpoints, HTTP status codes, and response shapes are fixed; do not change them without explicit discussion
- Commit format: `type(scope): description (#issue)` β€” max 80 chars
- Conventional Commits types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf`
- `CHANGELOG.md` `[Unreleased]` section must be updated before every commit

## Architecture Decision Records

Architectural decisions are documented in [`docs/adr/`](docs/adr/README.md).
When proposing structural changes, check both this file and the relevant ADR.
When a decision changes, update this file and create or amend the relevant ADR.

## Additional Resources

- **Architecture Decision Records**: [`docs/adr/`](docs/adr/README.md) β€” 12 ADRs documenting the "why" behind major architectural and technology choices in this project.
- New architecturally significant decisions (framework changes, persistence strategy, API contract changes, test strategy shifts) should include a new ADR in `docs/adr/` following the template in [`docs/adr/template.md`](docs/adr/template.md).

## Claude Code

Expand Down