improve BA skill
This commit is contained in:
267
ba-output/e-commerce/03-specification/AC_US-003_v1.0.md
Normal file
267
ba-output/e-commerce/03-specification/AC_US-003_v1.0.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# AC — Acceptance Criteria — US-003 Sửa số lượng / xoá sản phẩm trong giỏ hàng
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Version** | 1.0 |
|
||||
| **Date** | 2026-09-08 |
|
||||
| **Author** | BA (qua skill ba-3-specification) |
|
||||
| **Status** | 🟡 Draft |
|
||||
| **Approved by** | QA: — *(chưa có QA thật tham gia lần chạy này)* |
|
||||
| **Source** | `SRS_US002-003_v1.0.md` · `RBAC_CartCheckout_v1.0.md` §6 · `BR_CartCheckout_v1.0.md` §3 |
|
||||
| **Scope** | US-003 |
|
||||
|
||||
## Change Log
|
||||
|
||||
| Version | Date | Người sửa | Thay đổi | CR |
|
||||
|---|---|---|---|---|
|
||||
| 1.0 | 2026-09-08 | BA (qua skill ba-3-specification) | Bản đầu — 13 AC, 4 nhóm (2 AC còn mở chờ `OQ-028`/`OQ-032`, ghi rõ thay vì bịa) | — |
|
||||
|
||||
---
|
||||
|
||||
## 1. Bốn nhóm bắt buộc
|
||||
|
||||
| Nhóm | Nội dung | Tối thiểu | Số AC đã viết |
|
||||
|---|---|---|---|
|
||||
| 1. Luồng thành công | Tăng/giảm số lượng, xoá dòng, xoá nhóm, xoá giỏ, huỷ modal | 1/hành động | 6 |
|
||||
| 2. Validation | Số lượng không hợp lệ; số lượng về 0 | 1/rule | 2 (1 còn mở — `OQ-028`) |
|
||||
| 3. Lỗi hệ thống | 5xx cập nhật, timeout xoá, item bị xoá đồng thời | ≥1 | 3 |
|
||||
| 4. Phân quyền | Sửa/xoá CartItem không thuộc quyền sở hữu (Customer, Guest) | ≥1/vai trò | 2 (1 còn mở — `OQ-032`) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Danh sách AC
|
||||
|
||||
### Nhóm 1 — Luồng thành công
|
||||
|
||||
#### AC-US003-01 — Tăng số lượng CartItem thành công
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Liên quan** | SCR-04 · F01, C08, C09 |
|
||||
| **Vai trò** | ROLE-02 (tương tự ROLE-01) |
|
||||
|
||||
```
|
||||
Given CartItem X có quantity=2, Cart.status=active
|
||||
When tôi bấm nút "+" (F01) để tăng số lượng lên 3
|
||||
Then hệ thống gọi PATCH /v1/cart/items/{X} với quantity=3, nhận 200 OK
|
||||
And F01 hiển thị 3; tạm tính nhóm (C08) và tổng cộng (C09) cập nhật lại ngay theo giá trị mới
|
||||
```
|
||||
|
||||
#### AC-US003-02 — Giảm số lượng CartItem thành công (còn ≥1)
|
||||
|
||||
```
|
||||
Given CartItem X có quantity=3
|
||||
When tôi bấm nút "-" (F01) để giảm còn 2
|
||||
Then PATCH thành công, F01=2, C08/C09 cập nhật
|
||||
```
|
||||
|
||||
#### AC-US003-03 — Xoá CartItem thành công (đã xác nhận modal)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Liên quan** | SCR-04 · C07, C08, C09 |
|
||||
| **Vai trò** | ROLE-02 |
|
||||
|
||||
```
|
||||
Given CartItem X tồn tại trong nhóm seller "Shop A" (nhóm đang có 2 CartItem)
|
||||
When tôi bấm "Xoá" (C07) trên CartItem X, modal xác nhận hiện ra (theo UICONV §5), tôi bấm
|
||||
nút xác nhận trong modal
|
||||
Then hệ thống gọi DELETE /v1/cart/items/{X}, nhận 200/204
|
||||
And dòng CartItem X biến mất khỏi danh sách; tạm tính nhóm "Shop A" (C08) cập nhật (còn
|
||||
1 CartItem); tổng cộng (C09) cập nhật
|
||||
```
|
||||
|
||||
#### AC-US003-04 — Xoá CartItem cuối cùng của một nhóm seller
|
||||
|
||||
```
|
||||
Given nhóm seller "Shop B" chỉ có 1 CartItem
|
||||
When tôi xoá CartItem đó (đã xác nhận modal)
|
||||
Then toàn bộ khối nhóm "Shop B" (C02 + dòng CartItem) biến mất khỏi màn hình — không hiển
|
||||
thị một nhóm rỗng không có dòng nào
|
||||
```
|
||||
|
||||
#### AC-US003-05 — Xoá CartItem cuối cùng của toàn giỏ hàng
|
||||
|
||||
```
|
||||
Given giỏ hàng chỉ còn duy nhất 1 CartItem (1 nhóm, 1 dòng)
|
||||
When tôi xoá CartItem đó (đã xác nhận modal)
|
||||
Then màn hình chuyển sang trạng thái "Giỏ hàng trống" (theo SRS §2.A.3.6); nút
|
||||
"Tiến hành Checkout" (C11) ẩn/disable
|
||||
And Cart.status vẫn là active (KHÔNG tự chuyển abandoned — theo BR §3, chỉ hết hạn phiên
|
||||
mới chuyển abandoned)
|
||||
```
|
||||
|
||||
#### AC-US003-06 — Huỷ modal xác nhận xoá
|
||||
|
||||
```
|
||||
Given modal xác nhận xoá CartItem X đang mở
|
||||
When tôi bấm nút huỷ hoặc đóng modal (không xác nhận)
|
||||
Then CartItem X vẫn còn nguyên trong danh sách; không có request DELETE nào được gửi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Nhóm 2 — Validation
|
||||
|
||||
#### AC-US003-07 — Nhập số lượng không phải số nguyên dương hợp lệ
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Liên quan** | SCR-04 · F01 |
|
||||
| **Vai trò** | ROLE-02 |
|
||||
|
||||
```
|
||||
Given CartItem X có quantity=2
|
||||
When tôi nhập trực tiếp vào F01 giá trị không hợp lệ (VD "-1", "1.5", "abc", để trống)
|
||||
Then hệ thống hiện lỗi inline dưới F01: "Số lượng phải là số nguyên từ 1 trở lên."
|
||||
(E-CART-0002)
|
||||
And không gửi request PATCH; F01 giữ nguyên giá trị hợp lệ trước đó (không lưu giá trị lỗi)
|
||||
```
|
||||
|
||||
#### AC-US003-08 — Giảm số lượng về 0 *(🔴 chưa viết được đầy đủ — chờ `OQ-028`)*
|
||||
|
||||
```
|
||||
Given CartItem X có quantity=1 (đã ở mức tối thiểu)
|
||||
When tôi bấm nút "-" hoặc nhập trực tiếp "0" vào F01
|
||||
Then 🔴 CHƯA XÁC ĐỊNH — phụ thuộc OQ-028 (PO chưa chốt: (a) chặn nút "-"/nhập 0, hiện
|
||||
thông báo giữ tối thiểu 1, hay (b) tự động mở modal xác nhận xoá dòng)
|
||||
```
|
||||
|
||||
*QA không viết test case cho AC này cho tới khi `OQ-028` được trả lời — đây là chỗ SRS chưa
|
||||
viết xong, không phải QA bỏ sót.*
|
||||
|
||||
---
|
||||
|
||||
### Nhóm 3 — Lỗi hệ thống
|
||||
|
||||
#### AC-US003-09 — Server lỗi 5xx khi cập nhật số lượng
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Liên quan** | SCR-04 · F01 |
|
||||
| **Vai trò** | ROLE-02 |
|
||||
|
||||
```
|
||||
Given CartItem X có quantity=2
|
||||
When tôi đổi thành 5 (bấm "+" 3 lần hoặc nhập tay) và PATCH /v1/cart/items/{X} trả 500
|
||||
Then hệ thống hiện banner lỗi tại dòng CartItem: "Không thể cập nhật giỏ hàng, thử lại."
|
||||
(E-CART-0006)
|
||||
And 🔴 F01 trở về giá trị trước đó (2), KHÔNG giữ giá trị đã nhập lỗi (5); nút +/- mở lại
|
||||
được bấm ngay
|
||||
```
|
||||
|
||||
#### AC-US003-10 — Timeout khi xoá CartItem
|
||||
|
||||
```
|
||||
Given tôi bấm "Xoá" trên CartItem X (đã xác nhận modal)
|
||||
When request DELETE bị timeout theo ngưỡng NFR §1 (xem OQ-033)
|
||||
Then hệ thống hiện banner lỗi tại dòng: "Không thể cập nhật giỏ hàng, thử lại." (E-CART-0006)
|
||||
And CartItem X vẫn hiển thị trong danh sách (không xoá khỏi giao diện khi chưa có xác nhận
|
||||
từ server); nút "Xoá" bấm lại được
|
||||
```
|
||||
|
||||
#### AC-US003-11 — CartItem đã bị xoá bởi thao tác khác (đồng thời, VD 2 tab)
|
||||
|
||||
```
|
||||
Given CartItem X đang hiển thị trên màn hình của tôi, nhưng đã bị xoá khỏi giỏ hàng ở một
|
||||
tab/thiết bị khác trước đó
|
||||
When tôi bấm sửa số lượng (F01) hoặc bấm "Xoá" (C07) trên CartItem X
|
||||
Then PATCH/DELETE trả 404 ERR_NOT_FOUND hoặc 409 ERR_CONFLICT (xem API §4)
|
||||
And hệ thống hiện banner "Sản phẩm này đã được xoá khỏi giỏ hàng trước đó." (E-CART-0003),
|
||||
sau đó ẩn dòng CartItem X khỏi danh sách và cập nhật lại C08/C09
|
||||
```
|
||||
|
||||
Ba tình huống tối thiểu của nhóm này:
|
||||
|
||||
| # | Tình huống | AC |
|
||||
|---|---|---|
|
||||
| 1 | Server trả 5xx | AC-US003-09 |
|
||||
| 2 | Timeout / mất mạng | AC-US003-10 |
|
||||
| 3 | Dữ liệu bị người khác sửa/xoá trong lúc mình đang mở | AC-US003-11 |
|
||||
|
||||
---
|
||||
|
||||
### Nhóm 4 — Phân quyền
|
||||
|
||||
#### AC-US003-12 — Gọi thẳng API sửa/xoá CartItem không thuộc quyền sở hữu (Customer)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Liên quan** | SCR-04 |
|
||||
| **Vai trò** | ROLE-02 |
|
||||
|
||||
```
|
||||
Given tôi đăng nhập ROLE-02 với customerId = A; CartItem Y thuộc Cart của customerId = B
|
||||
When tôi gọi thẳng PATCH /v1/cart/items/{Y} với token của A
|
||||
Then hệ thống trả 403 ERR_FORBIDDEN_OWNERSHIP (E-CART-0005), không cập nhật CartItem Y
|
||||
And không có thông tin nào của CartItem Y bị lộ ra trong response lỗi
|
||||
```
|
||||
|
||||
#### AC-US003-13 — Guest cố sửa/xoá CartItem không thuộc session của mình *(🔴 chưa viết được đầy đủ — chờ `OQ-032`)*
|
||||
|
||||
```
|
||||
Given tương tự AC-US003-12 nhưng với ROLE-01 (Guest): X-Guest-Session-Id = S1 của tôi,
|
||||
CartItem Z thuộc Cart của session S2
|
||||
When tôi gọi thẳng PATCH /v1/cart/items/{Z} với X-Guest-Session-Id: S1
|
||||
Then 🔴 CHƯA XÁC ĐỊNH — đề xuất BA: trả 403 ERR_FORBIDDEN_OWNERSHIP (E-CART-0005) giống hệt
|
||||
AC-US003-12, cần Tech Lead xác nhận cơ chế đối chiếu session_id (OQ-032) trước khi coi
|
||||
AC này là chốt
|
||||
```
|
||||
|
||||
🔴 Chặn ở giao diện là trải nghiệm, **chặn ở backend mới là bảo mật**. Cả hai AC nhóm này đều
|
||||
kiểm tra gọi thẳng API, không chỉ kiểm tra ẩn nút trên giao diện.
|
||||
|
||||
---
|
||||
|
||||
## 3. Bảng dữ liệu biên
|
||||
|
||||
| Field | Dưới ngưỡng | Ngưỡng dưới | Trong khoảng | Ngưỡng trên | Trên ngưỡng | Rỗng | Ký tự đặc biệt | Khoảng trắng đầu/cuối |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| F01 Số lượng (≥1, ngưỡng trên **chưa chốt** — `OQ-030`) | `0` → lỗi `E-CART-0002` (hành vi cụ thể — `OQ-028`) | `1` → OK | `5` → OK | 🔴 chưa có ngưỡng trên xác nhận — `OQ-030` | 🔴 chưa có ngưỡng trên — `OQ-030` | Xoá trắng ô nhập → lỗi bắt buộc (`E-CART-0002`) | `"abc"`, `"1.5"`, `"-1"` → lỗi `E-CART-0002` | N/A — F01 là input dạng số (`type=number`), không nhận khoảng trắng |
|
||||
|
||||
---
|
||||
|
||||
## 4. Kịch bản kết hợp
|
||||
|
||||
| # | Kịch bản | Các bước | AC liên quan |
|
||||
|---|---|---|---|
|
||||
| S1 | Sửa số lượng rồi xoá hết một nhóm seller | SCR-04 (mở) → sửa số lượng CartItem của "Shop B" (tổng cập nhật) → xoá cả 2 CartItem còn lại của "Shop B" → nhóm "Shop B" biến mất, tổng cộng chỉ còn của "Shop A" | AC-US003-01, 03, 04 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Truy vết
|
||||
|
||||
| AC | US | BR | Field/Thành phần | Mã lỗi | Test case (QA điền) | Kết quả (QA điền) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| AC-US003-01 | US-003 | BR §3 CART | F01, C08, C09 | — | | |
|
||||
| AC-US003-02 | US-003 | BR §3 CART | F01, C08, C09 | — | | |
|
||||
| AC-US003-03 | US-003 | BR §3 CART | C07, C08, C09 | — | | |
|
||||
| AC-US003-04 | US-003 | — | C02, C07 | — | | |
|
||||
| AC-US003-05 | US-003 | BR §3 CART | C07, C10, C11 | — | | |
|
||||
| AC-US003-06 | US-003 | — | C07 | — | | |
|
||||
| AC-US003-07 | US-003 | — | F01 | E-CART-0002 | | |
|
||||
| AC-US003-08 | US-003 | — | F01 | E-CART-0002 (dự kiến) | *(chờ OQ-028)* | |
|
||||
| AC-US003-09 | US-003 | — | F01 | E-CART-0006 | | |
|
||||
| AC-US003-10 | US-003 | — | C07 | E-CART-0006 | | |
|
||||
| AC-US003-11 | US-003 | — | F01, C07 | E-CART-0003 | | |
|
||||
| AC-US003-12 | US-003 | RBAC §6 | — | E-CART-0005 | | |
|
||||
| AC-US003-13 | US-003 | RBAC §6 | — | E-CART-0005 (dự kiến) | *(chờ OQ-032)* | |
|
||||
|
||||
---
|
||||
|
||||
## 6. Xác nhận của QA
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Người xác nhận** | *(chưa có — chưa có QA thật tham gia lần chạy này)* |
|
||||
| **Ngày** | — |
|
||||
| ☐ Mọi AC đều test được (2 AC còn mở, chờ OQ trước khi viết test case) | |
|
||||
| ☐ Đủ 4 nhóm | |
|
||||
| ☐ Bảng dữ liệu biên đủ dùng để viết test case | |
|
||||
| ☐ Không có AC nào mâu thuẫn với AC khác | |
|
||||
|
||||
**AC bị QA từ chối:**
|
||||
|
||||
| AC | Lý do từ chối | BA sửa thế nào |
|
||||
|---|---|---|
|
||||
| | | |
|
||||
Reference in New Issue
Block a user