# AGENTS.md - Project Guidelines ## Project Overview A Kotlin Spring Boot web application template using modern JVM stack with database access layer. **Type**: Backend web service **Language**: Kotlin 2.2.21 **Build Tool**: Gradle (Kotlin DSL) **JDK**: Java 21 ## Tech Stack - **Framework**: Spring Boot 4.0.2 - **Web**: Spring Web MVC - **Security**: Spring Security (permissive local profile) - **Database**: PostgreSQL + jOOQ (typesafe SQL) + Liquibase (migrations) - **Build Features**: GraalVM Native Image support ## Project Structure ``` src/ ├── main/kotlin/com/example/demo/ │ ├── App.kt # Application entry point │ ├── Config.kt # Security configuration (local profile) │ ├── api/ # REST controllers │ │ └── HelloController.kt │ └── service/ # Business logic │ └── HelloService.kt ├── main/resources/ │ ├── application.yaml # App config (port 8081, postgres) │ └── db/changelog/ # Liquibase migrations │ └── db.changelog-master.yaml └── test/kotlin/com/example/demo/ └── AppTests.kt # Basic context load test ``` ## Key Conventions ### Code Style - Kotlin with strict JSR-305 annotations (`-Xjsr305=strict`) - Constructor injection for dependencies - Use `private val` for injected services ### Architecture Patterns - **Controller Layer**: Handle HTTP, delegate to services - **Service Layer**: Business logic, use jOOQ DSLContext for DB - **Database**: jOOQ-generated typesafe code in `build/generated-src/jooq/` ### Database Access - Use jOOQ generated tables: `Tables.HELLO`, `Tables.TASK` - Access records via `dslContext.select().from(Tables.X).fetch...` - Migrations via Liquibase YAML in `src/main/resources/db/changelog/` ## Testing - Framework: JUnit 5 with Spring Boot Test - Run: `./gradlew test` - Native test: `./gradlew nativeTest` ## Database Setup Requires PostgreSQL running locally: - Database: `postgres` - User/Password: `postgres`/`postgres` - URL: `jdbc:postgresql://localhost:5432/postgres` - Port: 5432 ## Common Commands ```bash # Run application ./gradlew bootRun # Build ./gradlew build # Run tests ./gradlew test # Generate jOOQ classes (requires DB to be running) ./gradlew generateJooq # Create native image ./gradlew nativeCompile # Build Docker image ./gradlew bootBuildImage ``` ## Important Notes - **jOOQ code generation**: Requires PostgreSQL to be running - **Security**: Local profile (`local`) disables all auth for development - **Port**: Application runs on port 8081 (not 8080) - **Virtual threads**: Enabled in `application.yaml` ## Adding New Features 1. Create Liquibase migration in `db.changelog-master.yaml` 2. Run `./gradlew generateJooq` to update generated classes 3. Create service class in `service/` package 4. Create controller in `api/` package 5. Write tests following existing patterns