56 lines
3.3 KiB
Markdown
56 lines
3.3 KiB
Markdown
# AGENTS.md
|
|
|
|
Spring Boot **4.1.0** / Java 17 REST backend for an LMS (PostgreSQL). Root package `aplp.backend.lms`.
|
|
|
|
## Commands
|
|
|
|
- Build: `./mvnw -DskipTests package`
|
|
- Run: `./mvnw spring-boot:run`
|
|
- All tests: `./mvnw test`
|
|
- Single test: `./mvnw test -Dtest=LmsApplicationTests`
|
|
- Requires JDK 17. No linter, formatter, or checkstyle is configured — don't invent one.
|
|
|
|
## Build gotcha: GitLab Maven registry
|
|
|
|
`aplp.backend:core:1.0-SNAPSHOT` is not built here; it resolves from the GitLab package registry (repository id `gitlab-maven` in `pom.xml`). A fresh checkout needs a token for server id `gitlab-maven` in `~/.m2/settings.xml` (or the artifact cached in `~/.m2/repository`). Credentials are not in the repo.
|
|
|
|
## `aplp.backend.core` shared types
|
|
|
|
Not defined in this repo; import them instead of recreating:
|
|
|
|
- `BaseEntity` — `@MappedSuperclass` for every entity: `id`, `createdAt/By`, `updatedAt/By`, `deletedAt/By`; timestamps set via `@PrePersist`/`@PreUpdate`.
|
|
- `ApiResponse<T>` — `ok(data)`, `ok(message, data)`, `error(code, message)`.
|
|
- `PagedResponse<T>` — `of(content, page, size, totalElements)`.
|
|
- `ErrorCode`, `DomainException`, `ResourceNotFoundException`, `TokenHasher.sha256Hex`.
|
|
|
|
## Architecture
|
|
|
|
Vertical slices per feature under `aplp.backend.lms.<feature>` (currently `course`, `lesson`, `section`); `common/` holds cross-cutting `api`, `config`, `security`. Layers per feature:
|
|
|
|
- `api/controller` — `@RestController`, returns `ResponseEntity<ApiResponse<...>>`
|
|
- `application/services`, `application/dtos` (Java records), `application/mappers` (MapStruct)
|
|
- `domain/entities`, `domain/enums`, `domain/repositories` (plain interfaces)
|
|
- `infrastructure/persistence` — `*RepositoryImpl` implements the domain repo and delegates to a Spring Data `*JpaRepository`
|
|
|
|
Conventions:
|
|
|
|
- Entities extend `BaseEntity`, use Lombok `@Getter/@Setter/@NoArgsConstructor`, `@Table` snake_case.
|
|
- Controllers stay thin; services throw `ResourceNotFoundException`; `GlobalExceptionHandler` maps exceptions to `ApiResponse`.
|
|
- Mappers are interfaces annotated `@Mapper(componentModel = "spring")`; Lombok/MapStruct annotation processing is already wired in `pom.xml`.
|
|
- Add derived queries to `*JpaRepository` and expose them through the domain repo interface.
|
|
|
|
## Database
|
|
|
|
- PostgreSQL, Hibernate default schema `lms`; datasource hardcoded in `src/main/resources/application.yaml`.
|
|
- **`spring.flyway.enabled: false` + `spring.jpa.hibernate.ddl-auto: update`**: Hibernate maintains the schema at runtime. Scripts in `db/migration` (`V{n}__desc.sql`) are history only and are NOT applied on startup. A schema change needs both the entity field and a migration; don't assume Flyway runs.
|
|
- jsonb columns use `@JdbcTypeCode(SqlTypes.JSON)` on a `String` field.
|
|
|
|
## Security
|
|
|
|
- `SecurityConfig` disables CSRF and `permitAll`s every request — endpoints are currently unauthenticated despite OpenAPI declaring a `bearerAuth` JWT scheme (Swagger UI at `/swagger-ui`).
|
|
- `JpaAuditingConfig` reads the current user from `SecurityContextHolder` and expects `Authentication.getPrincipal()` to be a `Long` userId.
|
|
|
|
## Testing
|
|
|
|
Only `LmsApplicationTests` (`@SpringBootTest contextLoads`) exists. There is no `src/test/resources` or test profile, so tests use the real `application.yaml` datasource and require access to the remote DB — `./mvnw test` fails without it.
|