142 lines
13 KiB
Markdown
142 lines
13 KiB
Markdown
# RBAC — Ma trận phân quyền — 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` · `BACKLOG_CartCheckout_v1.0.md` · `BR_CartCheckout_v1.0.md` · `01-discovery/RISK_CartCheckout_v1.0.md` (RISK-01 phương án OTP) |
|
||
| **Scope** | Module Giỏ hàng & Checkout — RQ-001…RQ-004. Chỉ 2 vai trò buyer-side (Guest, Customer); vai trò nội bộ (Seller, Admin, CSR, Ops) **không** thao tác trực tiếp trong phạm vi RQ-001…004, xem ghi chú §1. |
|
||
|
||
## 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 — 2 vai trò, ma trận 8 hành động | — |
|
||
|
||
---
|
||
|
||
> ⚠️ **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`.
|
||
|
||
## 0. Vì sao không bỏ RBAC dù chỉ có 2 vai trò
|
||
|
||
`domain-profiles.md`/`workflow.md` §2 cho phép bỏ `RBAC` ở `RIGOR = light` nếu **đúng 1 vai
|
||
trò**. Dự án này ở `RIGOR = standard` (không được bớt theo bảng "Bớt ở light"), và module này
|
||
có **2 vai trò** (Guest, Customer) với phạm vi dữ liệu khác nhau (Guest theo phiên, Customer
|
||
theo tài khoản) — nên `RBAC` vẫn bắt buộc, không được ghi "1 vai trò" để bỏ qua.
|
||
|
||
## 1. Vai trò
|
||
|
||
| ID | Vai trò | Ai thuộc vai trò này | Số người ước tính | Phạm vi dữ liệu | Vai trò hệ thống hiện có |
|
||
|---|---|---|---|---|---|
|
||
| ROLE-01 | Guest | Người dùng chưa đăng nhập, có `session_id` | Không giới hạn (bất kỳ ai truy cập web không đăng nhập) — theo mục tiêu quy mô "lớn" ở `BRIEF` §2 | Chỉ `Cart`/`Order` gắn với `session_id` của chính phiên đó | *(chưa có trong hệ thống — module đầu tiên, tạo mới)* |
|
||
| ROLE-02 | Customer | Người dùng đã đăng nhập (`user_account.role = customer`, theo tham chiếu SAD §5.2.1, không phải quyết định của module này) | Không giới hạn — hàng trăm nghìn–hàng triệu theo `BRIEF` §2 | Chỉ `Cart`/`Order` gắn với `customer_id` của chính họ | *(chưa có trong hệ thống — module đầu tiên, tạo mới)* |
|
||
|
||
**Vai trò cố ý không đưa vào ma trận này** (thuộc module khác, ngoài phạm vi RQ-001…004):
|
||
|
||
| Vai trò | Vì sao không có trong module này |
|
||
|---|---|
|
||
| Seller | Không thao tác trực tiếp lên `Cart`/`Order` lúc checkout — chỉ nhận `OrderSeller` sau khi đã tạo (thuộc FR-19, module Quản lý đơn hàng seller) |
|
||
| PlatformAdmin | Không có hành động quản trị nào trong phạm vi RQ-001…004 (không cấu hình/can thiệp giỏ hàng hay checkout của khách) |
|
||
| CSR / Ops | Có thể cần tra cứu đơn "kẹt chờ thanh toán" (`RISK-02`, xem `PROCESS` B9), nhưng đây là hành động **thuộc luồng xử lý sự cố sau checkout**, không phải một hành động của RQ-001…004 — nếu phát sinh nhu cầu tra cứu, cần `RBAC` riêng ở module Thanh toán/CSKH, ghi nhận là `OQ` mới nếu phát sinh ở GĐ3 |
|
||
|
||
## 2. Ma trận vai trò × hành động
|
||
|
||
*Ô ghi: `✅` được · `❌` không · `🔶` được nhưng có điều kiện (điều kiện ghi ngay trong ô).*
|
||
|
||
| Hành động | ROLE-01<br>Guest | ROLE-02<br>Customer | BR |
|
||
|---|---|---|---|
|
||
| Xem giỏ hàng của mình | ✅ (theo `session_id`) | ✅ (theo `customer_id`) | — |
|
||
| Thêm sản phẩm vào giỏ | ✅ | ✅ | — |
|
||
| Sửa số lượng / xoá sản phẩm trong giỏ | ✅ | ✅ | — |
|
||
| Xem giỏ hàng / đơn hàng của người khác | ❌ | ❌ | — |
|
||
| Nhập/chọn địa chỉ giao hàng lúc checkout | 🔶 chỉ nhập mới, không có sổ địa chỉ đã lưu (không có tài khoản) | ✅ chọn từ `customer_address` đã lưu hoặc nhập mới | BR-CART-07 |
|
||
| Xác nhận đặt hàng (tạo `Order` + tách `OrderSeller`) | ✅ (BR-CART-07 — đủ thông tin liên hệ tối thiểu) | ✅ | BR-CART-01, BR-CART-02, BR-CART-07 |
|
||
| Chọn phương thức thanh toán (COD/VNPay/Momo) | ✅ | ✅ | BR-CART-04 |
|
||
| Xem kết quả đặt hàng/thanh toán ngay sau khi hoàn tất (của chính đơn vừa tạo) | ✅ | ✅ | — |
|
||
| Tra cứu lại đơn đã đặt sau khi rời phiên | 🔶 chỉ trong thời hạn phiên còn hiệu lực (chưa chốt số ngày cụ thể — xem `BR_CartCheckout` §3 `CART`); hết phiên thì **không** tra cứu lại được vì không có tài khoản | ✅ không giới hạn thời gian (thuộc FR-08, tham chiếu, ngoài phạm vi chi tiết hoá ở module này) | — |
|
||
|
||
**Kiểm tra chất lượng ma trận:** không có cột nào toàn ✅ tuyệt đối — cả hai vai trò đều có ít
|
||
nhất một hành động ❌ (xem đơn hàng của người khác) hoặc 🔶 (tra cứu lại sau khi rời phiên đối
|
||
với Guest). Đã hỏi ngược *"vai trò nào KHÔNG được làm việc gì"*: cả Guest và Customer đều
|
||
**không** được xem giỏ hàng/đơn hàng của người khác — đây là ranh giới cốt lõi của module.
|
||
|
||
## 3. Separation of Duties (SoD)
|
||
|
||
🔴 **Không có bảng SoD với nội dung cặp hành động xung đột trong phạm vi RQ-001…004.** Lý do,
|
||
ghi rõ thay vì để trống theo đúng quy tắc "🔶 không điều kiện = chưa phân tích xong":
|
||
|
||
> Mọi hành động trong ma trận §2 (tạo giỏ, tách đơn, chọn thanh toán) đều do **chính khách hàng
|
||
> tự thực hiện trên dữ liệu của họ (self-service)**, không có bước "người thứ hai duyệt/chốt
|
||
> sổ" nào trong phạm vi module này — việc tách đơn (BR-CART-01) và xác nhận thanh toán
|
||
> (BR-CART-06) đều do **hệ thống tự động thực hiện theo rule**, không phải một nhân sự nội bộ
|
||
> phê duyệt. Do đó khái niệm SoD ("người tạo không được tự duyệt") **không áp dụng được** ở
|
||
> đây theo đúng nghĩa — không có ai "duyệt" ngoài chính hệ thống.
|
||
>
|
||
> Điều này **không có nghĩa là module này không cần audit**: mọi lần tạo `Order`/`Payment`
|
||
> vẫn phải ghi vết (ai, lúc nào, giá trị) — xem §5. SoD sẽ trở nên cần thiết khi module Quản lý
|
||
> đơn hàng (FR-08/19/25, ngoài phạm vi) có bước Seller/CSR/Admin can thiệp thủ công (VD CSR
|
||
> duyệt hoàn tiền) — `RBAC` của module đó phải có SoD riêng.
|
||
|
||
| ID | Cặp hành động xung đột | Quy tắc | Hệ thống chặn thế nào | Ai giám sát |
|
||
|---|---|---|---|---|
|
||
| *(không có trong phạm vi module này — xem giải thích trên)* | | | | |
|
||
|
||
## 4. Dữ liệu nhạy cảm
|
||
|
||
| Trường/dữ liệu | Loại | Ai được xem | Che thế nào | Xuất được không | Lưu bao lâu | Căn cứ |
|
||
|---|---|---|---|---|---|---|
|
||
| Địa chỉ giao hàng (`recipient_name`, `phone`, `address_line`) | PII | Chính Customer/Guest chủ đơn; hệ thống truyền cho seller tương ứng khi tách đơn (bắt buộc để giao hàng) | Không che khi hiển thị cho chính chủ; **mức che khi hiển thị cho seller — chưa chốt, liên quan `RISK-03` (chưa có đại diện Pháp chế)** | ❌ Không tự xuất được trong phạm vi module này | *(chưa chốt — xem `RISK` §GĐ1 mục retention, thuộc phạm vi Pháp chế/Bảo mật, `OQ-003`)* | `RISK-03`, NĐ13/2023 (dẫn theo `BRIEF` §7) |
|
||
| Số điện thoại | PII | Tương tự trên | Tương tự trên | ❌ | Tương tự trên | Tương tự trên |
|
||
| Giá trị giao dịch thanh toán (`Payment.amount`) | Tài chính | Chính chủ đơn; nội bộ Kế toán đối soát (STK-04) qua báo cáo — **ngoài phạm vi màn hình của module này** | Không che với chính chủ | ❌ Không tự xuất trong phạm vi module này | *(chưa chốt — thuộc lưu trữ chứng từ tài chính, ngoài phạm vi BA module này)* | NFR-05 |
|
||
| `gateway_transaction_ref` (VNPay/Momo) | Tài chính/kỹ thuật | Chính chủ đơn (chỉ hiển thị tham chiếu, không hiển thị chi tiết cổng thanh toán) | Không hiển thị đầy đủ chuỗi thô nếu chứa thông tin nội bộ cổng thanh toán — **chi tiết che thế nào chưa chốt, để GĐ3 xác nhận với Tech Lead** | ❌ | — | BR-CART-05 |
|
||
|
||
🔴 **Không có trường thẻ thanh toán** (số thẻ/CVV) trong phạm vi module này theo `BR-CART-05` —
|
||
không có gì để phân tích thêm ở dòng này, ghi nhận rõ để tránh hiểu nhầm là bị bỏ sót.
|
||
|
||
## 5. Lưu vết (audit)
|
||
|
||
| Hành động | Ghi vết | Nội dung ghi | Giữ bao lâu | Ai xem được |
|
||
|---|---|---|---|---|
|
||
| Tạo `Order`/`OrderSeller` (checkout) | ✅ | ai (customer_id/session_id) · lúc nào · nội dung đơn (US-004) | *(chưa chốt — liên quan retention dữ liệu tài chính, ngoài phạm vi quyết định của module này, xem `IMPACT` §1.6)* | Chính chủ đơn (qua tra cứu); nội bộ — ngoài phạm vi màn hình module này |
|
||
| Khởi tạo thanh toán / cập nhật `Payment.status` | ✅ | ai · lúc nào · phương thức · kết quả (BR-CART-06) | *(chưa chốt — tương tự trên)* | Tương tự trên |
|
||
| Đăng nhập/định danh Guest thất bại hoặc bất thường (VD spam tạo đơn liên tục) | 🔶 **Chưa chốt có cần cơ chế chống lạm dụng (rate limit) cho Guest checkout không** | — | — | — |
|
||
|
||
Ba câu hỏi cho mỗi hành động nhạy cảm:
|
||
1. **Ai được xem** — đã trả lời ở §4: chỉ chính chủ đơn trong phạm vi màn hình module này.
|
||
2. **Có cần lưu vết** — có, cho mọi hành động tạo `Order`/`Payment` (đúng theo nguyên tắc dữ
|
||
liệu tài chính phải có dấu vết), nhưng **thời hạn lưu cụ thể chưa chốt** — xem `IMPACT`
|
||
§1.6 và ghi chú retention ở GĐ1.
|
||
3. **Có cần lý do** — không áp dụng cho hành động tự phục vụ của khách hàng (tạo đơn/thanh
|
||
toán là quyền tự nhiên của họ, không cần giải trình lý do).
|
||
|
||
## 6. Hành vi khi không đủ quyền
|
||
|
||
*Quy tắc W7 — ba trạng thái khác nhau: không hiển thị · hiển thị nhưng disable · hiển thị và
|
||
read-only.*
|
||
|
||
| Tình huống | Hành vi | Lý do |
|
||
|---|---|---|
|
||
| Guest/Customer cố xem giỏ hàng/đơn hàng của người khác (đoán ID/URL) | Không hiển thị dữ liệu, trả lỗi từ chối truy cập (mã lỗi cụ thể — GĐ3) | Tránh lộ dữ liệu PII/tài chính của người khác |
|
||
| Guest cố tra cứu lại đơn sau khi hết hạn phiên | Không hiển thị được đơn cũ — hệ thống coi như phiên mới, **hành vi UX cụ thể (thông báo gì) chưa chốt, để GĐ3** | Guest không có cơ chế xác thực định danh liên phiên |
|
||
| Guest/Customer bấm "Đặt hàng" khi giỏ hàng không đủ tồn kho | Hiện nút, nhưng chặn hành động khi bấm, báo lỗi cụ thể theo item (BR-CART-02) — **không disable trước vì tồn kho có thể đổi liên tục (ASM-06)** | Giữ trải nghiệm mượt, tránh disable sai do dữ liệu tồn kho chưa cập nhật kịp |
|
||
| Guest/Customer bấm "Xác nhận đặt hàng" khi chưa chọn phương thức thanh toán | Hiện nút, **disable** cho tới khi chọn phương thức (BR-CART-04) | Ngăn submit thiếu dữ liệu bắt buộc |
|
||
| Gọi thẳng API tạo đơn/thanh toán không đủ điều kiện (VD Guest thiếu field bắt buộc BR-CART-07) | Trả lỗi 4xx + ghi log, không tạo bản ghi | Chặn ở cả FE và BE (W7 nhắc: chặn UI là trải nghiệm, chặn BE mới là bảo mật) |
|
||
|
||
## 7. Thay đổi so với phân quyền hiện tại
|
||
|
||
*Không áp dụng — `LIFECYCLE = greenfield`, không có phân quyền cũ nào để so sánh (đây là vai
|
||
trò/quyền hoàn toàn mới của module đầu tiên).*
|
||
|
||
## 8. Open Questions
|
||
|
||
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì |
|
||
|---|---|---|---|---|
|
||
| OQ-012 | Guest có cần giới hạn giá trị đơn hoặc xác thực OTP cho đơn giá trị cao không (liên quan `RISK-01` phương án (b))? | PO, Bảo mật *(chưa có người — `OQ-003` ở GĐ1)* | 2026-09-08 | §2 hàng "Xác nhận đặt hàng", `BR-CART-03` |
|
||
| *(mới)* OQ-015 | Có cần cơ chế chống lạm dụng (rate limit/CAPTCHA) cho Guest checkout để tránh spam tạo đơn giả không? | Tech Lead, Bảo mật | 2026-09-08 | §5, thiết kế kỹ thuật GĐ3 |
|
||
| *(mới)* OQ-016 | Mức che dữ liệu PII (địa chỉ/SĐT) khi truyền cho seller lúc tách đơn là gì? | Pháp chế/Bảo mật *(chưa có người — `OQ-003`)*, PO | 2026-09-08 | §4, `RISK-03` |
|