ADR-003 — Mô hình dữ liệu Order (cha) / OrderSeller (con) để tách đơn theo seller khi checkout
Tên file: adr/ADR-003_mo-hinh-order-orderseller-tach-don-theo-seller.md
|
|
| Status |
Proposed |
| Date |
2026-09-15 |
| Người quyết |
SA + Tech Lead (cấu trúc dữ liệu — decision-radar.md §5) |
| Người đề xuất |
SA (qua skill sa-2-architecture, hoạt động adr) |
| Điểm radar |
~6/10 |
| Supersedes |
— |
| Superseded by |
— |
| Liên quan |
ASR-003 · BR-CART-01 (BA) · DRV-01 · DRV-02 · DRV-06 · OQ-011 (BA, chưa đóng) · CMP-04 |
⚠️ ADR bất biến sau khi Accepted. Muốn đổi quyết định thì viết ADR mới có
Supersedes: ADR-003 và đổi trạng thái bản cũ thành Superseded by.
1. Bối cảnh
Giỏ hàng có thể chứa sản phẩm của nhiều seller. DRV-01 (blocker MVP) và DRV-06 (minh bạch
dòng tiền 3 bên khách–sàn–seller) buộc phải có một cách nhất quán để tách trách nhiệm tài chính
và vận chuyển giữa các seller trong cùng một lần đặt hàng. BR-CART-01 (BA) đã phát biểu quy tắc
nghiệp vụ: nhóm CartItem theo seller_id, tạo OrderSeller riêng cho mỗi nhóm, Order là tập
hợp các OrderSeller. Cơ chế tách chi tiết ("luôn đúng N đơn cho N seller, không gộp") vẫn
phụ thuộc OQ-011 (BA, ASM-03 chưa xác minh) — ADR này ghi nhận mô hình cấu trúc, không tự
đóng OQ-011.
Ràng buộc đang chi phối:
| Nguồn |
Nội dung |
BR-CART-01 (BA) |
Tách CartItem theo seller_id, tạo OrderSeller riêng cho mỗi nhóm |
ASR-003 |
Ép mô hình dữ liệu 1 Order — N OrderSeller — N OrderItem; mỗi OrderSeller có vòng đời trạng thái độc lập |
DRV-06 |
Dòng tiền minh bạch 3 bên, hoa hồng/payout theo từng seller |
OQ-011 (BA) |
Giỏ N seller luôn tách đúng N đơn, không gộp — chưa xác nhận bởi PO |
Cái đã biết chắc / cái còn là giả định:
| Điều |
🟢 Đã kiểm chứng / 🔴 Giả định |
Bằng chứng |
| Mô hình kinh doanh là marketplace đa seller, cần tách trách nhiệm tài chính/vận chuyển theo seller |
🟢 Đã kiểm chứng |
00-project-brief.md vòng 1, BR-CART-01 |
Không có ngoại lệ gộp nhiều seller vào 1 OrderSeller (VD cùng kho vận trung tâm) |
🔴 Giả định — PO chưa xác nhận |
OQ-011 (BA), ASM-03 |
2. Phương án đã cân nhắc
PA-1 — Một Order phẳng, không có cấu trúc con theo seller (dùng trường seller_id lặp ở từng OrderItem)
|
|
| Mô tả |
Chỉ có bảng Order/OrderItem, mỗi OrderItem gắn seller_id riêng; không có tầng OrderSeller trung gian — trạng thái/hoa hồng tính bằng cách nhóm động theo seller_id mỗi lần truy vấn |
| Ưu |
Đơn giản hơn về số bảng, ít JOIN hơn cho các truy vấn không cần phân seller |
| Nhược |
Không có đơn vị hạch toán/vận chuyển/đối soát độc lập theo seller — mỗi lần cần trạng thái giao hàng hoặc hoa hồng theo seller phải nhóm động, dễ sai lệch khi có seller thay đổi trạng thái không đồng thời; vi phạm ASR-003 ("mỗi OrderSeller có vòng đời trạng thái độc lập") |
| Chi phí đảo ngược |
Cao — thêm tầng OrderSeller sau khi đã có dữ liệu lịch sử cần migrate toàn bộ đơn hàng cũ |
PA-2 — Order (cha) — N OrderSeller (con) — N OrderItem (chọn)
|
|
| Mô tả |
Order là tập hợp logic của các OrderSeller; mỗi OrderSeller có status riêng, thuộc về đúng 1 Order cha và đúng 1 seller_id |
| Ưu |
Mỗi OrderSeller là đơn vị hạch toán/vận chuyển/đối soát độc lập — khớp trực tiếp BR-CART-01, DRV-06; các module tiêu thụ (Commission & Payout, Shipping & Fulfillment) chỉ cần đọc OrderSeller, không phải tự nhóm |
| Nhược |
Thêm một tầng bảng, thêm JOIN khi cần tổng Order (đã có công thức BR-CART-09 bù); ranh giới sở hữu dữ liệu giữa Cart & Order (tạo) và Commission/Shipping (tiêu thụ) cần rõ ràng |
| Chi phí đảo ngược |
Trung bình-cao — đổi mô hình sau go-live cần migrate toàn bộ đơn hàng lịch sử + sửa mọi module đọc Order |
PA-3 — Mỗi seller là một Order độc lập, không có Order cha chung
|
|
| Mô tả |
Bỏ hẳn khái niệm "đơn cha" — khách checkout giỏ 3 seller thì tạo 3 Order độc lập hoàn toàn, không có liên kết logic nào |
| Ưu |
Đơn giản nhất về mặt mô hình — mỗi Order tự chứa đủ thông tin |
| Nhược |
Khách hàng mất khả năng xem "một lần đặt hàng" gồm nhiều seller như một đơn vị trải nghiệm (UX); mất điểm neo cho thanh toán chung 1 lần cho nhiều seller (khởi tạo Payment 1 lần cho N OrderSeller) — vi phạm luồng B5-B8 đã có ở PROCESS_CartCheckout |
| Chi phí đảo ngược |
Cao — dựng lại khái niệm "đơn cha" sau này cần thêm bảng liên kết + backfill dữ liệu |
Bảng so sánh
| Tiêu chí |
PA-1 |
PA-2 |
PA-3 |
Đơn vị hạch toán/vận chuyển độc lập theo seller (ASR-003) |
❌ |
✅ |
✅ |
Trải nghiệm "một lần đặt hàng" cho nhiều seller (PROCESS B5-B8) |
🔶 Nhóm động |
✅ |
❌ |
| Số bảng/độ phức tạp |
Thấp |
Trung bình |
Thấp |
Khớp BR-CART-01 (BA) |
❌ |
✅ |
🔶 Một phần |
3. Quyết định
Chọn PA-2 — Order (cha) — N OrderSeller (con) — N OrderItem.
Vì sao: Đây là mô hình duy nhất khớp trực tiếp BR-CART-01 (nguồn nghiệp vụ đã chốt), đáp
ứng ASR-003 (mỗi OrderSeller có vòng đời độc lập) và giữ được trải nghiệm "một lần đặt hàng"
theo luồng đã thiết kế ở PROCESS_CartCheckout B5-B8.
Phạm vi áp dụng: Toàn bộ luồng checkout và mọi module tiêu thụ Order/OrderSeller
(Commission & Payout, Shipping & Fulfillment, Review).
Điều kiện chuyển Proposed → Accepted
| Điều kiện |
Ai xác nhận |
Trạng thái hiện tại |
OQ-011 (BA) — PO xác nhận không có ngoại lệ gộp seller (VD cùng kho vận trung tâm) |
PO |
Mở |
| Không bắt buộc POC (đây là quyết định mô hình dữ liệu, không phải con số hiệu năng) |
— |
N/A |
4. Phương án bị loại và lý do
| Phương án |
Loại vì |
Gắn với |
Điều kiện nào thì xét lại |
PA-1 — Order phẳng, không tầng OrderSeller |
Vi phạm ASR-003 (không có vòng đời độc lập theo seller); các module tiêu thụ phải tự nhóm động, dễ sai lệch |
ASR-003, BR-CART-01 |
Nếu về sau xác nhận không cần vòng đời độc lập theo seller (VD gộp hết trách nhiệm về sàn) — chưa có dấu hiệu |
PA-3 — Mỗi seller một Order độc lập, không cha chung |
Phá vỡ trải nghiệm "một lần đặt hàng" đã thiết kế ở PROCESS B5-B8; mất điểm neo thanh toán chung |
PROCESS_CartCheckout B5-B8 |
Nếu PO đổi mô hình sản phẩm sang "mỗi seller là một cửa hàng độc lập hoàn toàn, khách checkout riêng từng seller" — thay đổi nghiệp vụ lớn, chưa có dấu hiệu |
5. Hệ quả
Hệ quả tích cực
- Commission & Payout, Shipping & Fulfillment chỉ cần đọc
OrderSeller, không tự nhóm động —
giảm rủi ro sai lệch đối soát
- Khách hàng có trải nghiệm nhất quán "một lần đặt hàng" dù giỏ có nhiều seller
Hệ quả tiêu cực phải sống chung
- Thêm JOIN khi cần tổng
Order.total_amount (đã có công thức bù BR-CART-09)
- Nếu
OQ-011 trả lời "có ngoại lệ gộp seller" (VD cùng kho vận), mô hình này phải viết lại một
phần (không phải toàn bộ — vẫn giữ cấu trúc cha-con, chỉ đổi quy tắc nhóm)
Cái quyết định này khoá lại
| Muốn đổi về sau thì |
Tốn |
| Đổi mô hình tách đơn (VD gộp nhiều seller vào 1 đơn) |
Migrate toàn bộ đơn hàng lịch sử + sửa mọi module đọc Order — đây là core domain model, SAD §4.2 đã cảnh báo đây là loại thay đổi "không nên xảy ra thường xuyên" |
Việc phát sinh
| Việc |
Chủ |
Hạn |
Ghi ở đâu |
BA xác nhận OQ-011 với PO |
BA + PO |
Trước khi Accepted |
ba-output/.../00-index/OQ_e-commerce.md |
Thiết kế schema chi tiết Order/OrderSeller/OrderItem |
SA (hoạt động dat) |
GĐ2 tiếp theo |
DAT_e-commerce |
6. Cách kiểm chứng quyết định này được tuân thủ
| Cách kiểm |
Công cụ |
Chạy ở đâu |
FIT |
Mọi OrderSeller luôn có đúng 1 seller_id và thuộc đúng 1 Order cha (ràng buộc FK + constraint) |
DB schema constraint + migration test |
CI |
FIT-05 (ứng viên) |
Tổng Order.total_amount luôn bằng Σ OrderSeller.subtotal_amount (BR-CART-09) |
Unit test / DB trigger kiểm tra |
CI |
FIT-06 (ứng viên) |
7. Điều kiện xét lại
| Dấu hiệu |
Ngưỡng |
Ai theo dõi |
| PO xác nhận cần ngoại lệ gộp seller (VD cùng kho vận trung tâm) |
Khi OQ-011 trả lời khác giả định hiện tại |
PO + BA |
| Phát sinh nhu cầu đổi mô hình tách đơn thường xuyên |
≥ 2 lần yêu cầu thay đổi trong 6 tháng |
Tech Lead |
8. Tham chiếu
- POC: Không áp dụng
- Bài đo:
FIT-05, FIT-06 (ứng viên GĐ3)
- Tài liệu ngoài:
BR_CartCheckout_v1.0.md §1 BR-CART-01, §4 ERD (BA)
- Thảo luận:
ASR_e-commerce_v1.0.md §B2 ASR-003
9. Review log (không đổi Status)
| Ngày |
Người review |
Vai trò |
Quyết định |
Lý do chưa chuyển Accepted |
| 2026-09-15 |
Điều phối dự án (thay mặt Tech Lead, chế độ chạy thử) |
Tech Lead (ký thay, ngoại lệ DEC-01) |
Reviewed (Proposed giữ nguyên) — nội dung đủ làm cơ sở thiết kế tiếp (icd/dat/sec/inf/fail) |
Chờ OQ-011 — BA + PO xác nhận mô hình Order/OrderSeller |
Đây là ghi nhận review nội dung, không phải "sign" theo nghĩa gate: Status giữ nguyên
Proposed. Xem 00-index/ADL_e-commerce.md (Change Log — Review 2026-09-15) và ADL §8
"Việc phải làm" cho điều kiện chuyển Accepted. Confidence tổng thể của lượt review: 🔴 —
AG2 chưa ký.