# serve Spring Boot 3.5 + Java 17 + MyBatis-Plus + PostgreSQL + JWT auth backend. ## Quick start ```bash # env vars required by application.yaml export databaseHost=localhost databaseUsername=postgres databasePassword=postgres # build & test ./gradlew build # run ./gradlew bootRun # run a single test class ./gradlew test --tests 'space.anyi.serve.ServeApplicationTests' ``` ## Architecture - **Single module**, root package `space.anyi.serve`. - **Entrypoint**: `src/main/java/space/anyi/serve/ServeApplication.java` - **Security**: Stateless JWT in `Authorization: Bearer ` header. Public endpoints: `/auth/login`, `/auth/register`, `/swagger-ui/**`, `/v3/api-docs/**`. Everything else requires auth. Roles: `ROLE_admin`, `ROLE_user`, `ROLE_expert`. Method-level security via `@PreAuthorize`. - **ORM**: MyBatis-Plus `BaseMapper` + `ServiceImpl`. Logical delete field = `deleteFlag`. Mapper XML at `src/main/resources/mapper/`. - **DB**: PostgreSQL, schema `dev`. Credentials from env vars. Druid connection pool. - **API docs**: Swagger UI at `http://localhost:8080/swagger-ui.html` (SpringDoc OpenAPI). - **CORS**: Allows `http://localhost:5173` (Vite dev server). - **Exception handling**: `GlobalExceptionHandler` returns `Response` JSON (`code`, `message`, `data`). - **Pagination**: `PageVo` wraps MyBatis-Plus `Page`. ## Conventions - `@PreAuthorize("hasRole('admin')")` for admin-only endpoints. - `application.yaml` uses `${placeholder}` for secrets; never hardcode credentials. - SQL logging to stdout via MyBatis-Plus `log-impl: StdOutImpl`. - Actuator endpoints fully exposed (`management.endpoints.web.exposure.include: "*"`). - **No `/api` prefix**: Controller `@RequestMapping` paths must NOT use `/api/` prefix (e.g., `"posts"`, `"wallet"`, not `"api/posts"`). - **API contracts**: Request bodies must be DTO classes (in `entity/*/`), not `Map`. Responses must be VO classes (in `entity/*/`), not `Map`. - **OpenAPI**: Every DTO and VO class must have `@Schema(description = "...")`. Every DTO field must have `@Schema` and `jakarta.validation` annotations (`@NotBlank`, `@NotNull`, `@Size`, etc.) with Chinese `message`. - **Controller return types**: Always use `Response` with a concrete generic type (DTO or VO). Never raw `Response` or `Response>`. - No Dockerfile, no CI, no Makefile.