|
|
@@ -1,184 +1,115 @@
|
|
|
-# AGENTS.md - Development Guidelines for LXQ Spring Boot Application
|
|
|
+# AGENTS.md - LXQ Spring Boot Development Guidelines
|
|
|
|
|
|
## Project Overview
|
|
|
-Java Spring Boot enterprise application (v3.5.9, Java 21) with microservices architecture. Multi-module Maven project using MyBatis-Plus, Redis, RocketMQ, OAuth2, and Swagger for API documentation.
|
|
|
+Java 21, Spring Boot 3.5.9, Maven multi-module project with MyBatis-Plus, Redis, RocketMQ, OAuth2.
|
|
|
|
|
|
-## Development Environment Setup
|
|
|
+## Essential Commands
|
|
|
```bash
|
|
|
-# Start required services with Docker Compose
|
|
|
-docker-compose up -d lxq-mysql lxq-redis
|
|
|
-
|
|
|
-# Install Maven if not available (required for build commands)
|
|
|
-# Download from: https://maven.apache.org/download.cgi
|
|
|
-
|
|
|
-# IDE Configuration
|
|
|
-# Install Spring Java Format IntelliJ plugin:
|
|
|
-# https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin
|
|
|
+# Build & Run
|
|
|
+mvn clean compile # Compile
|
|
|
+mvn clean package # Package JAR
|
|
|
+mvn spring-boot:run # Run application
|
|
|
+mvn clean install # Install to local repo
|
|
|
+
|
|
|
+# Testing
|
|
|
+mvn test # Run all tests
|
|
|
+mvn test -Dtest=ClassName # Single test class
|
|
|
+mvn test -Dtest=ClassName#methodName # Single test method
|
|
|
+
|
|
|
+# Code Quality
|
|
|
+mvn spring-javaformat:apply # Format code (MANDATORY before commits)
|
|
|
+mvn validate # Check format during build
|
|
|
+
|
|
|
+# Environment builds
|
|
|
+mvn clean package -Pdev # Development (default)
|
|
|
+mvn clean package -Ptest # Test environment
|
|
|
+mvn clean package -Pprod # Production
|
|
|
```
|
|
|
|
|
|
-## Build & Package Commands
|
|
|
-```bash
|
|
|
-# Standard Maven commands (when Maven available)
|
|
|
-mvn clean compile # Compile the project
|
|
|
-mvn clean package # Package the application
|
|
|
-mvn clean install # Install to local repository
|
|
|
-mvn spring-boot:run # Run the application
|
|
|
-mvn test # Run all tests
|
|
|
-mvn spring-javaformat:apply # Format code (MANDATORY before commits)
|
|
|
-
|
|
|
-# Environment-specific builds
|
|
|
-mvn clean package -Pdev # Development build (default)
|
|
|
-mvn clean package -Ptest # Test environment build
|
|
|
-mvn clean package -Pprod # Production build
|
|
|
-
|
|
|
-# Run single test (when tests exist)
|
|
|
-mvn test -Dtest=ClassName#methodName
|
|
|
-mvn test -Dtest=ClassName
|
|
|
-
|
|
|
-# Code formatting validation (runs automatically during validate phase)
|
|
|
-mvn validate # Check code format
|
|
|
+## Code Style
|
|
|
+- **Formatter**: Spring Java Format plugin (v0.0.39) - REQUIRED before commits
|
|
|
+- **Indentation**: 4 spaces, no tabs
|
|
|
+- **Line endings**: LF (Unix)
|
|
|
+- **Max line length**: 120 chars
|
|
|
+- **No wildcard imports**
|
|
|
+- **Line comments only** (no block comments)
|
|
|
+
|
|
|
+## Naming Conventions
|
|
|
+| Element | Convention | Examples |
|
|
|
+|---------|------------|----------|
|
|
|
+| Class/Interface | PascalCase | `SysUserController`, `UserDTO` |
|
|
|
+| Method/Variable | camelCase | `getUserById`, `saveUser()` |
|
|
|
+| Constant | UPPER_SNAKE_CASE | `DEFAULT_PAGE_SIZE`, `COMMON_STATUS` |
|
|
|
+| Package | `com.lxq.{module}.biz.{layer}` | `com.lxq.admin.biz.controller` |
|
|
|
+
|
|
|
+## Architecture Layers
|
|
|
```
|
|
|
-
|
|
|
-## Code Style & Formatting Guidelines
|
|
|
-- **MANDATORY**: Spring Java Format plugin (v0.0.39) - must run before commits
|
|
|
-- **Package naming**: `com.lxq.*` convention (e.g., `com.lxq.admin.biz.controller`)
|
|
|
-- **Import organization**: Standard Java conventions, no wildcard imports
|
|
|
-- **Class naming**: PascalCase (e.g., `SysUserController`, `UserDTO`)
|
|
|
-- **Method naming**: camelCase (e.g., `getUserById`, `saveUser`)
|
|
|
-- **Constants**: UPPER_SNAKE_CASE (e.g., `COMMON_STATUS`, `DEFAULT_PAGE_SIZE`)
|
|
|
-- **Variables**: camelCase
|
|
|
-- **Lombok usage**: `@Data`, `@AllArgsConstructor`, `@Slf4j` for boilerplate reduction
|
|
|
-- **Line endings**: Use LF (Unix style)
|
|
|
-- **Indentation**: 4 spaces (no tabs)
|
|
|
-- **Max line length**: 120 characters
|
|
|
-
|
|
|
-## Architecture & Layer Patterns
|
|
|
+com.lxq.{module}.biz.controller/ # REST endpoints
|
|
|
+com.lxq.{module}.biz.service/ # Business logic
|
|
|
+com.lxq.{module}.biz.mapper/ # Data access
|
|
|
+com.lxq.{module}.biz.model/ # Entities
|
|
|
+com.lxq.{module}.biz.domain.dto/ # Input DTOs
|
|
|
+com.lxq.{module}.biz.domain.vo/ # Response VOs
|
|
|
```
|
|
|
-com.lxq.admin.biz.controller/ # REST endpoints (@RestController)
|
|
|
-com.lxq.system.biz.service/ # Business logic (extends IService<Entity>)
|
|
|
-com.lxq.system.biz.mapper/ # MyBatis data access (extends BaseMapper<Entity>)
|
|
|
-com.lxq.system.biz.model/ # Entity classes (@TableName)
|
|
|
-com.lxq.system.biz.domain.dto/ # Data transfer objects (@Data, @Schema)
|
|
|
-com.lxq.system.biz.domain.vo/ # View objects for API responses
|
|
|
+
|
|
|
+## Layer Patterns
|
|
|
+- **Controllers**: `@RestController`, `@AllArgsConstructor`, return `R<T>`
|
|
|
+- **Services**: Extend `IService<Entity>`, use `@SysLog`
|
|
|
+- **Mappers**: Extend `BaseMapper<Entity>`
|
|
|
+- **DTOs**: `@Data`, `@Schema`, extend Entity when appropriate
|
|
|
+- **VOs**: `@Data`, `@Schema` for API responses
|
|
|
+
|
|
|
+## Database & ORM
|
|
|
+```java
|
|
|
+@TableName("table_name")
|
|
|
+@TableId(type = IdType.AUTO)
|
|
|
+public class Entity { } // del_flag for logical deletion
|
|
|
+
|
|
|
+// Query with type-safe wrapper
|
|
|
+Wrappers.<Entity>query().lambda()
|
|
|
+ .eq(Entity::getField, value)
|
|
|
+ .orderByDesc(Entity::getCreateTime);
|
|
|
```
|
|
|
+- **Dynamic Datasource**: `@DS("datasource_name")`
|
|
|
+- **Joins**: Use MyBatis-Plus-Join library
|
|
|
|
|
|
-**Layer Structure**: Controller → Service → Mapper → Domain
|
|
|
-- **Controllers**: Use `@RestController`, `@RequestMapping`, `@AllArgsConstructor`
|
|
|
-- **Services**: Extend `IService<Entity>` from MyBatis-Plus
|
|
|
-- **Mappers**: Extend `BaseMapper<Entity>` from MyBatis-Plus
|
|
|
-- **DTOs**: Separate from entities, extend entity when appropriate
|
|
|
-- **VOs**: For API responses, use Lombok `@Data`
|
|
|
-
|
|
|
-## API Documentation Standards
|
|
|
-- **Framework**: Swagger/OpenAPI 3 with Knife4j v4.3.0
|
|
|
-- **Required Annotations**:
|
|
|
- ```java
|
|
|
- @Tag(description = "module", name = "description") // On class
|
|
|
- @Operation(summary = "action", description = "details") // On methods
|
|
|
- @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) // For secured APIs
|
|
|
- ```
|
|
|
-- **Parameter Documentation**: Use `@ParameterObject` for query parameters
|
|
|
-- **Response Documentation**: Use `@Schema(description = "...")` on DTOs/VOs
|
|
|
-- **Swagger UI**: Available at `/doc.html` when `swagger.enabled=true`
|
|
|
-- **Example**: See `SysUserController.java` for complete annotation patterns
|
|
|
-
|
|
|
-## Database & ORM Guidelines
|
|
|
-- **ORM**: MyBatis-Plus v3.5.15 with Spring Boot 3 integration
|
|
|
-- **Entity Conventions**:
|
|
|
- ```java
|
|
|
- @TableName("sys_user") // Table mapping
|
|
|
- @TableId(type = IdType.AUTO) // Auto ID generation
|
|
|
- // Logical deletion: del_flag (0=not deleted, 1=deleted)
|
|
|
- ```
|
|
|
-- **Mapper Patterns**: Extend `BaseMapper<Entity>` from MyBatis-Plus
|
|
|
-- **Service Patterns**: Extend `IService<Entity>` from MyBatis-Plus
|
|
|
-- **Dynamic Datasource**: Use `@DS("datasource_name")` annotation
|
|
|
-- **Query Builder**: Use `Wrappers.<Entity>query().lambda()` for type-safe queries
|
|
|
-- **Join Queries**: Use MyBatis-Plus-Join for complex queries
|
|
|
-- **Logical Deletion**: Automatically handled (del_flag: 0/1)
|
|
|
-
|
|
|
-## Security & Authorization
|
|
|
-- **Framework**: Spring Authorization Server v1.1.2 with OAuth2
|
|
|
-- **Security Annotations**:
|
|
|
- ```java
|
|
|
- @PreAuthorize("@pms.hasPermission('permission_key')") // Method security
|
|
|
- @Inner // Internal APIs (bypass OAuth2)
|
|
|
- @EnableLoginResourceServer / @EnableAuthResourceServer // Configuration
|
|
|
- ```
|
|
|
-- **Security Utilities**: `SecurityUtils.getUser()` for current user info
|
|
|
-- **Permission Format**: `module_action` (e.g., `sys_user_add`, `sys_user_del`)
|
|
|
-- **Token Handling**: Automatic via resource server configuration
|
|
|
-- **Public Endpoints**: Configure in `security.oauth2.ignore.urls`
|
|
|
-
|
|
|
-## Testing Guidelines
|
|
|
-- **Framework**: Spring Boot Test (`spring-boot-starter-test`)
|
|
|
-- **Test Structure**: Create `src/test/java` following main package structure
|
|
|
-- **Test Naming**: `*Test.java` for test classes (e.g., `SysUserServiceTest`)
|
|
|
-- **Key Annotations**: `@SpringBootTest`, `@Test`, `@MockBean`, `@ExtendWith`
|
|
|
-- **Single Test Execution**: `mvn test -Dtest=ClassName#methodName`
|
|
|
-- **Integration Tests**: Use `@SpringBootTest` with test configuration
|
|
|
-- **Service Testing**: Mock dependencies with `@MockBean`
|
|
|
-- **Note**: No test directories currently exist - create following package structure
|
|
|
-
|
|
|
-## Error Handling & Logging
|
|
|
-- **Response Wrapper**: Always return `R<T>` from controllers
|
|
|
- ```java
|
|
|
- return R.ok(data); // Success response
|
|
|
- return R.failed("error"); // Error response
|
|
|
- return R.failed(errorEnum); // Error with enum
|
|
|
- ```
|
|
|
-- **Logging**: Use `@SysLog("operation description")` on service methods
|
|
|
-- **Exception Handling**: Use global exception handler with `@RestControllerAdvice`
|
|
|
-- **Logging Framework**: SLF4J with `@Slf4j` annotation
|
|
|
-- **Audit Trail**: `@SysLog` automatically logs business operations
|
|
|
-
|
|
|
-## Configuration Management
|
|
|
-- **Main Config**: `application.yml` in admin module
|
|
|
-- **Environment Files**: `application-{profile}.yml` (dev/test/prod)
|
|
|
-- **Property Injection**: Use `@ConfigurationProperties`
|
|
|
-- **Profile Activation**: `spring.profiles.active=@profiles.active@`
|
|
|
-- **Database Config**: Dynamic datasource with primary/main setup
|
|
|
-- **Swagger Config**: Customizable via `swagger.*` properties
|
|
|
-- **Server Config**: Port 8080, context path `/v1/admin`
|
|
|
-
|
|
|
-## Common Patterns & Examples
|
|
|
-
|
|
|
-### Controller Method Template
|
|
|
+## API Documentation (Knife4j/Swagger)
|
|
|
```java
|
|
|
-@SysLog("操作描述")
|
|
|
-@PostMapping("/action")
|
|
|
-@PreAuthorize("@pms.hasPermission('module_action')")
|
|
|
-@Operation(summary = "操作", description = "详细描述")
|
|
|
-public R<ResultVO> action(@Valid @RequestBody RequestDTO request) {
|
|
|
- return R.ok(service.action(request));
|
|
|
-}
|
|
|
+@Tag(description = "module", name = "description") // Class
|
|
|
+@Operation(summary = "action", description = "details") // Method
|
|
|
+@ParameterObject // Query params
|
|
|
+@Schema(description = "...") // Fields
|
|
|
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) // Secured APIs
|
|
|
```
|
|
|
|
|
|
-### DTO Template
|
|
|
+## Security
|
|
|
```java
|
|
|
-@Data
|
|
|
-@Schema(description = "对象描述")
|
|
|
-@EqualsAndHashCode(callSuper = true)
|
|
|
-public class EntityDTO extends Entity {
|
|
|
- @Schema(description = "字段描述")
|
|
|
- private String field;
|
|
|
-}
|
|
|
+@PreAuthorize("@pms.hasPermission('module_action')") // Permission check
|
|
|
+@Inner // Internal API (bypass OAuth2)
|
|
|
+SecurityUtils.getUser() // Current user info
|
|
|
```
|
|
|
+- Permission format: `module_action` (e.g., `sys_user_add`)
|
|
|
|
|
|
-### Query Template
|
|
|
+## Error Handling
|
|
|
```java
|
|
|
-Entity entity = service.getOne(Wrappers.<Entity>query()
|
|
|
- .lambda()
|
|
|
- .eq(Entity::getField, value)
|
|
|
- .orderByDesc(Entity::getCreateTime));
|
|
|
+return R.ok(data); // Success
|
|
|
+return R.failed("error message"); // Error
|
|
|
+return R.failed(ErrorEnum); // Error with enum
|
|
|
+
|
|
|
+@Slf4j // Logger
|
|
|
+@RestControllerAdvice // Global exception handler
|
|
|
```
|
|
|
|
|
|
-## Key Requirements Summary
|
|
|
+## Key Requirements
|
|
|
1. **ALWAYS** run `mvn spring-javaformat:apply` before commits
|
|
|
-2. **ALWAYS** return `R<T>` from controller methods
|
|
|
-3. **ALWAYS** use `@PreAuthorize` for security checks
|
|
|
+2. **ALWAYS** return `R<T>` from controllers
|
|
|
+3. **ALWAYS** use `@PreAuthorize` for security
|
|
|
4. **ALWAYS** document APIs with Swagger annotations
|
|
|
5. **FOLLOW** Controller → Service → Mapper pattern
|
|
|
6. **USE** DTOs for input, VOs for output
|
|
|
-7. **APPLY** `@SysLog` for business operations
|
|
|
-8. **USE** MyBatis-Plus Wrappers for type-safe queries
|
|
|
+7. **USE** `@SysLog` for business operations
|
|
|
+
|
|
|
+## Configuration
|
|
|
+- Main config: `lxq-admin/src/main/resources/application.yml`
|
|
|
+- Profiles: `application-{dev|test|prod}.yml`
|
|
|
+- Server: Port 8080, context path `/v1/admin`
|