Files
Leonard-ThindPad-P50 2c7bcde741 improve BA skill
2026-09-09 06:34:57 +07:00

32 KiB
Raw Permalink Blame History

BR — Business Rules — Giỏ hàng & Checkout (e-commerce)

Version 1.0
Date 2026-09-08
Author BA (qua skill ba-2-analysis)
Status 🟡 Draft
Approved by —
Profile screen · greenfield · standard
Source 01-discovery/BRIEF_CartCheckout_v1.0.md · 01-discovery/RISK_CartCheckout_v1.0.md · PROCESS_CartCheckout_v1.0.md · BACKLOG_CartCheckout_v1.0.md · e-commerce/docs/sections/06-luong-xu-ly.md §6.4 (BR-01, BR-02, tham chiếu kỹ thuật, không phải nguồn quyết định BA) · e-commerce/docs/sections/05-thiet-ke-du-lieu.md §5.2.3–5.2.4 (tham chiếu entity, không chép schema vật lý)
Scope Module Giỏ hàng & Checkout — RQ-001…RQ-004

Change Log

Version Date Người sửa Thay đổi CR
1.0 2026-09-08 BA (qua skill ba-2-analysis) Bản đầu — 8 business rule, ERD, 2 vòng đời trạng thái —

⚠️ Ngoại lệ gate G1 — xem cảnh báo đầy đủ ở đầu PROCESS_CartCheckout_v1.0.md và DEC-02 ở 00-index/DECISION_e-commerce.md. Ba quy tắc dưới đây (BR-CART-01, BR-CART-03, BR-CART-06) phụ thuộc giả định chưa được PO/Tech Lead xác nhận — không được coi là đã chốt cho tới khi OQ liên quan được trả lời.

1. Danh sách quy tắc

BR-CART-01 — Tách đơn hàng theo seller khi checkout

Loại Quy trình / Tính toán
Nguồn 🟠 Quyết định mô hình kinh doanh đã chốt (marketplace đa seller) — 00-project-brief.md vòng 1; cơ chế tách chi tiết ("luôn đúng N đơn cho N seller, không gộp") chưa được PO xác nhận riêng cho module này (ASM-03, chưa xác minh)
Người chốt STK-01 (PO sàn) — ở mức mô hình kinh doanh; cơ chế tách chi tiết chưa chốt, xem OQ-011
RQ RQ-002
US áp dụng US-004
Khi vi phạm Chặn — không tạo được Order nếu không nhóm được CartItem theo seller_id hợp lệ
Có ngoại lệ Chưa xác định — nếu PO xác nhận có ngoại lệ gộp seller (VD cùng kho vận), rule này phải viết lại hoàn toàn (xem ASM-03)
Có thể đổi trong 1 năm Có — đây là quyết định thiết kế nghiệp vụ, không phải quy định pháp luật

Phát biểu:

Khi Customer/Guest xác nhận đặt hàng (checkout), hệ thống nhóm CartItem theo seller_id và tạo một OrderSeller (đơn con) riêng cho mỗi nhóm; Order (đơn cha) là tập hợp các OrderSeller con, mỗi OrderSeller có vòng đời trạng thái độc lập (xem §3).

Điều kiện áp dụng: Áp dụng cho mọi giỏ hàng có ≥1 sản phẩm hợp lệ (đủ tồn kho theo BR-CART-02) tại thời điểm checkout, không phân biệt Customer hay Guest.

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Giỏ có 2 sản phẩm của seller A, 1 sản phẩm của seller B Tạo 1 Order + 2 OrderSeller (A, B)
Biên Giỏ có sản phẩm của 1 seller duy nhất Tạo 1 Order + 1 OrderSeller — vẫn đúng cấu trúc cha-con dù chỉ 1 con
Chưa xác định Hai seller cùng thuộc một kho vận trung tâm (nếu có mô hình này trong tương lai) Chưa có quy tắc — OQ-011, không tự giả định là gộp hay không gộp

BR-CART-02 — Giữ tồn kho khi checkout (chống oversell)

