# APLP Backend — Architecture | | | | --- | --- | | **Module** | `aplp.backend.spring` | | **Role** | Backend cho **aplp-web** (learner application) | | **Status** | Draft | --- ## 1. Architectural Direction Backend theo **Modular Monolith**, kết hợp: ``` Modular Monolith + Clean Architecture 4 Layers + DDD-oriented + Vertical Slice / Business Module ``` Nguyên tắc nền tảng: > **Business behavior first, database second.** > **Modular Monolith first; extract service chỉ khi có demonstrated need.** ## 2. Request Flow ``` Controller (API layer) ↓ Application / Service (use case) ↓ Domain (business rules / model) ↓ Persistence (repository) ↓ Database ``` ## 3. Clean Architecture — 4 Layers Mỗi business module có 4 layer rõ ràng: | Layer | Trách nhiệm | Should NOT do | | --- | --- | --- | | **Interface/API** | HTTP entry point, DTO request/response, validation cơ bản, tách biệt khỏi domain | Chứa business logic | | **Application** | Use case orchestration, transactions, authorization | Chứa domain business rules | | **Domain** | Entities, value objects, business rules, domain services | Phụ thuộc DB/HTTP | | **Persistence** | Repository implementation, mapping, DB access | Chứa business rules | **Dependency rule:** chỉ phụ thuộc từ ngoài vào trong (API → Application → Domain); Persistence implement interface do Domain/Application định nghĩa. ## 4. Modular Monolith - Code tổ chức theo **business module** (vertical slice), không theo technical layer toàn cục. - Mỗi module đóng gói `interface + application + domain + persistence` cho một business capability. - Module giao tiếp qua public API/interface; **không** import nội bộ module khác. - Module registry/config ở application root. ### Module Boundary ``` com.aplp.backend └── (vd: identity, learner, content, learning, assessment, adaptive, ...) ├── api (controller, dto) ├── application (use case, service) ├── domain (model, domain service, rules, repository interface) └── persistence (repository impl, entity mapping, jpa) ``` ## 5. DDD Orientation - **Aggregate** là ranh giới bảo toàn bất biến (invariant) trong cùng transaction. - **Value Objects** dùng cho khái niệm không có identity riêng (Score, Money, MasteryLevel). - **Domain Event** (optional, temporal) dùng khi cần tách rời side-effect giữa modules — **không** lạm dụng cho tất cả luồng. - **Repository interface** ở domain, implementation ở persistence. ## 6. Database - Relational database: **PostgreSQL** (chosen). Dev chạy qua `docker-compose` (port 5433); test dùng H2 (PostgreSQL mode). - Migrations: **Flyway** (chosen) tại `src/main/resources/db/migration`. `spring.jpa.hibernate.ddl-auto=validate`. - Schema phản ánh domain model, không thiết kế "database-first". ## 7. Cross-Cutting Concerns - **Security / AuthN**: xử lý ở API/boundary layer (Phase 0). - **Validation**: input validation ở API; business invariant validation ở domain. - **Logging & Observability**: structured logging, common config (Phase 9 mở rộng metrics/tracing). - **Errors**: exception mapping, đồng nhất response format. ## 8. Deferred (tránh dùng khi chưa có justification) - Microservices split - API Gateway - Kafka / Event-driven - Redis - Elasticsearch - CQRS / Event Sourcing ## 9. Deployment - **Docker first** (containerize backend). - **Kubernetes later** khi có nhu cầu scale/ops. ## 10. Open Questions (backend-specific) | ID | Question | Impact | Proposed Direction | Status | | --- | --- | --- | --- | --- | | ARC-001 | Spring Boot version nào cho foundation? | Setup | Dùng phiên bản ổn định mới nhất hỗ trợ Java LTS | **Resolved**: Spring Boot 3.5.16 + Java 21 (Maven) | | ARC-002 | JWT hay session cho authentication? | Security | JWT stateless + refresh flow | **Resolved**: JWT (access + rotating refresh, refresh token hash lưu DB) | | ARC-003 | DB: PostgreSQL vs MySQL? | Setup | PostgreSQL | **Resolved**: PostgreSQL 17 (docker-compose) | | ARC-004 | Migration: Flyway vs Liquibase? | Setup | Flyway | **Resolved**: Flyway | | ARC-005 | Content đọc từ LMS qua API hay shared read model? | Module boundary | API/read model của LMS | Open (Phase 2) | | ARC-006 | Transaction boundary giữa module nào cần được phân tách? | Data consistency | Ghi rõ trong từng use case | Open |