# 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`. 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` - `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 ```