Files
aplp.backend.web/docs/CONVENTIONS.md
T
2026-08-22 08:29:30 +07:00

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 (xem ARCHITECTURE.md).
  • Tên class theo responsibility:
    • Controller: XxxController
    • Use case: XxxUseCase hoặc XxxService
    • Request/Response DTO: XxxRequest, XxxResponse
    • Aggregate/Root: tên domain concept (vd Learner, Course)
    • Repository interface: XxxRepository (định nghĩa ở domain)

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 (@Transactional trê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 validationapi layer (bean validation trên DTO).
  • Business invariant trong domain (domain exception).
  • Response lỗi dùng format đồng nhất (vd ApiError với code + message).

5. Errors & Exceptions

  • DomainException cho lỗi business; mapping sang HTTP status ở api layer.
  • 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 ErrorCodecommon/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/api response.
  • 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)