Loại Điều kiện hành động
Nguồn 🟠 Chính sách vận hành (bảo vệ trải nghiệm khách + quyền lợi seller khỏi bán vượt tồn kho); cơ chế kỹ thuật tham khảo SAD §6.4 BR-02, cần Tech Lead xác nhận khả thi
Người chốt (chưa có Tech Lead thật xác nhận — xem ngoại lệ gate)
RQ RQ-001, RQ-002
US áp dụng US-004
Khi vi phạm Chặn — trả lỗi, không tạo Order, giữ nguyên giỏ hàng để khách điều chỉnh
Có ngoại lệ Không
Có thể đổi trong 1 năm Có — là quyết định vận hành, có thể tinh chỉnh ngưỡng/cơ chế khi có dữ liệu tải thật

Phát biểu:

Tại thời điểm checkout, hệ thống phải kiểm tra tồn kho khả dụng cho từng sản phẩm trong giỏ hàng; nếu bất kỳ sản phẩm nào không đủ số lượng yêu cầu, hệ thống chặn việc tạo đơn và báo lỗi thay vì tạo đơn với số lượng vượt tồn kho thực có.

Điều kiện áp dụng: Áp dụng cho mọi lần POST /checkout (theo tên gọi tham chiếu SAD), không phân biệt Customer/Guest, không phân biệt phương thức thanh toán.

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Tồn kho khả dụng 10, khách mua 3 Cho qua, tạo đơn
Vi phạm Tồn kho khả dụng 2, khách mua 3 Chặn, báo lỗi mã E-CART-0001 (mã cụ thể — GĐ3 xác nhận)
Biên Tồn kho khả dụng đúng bằng số lượng yêu cầu Cho qua (biên >=, không phải >)

BR-CART-03 — Giới hạn giá trị đơn hàng thanh toán COD

Loại Điều kiện hành động
Nguồn 🟠 Chính sách rủi ro tài chính (đề xuất, chưa có chính sách chính thức)
Người chốt ☐ Chưa chốt — xem OQ-006
RQ RQ-003
US áp dụng US-007
Khi vi phạm (Chưa xác định — phụ thuộc phương án PO chọn)
Có ngoại lệ (Chưa xác định)
Có thể đổi trong 1 năm Có

Phát biểu:

🔴 Chưa có phát biểu chính thức. ASM-05 (GĐ1) giả định "COD không có giới hạn giá trị đơn ở MVP", nhưng RISK-01 (🔴 mức cao) cảnh báo hệ quả nếu giả định này sai: seller chịu phí hoàn hàng khi khách từ chối một phần đơn COD đa seller. BA không tự đặt một con số (VD "giới hạn 5.000.000đ") vì đây là quyết định tài chính/rủi ro, phải do PO quyết — xem OQ-006.

Điều kiện áp dụng: (Chưa xác định — chờ PO chọn 1 trong 2 phương án dưới)

Hai phương án BA đề xuất cho PO chọn (theo RISK-01):

Phương án Mô tả Ưu điểm Nhược điểm
(a) Giới hạn giá trị Đặt ngưỡng tối đa cho tổng giá trị đơn COD đa seller — vượt ngưỡng phải chọn thanh toán trước Đơn giản, dễ thực hiện Cần chốt con số cụ thể, có thể chặn nhầm khách hàng hợp lệ giá trị cao
(b) Xác thực bổ sung Yêu cầu OTP/đặt cọc cho đơn COD giá trị cao Không chặn hoàn toàn, chỉ tăng ma sát ở đơn rủi ro Phức tạp hơn kỹ thuật, cần tích hợp OTP

Ví dụ đúng / sai: (chưa viết được — phụ thuộc phương án PO chọn)


BR-CART-04 — Điều kiện chọn phương thức thanh toán

Loại Điều kiện hành động
Nguồn 🟠 Quyết định sản phẩm đã chốt (đối tác thanh toán mặc định VNPay/Momo/COD)
Người chốt STK-01 (PO sàn), qua 00-project-brief.md vòng 1
RQ RQ-003
US áp dụng US-007, US-008
Khi vi phạm Chặn — không cho tiếp tục checkout nếu chưa chọn phương thức
Có ngoại lệ Không
Có thể đổi trong 1 năm Có

Phát biểu:

Customer và Guest đều được chọn một trong ba phương thức thanh toán: VNPay, Momo, hoặc COD, cho mọi đơn hàng trong phạm vi module này — không có ràng buộc phân biệt theo vai trò ở mức GĐ2 (GĐ3 xác nhận lại nếu phát sinh ràng buộc theo khu vực địa lý/giá trị đơn).

