Instruction file imported from JianwenShaw/mediask-be (
.cursor/rules/development-rule.mdc). Copyright stays with the author.
alwaysApply: true description: Java development standards, code standards, DDD domain-driven design layered architecture, architecture design naming conventions, JDK21 features, high cohesion low coupling, ApplicationService, DomainService, Infrastructure layer, DAL layer, Request DTO VO DO, Utils, Helper, code style, best practices. IMPORTANT: You must be able to understand and respond to user queries in both English and Chinese. When users ask questions in Chinese, respond in clear, fluent Chinese.
Project Architecture
Layered Architecture (DDD)
This project adopts DDD (Domain-Driven Design) layered architecture with the following module division:
mediask-api # API Layer - REST controllers, request/response, parameter validation
mediask-service # Application Service Layer - business orchestration, use case implementation, Request/DTO conversion
mediask-domain # Domain Layer - entities, value objects, domain services, repository interfaces (core business logic)
mediask-infra # Infrastructure Layer - repository implementations, cache, distributed locks, file storage, AI clients
mediask-dal # Data Access Layer - DO entities, Mapper interface definitions
mediask-common # Common Layer - utility classes, constants, exceptions, unified responses
Dependency Rules (Strictly Follow)
API → Service → Domain
↓ ↓
Common Infra → Domain, DAL, Common
↓
DAL → Common
Key Constraints:
- ✅ API layer can only depend on Service layer and Common layer
- ✅ Service layer can only depend on Domain layer, Infra layer and Common layer
- ✅ Domain layer can only depend on Common layer (core business logic, no infrastructure dependencies)
- ✅ Infra layer implements Domain layer repository interfaces, depends on Domain, DAL, Common
- ✅ DAL layer only contains DO and Mapper, depends on Common layer
- ❌ Cross-layer dependencies are prohibited (e.g., API directly depends on Domain or Infra)
- ❌ Circular dependencies are prohibited
Naming Conventions (Enforced)
Application Layer Naming
| Layer | Type | Naming Convention | Examples |
|---|---|---|---|
| API Layer | HTTP Request Object | XxxRequest |
LoginRequest, RegisterRequest |
| API Layer | HTTP Response Object | XxxResponse |
LoginResponse, CurrentUserResponse |
| Service Layer | Application Request Object | XxxRequest |
LoginRequest, CreateScheduleRequest |
| Service Layer | Application Response Object | XxxDTO |
LoginResponseDTO, CurrentUserDTO |
| Domain Layer | Domain Service | XxxDomainService |
AutoScheduleDomainService |
| Domain Layer | Domain Entity | Business Name | DoctorSchedule, AppointmentSlot |
| Domain Layer | Value Object | Business Name | DoctorId, TimePeriod, ScheduleStatus |
| DAL Layer | Data Object | XxxDO |
UserDO, DoctorScheduleDO |
| DAL Layer | Mapper | XxxMapper |
UserMapper, DoctorScheduleMapper |
| Infra Layer | Repository Implementation | XxxRepositoryImpl |
DoctorScheduleRepositoryImpl |
| Infra Layer | Converter | XxxConverter |
ScheduleConverter |
| Common Layer | Utility Class | XxxUtils |
DateUtils, StringUtils |
| Common Layer | Helper Class | XxxHelper |
EncryptHelper, ValidationHelper |
Common Object Type Descriptions
| Type | Full Name | Purpose | Naming Convention | Examples |
|---|---|---|---|---|
| DTO | Data Transfer Object | Objects that transfer data between layers, no business logic | XxxDTO |
LoginResponseDTO, UserInfoDTO |
| VO | View Object | Used for passing data from UI layer to application layer, essentially a type of DTO. Note: Do not confuse with DDD's Value Object | XxxVO |
UserInfoVO, DoctorDetailVO |
| DO | Data Object | Database table mapping object (this project uses DO, not PO) | XxxDO |
UserDO, DoctorScheduleDO |
| PO | Persistence Object | Persistence object (traditional naming, this project uniformly uses DO) | - | - |
| Utils | - | Utility class providing static methods | XxxUtils |
DateUtils, StringUtils |
| Helper | - | Helper class that assists with certain operations | XxxHelper |
EncryptHelper, ValidationHelper |
Important Notes
-
Request vs Command:
- ✅ Use
Request(more aligned with traditional DDD practices) - ❌ Do not use
Command(unless explicitly adopting CQRS pattern)
- ✅ Use
-
DTO vs VO:
- Service layer output uses
DTO(Data Transfer Object) - API layer output uses
ResponseorVO(View Object) - Note: VO is View Object, do not confuse with DDD's Value Object
- Service layer output uses
-
DO vs PO:
- This project uniformly uses
DO(Data Object) as database table mapping objects - Do not use
PO(Persistence Object) naming - DO is placed in DAL layer, uses MyBatis-Plus annotations
- This project uniformly uses
-
Utils vs Helper:
Utils: Utility classes providing static methods, usually statelessHelper: Helper classes that may contain state or more complex logic- Both are placed in Common layer
-
Domain Service Naming:
- Domain services use
XxxDomainServicesuffix to distinguish from application services - Application services use
XxxApplicationServicesuffix
- Domain services use
Code Style
Reference Documentation
Please strictly refer to the code style documentation:
/home/ethan/dev/mediask-be/MediAskDocs/docs/02-CODE_STANDARDS.md
Core Principles
- Clear Naming: Variable, method, and class names must clearly express business meaning, abbreviations and pinyin are prohibited
- Single Responsibility: Each class and method does one thing only
- High Cohesion Low Coupling: Related functionality is aggregated, module dependencies are minimized
- Elegant and Concise: Code should be readable and maintainable, avoid over-engineering
JDK 21 Features Usage Guide
Recommended Features
-
Record Classes: For immutable data transfer objects
public record LoginResponseDTO(Long userId, String username, String token) {} -
Pattern Matching: Switch expressions and pattern matching
return switch (userType) { case ADMIN -> List.of("schedule:create", "schedule:update"); case DOCTOR -> List.of("schedule:update"); case PATIENT -> Collections.emptyList(); }; -
Text Blocks: Multi-line strings
String sql = """ SELECT * FROM users WHERE id = ? """; -
Sealed Classes: Restrict class inheritance (for value objects or enum extensions)
-
var Keyword: Local variable type inference (use moderately, maintain readability)
Virtual Threads Notes ⚠️
-
Database Connection Pool:
- MySQL driver may have performance degradation in virtual thread environment
- Use traditional thread pool for database operations, avoid virtual threads
- Connection pool size needs to be adjusted based on actual situation
-
I/O Intensive Operations:
- File operations and network requests can use virtual threads
- But actual performance needs to be verified
-
Principle: Performance first, don't blindly use new features
DDD Development Guidelines
Domain Layer
-
Entity:
- Contains business identity and business logic
- Created through factory methods or constructors
- Encapsulates business rules, does not expose internal state
-
Value Object:
- Immutable, equality determined by value
- Implemented using Record or final class
-
Domain Service:
- Handles business logic across entities
- Naming:
XxxDomainService - Does not depend on infrastructure, only depends on domain objects and Common
-
Repository Interface:
- Defined in Domain layer
- Uses domain objects as parameters and return values
- Implementation is placed in Infra layer
Application Layer
-
Application Service:
- Coordinates domain services and repositories to complete use cases
- Manages transaction boundaries
- Handles Request/DTO conversion
- Naming:
XxxApplicationService
-
Request/DTO:
- Request: Application layer input parameters (
XxxRequest) - DTO: Application layer output objects (
XxxDTO) - Placed in
application/requestandapplication/dtopackages
- Request: Application layer input parameters (
Infrastructure Layer
-
Repository Implementation:
- Implements Domain layer repository interfaces
- Uses MyBatis-Plus or JPA
- Conversion between DO and domain objects
-
Infrastructure Components:
- Redis configuration, distributed locks
- File storage, AI clients
- JWT service, password encoder
- All technical implementation details
Data Access Layer (DAL)
-
DO (Data Object):
- Database table mapping object (equivalent to traditional PO)
- Uses MyBatis-Plus annotations
- Naming:
XxxDO - Note: This project uniformly uses DO, does not use PO naming
-
Mapper:
- MyBatis Mapper interface
- Only contains data access methods
- Does not contain business logic
Common Layer
-
Utility Classes (Utils):
- Utility classes providing static methods
- Usually stateless
- Naming:
XxxUtils - Examples:
DateUtils,StringUtils,CollectionUtils
-
Helper Classes:
- Helper classes that assist with certain operations
- May contain state or more complex logic
- Naming:
XxxHelper - Examples:
EncryptHelper,ValidationHelper,FileHelper
Spring Security Component Layering
-
API Layer:
SecurityConfig- Web security configurationJwtAuthenticationFilter- JWT authentication filter- Exception handlers (
JwtAuthenticationEntryPoint,JwtAccessDeniedHandler)
-
Infra Layer:
PasswordEncoderConfig- Password encoder configurationJwtService- JWT serviceJwtProperties- JWT configuration properties
-
Service Layer:
- Uses
PasswordEncoderthrough dependency injection (does not directly depend on Spring Security)
- Uses
Code Quality Requirements
-
Exception Handling:
- Use project's unified exception system (
BizException) - Do not swallow exceptions, log them
- Exception messages should be clear for troubleshooting
- Use project's unified exception system (
-
Logging Standards:
- Use SLF4J + Logback
- Record INFO logs for key business operations
- Record ERROR logs for exceptions, include context information
-
Transaction Management:
- Use
@Transactionalon application service methods - Explicitly specify
rollbackFor = Exception.class - Avoid using transaction annotations directly in domain objects
- Use
-
Parameter Validation:
- API layer uses
@Validor@Validated - Service layer uses
AssertUtilfor business validation - Validation failures throw clear business exceptions
- API layer uses
-
Null Value Handling:
- Use
Optionalto handle potentially null values - Avoid
nullpassing, use null object pattern or explicit handling
- Use
Performance Optimization Principles
-
Database Queries:
- Avoid N+1 query problems
- Use indexes appropriately
- Use batch methods for batch operations
-
Caching Strategy:
- Use Redis cache for hot data
- Pay attention to cache penetration, breakdown, and avalanche issues
- Use distributed locks to ensure data consistency
-
Object Conversion:
- Use MapStruct for object conversion (compile-time generation, high performance)
- Avoid manual getter/setter conversion
Prohibited Practices
- ❌ Prohibited to use Spring annotations in Domain layer (except
@Servicefor domain services) - ❌ Prohibited to directly depend on DAL layer in Domain layer
- ❌ Prohibited to directly use Mapper in Service layer (through Repository interface)
- ❌ Prohibited to directly call Domain layer from API layer
- ❌ Prohibited to use abbreviations and pinyin in naming
- ❌ Prohibited to perform database queries in loops
- ❌ Prohibited to ignore exceptions or use empty catch blocks
Best Practices
- Prefer composition over inheritance
- Use dependency injection, avoid hard-coded dependencies
- Keep methods short, single responsibility
- Use meaningful variable and method names
- Refactor promptly, keep code clean
- Write clear comments explaining "why" rather than "what"