From 1498fb86b5150f1f438e534553383d0f837c7983 Mon Sep 17 00:00:00 2001 From: Nano Taboada <87288+nanotaboada@users.noreply.github.com> Date: Sat, 24 Jan 2026 15:25:12 -0300 Subject: [PATCH 1/2] docs: optimize AI agent instructions for token efficiency - Reduce copilot-instructions.md to thin pointer file (~500 tokens) - Add AGENTS.md with operational procedures (on-demand loading) - Implement tiered loading to minimize auto-loaded token cost - Add token efficiency headers explaining load strategy Instructions now use thin pointer architecture: essential context auto-loads, detailed procedures load on-demand via #file reference. --- .github/copilot-instructions.md | 312 +++++------------------------ AGENTS.md | 342 ++++++++++++++++++++++++++++++++ 2 files changed, 395 insertions(+), 259 deletions(-) create mode 100644 AGENTS.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6503b81..5ab9bf2 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,286 +1,80 @@ -# Copilot Instructions for java.samples.spring.boot +# GitHub Copilot Instructions -## Project Overview +> **⚡ Token Efficiency Note**: This is a minimal pointer file (~500 tokens, auto-loaded by Copilot). +> For complete operational details, reference: `#file:AGENTS.md` (~2,500 tokens, loaded on-demand) +> For specialized knowledge, use: `#file:SKILLS//SKILL.md` (loaded on-demand when needed) -This is a RESTful Web Service proof-of-concept built with **Spring Boot 4** targeting **JDK 25 (LTS)**. The application demonstrates a clean, layered architecture implementing a CRUD API for managing books. It uses a **SQLite database** for runtime persistence (with a pre-seeded database in Docker) and **H2 in-memory** for fast test execution. +## 🎯 Quick Context -**Key URLs:** +**Project**: Spring Boot REST API demonstrating modern Java patterns +**Stack**: Java 25 (LTS) • Spring Boot 4 • JPA/Hibernate • SQLite • Maven • Docker +**Pattern**: Controller → Service → Repository → JPA (layered architecture) +**Philosophy**: Learning-focused PoC emphasizing Spring Boot best practices -- API Server: `http://localhost:9000` -- Swagger/OpenAPI Docs: `http://localhost:9000/swagger/index.html` -- Actuator Health: `http://localhost:9001/actuator/health` +## 📐 Core Conventions -## Tech Stack +- **Naming**: camelCase (methods/variables), PascalCase (classes) +- **Annotations**: Use Spring stereotypes (@RestController, @Service, @Repository) +- **Lombok**: Reduce boilerplate (@Data, @Builder, @AllArgsConstructor) +- **Dependency Injection**: Constructor injection (Lombok @RequiredArgsConstructor) +- **Testing**: JUnit 5 + AssertJ for fluent assertions +- **Build**: Use `./mvnw` wrapper, NOT system Maven -### Core Framework & Runtime - -- **Java**: JDK 25 (LTS) - use modern Java features where appropriate -- **Spring Boot**: 4.0.0 with modular starter dependencies (WebMVC, Data JPA, Validation, Cache, Actuator) -- **Build Tool**: Maven 3.9+ (use `./mvnw` wrapper, NOT system Maven) -- **Database**: SQLite (runtime) with Xerial JDBC driver; H2 in-memory (test scope only) - -### Key Dependencies - -- **Lombok** 1.18.42: Auto-generate boilerplate code (getters, setters, constructors) -- **ModelMapper** 3.2.6: Entity-to-DTO mapping -- **SpringDoc OpenAPI** 2.8.14: API documentation (Swagger UI) -- **JaCoCo** 0.8.14: Code coverage reporting -- **AssertJ** 3.27.6: Fluent test assertions -- **SQLite JDBC** 3.47.1.0: SQLite database driver (Xerial) -- **Hibernate Community Dialects**: Provides `SQLiteDialect` for JPA/Hibernate - -### Testing - -- **JUnit 5** (Jupiter): Test framework -- **Mockito**: Mocking framework -- **Spring Boot Test**: `@WebMvcTest`, `@DataJpaTest`, `@AutoConfigureCache`, etc. -- **AssertJ**: Preferred assertion library (use over standard JUnit assertions) - -### DevOps & CI/CD - -- **Docker**: Multi-stage build with Eclipse Temurin Alpine images and pre-seeded SQLite database -- **Docker Compose**: Local containerized deployment with persistent storage volume -- **GitHub Actions**: CI pipeline with coverage reporting (Codecov, Codacy) - -## Project Structure +## 🏗️ Architecture at a Glance ``` -src/main/java/ar/com/nanotaboada/java/samples/spring/boot/ -├── Application.java # Main entry point, @SpringBootApplication -├── controllers/ # REST endpoints (@RestController) -│ └── BooksController.java -├── services/ # Business logic (@Service, caching) -│ └── BooksService.java -├── repositories/ # Data access (@Repository, Spring Data JPA) -│ └── BooksRepository.java -└── models/ # Domain entities & DTOs - ├── Book.java # JPA entity - ├── BookDTO.java # Data Transfer Object with validation - └── UnixTimestampConverter.java # JPA converter for LocalDate ↔ Unix timestamp - -src/test/java/.../test/ -├── controllers/ # Controller tests (@WebMvcTest) -├── services/ # Service layer tests -├── repositories/ # Repository tests (@DataJpaTest) -├── BookFakes.java # Test data factory for Book entities -└── BookDTOFakes.java # Test data factory for BookDTO - -src/main/resources/ -├── application.properties # Application configuration (SQLite) -└── logback-spring.xml # Logging configuration - -src/test/resources/ -└── application.properties # Test configuration (H2 in-memory) - -scripts/ -├── entrypoint.sh # Docker entrypoint (copies seed DB on first run) -└── healthcheck.sh # Docker health check using Actuator - -storage/ -└── books-sqlite3.db # Pre-seeded SQLite database with sample books +Controller → Service → Repository → JPA → Database + ↓ ↓ ↓ +Validation Cache Query Methods ``` -**Package Naming Convention**: `ar.com.nanotaboada.java.samples.spring.boot.` -**Test Package Convention**: Add `.test` before layer name (e.g., `...samples.spring.boot.test.controllers`) - -## Coding Guidelines - -### Architecture & Design Patterns - -- **Layered Architecture**: Controller → Service → Repository → Entity -- **DTOs**: Use `BookDTO` for API requests/responses; `Book` entity is internal -- **Dependency Injection**: Use constructor injection (Lombok `@RequiredArgsConstructor` or explicit constructors) -- **Caching**: Service layer uses Spring Cache annotations (`@Cacheable`, `@CachePut`, `@CacheEvict`) -- **Validation**: Use Jakarta Bean Validation annotations on DTOs (`@NotBlank`, `@ISBN`, `@URL`, etc.) - -### Java Style +- **Controllers**: REST endpoints with @RestController +- **Services**: Business logic with @Service + caching +- **Repositories**: JpaRepository with derived queries +- **DTOs**: ModelMapper for entity ↔ DTO transformations +- **Cache**: Spring Cache abstraction (1-hour TTL) -- **Lombok**: Prefer `@Data`, `@RequiredArgsConstructor`, `@NoArgsConstructor`, `@AllArgsConstructor` over manual code -- **Streams**: Use Java Streams API for collection processing (see `BooksService.retrieveAll()`) -- **Modern Java**: Leverage JDK 25 features (records, pattern matching, sealed classes, etc.) where beneficial -- **Comments**: Section dividers used in controllers/services (e.g., `/* HTTP POST */`) +## ✅ Copilot Should -### Testing Conventions +- Generate idiomatic Spring Boot code with proper annotations +- Use JPA repository patterns (derived queries, @Query) +- Follow REST conventions with ResponseEntity +- Write tests with @SpringBootTest and MockMvc +- Apply Lombok annotations to reduce boilerplate +- Use ModelMapper for DTO transformations +- Implement proper exception handling with @ControllerAdvice -- **Test Class Naming**: `Tests` (plural, e.g., `BooksControllerTests`) -- **Test Method Naming**: `given_when_then` (BDD style) -- **Assertions**: Use AssertJ fluent assertions (`assertThat(...).isEqualTo(...)`) -- **Mocking**: Use `@MockitoBean` for Spring beans (new in Spring Boot 4.0), verify interactions with `verify()` -- **Test Data**: Use fake data factories (`BookFakes`, `BookDTOFakes`) for consistent test data -- **Display Names**: Use `@DisplayName` for readable test descriptions -- **Caching in Tests**: Add `@AutoConfigureCache` to slice tests (`@WebMvcTest`, `@DataJpaTest`) when caching is needed +## 🚫 Copilot Should Avoid -### Coverage Exclusions +- Field injection (use constructor injection) +- Using `new` for services (breaks DI) +- Missing @Transactional on service methods +- Exposing entities directly in controllers (use DTOs) +- System.out.println (use SLF4J logging) +- Hardcoded configuration (use @Value or application.yml) -JaCoCo excludes from coverage (see `pom.xml` and `codecov.yml`): - -- `Application.java` (main class) -- `models/**` package (POJOs with Lombok) -- Test files and resources - -## Build & Run Commands - -### Maven Commands (ALWAYS use wrapper) +## ⚡ Quick Commands ```bash -# Clean and compile -./mvnw clean compile - -# Run tests -./mvnw test - -# Run tests with coverage -./mvnw verify - -# Package application -./mvnw package - -# Run application locally +# Run with hot reload ./mvnw spring-boot:run -# Skip tests during build (use sparingly) -./mvnw package -DskipTests -``` - -**Critical Requirements**: - -- **ALWAYS use `./mvnw` wrapper** (Unix/macOS) or `mvnw.cmd` (Windows), NOT `mvn` -- **JDK 25 is REQUIRED**: The project targets JDK 25 (LTS) -- **JAVA_HOME must be set**: Maven wrapper requires JAVA_HOME pointing to JDK 25 installation - -### Docker Commands - -```bash -# Build image -docker compose build +# Test with coverage +./mvnw clean test jacoco:report -# Start application container +# Docker docker compose up -# Start in detached mode -docker compose up -d - -# Stop and remove containers -docker compose down - -# View logs -docker compose logs -f -``` - -**Exposed Ports**: - -- `9000`: Main API server -- `9001`: Actuator management endpoints - -**Persistent Storage**: - -The Docker container uses a "hold" pattern for the pre-seeded SQLite database: - -1. Build stage copies `storage/books-sqlite3.db` to `/app/hold/` in the image -2. On first container run, `entrypoint.sh` copies the database to `/storage/` volume -3. Subsequent runs use the existing database from the volume -4. To reset: `docker compose down -v` removes volumes, next `up` restores seed data - -## Common Tasks & Patterns - -### Adding a New REST Endpoint - -1. Add method to `BooksController` with appropriate HTTP mapping (`@GetMapping`, `@PostMapping`, etc.) -2. Annotate with `@Operation` and `@ApiResponses` for OpenAPI documentation -3. Implement business logic in `BooksService` -4. Add/update repository method if needed -5. Write controller tests using `@WebMvcTest` and `MockMvc` -6. Write service tests with mocked repository - -### Adding a New Entity/Resource - -1. Create JPA entity in `models/` with `@Entity`, `@Table`, Lombok annotations -2. Create corresponding DTO with validation annotations -3. Create repository interface extending `CrudRepository` -4. Create service class with `@Service` and caching annotations -5. Create controller with `@RestController` and OpenAPI annotations -6. Create test data factories (e.g., `EntityFakes.java`) -7. Write comprehensive tests for all layers - -### Updating Dependencies - -- Dependencies are managed by Dependabot (daily checks) -- Spring Boot dependencies are grouped and ignored for individual updates -- Manually update versions in `pom.xml` `` section if needed - -### Running Coverage Reports - -```bash -./mvnw clean verify -# Report available at: target/site/jacoco/index.html +# Swagger: http://localhost:9000/swagger-ui/index.html +# Actuator: http://localhost:9001/actuator/health ``` -## Troubleshooting - -### Build Failures - -- **Lombok not working**: Ensure annotation processor is enabled in IDE and `maven-compiler-plugin` includes Lombok path -- **Tests failing**: Tests use H2 in-memory database via `src/test/resources/application.properties` -- **Port already in use**: Change `server.port` in `application.properties` or kill process using ports 9000/9001 -- **JAVA_HOME not set**: Run `export JAVA_HOME=$(/usr/libexec/java_home -v 25)` on macOS or set to JDK 25 path on other systems -- **CacheManager errors in tests**: Add `@AutoConfigureCache` annotation to slice tests (`@WebMvcTest`, `@DataJpaTest`) -- **SQLite file not found**: Ensure `storage/books-sqlite3.db` exists for local development - -### Docker Issues - -- **Container health check failing**: Verify Actuator is accessible at `http://localhost:9001/actuator/health` -- **Build context too large**: Ensure `.dockerignore` excludes `target/` and `.git/` -- **Database not persisting**: Check that `java-samples-spring-boot_storage` volume exists (`docker volume ls`) -- **Stale seed data**: Run `docker compose down -v` to remove volumes and restore fresh seed data on next `up` - -### Common Pitfalls - -- **Don't use system Maven**: Always use `./mvnw` wrapper -- **Don't modify `Application.java` coverage**: It's excluded by design -- **Don't test Lombok-generated code**: Focus on business logic -- **Repository interfaces**: Custom query methods may not show in coverage (JaCoCo limitation) -- **Spring Boot 4.0 modular packages**: Test annotations like `@WebMvcTest`, `@DataJpaTest`, and `@AutoConfigureCache` are now in modular packages (e.g., `org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest`) - -### SQLite Configuration Notes - -- **Date storage**: LocalDate fields are stored as Unix timestamps (INTEGER) for robustness - no parsing issues -- **Converter**: `UnixTimestampConverter` handles LocalDate ↔ epoch seconds conversion via JPA `@Convert` -- **DDL auto**: Use `ddl-auto=none` since the database is pre-seeded (SQLite has limited ALTER TABLE support) -- **Tests use H2**: The converter works seamlessly with both H2 and SQLite databases - -## CI/CD Pipeline - -### GitHub Actions Workflow (`.github/workflows/maven.yml`) - -1. **Verify Job**: Compile, test, generate coverage with `mvn verify` -2. **Coverage Job**: Upload JaCoCo reports to Codecov and Codacy -3. **Container Job**: Build and push Docker image to GitHub Container Registry (on `master` push only) - -**Required Secrets**: - -- `CODECOV_TOKEN`: Codecov integration token -- `CODACY_PROJECT_TOKEN`: Codacy integration token -- `GITHUB_TOKEN`: Automatically provided for GHCR push - -## Contributing - -Follow [Conventional Commits](https://www.conventionalcommits.org/): - -- `feat:` for new features -- `fix:` for bug fixes -- `chore:` for maintenance tasks - -**Commit Style**: Keep commits logical and atomic. Squash checkpoint commits before PR. - -**PR Requirements**: +## 📚 Need More Detail? -- All tests must pass -- Coverage should not decrease significantly -- Follow existing code style and patterns -- Update API documentation if endpoints change +**For operational procedures**: Load `#file:AGENTS.md` +**For Docker expertise**: *(Planned)* `#file:SKILLS/docker-containerization/SKILL.md` +**For testing patterns**: *(Planned)* `#file:SKILLS/testing-patterns/SKILL.md` -## Additional Resources +--- -- **Code of Conduct**: See `CODE_OF_CONDUCT.md` -- **Detailed Contributing Guide**: See `CONTRIBUTING.md` -- **Project Philosophy**: Small, incremental changes over large rewrites (per Linus Torvalds quote in CONTRIBUTING.md) +💡 **Why this structure?** Copilot auto-loads this file on every chat (~500 tokens). Loading `AGENTS.md` or `SKILLS/` explicitly gives you deep context only when needed, saving 80% of your token budget! diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..cf823f5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,342 @@ +# AGENTS.md + +> **⚡ Token Efficiency Note**: This file contains complete operational instructions (~2,500 tokens). +> **Auto-loaded**: NO (load explicitly with `#file:AGENTS.md` when you need detailed procedures) +> **When to load**: Complex workflows, troubleshooting, CI/CD setup, detailed architecture questions +> **Related files**: See `#file:.github/copilot-instructions.md` for quick context (auto-loaded, ~500 tokens) + +--- + +## Quick Start + +```bash +# Build project with Maven +./mvnw clean install + +# Run application +./mvnw spring-boot:run +# Server starts on http://localhost:8080 + +# View API documentation +# Open http://localhost:8080/swagger-ui.html in browser + +# View health and metrics +# Open http://localhost:8080/actuator/health +``` + +## Java Version + +This project requires **JDK 25 (LTS)** specified in `.java-version`. + +Maven wrapper (`./mvnw`) is included, so Maven installation is optional. + +## Development Workflow + +### Running Tests + +```bash +# Run all tests +./mvnw test + +# Run tests with coverage report (JaCoCo, matches CI) +./mvnw clean test jacoco:report + +# View coverage report in browser +open target/site/jacoco/index.html + +# Run specific test class +./mvnw test -Dtest=BooksControllerTest + +# Run specific test method +./mvnw test -Dtest=BooksControllerTest#testGetAllBooks + +# Run tests without rebuilding +./mvnw surefire:test +``` + +**Coverage requirement**: Tests must maintain high coverage. JaCoCo reports are generated in `target/site/jacoco/`. + +### Code Quality + +```bash +# Compile without running tests +./mvnw compile + +# Verify code (compile + test) +./mvnw verify + +# Clean build artifacts +./mvnw clean + +# Run full build (clean + compile + test + package) +./mvnw clean install + +# Package as JAR (without tests, faster) +./mvnw clean package -DskipTests +``` + +**Pre-commit checklist**: +1. Run `./mvnw clean install` - must pass all tests and build successfully +2. Check JaCoCo coverage report - maintain existing coverage levels +3. Ensure code compiles without warnings + +**Spring Boot DevTools**: Auto-restart on code changes when running with `./mvnw spring-boot:run` (built-in hot reload). + +### Build Artifacts + +After building, JAR file is located at: +``` +target/java.samples.spring.boot-{version}.jar +``` + +Run the JAR directly: +```bash +java -jar target/java.samples.spring.boot-*.jar +``` + +### Database Management + +This project uses **H2 in-memory database for tests** and **SQLite for runtime**. + +**Runtime (SQLite)**: +```bash +# Database auto-initializes on first startup +# Pre-seeded database ships in storage/books.db + +# To reset database to seed state +rm storage/books.db +# Next app startup will recreate via JPA + +# Database location: storage/books.db +``` + +**Tests (H2)**: +- In-memory database per test run +- Automatically cleared after each test +- Configuration in `src/test/resources/application-test.properties` + +## Docker Workflow + +```bash +# Build container image +docker compose build + +# Start application in container +docker compose up + +# Start in detached mode (background) +docker compose up -d + +# View logs +docker compose logs -f + +# Stop application +docker compose down + +# Stop and remove database volume (full reset) +docker compose down -v + +# Health check (when running) +curl http://localhost:8080/actuator/health +``` + +**First run behavior**: Container initializes SQLite database with seed data. Volume persists data between runs. + +## CI/CD Pipeline + +### Continuous Integration (maven.yml) + +**Trigger**: Push to `master` or PR to `master` + +**Jobs**: +1. **Setup**: JDK 25 installation, Maven dependency caching +2. **Lint**: Commit message validation (commitlint) +3. **Build**: `./mvnw clean install` (compile + test + package) +4. **Test**: Tests already run during install, coverage reports generated +5. **Coverage**: JaCoCo report upload to Codecov and Codacy + +**Local validation** (run this before pushing): +```bash +# Matches CI exactly +./mvnw clean install + +# This runs: clean → compile → test → package +# Coverage report automatically generated at target/site/jacoco/ +``` + +## Project Architecture + +**Structure**: Layered architecture (Controller → Service → Repository) + +``` +src/main/java/ar/com/nanotaboada/java/samples/spring/boot/ +├── Application.java # @SpringBootApplication entry point + +├── controllers/ # REST endpoints +│ └── BooksController.java # @RestController, OpenAPI annotations + +├── services/ # Business logic +│ └── BooksService.java # @Service, @Cacheable + +├── repositories/ # Data access +│ └── BooksRepository.java # @Repository, Spring Data JPA + +└── models/ # Domain models + ├── Book.java # @Entity, JPA model + ├── BookDTO.java # Data Transfer Object, validation + └── UnixTimestampConverter.java # JPA converter + +src/test/java/ # Test classes + ├── BooksControllerTest.java + ├── BooksServiceTest.java + └── BooksRepositoryTest.java +``` + +**Key patterns**: +- Spring Boot 4 with Spring MVC +- Spring Data JPA for database operations +- Custom validation annotations for ISBN and URL +- OpenAPI 3.0 annotations for Swagger docs +- `@Cacheable` for in-memory caching +- DTOs with Bean Validation (JSR-380) +- Actuator for health monitoring and metrics +- Maven multi-module support ready + +## API Endpoints + +**Base URL**: `http://localhost:8080` + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `/books` | Get all books | +| `GET` | `/books/{id}` | Get book by ID | +| `POST` | `/books` | Create new book | +| `PUT` | `/books/{id}` | Update book | +| `DELETE` | `/books/{id}` | Delete book | +| `GET` | `/actuator/health` | Health check | +| `GET` | `/swagger-ui.html` | API documentation | + +## Troubleshooting + +### Port already in use +```bash +# Kill process on port 8080 +lsof -ti:8080 | xargs kill -9 +``` + +### Maven dependency issues +```bash +# Force update dependencies +./mvnw clean install -U + +# Clear local Maven repository cache (nuclear option) +rm -rf ~/.m2/repository +./mvnw clean install +``` + +### Compilation errors +```bash +# Verify Java version +java --version # Should be 25.x + +# Clean and rebuild +./mvnw clean compile + +# Skip tests if needed to check compilation +./mvnw clean compile -DskipTests +``` + +### Database locked errors +```bash +# Stop all running instances +pkill -f "spring-boot:run" + +# Reset database +rm storage/books.db +``` + +### Test failures +```bash +# Run tests with verbose output +./mvnw test -X + +# Run single test for debugging +./mvnw test -Dtest=BooksControllerTest#testGetAllBooks -X +``` + +### Maven wrapper issues +```bash +# Make wrapper executable +chmod +x mvnw + +# Or use system Maven +mvn clean install +``` + +### Docker issues +```bash +# Clean slate +docker compose down -v +docker compose build --no-cache +docker compose up +``` + +## Testing the API + +### Using Swagger UI (Recommended) +Open http://localhost:8080/swagger-ui.html - Interactive documentation with "Try it out" + +### Using curl +```bash +# Health check +curl http://localhost:8080/actuator/health + +# Get all books +curl http://localhost:8080/books + +# Get book by ID +curl http://localhost:8080/books/1 + +# Create book +curl -X POST http://localhost:8080/books \ + -H "Content-Type: application/json" \ + -d '{ + "isbn": "9780132350884", + "title": "Clean Code", + "author": "Robert C. Martin", + "published": 1217548800, + "pages": 464, + "description": "A Handbook of Agile Software Craftsmanship", + "website": "https://www.pearson.com/en-us/subject-catalog/p/clean-code-a-handbook-of-agile-software-craftsmanship/P200000009044" + }' + +# Update book +curl -X PUT http://localhost:8080/books/1 \ + -H "Content-Type: application/json" \ + -d '{ + "isbn": "9780132350884", + "title": "Clean Code - Updated", + "author": "Robert C. Martin", + "published": 1217548800, + "pages": 464, + "description": "Updated description", + "website": "https://www.pearson.com/example" + }' + +# Delete book +curl -X DELETE http://localhost:8080/books/1 +``` + +## Important Notes + +- **Never commit secrets**: No API keys, tokens, or credentials in code +- **Test coverage**: Maintain high coverage (use JaCoCo reports) +- **Commit messages**: Follow conventional commits (enforced by commitlint) +- **Java version**: Must use JDK 25 for consistency with CI/CD +- **Maven wrapper**: Always use `./mvnw` instead of `mvn` for consistency +- **Database**: SQLite is for demo/development only - not production-ready +- **H2 for tests**: Tests use in-memory H2, runtime uses SQLite +- **OpenAPI annotations**: Required for all new endpoints (Swagger docs) +- **Caching**: Uses Spring's `@Cacheable` - clears on updates/deletes +- **Validation**: Custom ISBN and URL validators in BookDTO +- **Unix timestamps**: Published dates stored as Unix timestamps (seconds since epoch) From 51fdabd20b1f9a23b8e4b93a02a43634035ef4d5 Mon Sep 17 00:00:00 2001 From: Nano Taboada Date: Sat, 24 Jan 2026 16:31:15 -0300 Subject: [PATCH 2/2] docs: correct database filenames and config in AGENTS.md - Update runtime DB filename to storage/books-sqlite3.db - Clarify spring.jpa.hibernate.ddl-auto=none disables schema generation - Fix test config path to src/test/resources/application.properties --- AGENTS.md | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cf823f5..83d08c7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,8 +1,8 @@ # AGENTS.md -> **⚡ Token Efficiency Note**: This file contains complete operational instructions (~2,500 tokens). -> **Auto-loaded**: NO (load explicitly with `#file:AGENTS.md` when you need detailed procedures) -> **When to load**: Complex workflows, troubleshooting, CI/CD setup, detailed architecture questions +> **⚡ Token Efficiency Note**: This file contains complete operational instructions (~2,500 tokens). +> **Auto-loaded**: NO (load explicitly with `#file:AGENTS.md` when you need detailed procedures) +> **When to load**: Complex workflows, troubleshooting, CI/CD setup, detailed architecture questions > **Related files**: See `#file:.github/copilot-instructions.md` for quick context (auto-loaded, ~500 tokens) --- @@ -76,6 +76,7 @@ open target/site/jacoco/index.html ``` **Pre-commit checklist**: + 1. Run `./mvnw clean install` - must pass all tests and build successfully 2. Check JaCoCo coverage report - maintain existing coverage levels 3. Ensure code compiles without warnings @@ -85,11 +86,13 @@ open target/site/jacoco/index.html ### Build Artifacts After building, JAR file is located at: + ``` target/java.samples.spring.boot-{version}.jar ``` Run the JAR directly: + ```bash java -jar target/java.samples.spring.boot-*.jar ``` @@ -99,21 +102,24 @@ java -jar target/java.samples.spring.boot-*.jar This project uses **H2 in-memory database for tests** and **SQLite for runtime**. **Runtime (SQLite)**: + ```bash # Database auto-initializes on first startup -# Pre-seeded database ships in storage/books.db +# Pre-seeded database ships in storage/books-sqlite3.db # To reset database to seed state -rm storage/books.db -# Next app startup will recreate via JPA +rm storage/books-sqlite3.db +# WARNING: spring.jpa.hibernate.ddl-auto=none disables schema generation +# Deleting the DB will cause startup failure - restore from backup or manually reinitialize -# Database location: storage/books.db +# Database location: storage/books-sqlite3.db ``` **Tests (H2)**: + - In-memory database per test run - Automatically cleared after each test -- Configuration in `src/test/resources/application-test.properties` +- Configuration in `src/test/resources/application.properties` ## Docker Workflow @@ -149,6 +155,7 @@ curl http://localhost:8080/actuator/health **Trigger**: Push to `master` or PR to `master` **Jobs**: + 1. **Setup**: JDK 25 installation, Maven dependency caching 2. **Lint**: Commit message validation (commitlint) 3. **Build**: `./mvnw clean install` (compile + test + package) @@ -156,6 +163,7 @@ curl http://localhost:8080/actuator/health 5. **Coverage**: JaCoCo report upload to Codecov and Codacy **Local validation** (run this before pushing): + ```bash # Matches CI exactly ./mvnw clean install @@ -193,6 +201,7 @@ src/test/java/ # Test classes ``` **Key patterns**: + - Spring Boot 4 with Spring MVC - Spring Data JPA for database operations - Custom validation annotations for ISBN and URL @@ -219,12 +228,14 @@ src/test/java/ # Test classes ## Troubleshooting ### Port already in use + ```bash # Kill process on port 8080 lsof -ti:8080 | xargs kill -9 ``` ### Maven dependency issues + ```bash # Force update dependencies ./mvnw clean install -U @@ -235,6 +246,7 @@ rm -rf ~/.m2/repository ``` ### Compilation errors + ```bash # Verify Java version java --version # Should be 25.x @@ -247,6 +259,7 @@ java --version # Should be 25.x ``` ### Database locked errors + ```bash # Stop all running instances pkill -f "spring-boot:run" @@ -256,6 +269,7 @@ rm storage/books.db ``` ### Test failures + ```bash # Run tests with verbose output ./mvnw test -X @@ -265,6 +279,7 @@ rm storage/books.db ``` ### Maven wrapper issues + ```bash # Make wrapper executable chmod +x mvnw @@ -274,6 +289,7 @@ mvn clean install ``` ### Docker issues + ```bash # Clean slate docker compose down -v @@ -284,9 +300,11 @@ docker compose up ## Testing the API ### Using Swagger UI (Recommended) -Open http://localhost:8080/swagger-ui.html - Interactive documentation with "Try it out" + +Open - Interactive documentation with "Try it out" ### Using curl + ```bash # Health check curl http://localhost:8080/actuator/health