Files
2026-09-15 23:08:38 +07:00

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.