# Luồng Dữ Liệu và Kiến trúc CQRS (Data Flow)

Tài liệu này giải thích cách luồng dữ liệu chạy trong hệ thống DSCons khi áp dụng **Modular Monolith & CQRS**. Đảm bảo tuân thủ Điều luật 5 (Chống Bus Factor).

## 1. Luồng Ghi Dữ Liệu (Write Flow - Command)
Luồng ghi được thiết kế để bảo vệ **tính toàn vẹn nghiệp vụ** (Business Integrity). Mọi thay đổi hệ thống đều phải đi qua Domain Layer.

```mermaid
sequenceDiagram
    participant Client
    participant API (FastAPI)
    participant CommandHandler
    participant Domain (Entity)
    participant Repository (Infra)
    participant EventBus
    participant DB (Schema: projects)

    Client->>API: POST /v1/erp/projects
    API->>CommandHandler: CreateProjectCommand(DTO)
    activate CommandHandler
    Note right of CommandHandler: @transactional
    
    CommandHandler->>Repository: Check existing (vd: check duplicate)
    CommandHandler->>Domain: Project.create(name, code, ...)
    activate Domain
    Note right of Domain: Business Rules Validation
    Domain-->>CommandHandler: project_entity
    deactivate Domain
    
    CommandHandler->>Repository: save(project_entity)
    Repository->>DB: INSERT INTO projects.projects...
    
    CommandHandler->>EventBus: publish('ProjectCreatedIntegrationEvent')
    Note right of EventBus: Ghi event vào Outbox table
    
    CommandHandler-->>API: Trả về ID dự án
    deactivate CommandHandler
    API-->>Client: 201 Created
```

## 2. Luồng Đọc Dữ Liệu (Read Flow - Query)
Luồng đọc được thiết kế để **tối ưu hiệu năng**. Nó bỏ qua toàn bộ Domain Layer (vì đọc dữ liệu không làm thay đổi trạng thái, không cần kiểm tra luật nghiệp vụ).

```mermaid
sequenceDiagram
    participant Client
    participant API (FastAPI)
    participant QueryHandler
    participant DB View (projects)

    Client->>API: GET /v1/erp/projects/{id}
    API->>QueryHandler: GetProjectDetailsQuery(id)
    activate QueryHandler
    
    QueryHandler->>DB View: Lấy dữ liệu bằng Raw SQL / SQLAlchemy Core
    Note right of QueryHandler: Lấy dữ liệu DTO thô, không build Object Entity
    DB View-->>QueryHandler: raw_data (dict)
    
    QueryHandler-->>API: ProjectDetailsDTO
    deactivate QueryHandler
    API-->>Client: 200 OK
```

## 3. Giao tiếp chéo giữa các Module (Cross-Module Communication)
Để đảm bảo **Schema Isolation** (Không Module nào được đụng vào CSDL của Module khác), việc đồng bộ dữ liệu dùng Event-Driven.

```mermaid
sequenceDiagram
    participant OutboxWorker (Background)
    participant EventBus (In-Memory/Queue)
    participant Module Projects
    participant Module Accounting

    Note over Module Projects, Module Accounting: Projects không biết sự tồn tại của Accounting
    
    OutboxWorker->>EventBus: Đọc 'ProjectCreatedIntegrationEvent' từ DB Outbox
    EventBus->>Module Accounting: Gọi Subscriber đã đăng ký
    activate Module Accounting
    
    Module Accounting->>Module Accounting (Domain): CreateBudgetCommand(project_id)
    Note right of Module Accounting (Domain): Tạo ngân sách tài chính
    Module Accounting (Domain)->>DB (Schema: accounting): INSERT INTO accounting.budgets...
    
    deactivate Module Accounting
```
