5.9 KiB
DOM — Domain Model —
| Version | 1.0 |
| Date | YYYY-MM-DD |
| Author | (skill sa-2-architecture) |
| Status | 🟡 Draft |
| Approved by | Tech Lead: — · BE Lead: — |
| Source | SAD_… v1.0 · DAT_… v1.0 · BR_… của BA · BACKLOG_… của BA |
| Scope | |
| Confidence | 🟡 |
Change Log
| Version | Date | Người sửa | Thay đổi | ADR |
|---|---|---|---|---|
| 1.0 | Bản đầu | — |
Thẩm quyền khi mâu thuẫn: sơ đồ thắng về quan hệ và luồng; bảng thắng về ràng buộc và con số.
BRcủa BA là nguồn của mọi invariant ở đây;DOMchỉ nói invariant đó sống ở class nào. Lệch vớiBR⇒OQ, không tự sửa rule.
Vì sao có tài liệu này:
DATnói ai sở hữu dữ liệu gì,PDMnói bảng vật lý trông thế nào. Không cóDOM, dev tự suy ra aggregate từ bảng — và mỗi người suy một kiểu, transaction boundary lệch nhau, invariant bị kiểm ở ba chỗ hoặc không chỗ nào.
1. Bounded context và aggregate
Một dòng mỗi aggregate. Aggregate là ranh giới transaction: mọi invariant trong aggregate được
kiểm trong một lần ghi; giữa các aggregate chỉ có eventual consistency (DAT §4).
| Bounded context | CMP-nn sở hữu |
Aggregate root | Entity con | Value object | Invariant chính (BR) |
Sự kiện phát ra |
|---|---|---|---|---|---|---|
| Cart & Order | CMP-04 |
Order |
OrderSeller, OrderItem |
Money, Address |
BR-014 tổng tiền = Σ dòng |
OrderPlaced |
🔴 Một entity thuộc đúng một aggregate. Entity xuất hiện ở hai aggregate ⇒ một trong hai chỉ được giữ id tham chiếu (không giữ object), ghi rõ ở §3.
2. Class diagram theo bounded context
Một sơ đồ mỗi bounded context, ≤ 12 class. Chỉ vẽ thuộc tính nghiệp vụ và phương thức đổi trạng
thái; getter/setter, DTO, repository không vẽ ở đây (thuộc AGD).
2.1
classDiagram
class Order {
+OrderId id
+CustomerId customerId
+Money totalAmount
+OrderStatus status
+place(cart) Order
+cancel(reason)
}
class OrderSeller {
+SellerId sellerId
+Money subtotal
+confirm()
}
class OrderItem {
+ProductVariantId variantId
+int quantity
+Money unitPriceSnapshot
}
class Money {
<<value object>>
+decimal amount
+Currency currency
}
Order "1" *-- "1..*" OrderSeller : splits into
OrderSeller "1" *-- "1..*" OrderItem : contains
Order ..> Money
OrderItem ..> Money
Bảng đi kèm (W13 — sơ đồ không nói được invariant kiểm ở đâu và ai được gọi):
| Class | Loại | Thuộc tính nghiệp vụ | Invariant (BR) |
Kiểm ở phương thức | Ai được gọi (ROLE/CMP) |
Bảng PDM |
|---|---|---|---|---|---|---|
Order |
aggregate root | totalAmount, status |
BR-014, BR-021 |
place(), cancel() |
ROLE-01 qua IF-002 |
TBL-012 order |
Money |
value object | amount, currency |
BR-003 không âm |
constructor | — | cột *_amount |
Quan hệ: *-- composition (cùng transaction) · o-- aggregation (khác vòng đời) · ..> phụ
thuộc · --> tham chiếu bằng id sang aggregate khác.
2.2 <Bounded context tiếp theo>
(cùng cấu trúc)
3. Tham chiếu xuyên aggregate
Chỗ hay sai nhất: giữ object của aggregate khác thay vì id, rồi load cả cây.
| Từ aggregate | Tham chiếu tới | Bằng gì | Đọc dữ liệu kia bằng | Trễ chấp nhận (DAT §4) |
|---|---|---|---|---|
Order |
Customer |
CustomerId |
IF-0nn / read model |
eventual ≤ … |
OrderItem |
ProductVariant |
ProductVariantId + snapshot giá/tên |
snapshot lúc đặt | không cần đồng bộ |
🔴 Snapshot hay tham chiếu sống? Giá, tên, địa chỉ lúc giao dịch phải là snapshot (thay đổi sau đó không được đổi lịch sử). Ghi rõ từng trường, đây là nguồn của nhiều bug đối soát.
4. Vòng đời trạng thái → class
Bảng chuyển trạng thái nằm ở BR §3; đây chỉ map xuống class và phương thức.
| Entity | Enum trạng thái | Thuộc BR |
Phương thức chuyển | Guard kiểm ở đâu | Ghi vết (SEC §audit) |
|---|---|---|---|---|---|
Order |
OrderStatus |
BR-021 |
confirm(), cancel() |
trong aggregate | order_status_history |
5. Domain event
| Sự kiện | Phát từ aggregate | Khi nào | Payload tối thiểu | Người nhận (CMP) |
Contract (CTR) |
|---|---|---|---|---|---|
OrderPlaced |
Order |
place() commit xong |
orderId, customerId, sellerIds[], totalAmount |
CMP-06, CMP-09 |
contracts/asyncapi/order-events.yaml#OrderPlaced |
🔴 Payload event không chứa PII ngoài id trừ khi SEC §5 cho phép đích danh.
6. Đối chiếu
| Kiểm | Kết quả | Hành động |
|---|---|---|
Mọi thực thể trong DAT §1 có class ở §2 |
n/n | |
Mọi BR loại "ràng buộc dữ liệu"/"tính toán" có class kiểm |
n/n | |
Mọi entity có trạng thái ở BR §3 có enum + phương thức ở §4 |
n/n | |
Mọi class root có bảng trong PDM §2 |
n/n | (điền khi PDM xong) |
7. Giả định & Ngoài phạm vi
Giả định:
| ID | Giả định | Cách xác minh | Nếu sai |
|---|
Ngoài phạm vi:
- (ví dụ: không mô hình hoá module báo cáo — chỉ đọc, dùng read model của
DAT§4)
8. Open Questions
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | Hệ quả nếu trả lời ngược |
|---|