Điều kiện áp dụng: Áp dụng tại bước B6 (PROCESS_CartCheckout_v1.0.md), sau khi Order/ OrderSeller đã được tạo (BR-CART-01).

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Guest chọn COD Cho qua
Hợp lệ Customer chọn VNPay Cho qua
Vi phạm Không chọn phương thức nào, bấm tiếp tục Chặn, báo lỗi bắt buộc chọn

BR-CART-05 — Không lưu trữ thông tin thẻ thanh toán

Loại Ràng buộc dữ liệu
Nguồn 🔴 Tuân thủ pháp lý — phạm vi PCI-DSS thu hẹp, NFR-05 (e-commerce/docs/sections/02-phan-tich-yeu-cau.md)
Người chốt STK-01 (PO sàn) + yêu cầu kỹ thuật/pháp lý đã chốt ở cấp dự án
RQ RQ-003
US áp dụng US-008
Khi vi phạm Chặn — về mặt thiết kế, hệ thống sàn không được có trường lưu số thẻ/CVV ở bất kỳ đâu trong phạm vi module này
Có ngoại lệ Không
Có thể đổi trong 1 năm Không — đây là ràng buộc pháp lý/hợp đồng với đối tác thanh toán, không tự ý thay đổi

Phát biểu:

Hệ thống sàn không được lưu trữ số thẻ thanh toán, mã CVV, hoặc bất kỳ dữ liệu thẻ nhạy cảm nào; mọi xử lý thẻ do VNPay/Momo thực hiện, hệ thống sàn chỉ lưu tham chiếu giao dịch (gateway_transaction_ref) và kết quả (thành công/thất bại).

Điều kiện áp dụng: Áp dụng cho toàn bộ luồng thanh toán VNPay/Momo (US-008). Không áp dụng cho COD (không có dữ liệu thẻ).

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Hệ thống chỉ lưu gateway_transaction_ref, status, amount Đúng thiết kế
Vi phạm Bất kỳ trường nào lưu số thẻ/CVV Vi phạm nghiêm trọng — chặn ở review thiết kế GĐ3, không chờ tới UAT

BR-CART-06 — Xác thực webhook xác nhận thanh toán

Loại Điều kiện hành động (kỹ thuật, ảnh hưởng nghiệp vụ)
Nguồn 🟢 Đề xuất kỹ thuật, cần Tech Lead xác nhận khả thi (ASM-01 chưa xác minh)
Người chốt ☐ Chưa chốt — xem OQ-010
RQ RQ-003
US áp dụng US-008
Khi vi phạm Chặn — webhook không hợp lệ (chữ ký sai/quá hạn) thì không được cập nhật Payment.status
Có ngoại lệ Không
Có thể đổi trong 1 năm Có — là cơ chế kỹ thuật, có thể đổi nếu VNPay/Momo đổi API

Phát biểu:

Hệ thống chỉ chấp nhận cập nhật Payment.status = success khi nhận được webhook có chữ ký hợp lệ từ VNPay/Momo và trong khoảng thời gian hợp lệ kể từ khi giao dịch được khởi tạo — 🔴 con số cụ thể (bao nhiêu phút) chưa được PO/Tech Lead chốt cho module này, chỉ có giả định kỹ thuật tham khảo (không phải quyết định BA) ở tài liệu SAD.

Điều kiện áp dụng: Áp dụng cho US-008 (VNPay/Momo). Không áp dụng cho COD (US-007, không có webhook).

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Webhook có chữ ký đúng, trong hạn Cập nhật Payment.status = success
Vi phạm Chữ ký sai Từ chối, không cập nhật, ghi log
Chưa xác định Webhook không tới trong thời gian chờ Xem PROCESS B9 — cần cơ chế đối soát bù, ngoài phạm vi US module này

BR-CART-07 — Điều kiện tối thiểu cho Guest checkout

Loại Điều kiện hành động
Nguồn 🟠 Quyết định sản phẩm đã chốt (Guest checkout được xác nhận ở cấp dự án)
Người chốt STK-01 (PO sàn), qua sections/01-tong-quan.md §1.2
RQ RQ-004
US áp dụng US-006
Khi vi phạm Chặn — thiếu thông tin liên hệ tối thiểu thì không cho xác nhận đặt hàng
Có ngoại lệ Không
Có thể đổi trong 1 năm Có

Phát biểu:

