3.9 KiB
3.9 KiB
APLP Backend — Conventions
| Status | Draft |
1. Naming & Package
- Base package:
com.aplp.backend - Mỗi module:
com.aplp.backend.<module>.<layer>với layer =api | application | domain | persistence(xemARCHITECTURE.md). - Tên class theo responsibility:
- Controller:
XxxController - Use case:
XxxUseCasehoặcXxxService - Request/Response DTO:
XxxRequest,XxxResponse - Aggregate/Root: tên domain concept (vd
Learner,Course) - Repository interface:
XxxRepository(định nghĩa ở domain)
- Controller:
2. Layer Rules
| Layer | Được phép | Cấm |
|---|---|---|
api |
AuthN/authorization (framework), input validation, DTO mapping | Business rules |
application |
Orchestrate use case, transaction, call domain/persistence | Nhúng business rules riêng |
domain |
Business logic, invariants, domain services, repository interface | Spring/JPA/HTTP dependencies |
persistence |
Repository impl, JPA entities, mappers | Business logic |
- Domain không import Spring/JPA/HTTP.
- Persistence entities tách biệt (hoặc mappers) khỏi domain model nếu cần.
3. Transaction
- Transaction mở ở Application layer (
@Transactionaltrên use case/service). - Không ném transaction qua domain khi chỉ để đọc.
- Repository phương thức read nên read-only transaction khi cần.
4. Validation
- Input/API validation ở
apilayer (bean validation trên DTO). - Business invariant trong
domain(domain exception). - Response lỗi dùng format đồng nhất (vd
ApiErrorvới code + message).
5. Errors & Exceptions
DomainExceptioncho lỗi business; mapping sang HTTP status ởapilayer.- Error response nhất quán:
code,message,details(tuỳ thỏa thuận). - Kèm
traceId/requestId để dễ debug (Phase 0). - Error code dùng global enum
ErrorCodeởcommon/api(kèm HTTP status); mở rộng bằng cách thêm hằng số khi có module mới.
6. DTO Mapping
- Không để JPA entity lọt ra ngoài
persistence/apiresponse. - Mapping thủ công (static method) trong repository impl / DTO factory — quyết định ở Phase 0 (không dùng MapStruct cho giai đoạn này; thêm khi có justification).
7. Repository
- Interface repository của module ở
domain; implementation ởpersistence. - Chỉ expose các method cần thiết cho use case, không leek Query/spec toàn module.
- Query đặc thù (search, aggregation) nằm trong repository implementation.
8. Domain Events (khi cần)
- Dùng để tách rời side-effect giữa module (vd assessment hoàn thành → cập nhật adaptive state).
- Không lạm dụng: nếu đồng bộ đơn giản và cùng transaction, gọi trực tiếp qua interface.
- Nếu dùng Spring events: publish ở application layer, không trong domain.
9. Config & Secrets
- Cấu hình theo environment (
application.yml, profile dev/prod). - Không commit secret/key vào repo. Dùng env vars hoặc bí quyết quản lý (vault) khi có.
- Không log secret/token/password.
10. Testing
- Unit test cho
domain+application. - Test repository/persistence khi cần.
- Integration test cho API layer.
- Quyết định framework/test DB ở Phase 0.
11. Code Style
- Java theo tiêu chuẩn project (indent 4 spaces — xác nhận khi setup).
- Code của backend không comment thừa; tên rõ nghĩa.
@author/metadata không bắt buộc.
12. Open Questions
| ID | Question | Status |
|---|---|---|
| CON-001 | Dùng MapStruct hay mapping thủ công? | Resolved: thủ công (Phase 0) |
| CON-002 | Error code convention (enum per module vs global)? | Resolved: global ErrorCode trong common/api |
| CON-003 | JPA entities tách hay dùng chung domain model? | Resolved: tách riêng (*JpaEntity trong persistence, domain model trong domain) |