Files
sys-analysis-design/sa-output/e-commerce/02-architecture/adr/ADR-003_mo-hinh-order-orderseller-tach-don-theo-seller.md
Canhchimlac 343ad8bbbc save
2026-09-15 16:02:30 +07:00

11 KiB
Raw Blame History

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ý.