Guest phải cung cấp tối thiểu thông tin liên hệ và địa chỉ giao hàng để hoàn tất checkout mà không cần tạo tài khoản (không cần mật khẩu) — 🔴 danh sách field bắt buộc cụ thể (họ tên, số điện thoại, email có bắt buộc không) chưa được chốt ở mức GĐ2, để GĐ3 làm bảng field đầy đủ khi có thiết kế màn hình.

Điều kiện áp dụng: Áp dụng cho toàn bộ luồng checkout khi customer_id = null (Guest).

Ví dụ đúng / sai:

Trường hợp Dữ liệu Kết quả mong đợi
Hợp lệ Guest điền đủ trường bắt buộc (danh sách — GĐ3 xác nhận) Cho qua
Vi phạm Thiếu trường bắt buộc Chặn, báo lỗi field cụ thể (GĐ3)

2. Bảng tổng hợp

ID Tên Loại Nguồn US áp dụng Khi vi phạm Mã lỗi (GĐ3)
BR-CART-01 Tách đơn theo seller Quy trình/Tính toán 🟠 (cơ chế chi tiết chưa chốt — OQ-011) US-004 Chặn E-CART-00nn
BR-CART-02 Giữ tồn kho khi checkout Điều kiện hành động 🟠 US-004 Chặn E-CART-0001
BR-CART-03 Giới hạn giá trị đơn COD Điều kiện hành động ☐ Chưa chốt — OQ-006 US-007 (chưa xác định) (chưa xác định)
BR-CART-04 Điều kiện chọn phương thức thanh toán Điều kiện hành động 🟠 US-007, US-008 Chặn E-CART-00nn
BR-CART-05 Không lưu thông tin thẻ Ràng buộc dữ liệu 🔴 US-008 Chặn (thiết kế) N/A — chặn ở review thiết kế
BR-CART-06 Xác thực webhook thanh toán Điều kiện hành động 🟢 (chưa chốt — OQ-010) US-008 Chặn E-CART-00nn
BR-CART-07 Điều kiện tối thiểu Guest checkout Điều kiện hành động 🟠 (field cụ thể — GĐ3) US-006 Chặn E-CART-00nn

3. Vòng đời trạng thái

Bắt buộc với mọi thực thể có trạng thái (quy tắc W6). Ba thực thể có trạng thái trong phạm vi module này: CART, ORDER_SELLER (chỉ đoạn khởi tạo — phần sau thuộc module khác), PAYMENT.

Thực thể: CART

Bốn câu phải trả lời:

Câu hỏi Trả lời
Trạng thái khởi tạo active (Đang hoạt động)
Trạng thái cuối (không đi tiếp được) converted (Đã chuyển thành đơn) hoặc abandoned (Bỏ quên)
Từ trạng thái cuối quay lại được không Không — giỏ hàng mới phải được tạo lại
Trạng thái nào cho phép xoá Chỉ active — Customer/Guest được xoá từng CartItem, không "xoá" bản ghi Cart (chỉ chuyển trạng thái)

Sơ đồ:

stateDiagram-v2
    state "Đang hoạt động" as Active
    state "Đã chuyển thành đơn" as Converted
    state "Bỏ quên" as Abandoned

    [*] --> Active
    Active --> Converted: Checkout thành công (BR-CART-01, BR-CART-02)
    Active --> Abandoned: Hết hạn phiên (tự động, hệ thống)
    Converted --> [*]
    Abandoned --> [*]

Bảng chuyển trạng thái:

# Nguồn Sự kiện Điều kiện Đích Ai được làm BR Ghi vết
1 Active Checkout Đủ tồn kho tất cả item (BR-CART-02) Converted Customer/Guest BR-CART-01, BR-CART-02 ✅ (thông qua Order được tạo)
2 Active Hết hạn phiên Thời hạn cụ thể — chưa chốt ở GĐ2, tham khảo kỹ thuật SAD §5.3.1 (Guest 7 ngày/Customer 30 ngày), cần Tech Lead xác nhận áp dụng đúng con số này Abandoned Hệ thống (tự động) — ➖ Không ghi vết chi tiết (chấp nhận mất theo thiết kế kỹ thuật tham khảo)

Chuyển trạng thái KHÔNG được phép:

Từ Sang Vì sao cấm
Converted Active Mất dấu vết đơn đã tạo — giỏ đã chuyển thành đơn không thể "mở lại" để sửa tiếp
Abandoned Converted Giỏ đã hết hạn — khách phải thêm lại sản phẩm vào giỏ mới, không checkout trực tiếp từ giỏ bỏ quên

