|
1 | 1 | # CLAUDE.md |
2 | 2 |
|
3 | | -@.github/copilot-instructions.md |
| 3 | +## Overview |
| 4 | + |
| 5 | +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). |
| 6 | + |
| 7 | +## Tech Stack |
| 8 | + |
| 9 | +- **Language**: Java 25 (LTS, required) |
| 10 | +- **Framework**: Spring Boot 4.0.0 (Spring MVC) |
| 11 | +- **ORM**: Spring Data JPA + Hibernate |
| 12 | +- **Database**: SQLite (file-based runtime, in-memory for tests) |
| 13 | +- **Build**: Maven 3 — always use `./mvnw` wrapper |
| 14 | +- **Validation**: Bean Validation (JSR-380) |
| 15 | +- **Caching**: Spring `@Cacheable` (simple in-memory, no expiry) |
| 16 | +- **Mapping**: ModelMapper |
| 17 | +- **Logging**: SLF4J |
| 18 | +- **Testing**: JUnit 5 + AssertJ + MockMvc + Mockito |
| 19 | +- **Coverage**: JaCoCo |
| 20 | +- **API Docs**: SpringDoc OpenAPI 3 (Swagger) |
| 21 | +- **Boilerplate**: Lombok |
| 22 | +- **Containerization**: Docker |
| 23 | + |
| 24 | +## Structure |
| 25 | + |
| 26 | +```text |
| 27 | +src/main/java/ |
| 28 | +├── controllers/ — HTTP handlers; delegate to services, no business logic [HTTP layer] |
| 29 | +├── services/ — Business logic + @Cacheable caching [business layer] |
| 30 | +├── repositories/ — Spring Data JPA with derived queries [data layer] |
| 31 | +├── models/ — Player entity + DTOs |
| 32 | +└── converters/ — JPA AttributeConverter for ISO-8601 date handling |
| 33 | +src/main/resources/ — application.properties, Logback config |
| 34 | +src/test/java/ — test classes mirroring main structure |
| 35 | +src/test/resources/ — test config, schema (ddl.sql), seed data (dml.sql) |
| 36 | +storage/ — SQLite database file (runtime) |
| 37 | +``` |
| 38 | + |
| 39 | +**Layer rule**: `Controller → Service → Repository → JPA`. Controllers must not access repositories directly. Business logic must not live in controllers. |
| 40 | + |
| 41 | +## Coding Guidelines |
| 42 | + |
| 43 | +- **Naming**: camelCase (methods/variables), PascalCase (classes), UPPER_SNAKE_CASE (constants) |
| 44 | +- **Files**: class name matches file name |
| 45 | +- **DI**: Constructor injection via Lombok `@RequiredArgsConstructor`; never field injection |
| 46 | +- **Annotations**: `@RestController`, `@Service`, `@Repository`, `@Entity`, `@Data`/`@Builder`/`@AllArgsConstructor` (Lombok) |
| 47 | +- **Transactions**: `@Transactional(readOnly = true)` on read service methods; `@Transactional` on writes |
| 48 | +- **Errors**: `@ControllerAdvice` for global exception handling |
| 49 | +- **Logging**: SLF4J only; never `System.out.println` |
| 50 | +- **DTOs**: Never expose entities directly in controllers — always use DTOs |
| 51 | +- **Tests**: BDD Given-When-Then naming (`givenX_whenY_thenZ`); AssertJ BDD style (`then(result).isNotNull()`); in-memory SQLite auto-clears after each test |
| 52 | +- **Avoid**: field injection, `new` for Spring beans, missing `@Transactional`, exposing entities in controllers, hardcoded configuration |
| 53 | + |
| 54 | +## Commands |
| 55 | + |
| 56 | +### Quick Start |
| 57 | + |
| 58 | +```bash |
| 59 | +./mvnw spring-boot:run # port 9000 |
| 60 | +./mvnw clean test # run tests |
| 61 | +./mvnw clean test jacoco:report # tests + coverage |
| 62 | +open target/site/jacoco/index.html # view coverage report |
| 63 | +docker compose up |
| 64 | +docker compose down -v |
| 65 | +``` |
| 66 | + |
| 67 | +### Pre-commit Checks |
| 68 | + |
| 69 | +1. `./mvnw clean install` — must succeed |
| 70 | +2. All tests pass |
| 71 | +3. Check coverage at `target/site/jacoco/index.html` |
| 72 | +4. No compilation warnings |
| 73 | +5. Commit message follows Conventional Commits format (enforced by commitlint) |
| 74 | +6. If this commit introduces or changes an architectural decision, update `CLAUDE.md` and create or amend the relevant ADR in `docs/adr/`. |
| 75 | + |
| 76 | +### Commits |
| 77 | + |
| 78 | +Format: `type(scope): description (#issue)` — max 80 chars |
| 79 | +Types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf` |
| 80 | +Example: `feat(api): add player stats endpoint (#42)` |
| 81 | + |
| 82 | +## Agent Mode |
| 83 | + |
| 84 | +### Proceed freely |
| 85 | + |
| 86 | +- Route handlers and controller endpoints |
| 87 | +- Service layer business logic |
| 88 | +- Repository custom queries |
| 89 | +- Unit and integration tests |
| 90 | +- Exception handling in `@ControllerAdvice` |
| 91 | +- Documentation updates, bug fixes, and refactoring |
| 92 | +- Utility classes and helpers |
| 93 | + |
| 94 | +### Ask before changing |
| 95 | + |
| 96 | +- Database schema (entity fields, relationships) |
| 97 | +- Dependencies (`pom.xml`) |
| 98 | +- CI/CD configuration (`.github/workflows/`) |
| 99 | +- Docker setup |
| 100 | +- Application properties |
| 101 | +- API contracts (breaking DTO changes) |
| 102 | +- Caching strategy or TTL values |
| 103 | +- Package structure |
| 104 | + |
| 105 | +### Never modify |
| 106 | + |
| 107 | +- `.java-version` (JDK 25 required) |
| 108 | +- Maven wrapper scripts (`mvnw`, `mvnw.cmd`) |
| 109 | +- Port configuration (9000/9001) |
| 110 | +- Test database configuration (in-memory SQLite) |
| 111 | +- Production configurations or deployment secrets |
| 112 | + |
| 113 | +### Creating Issues |
| 114 | + |
| 115 | +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. |
| 116 | + |
| 117 | +**Feature request** (`enhancement` label): |
| 118 | +- **Problem**: the pain point being solved |
| 119 | +- **Proposed Solution**: expected behavior and functionality |
| 120 | +- **Suggested Approach** *(optional)*: implementation plan if known |
| 121 | +- **Acceptance Criteria**: at minimum — behaves as proposed, tests added/updated, no regressions |
| 122 | +- **References**: related issues, docs, or examples |
| 123 | + |
| 124 | +**Bug report** (`bug` label): |
| 125 | +- **Description**: clear summary of the bug |
| 126 | +- **Steps to Reproduce**: numbered, minimal steps |
| 127 | +- **Expected / Actual Behavior**: one section each |
| 128 | +- **Environment**: runtime versions + OS |
| 129 | +- **Additional Context**: logs, screenshots, stack traces |
| 130 | +- **Possible Solution** *(optional)*: suggested fix or workaround |
| 131 | + |
| 132 | +### Key workflows |
| 133 | + |
| 134 | +**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`. |
| 135 | + |
| 136 | +**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`. |
| 137 | + |
| 138 | +**After completing work**: Suggest a branch name (e.g. `feat/add-player-stats`) and a commit message following Conventional Commits including co-author line: |
| 139 | + |
| 140 | +```text |
| 141 | +feat(scope): description (#issue) |
| 142 | +
|
| 143 | +Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
| 144 | +``` |
| 145 | + |
| 146 | +## Invariants (never change without explicit discussion) |
| 147 | + |
| 148 | +- Port: 9000 |
| 149 | +- API contract: endpoints, HTTP status codes, and response shapes are fixed; do not change them without explicit discussion |
| 150 | +- Commit format: `type(scope): description (#issue)` — max 80 chars |
| 151 | +- Conventional Commits types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf` |
| 152 | +- `CHANGELOG.md` `[Unreleased]` section must be updated before every commit |
| 153 | + |
| 154 | +## Architecture Decision Records |
| 155 | + |
| 156 | +Architectural decisions are documented in [`docs/adr/`](docs/adr/README.md). |
| 157 | +When proposing structural changes, check both this file and the relevant ADR. |
| 158 | +When a decision changes, update this file and create or amend the relevant ADR. |
| 159 | + |
| 160 | +## Additional Resources |
| 161 | + |
| 162 | +- **Architecture Decision Records**: [`docs/adr/`](docs/adr/README.md) — 12 ADRs documenting the "why" behind major architectural and technology choices in this project. |
| 163 | +- 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). |
4 | 164 |
|
5 | 165 | ## Claude Code |
6 | 166 |
|
|
0 commit comments