96 lines
3.5 KiB
Markdown
96 lines
3.5 KiB
Markdown
# Plan: Scaffold Spring Boot Project + UserService
|
|
|
|
## Context
|
|
New empty project directory. User wants a full Spring Boot project scaffolded, then a `UserService` added following the same pattern as `ProductService`. The prompt referenced Spring Boot 4, which is not yet released — Spring Boot **3.4.x** (latest stable, supports Java 21 and virtual threads) will be used instead.
|
|
|
|
## Project Layout
|
|
|
|
```
|
|
/home/directlx/claude-src/cluade-user/
|
|
├── pom.xml
|
|
├── CLAUDE.md
|
|
└── src/
|
|
├── main/
|
|
│ ├── java/com/example/app/
|
|
│ │ ├── AppApplication.java
|
|
│ │ ├── exception/
|
|
│ │ │ └── ResourceNotFoundException.java
|
|
│ │ ├── model/
|
|
│ │ │ ├── User.java
|
|
│ │ │ └── Product.java
|
|
│ │ ├── repository/
|
|
│ │ │ ├── UserRepository.java
|
|
│ │ │ └── ProductRepository.java
|
|
│ │ └── service/
|
|
│ │ ├── ProductService.java ← reference pattern
|
|
│ │ └── UserService.java ← main deliverable
|
|
│ └── resources/
|
|
│ └── application.properties
|
|
└── test/
|
|
└── java/com/example/app/
|
|
└── service/
|
|
└── UserServiceTest.java
|
|
```
|
|
|
|
## Key Decisions
|
|
|
|
- **Build**: Maven with `spring-boot-starter-parent` 3.4.2
|
|
- **Java**: 21 (records for entities, sealed classes available)
|
|
- **DB**: H2 in-memory (dev-ready; swap for PostgreSQL via `application.properties`)
|
|
- **Dependencies**: `spring-boot-starter-web`, `spring-boot-starter-data-jpa`, `h2`, `spring-boot-starter-test`
|
|
- **Package**: `com.example.app` (conventional; user can rename)
|
|
|
|
## Files to Create
|
|
|
|
### `pom.xml`
|
|
Spring Boot 3.4.2 parent, Java 21, web + JPA + H2 + test starters.
|
|
|
|
### `AppApplication.java`
|
|
Standard `@SpringBootApplication` entry point.
|
|
|
|
### `exception/ResourceNotFoundException.java`
|
|
`@ResponseStatus(HttpStatus.NOT_FOUND)` extending `RuntimeException` — used by both services for proper error handling.
|
|
|
|
### `model/Product.java` + `model/User.java`
|
|
JPA `@Entity` classes with `@Id @GeneratedValue`. User has: `id`, `name`, `email`, `createdAt`. Product has: `id`, `name`, `price`.
|
|
|
|
### `repository/ProductRepository.java` + `repository/UserRepository.java`
|
|
Extend `JpaRepository<T, Long>`. UserRepository adds `findByEmail(String email)`.
|
|
|
|
### `service/ProductService.java` (reference pattern)
|
|
Constructor-injected `ProductRepository`, `@Service`, methods: `findById`, `findAll`, `create`, `update`, `delete` — throws `ResourceNotFoundException` on missing entity.
|
|
|
|
### `service/UserService.java` (main deliverable)
|
|
Identical pattern to ProductService:
|
|
- `@Service` + constructor injection of `UserRepository`
|
|
- `findById(Long id)` — throws `ResourceNotFoundException`
|
|
- `findAll()` — returns `List<User>`
|
|
- `create(User user)` — saves and returns
|
|
- `update(Long id, User updated)` — finds, patches fields, saves
|
|
- `delete(Long id)` — finds (validates existence), then deletes
|
|
|
|
### `application.properties`
|
|
H2 console enabled, JPA `ddl-auto=create-drop`, show-sql for development.
|
|
|
|
### `UserServiceTest.java`
|
|
Mockito-based unit test (`@ExtendWith(MockitoExtension.class)`) covering findById (found + not-found), findAll, create, update, delete.
|
|
|
|
### `CLAUDE.md`
|
|
Project-specific guidance for future Claude sessions.
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
# Build
|
|
mvn clean compile
|
|
|
|
# Run tests
|
|
mvn test
|
|
|
|
# Run single test class
|
|
mvn test -Dtest=UserServiceTest
|
|
|
|
# Start the app
|
|
mvn spring-boot:run
|
|
```
|