Thực thể: ORDER_SELLER (chỉ đoạn khởi tạo trong phạm vi module này)

🔴 Vòng đời đầy đủ của OrderSeller (packed/shipped/delivered/returned…) thuộc module Quản lý đơn hàng (FR-08/FR-19, ngoài phạm vi RQ-001…004). Phần dưới đây chỉ mô tả đoạn khởi tạo mà module Giỏ hàng & Checkout chịu trách nhiệm, để BA GĐ3 của module kế tiếp kế thừa đúng điểm nối.

Bốn câu phải trả lời (trong phạm vi module này):

Câu hỏi Trả lời
Trạng thái khởi tạo pending (Chờ thanh toán)
Trạng thái cuối (trong phạm vi module này) confirmed (Đã xác nhận — bàn giao module khác) hoặc cancelled (Đã huỷ)
Từ trạng thái cuối quay lại được không Không, trong phạm vi module này (huỷ sau confirmed là nghiệp vụ FR-08, ngoài phạm vi)
Trạng thái nào cho phép xoá Không — không cho phép xoá OrderSeller, chỉ chuyển trạng thái (bắt buộc giữ dấu vết tài chính/đối soát)

Sơ đồ:

stateDiagram-v2
    state "Chờ thanh toán" as Pending
    state "Đã xác nhận" as Confirmed
    state "Đã huỷ" as Cancelled

    [*] --> Pending: Checkout tạo đơn con (BR-CART-01)
    Pending --> Confirmed: Thanh toán thành công (COD hoặc webhook VNPay/Momo — BR-CART-06)
    Pending --> Cancelled: Thanh toán thất bại/hết hạn chờ, hoặc khách huỷ trước khi thanh toán
    Confirmed --> [*]: Bàn giao module Quản lý đơn hàng seller (FR-19, ngoài phạm vi)
    Cancelled --> [*]

Bảng chuyển trạng thái:

# Nguồn Sự kiện Điều kiện Đích Ai được làm BR Ghi vết
1 Pending Thanh toán COD Đơn không vượt giới hạn COD (nếu BR-CART-03 được chốt) Confirmed Hệ thống (tự động khi US-007 xác nhận) BR-CART-03 (chưa chốt), BR-CART-04 ✅
2 Pending Webhook thanh toán thành công Webhook hợp lệ (BR-CART-06) Confirmed Hệ thống (tự động) BR-CART-06 ✅
3 Pending Thanh toán thất bại / hết hạn chờ (Thời hạn chờ cụ thể — chưa chốt, ngoài phạm vi US module này, xem PROCESS B9) Cancelled Hệ thống (tự động) — ✅

Chuyển trạng thái KHÔNG được phép:

Từ Sang Vì sao cấm
Confirmed Pending Mất dấu vết đơn đã xác nhận thanh toán — ảnh hưởng đối soát tài chính
Cancelled Confirmed Đơn đã huỷ không thể tự khôi phục — khách phải đặt lại từ đầu

Thực thể: PAYMENT

Bốn câu phải trả lời:

Câu hỏi Trả lời
Trạng thái khởi tạo pending
Trạng thái cuối success hoặc failed (trong phạm vi module này — refunded thuộc FR-25, ngoài phạm vi)
Từ trạng thái cuối quay lại được không Không, trong phạm vi module này
Trạng thái nào cho phép xoá Không — bản ghi thanh toán không bao giờ bị xoá (bắt buộc giữ cho đối soát/kiểm toán)

Sơ đồ:

stateDiagram-v2
    state "Chờ xử lý" as Pending
    state "Thành công" as Success
    state "Thất bại" as Failed

    [*] --> Pending: Khởi tạo thanh toán (US-007/US-008)
    Pending --> Success: COD xác nhận / webhook VNPay-Momo hợp lệ (BR-CART-06)
    Pending --> Failed: Webhook báo lỗi / hết hạn chờ (cơ chế cụ thể ngoài phạm vi US module này)
    Success --> [*]
    Failed --> [*]

Bảng chuyển trạng thái:

