From f94c2139a169b6ae5691a035ed0a86c9107a40bf Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Mon, 8 Jun 2026 13:00:45 -0300 Subject: [PATCH 1/2] docs(claude): consolidate project documentation into CLAUDE.md (#335) Co-authored-by: Claude Sonnet 4.6 --- .coderabbit.yaml | 11 ++- .github/copilot-instructions.md | 148 ----------------------------- CHANGELOG.md | 8 ++ CLAUDE.md | 162 +++++++++++++++++++++++++++++++- 4 files changed, 177 insertions(+), 152 deletions(-) delete mode 100644 .github/copilot-instructions.md diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 33ed1cb..0154d70 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -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: | @@ -193,12 +196,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: | @@ -355,7 +360,7 @@ knowledge_base: code_guidelines: enabled: true filePatterns: - - ".github/copilot-instructions.md" + - "CLAUDE.md" learnings: scope: auto issues: diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 3ca2f34..0000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,148 +0,0 @@ -# GitHub Copilot Instructions - -## 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) - -### 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 -``` - -## 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). diff --git a/CHANGELOG.md b/CHANGELOG.md index 2715904..d8691c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index 8ef5c13..f252ba6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 +``` + +## 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 From 9fb61cdb08424a8d520205ccebc8110f27d14ebf Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Mon, 8 Jun 2026 13:18:08 -0300 Subject: [PATCH 2/2] fix(coderabbit): correct test datasource and add missing commit types (#335) Co-authored-by: Claude Sonnet 4.6 --- .coderabbit.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 0154d70..65d729e 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -109,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: | @@ -237,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: