# Spring Boot 3 service (Java 21)

## Build
- Maven: `./mvnw verify` (Gradle projects: `./gradlew check`). Run locally with `./mvnw spring-boot:run`.

## Code style
- Constructor injection only (final fields, no `@Autowired` on fields). Lombok only if the project already uses it.
- DTOs are Java `record`s; never expose JPA entities from controllers.
- Package by feature: `com.acme.orders.{OrderController, OrderService, OrderRepository, dto}`.
- Validate request bodies with `@Valid` and Jakarta constraints (`@NotBlank`, `@Size`). Errors return RFC 9457 `ProblemDetail` from a `@RestControllerAdvice`.
- `@Transactional` belongs on service methods, read-only where possible (`@Transactional(readOnly = true)`).
- JPA: avoid N+1 with fetch joins or `@EntityGraph`; paginate with `Pageable`. Schema changes are Flyway migrations in `db/migration`, never `ddl-auto=update`.
- Use `RestClient` for outbound HTTP (not `RestTemplate` in new code). Virtual threads are allowed via `spring.threads.virtual.enabled=true` if already enabled.
- Config with `@ConfigurationProperties` records, not scattered `@Value`.

## Tests
- `@WebMvcTest` for controllers, `@DataJpaTest` with Testcontainers Postgres for repositories, `@SpringBootTest` only for a few integration paths.

## Don't
- Don't catch `Exception` and return 200, or log secrets/PII.