# Nguồn Sự kiện Điều kiện Đích Ai được làm BR Ghi vết
1 Pending Xác nhận COD 🔴 Chưa chốt — Payment.status của COD ghi success ngay hay giữ pending tới khi thực thu? Xem OQ-013 Success (giả định, chưa chốt) Hệ thống (chưa xác định) ✅
2 Pending Webhook VNPay/Momo thành công Chữ ký hợp lệ, trong hạn (BR-CART-06) Success Hệ thống BR-CART-06 ✅
3 Pending Webhook báo lỗi/hết hạn (cơ chế cụ thể — ngoài phạm vi US module này) Failed Hệ thống — ✅

Chuyển trạng thái KHÔNG được phép:

Từ Sang Vì sao cấm
Success Pending Mất dấu vết giao dịch đã ghi nhận thành công — sai lệch đối soát
Failed Success Không tự động — nếu cần xử lý lại phải tạo bản ghi Payment mới, không sửa bản ghi cũ

4. Mô hình dữ liệu khái niệm (ERD)

🔴 Mục bắt buộc vì US-004 chạm ≥2 thực thể. Mô hình khái niệm — không kiểu dữ liệu vật lý, không index, không bảng trung gian (đó là việc của Solution Architect/dev; tham chiếu e-commerce/docs/sections/05-thiet-ke-du-lieu.md §5.2.3–5.2.4 chỉ để đối chiếu tên thực thể, không chép nguyên cấu trúc bảng).

erDiagram
    CUSTOMER ||--o{ CART : "sở hữu (nếu đăng nhập)"
    CART ||--o{ CART_ITEM : "chứa"
    CART_ITEM }o--|| PRODUCT_VARIANT : "tham chiếu"
    CART_ITEM }o--|| SELLER : "thuộc về"
    CUSTOMER ||--o{ ORDER : "đặt (nếu đăng nhập)"
    ORDER ||--o{ ORDER_SELLER : "tách thành"
    ORDER ||--o| PAYMENT : "thanh toán bởi"
    ORDER_SELLER ||--o{ ORDER_ITEM : "chứa"
    ORDER_SELLER }o--|| SELLER : "thuộc về"
    ORDER_ITEM }o--|| PRODUCT_VARIANT : "tham chiếu"

    CART {
        string id PK "khoá kỹ thuật"
        string customer_id FK "nullable — null nếu Guest"
        string session_id "định danh phiên — dùng khi Guest"
        enum status "active/converted/abandoned — xem BR §3"
    }
    CART_ITEM {
        string id PK
        string cart_id FK
        string product_variant_id FK
        string seller_id FK
        int quantity "> 0"
    }
    ORDER {
        string id PK
        string customer_id FK "nullable — Guest checkout (RQ-004)"
        string order_number "khoá nghiệp vụ, duy nhất, dễ đọc"
        decimal total_amount "VND — tổng các OrderSeller con"
        enum status "pending_payment/… — dẫn xuất từ trạng thái các OrderSeller con, chi tiết ở module khác"
    }
    ORDER_SELLER {
        string id PK
        string order_id FK
        string seller_id FK
        string sub_order_number "khoá nghiệp vụ, duy nhất"
        decimal subtotal_amount "VND"
        enum status "pending/confirmed/cancelled — xem BR §3 (đoạn khởi tạo)"
    }
    ORDER_ITEM {
        string id PK
        string order_seller_id FK
        string product_variant_id FK
        int quantity
        decimal unit_price "VND, snapshot tại thời điểm đặt hàng"
    }
    PAYMENT {
        string id PK
        string order_id FK
        enum method "vnpay/momo/cod — BR-CART-04"
        decimal amount "VND"
        enum status "pending/success/failed — xem BR §3"
    }

Ký hiệu lực lượng: ||--o{ một-nhiều · ||--o| một-không hoặc một · }o--|| nhiều-một.

4.1 Bảng thực thể

Thực thể Tên nghiệp vụ Khoá nghiệp vụ Số bản ghi hiện có Ai tạo Vòng đời BR
CART Giỏ hàng (id kỹ thuật — chưa có khoá nghiệp vụ do khách hàng nhận biết; customer_id/session_id là khoá truy vấn, không phải khoá nghiệp vụ theo nghĩa người dùng gõ ra) 0 — greenfield Customer/Guest (US-001) §3 CART BR-CART-01, BR-CART-02
CART_ITEM Dòng sản phẩm trong giỏ (cart_id, product_variant_id) 0 Customer/Guest Theo CART cha —
ORDER Đơn hàng (cha) order_number 0 Hệ thống, khi checkout (US-004) Dẫn xuất từ ORDER_SELLER con BR-CART-01
ORDER_SELLER Đơn hàng con theo seller sub_order_number 0 Hệ thống, khi checkout (US-004) §3 ORDER_SELLER (đoạn khởi tạo) BR-CART-01, BR-CART-02
ORDER_ITEM Dòng sản phẩm trong đơn con (id kỹ thuật, không có khoá nghiệp vụ riêng — thuộc về ORDER_SELLER) 0 Hệ thống, khi checkout Theo ORDER_SELLER cha —
PAYMENT Giao dịch thanh toán gateway_transaction_ref (chỉ có với VNPay/Momo — COD chưa rõ khoá nghiệp vụ tương đương, xem OQ-013) 0 Hệ thống, khi US-007/US-008 §3 PAYMENT BR-CART-03…06

Khoá nghiệp vụ là thứ người dùng dùng để nhận biết — order_number/sub_order_number là mã đơn hàng khách/seller nhìn thấy và trao đổi (VD tra cứu, khiếu nại), khác với id kỹ thuật.

4.2 Quan hệ cần làm rõ

Quan hệ Xoá bên "một" thì bên "nhiều" ra sao Bắt buộc có quan hệ? Đổi được sang bên khác? BR
CART → CART_ITEM Không áp dụng "xoá" CART — chỉ chuyển trạng thái (§3); xoá CART_ITEM riêng lẻ là hành vi hợp lệ (US-003) ✅ mỗi CART_ITEM luôn thuộc đúng 1 CART ❌ —
ORDER → ORDER_SELLER Không áp dụng "xoá" ORDER (bắt buộc giữ dấu vết tài chính) ✅ mỗi ORDER_SELLER luôn thuộc đúng 1 ORDER cha ❌ BR-CART-01
ORDER_SELLER → ORDER_ITEM Không áp dụng "xoá" ✅ ❌ BR-CART-01
ORDER → PAYMENT Không áp dụng "xoá" 🔶 một ORDER có 0 hoặc 1 PAYMENT tại một thời điểm — trường hợp đổi phương thức thanh toán giữa chừng (huỷ Payment cũ, tạo Payment mới) chưa được chốt, xem OQ mới nếu phát sinh ở GĐ3 🔶 xem trên BR-CART-04

4.3 Thực thể ngoài phạm vi

Thực thể có nhắc tới nhưng do module/service khác sở hữu — nêu rõ để không ai định tạo bảng cho nó trong phạm vi module Giỏ hàng & Checkout.

Thực thể Ai sở hữu Lấy về bằng cách nào Cache không
CUSTOMER Module Tài khoản (FR-01/FR-03, Identity & Access) Tham chiếu qua customer_id (FK logic) Không cache PII ngoài những trường cần thiết cho hiển thị checkout (địa chỉ, tên người nhận) — chi tiết mã hoá/cache thuộc Tech Lead/GĐ3
SELLER Module Quản trị Seller (FR-17/FR-23) Tham chiếu qua seller_id (FK logic) Cache tên hiển thị seller cho màn hình giỏ hàng — không cache dữ liệu KYC/tài chính của seller
PRODUCT_VARIANT Module Catalog & Tìm kiếm (FR-04/FR-18) Tham chiếu qua product_variant_id; giá được snapshot vào CART_ITEM/ORDER_ITEM tại thời điểm thêm giỏ/đặt hàng (xem ASM-06, OQ-009) Có — snapshot giá tại thời điểm thêm giỏ, cần đối chiếu lại khi checkout (US-004)

5. Công thức tính toán

ID Đại lượng Công thức Đơn vị Làm tròn Nguồn dữ liệu Ví dụ
BR-CART-08 Tổng tiền một OrderSeller Σ (ORDER_ITEM.quantity × ORDER_ITEM.unit_price) — chưa chốt có gồm phí vận chuyển ước tính (US-005) hay không VND Chưa chốt — cần OQ mới ở GĐ3 nếu phát sinh ORDER_ITEM (chưa có ví dụ số cụ thể — chờ chốt có gồm phí ship không)
BR-CART-09 Tổng tiền Order (cha) Σ (ORDER_SELLER.subtotal_amount) VND Không làm tròn thêm (đã làm tròn ở từng OrderSeller) ORDER_SELLER Đơn A: 250.000đ + Đơn B: 180.000đ = 430.000đ

🔴 BR-CART-08 chưa chốt được vì phụ thuộc: (a) phí vận chuyển có tính vào subtotal_amount hay tách riêng một trường phí ship, và (b) coupon/điểm thưởng (module khác, OQ-004/DEC-03) áp giảm giá ở cấp Order hay từng OrderSeller. Đây là khoảng trống thật cần Tech Lead + PO xác nhận trước khi viết AC ở GĐ3 — không tự chọn cách tính.

6. Kiểm tra mâu thuẫn giữa các rule

Đối chiếu từng cặp rule cùng tác động lên một thực thể (ORDER_SELLER, PAYMENT).

# Rule A Rule B Mâu thuẫn ở đâu Trạng thái
1 BR-CART-02 (giữ tồn kho, chặn nếu thiếu) BR-CART-01 (tách đơn theo seller) Không mâu thuẫn trực tiếp — BR-CART-02 chạy trước BR-CART-01 trong luồng (xem PROCESS B1 sơ đồ: kiểm tra tồn kho ở D1 trước khi tách đơn ở B5) ✅ Không mâu thuẫn — đã xác nhận thứ tự
2 BR-CART-03 (giới hạn COD, chưa chốt) BR-CART-04 (mọi phương thức đều được chọn tự do) Nếu PO chốt BR-CART-03 theo phương án (a) giới hạn giá trị, nó sẽ thu hẹp BR-CART-04 (không còn "tự do chọn mọi phương thức" cho đơn giá trị cao) — cần cập nhật BR-CART-04 khi BR-CART-03 chốt 🔴 Chờ PO quyết — OQ-006
3 BR-CART-06 (chặn khi webhook không hợp lệ/quá hạn) Nhu cầu trải nghiệm khách "biết ngay kết quả thanh toán" (RISK-02) Nếu thời gian chờ webhook quá dài, khách không biết đơn có được xác nhận hay không — không phải mâu thuẫn giữa hai rule mà là khoảng trống thiết kế (cơ chế đối soát bù) chưa có rule nào lấp — xem PROCESS B9, ngoài phạm vi US module này 🟠 Ghi nhận là khoảng trống, không phải mâu thuẫn rule-rule

Kết luận: không phát hiện mâu thuẫn rule-rule nghiêm trọng trong phạm vi các rule đã chốt được nội dung. Mâu thuẫn tiềm ẩn ở dòng #2 phụ thuộc hoàn toàn vào việc PO trả lời OQ-006.

7. Rule của hệ thống hiện tại bị thay đổi

Không áp dụng — LIFECYCLE = greenfield, không có hệ thống/rule cũ nào bị thay đổi bởi module này (xác nhận F7, ELICITATION_CartCheckout_2026-09-08.md).

8. Open Questions

ID Câu hỏi Hỏi ai Từ ngày Chặn gì
OQ-006 (GĐ1, nhắc lại) Giới hạn giá trị đơn COD là gì? PO, Kế toán đối soát 2026-09-08 BR-CART-03
OQ-010 Xác nhận khả thi ASM-01 (webhook VNPay/Momo) Tech Lead 2026-09-08 BR-CART-06
OQ-011 Xác nhận ASM-03 — giỏ N seller luôn tách đúng N đơn, không gộp PO 2026-09-08 BR-CART-01
OQ-013 Payment.status của COD ghi "success" ngay hay giữ "pending" tới khi thực thu? Kế toán đối soát, PO 2026-09-08 PAYMENT §3 bảng chuyển #1
(mới) OQ-014 Order.total_amount/OrderSeller.subtotal_amount có gồm phí vận chuyển ước tính (US-005) không? Coupon/điểm thưởng áp giảm giá ở cấp Order hay từng OrderSeller? PO, Tech Lead 2026-09-08 BR-CART-08/09, US-005, AC ở GĐ3

9. Ngoài phạm vi

  • Thông điệp lỗi hiển thị nguyên văn (VD nội dung E-CART-0001) → GĐ3 SRS §bảng mã lỗi
  • Ai được thực hiện hành động → RBAC_CartCheckout_v1.0.md
  • Công thức tính hoa hồng, payout, điểm loyalty (BR-03…BR-08 ở SAD) → module Commission & Payout / Promotion & Loyalty, ngoài phạm vi module này
  • Cơ chế đối soát bù thanh toán chi tiết (reconciliation job) → thiết kế kỹ thuật GĐ3 của module Thanh toán