Files
sys-analysis-design/ba-output/e-commerce/03-specification/WF_US002-003_v1.0.md
Leonard-ThindPad-P50 2c7bcde741 improve BA skill
2026-09-09 06:34:57 +07:00

218 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WF — Wireframe & bố cục — US-002, US-003 (SCR-04 Giỏ hàng)
| | |
|---|---|
| **Version** | 1.0 |
| **Date** | 2026-09-08 |
| **Author** | BA (qua skill ba-3-specification, activity `wf`) |
| **Status** | 🟡 Draft |
| **Approved by** | Designer: — · PO: — *(dự án không có Designer riêng — PO ký thay, `DEC-01`)* |
| **Source** | `SRS_US002-003_v1.0.md` v1.0 · `UICONV_e-commerce_v1.0.md` v1.1 · prototype: `e-commerce/docs/sections/07-giao-dien.md` §7.1.1 SCR-04 (status: approved, version 1) |
| **Scope** | US-002, US-003 · `SCR-04` |
| **Nguồn bố cục** | 🎨 **Prototype tham chiếu** — `e-commerce/docs/sections/07-giao-dien.md` §7.1.1 SCR-04, coi là nguồn sự thật về bố cục dạng văn bản (`DEC-01` v1.2) |
| **Tệp kèm** | `WF_US002-003_v1.0.html` |
## Change Log
| Version | Date | Người sửa | Thay đổi | CR |
|---|---|---|---|---|
| 1.0 | 2026-09-08 | BA (qua skill ba-3-specification, activity `wf`) | Bản đầu — bố cục `SCR-04` chế độ 🎨, 6 dòng lệch ở §5 (4 chưa quyết, 1 đã xử lý theo `UICONV` mặc định, 1 mức thấp không chặn) | — |
> **Quy ước đọc** *(quy tắc W11)*. Bảng thành phần trong `SRS` §2.A.3.1 quyết định **một phần tử
> có tồn tại không** và **hành xử thế nào**. Tài liệu này và tệp HTML kèm theo quyết định **nó
> nằm ở đâu, thứ tự nào, to bằng nào, trông ra sao ở từng trạng thái**. Mâu thuẫn ⇒ SRS thắng về
> tồn tại/hành vi, WF thắng về bố cục — mâu thuẫn đó được ghi ở §5, không im lặng.
---
## 0. Nguồn bố cục và độ tin cậy
| | |
|---|---|
| **Prototype tham chiếu** | `e-commerce/docs/sections/07-giao-dien.md` §7.1.1 SCR-04 — mô tả văn bản có cấu trúc (mục đích, persona, FR phục vụ, bố cục, 3 trạng thái, validation), `status: approved`, `version: 1` |
| **Định dạng** | Mô tả văn bản có cấu trúc (không phải Figma/ảnh) — SAD §7.0 xác nhận "không có brand guideline cố định" |
| **Mức phủ** | 1/1 màn hình của US-002/US-003 (`SCR-04`) có mô tả trong prototype |
| **Design system** | Chưa chọn — `OQ-022` (đã mở ở `UICONV`) |
| **Độ tin cậy** | 🎨 SAD §7 đã `approved` ở cấp SA/dự án ⇒ WF là **bản ghi lại** bố cục của SCR-04 và đối chiếu với `SRS` |
## 1. Bản đồ prototype ↔ màn hình
| SCR | Tên màn hình | Có trong prototype | Frame / trang / mục trong prototype | Mức khớp với SRS | Ghi chú |
|---|---|---|---|---|---|
| SCR-04 | Giỏ hàng | ✅ | SAD §7.1.1 "SCR-04 — Giỏ hàng" | 🔴 khác tồn tại/hành vi | 4 điểm lệch — xem §5 (#1–#4) |
## 2. Khung bố cục chung
*Lấy từ `UICONV` §1. Chỉ ghi phần khác/bổ sung cho SCR-04.*
| | |
|---|---|
| **Grid** | 🔴 Chưa chốt — `UICONV` §1, `OQ-018` (áp dụng chung, không riêng SCR-04) |
| **Vùng cố định** | Header toàn site kế thừa `SCR-01` (logo, tìm kiếm, `LanguageSwitcher`, `CurrencyToggle`, icon giỏ hàng, icon tài khoản) — theo `UICONV` §1. SCR-04 không có sidebar/menu cố định riêng |
| Breakpoint | Khoảng (px) | Bố cục | Nguồn |
|---|---|---|---|
| Desktop | ≥ 1024 *(ngưỡng chính xác — `OQ-018`)* | Danh sách nhóm seller full-width, sidebar tổng kết bên phải | `UICONV` §1 + SAD §7.1.1 (mô tả "Sidebar/footer tổng kết") |
| Tablet | 768–1023 | 🔴 Chưa mô tả riêng trong SAD — BA đề xuất giữ như desktop nhưng tổng kết chuyển xuống dưới danh sách (footer thay vì sidebar) | BA đề xuất, chưa xác nhận — mức thấp, không chặn G3 |
| Mobile | < 768 | Danh sách nhóm seller full-width, tổng kết chuyển thành **footer cố định đáy màn hình** ("Sidebar/footer tổng kết" — SAD dùng cả hai từ, BA diễn giải: sidebar ở desktop, footer ở mobile) | SAD §7.1.1 + BA diễn giải |
---
## 3. Bố cục từng màn hình
### 3.1 SCR-04 — Giỏ hàng
| | |
|---|---|
| **Loại** | Chi tiết (không phân trang) |
| **Prototype** | SAD §7.1.1 SCR-04 |
| **HTML** | `WF_US002-003_v1.0.html#SCR-04` |
| **Thành phần (SRS §2.A.3.1)** | C01–C13, F01 — khớp đủ (xem tự kiểm §"Tự chấm") |
#### 3.1.1 Bảng vùng
| Vùng | Tên | Vị trí desktop | Vị trí mobile | Chứa thành phần | Chiều rộng | Ưu tiên hiển thị |
|---|---|---|---|---|---|---|
| Z1 | Header màn hình | Hàng 1, full | Hàng 1, full | C01 | 100% | 1 |
| Z2 | Danh sách nhóm seller | Hàng 2, cột trái (2/3) | Hàng 2, full (trên footer tổng kết) | C02, C03, C04, C05, C06, F01, C07 (lặp theo nhóm/dòng) | 66% desktop / 100% mobile | 1 |
| Z3 | Tổng kết (sidebar desktop / footer mobile) | Hàng 2, cột phải (1/3), sticky | Cố định đáy màn hình | C09, C11 (C08 nằm trong từng nhóm ở Z2, không lặp lại ở Z3) | 33% desktop / 100% mobile | 1 |
| Z4 | Trạng thái đặc biệt (rỗng/lỗi) | Thay chỗ Z2 khi kích hoạt | Thay chỗ Z2 khi kích hoạt | C10, C12, C13 | Bằng Z2 | 1 |
*Ưu tiên hiển thị: 1 = luôn hiện.*
**Ghi chú vị trí C08 (tạm tính nhóm):** theo mô tả SAD "mỗi nhóm = 1 seller... tạm tính theo VND" nằm cuối mỗi khối nhóm trong Z2 (không phải trong Z3) — khác với cách trình bày "tổng kết ở sidebar" chỉ áp dụng cho **tổng toàn giỏ** (C09), không áp dụng cho tạm tính từng nhóm (C08).
#### 3.1.2 Vị trí thành phần
*Tập `C-id`/`F-id` phải khớp hai chiều với `SRS` §2.A.3.1 — xem "Tự chấm" cuối tài liệu.*
| C-id | Tên thành phần | Vùng | Thứ tự trong vùng | Kích thước / độ rộng | Kiểu trình bày | Phần tử trong prototype | Khớp |
|---|---|---|---|---|---|---|---|
| C01 | lbl_header_title | Z1 | 1 | auto | Tiêu đề cấp 1 | "Header: tiêu đề 'Giỏ hàng của bạn' + số lượng sản phẩm" | ✅ |
| C02 | grp_seller_header | Z2 | 1 (đầu mỗi nhóm, lặp) | 100% | Nhãn | "danh sách nhóm theo seller (mỗi nhóm = 1 seller, hiển thị tên gian hàng)" | ✅ |
| C03 | img_cart_item | Z2 | 1 (trong mỗi dòng) | 64px (đề xuất, chưa xác nhận — mức thấp) | Ảnh | "CartItem (ảnh...)" | ✅ |
| C04 | lbl_product_name | Z2 | 2 | auto | Nhãn | "CartItem (...tên...)" | ✅ |
| C05 | lbl_variant | Z2 | 3 | auto | Nhãn | "CartItem (...biến thể...)" | ✅ |
| C06 | lbl_unit_price | Z2 | 4 | auto | Nhãn | "CartItem (...đơn giá...)" | 🟠 *(nguồn giá — `OQ-029` — bố cục khớp, nội dung/nguồn dữ liệu chưa chốt)* |
| F01 | input_quantity | Z2 | 5 | 96px (đề xuất) | Ô nhập số (bộ đếm +/-) | "CartItem (...bộ đếm số lượng...)" | ✅ |
| C07 | btn_delete_item | Z2 | 6 | auto | Nút nguy hiểm | "CartItem (...nút xoá)" | ✅ |
| C08 | lbl_seller_subtotal | Z2 | 7 (cuối mỗi nhóm) | auto | Nhãn | "mỗi nhóm... hiển thị tên gian hàng" *(SAD không tách riêng "tạm tính theo nhóm" — BA suy ra từ "danh sách nhóm theo seller" + "tạm tính" ở footer; xem §5 #6)* | 🟠 |
| C09 | lbl_cart_total | Z3 | 1 | auto | Nhãn | "Sidebar/footer tổng kết: tổng số lượng đã chọn, tạm tính (subtotal theo VND)" | ✅ |
| C10 | btn_continue_shopping | Z4 | 2 (trong khối rỗng) | auto | Nút phụ | "empty = 'Giỏ hàng trống' + nút 'Tiếp tục mua sắm'" | ✅ |
| C11 | btn_checkout | Z3 | 2 | 100% (nút chính, nổi bật) | Nút chính | "nút 'Tiến hành Checkout'" | ✅ *(bố cục khớp; điều kiện bật/tắt theo checkbox — xem §5 #1, KHÔNG áp dụng ở SRS này)* |
| C12 | banner_error_load | Z4 | 1 | 100% | Banner | "error = cảnh báo dòng sản phẩm hết hàng/giá thay đổi (badge...)" *(SAD mô tả lỗi ở mức dòng, BA áp dụng mẫu banner lỗi tải chung của `UICONV` §6 cho lỗi `GET /v1/cart` — không phải cùng ý nghĩa với badge SAD, xem §5 #2/#3)* | 🟠 |
| C13 | btn_retry_load | Z4 | 1 (trong C12) | auto | Nút phụ | Suy ra từ mẫu "lỗi tải + retry" chung toàn site (`UICONV` §6), SAD không viết riêng cho SCR-04 | 🟠 |
**Thành phần chỉ có ở prototype, chưa có trong SRS này** *(không gán C-id — theo quy tắc "không tự thêm vào SRS")*:
| Mô tả trong prototype (SAD §7.1.1) | Vì sao chưa vào SRS | Xem §5 |
|---|---|---|
| Checkbox chọn/bỏ chọn từng dòng `CartItem` hoặc cả nhóm | Không có `US` nào trong `BACKLOG` định nghĩa tính năng chọn từng phần giỏ hàng | #1 |
| Badge "Sản phẩm đã hết hàng" chặn tick chọn | Phụ thuộc mục trên (checkbox) + kiểm tra tồn kho real-time ngoài scope US-002/US-003 theo `BACKLOG` | #2 |
| Badge "Giá đã thay đổi" | Nguồn giá hiển thị (snapshot/real-time) chưa xác nhận thuộc scope US-002 | #3 |
**Kiểu trình bày** dùng đúng từ vựng `UICONV` §11 (Nhãn, Nút chính, Nút phụ, Nút nguy hiểm, Ô nhập số, Card, Modal, Banner...).
#### 3.1.3 Trạng thái hiển thị
| Trạng thái | Vùng thay đổi | Hiển thị gì | Khoá text (SRS §4.2) | Nút hành động |
|---|---|---|---|---|
| Đang tải lần đầu | Z2 | Skeleton 3 dòng (theo `UICONV` §6) | — | — |
| **Chưa có dữ liệu nào (rỗng)** | Z2→Z4 | Minh hoạ + câu dẫn + nút | `cart.empty.title` | C10 |
| Lỗi tải dữ liệu | Z2→Z4 | Banner C12 thay chỗ danh sách | `cart.error.load` | C13 |
| Đang gửi (sửa số lượng/xoá 1 dòng) | Đúng dòng `CartItem` đang xử lý trong Z2 | Spinner cục bộ tại dòng, F01/C07 disable | — | — |
🔴 Hai trạng thái rỗng: SCR-04 chỉ có MỘT loại rỗng (chưa có dữ liệu), không có "bộ lọc không
khớp" (giỏ hàng không có bộ lọc) — khác với mẫu chung `UICONV` §6 vốn có hai loại rỗng. Đây
không phải lệch, mà là **không áp dụng** loại rỗng thứ hai.
#### 3.1.4 Responsive
| Breakpoint | Thay đổi so với desktop | Thành phần ẩn / gộp / đổi kiểu |
|---|---|---|
| Tablet | 🔴 Chưa mô tả riêng trong SAD — BA đề xuất giữ layout 1 cột, Z3 chuyển xuống footer | Mức thấp, không chặn G3 |
| Mobile | Z3 (C09, C11) chuyển thành footer cố định đáy màn hình; Z2 giữ danh sách dạng dọc | Không ẩn thành phần nào, chỉ đổi vị trí Z3 |
#### 3.1.5 Tương tác trình bày
| Thành phần | Sự kiện | Phản hồi trình bày | Ngưỡng / thời lượng | Nguồn |
|---|---|---|---|---|
| F01 | Bấm +/- hoặc rời field sau khi gõ tay | Gọi `PATCH` ngay, dòng chuyển spinner cục bộ | 🔴 chưa có ngưỡng debounce khi gõ tay — `OQ` mới nếu cần, mức thấp không chặn G3 | BA đề xuất |
| C07 | Bấm "Xoá" | Mở modal xác nhận giữa màn (theo `UICONV` §5) | — | `UICONV` §5 |
| Toàn màn | Sửa/xoá thành công | Cập nhật C08/C09 tại chỗ, không toast (🔴 `UICONV` §5 chưa chốt vị trí/thời lượng toast — `OQ-020`, đã mở) | — | `UICONV` §5 (chưa chốt) |
#### 3.1.6 Thứ tự focus
| Thứ tự | ID | Ghi chú |
|---|---|---|
| 1 | F01 (dòng đầu tiên) | Focus mặc định khi vào màn hình — 🔴 chưa xác nhận với PO/Dev FE, mức thấp không chặn G3 |
---
## 4. Luồng màn hình theo prototype
| Từ | Hành động | Đến | Có trong SRS §2.A.2 | Có trong prototype |
|---|---|---|---|---|
| SCR-01 | Bấm icon giỏ hàng | SCR-04 | ✅ | ✅ (SAD §7.2.1 bước D "Thêm vào giỏ hàng (SCR-04)") |
| SCR-04 | Bấm "Tiến hành Checkout" (C11) | SCR-05 | ✅ (ngoài phạm vi hành vi) | ✅ (SAD §7.2.1 bước E→H) |
| SCR-04 | Bấm "Tiếp tục mua sắm" (C10, giỏ rỗng) | SCR-01 | ✅ | 🟠 SAD không vẽ rõ cạnh này trong `7.2.1` (chỉ mô tả trong bố cục SCR-04, không có trong flowchart) — không mâu thuẫn, chỉ là chưa vẽ |
---
## 5. Lệch giữa prototype và SRS
| # | Màn hình | Prototype có | SRS nói | Loại lệch | Bên thắng theo W11 | Xử lý | Ai quyết | Trạng thái |
|---|---|---|---|---|---|---|---|---|
| 1 | SCR-04 | Checkbox chọn/bỏ chọn từng dòng hoặc cả nhóm seller; nút Checkout ngụ ý chỉ áp dụng cho phần đã chọn | `SRS` §1.5 dòng 3: không có tính năng chọn từng phần; C11 chỉ disable khi giỏ có 0 `CartItem` | Tồn tại | Chưa quyết — đây là khoảng trống scope, không phải "SRS đã nói khác" | PO xác nhận có bổ sung tính năng chọn từng phần vào phạm vi US-002/US-003 (hoặc US mới) hay giữ nguyên "Checkout toàn giỏ" | PO | ☐ (`OQ-031`) |
| 2 | SCR-04 | Badge "Sản phẩm đã hết hàng" chặn tick chọn | `SRS` §1.5 dòng 4: không kiểm tra tồn kho tại màn Giỏ hàng (khoanh vùng theo `BACKLOG`, thuộc US-004) | Tồn tại/Hành vi | Chưa quyết | PO + Tech Lead xác nhận có đưa kiểm tra tồn kho real-time vào US-002/US-003 hay giữ ở US-004 | PO, Tech Lead | ☐ (`OQ-030`) |
| 3 | SCR-04 | Badge "Giá đã thay đổi"; đơn giá hiển thị ngụ ý là giá real-time (để so sánh phát hiện thay đổi) | `SRS` C06: nguồn giá chưa chốt (snapshot hay real-time) | Tồn tại/Hành vi | Chưa quyết | PO + Tech Lead xác nhận nguồn giá trước, sau đó mới quyết có badge này không | PO, Tech Lead | ☐ (`OQ-029`) |
| 4 | SCR-04 | "số lượng ≥ 1 và ≤ tồn kho hiện tại" (validation chính của SAD SCR-04) | `SRS` F01: chỉ xác nhận ràng buộc dưới (≥1); ràng buộc trên chưa chốt | Hành vi | Chưa quyết | PO + Tech Lead xác nhận có kiểm tra tồn kho khi sửa số lượng ở màn Giỏ hàng không (cùng nguồn với #2) | PO, Tech Lead | ☐ (`OQ-030`, gộp cùng #2) |
| 5 | SCR-04 | Chỉ liệt kê "nút xoá" trong `CartItem`, không nhắc xác nhận trước khi xoá | `SRS`/`WF` áp dụng modal xác nhận mặc định theo `UICONV` §5 (quy ước chung cho "xoá") | Hành vi | **SRS** (áp dụng đúng quy ước dự án, không phải SRS tự ý khác `UICONV`) | Đã xử lý — không cần PO quyết thêm, ghi nhận ở đây để không ai tưởng là bỏ sót | — | ✅ Đã xử lý |
| 6 | SCR-04 | Không nêu rõ tiêu chí sắp xếp nhóm seller/dòng `CartItem` trong mỗi nhóm | `SRS` §2.A.3.2: BA đề xuất theo thời điểm thêm vào giỏ, mức thấp không chặn G3 | Bố cục nhỏ | **Prototype** (không có, để BA/Dev FE quyết định tự do) | Giữ đề xuất của BA, PO xác nhận không bắt buộc trước G3 | PO *(không chặn)* | ☐ *(không chặn G3 — mức thấp)* |
**Tổng kết:** đã đối chiếu 1 màn hình (`SCR-04`); **6 dòng lệch** — 4 dòng loại Tồn tại/Hành vi
**chưa quyết** (🔴 chặn G3: #1, #2, #3, #4 — thực chất #2 và #4 cùng một nguồn `OQ-030`, đếm là
2 câu hỏi độc lập `OQ-029`/`OQ-030`/`OQ-031`), 1 dòng Hành vi đã xử lý bằng cách áp dụng mặc định
`UICONV` (#5, không chặn), 1 dòng Bố cục mức thấp không chặn (#6).
## 6. Bàn giao
| | |
|---|---|
| **Designer còn phải làm** | Không có Designer riêng ở dự án này (`DEC-01`) — việc còn lại (màu, typography, icon, minh hoạ trạng thái rỗng, motion, khoảng cách chính xác) chuyển cho **Dev FE**, dùng `UICONV` §11 làm ràng buộc tối thiểu và tự chọn design system theo `OQ-022` khi được Tech Lead xác nhận |
| **Dev FE dùng WF để** | Dựng layout Z1–Z4 và chọn component theo §3.1.2; **không** suy ra hành vi từ WF — hành vi ở `SRS` |
| **Không được suy ra từ WF** | Khoảng cách/kích thước chính xác (chưa có design system); màu; font; ngưỡng debounce F01 (chưa chốt) |
| **Khi prototype thay đổi** | Cập nhật `07-giao-dien.md` SCR-04 (SA/BE) → BA cập nhật §1, §5 và version WF; `SRS` chỉ đổi nếu lệch loại Tồn tại/Hành vi được PO chấp nhận qua `CR` (vì `SRS` chưa `✅ Baselined`, chưa cần `CR` chính thức, chỉ cần sửa trực tiếp + Change Log) |
## 7. Open Questions
| ID | Câu hỏi | Hỏi ai | Từ ngày | Chặn gì | 🔴 chặn G3? |
|---|---|---|---|---|---|
| OQ-031 | Checkout áp dụng toàn giỏ hay theo dòng được chọn? | PO | 2026-09-08 | §5 #1, C11 | 🔴 |
| OQ-030 | Kiểm tra tồn kho khi sửa số lượng tại màn Giỏ hàng — có hay không? | PO, Tech Lead | 2026-09-08 | §5 #2, #4, F01 | 🔴 |
| OQ-029 | Nguồn giá hiển thị C06 — snapshot hay real-time? | PO, Tech Lead | 2026-09-08 | §5 #3, C06 | 🔴 |
---
## Tự chấm
| # | Tiêu chí | ☐/✅ | Ghi chú |
|---|---|---|---|
| 1 | Mọi `SCR` trong `SRS` §2.A.1 có một mục §3 | ✅ | Chỉ 1 SCR (SCR-04), có §3.1 |
| 2 | Mọi `C-id`/`F-id` khớp hai chiều giữa `SRS` §2.A.3.1 và WF §3.1.2 | ✅ | Xem kết quả chạy thật ngay dưới bảng này |
| 3 | Mỗi màn hình có §3.x.3 với trạng thái rỗng | ✅ (có 1 loại rỗng, ghi rõ lý do không có loại thứ 2) | — |
| 4 | Mỗi màn hình web có responsive ≥ 2 breakpoint | ✅ | Desktop/Tablet/Mobile — Tablet mức đề xuất thấp |
| 5 | Mọi con số ở §3.x.5 có nguồn (UICONV/prototype/OQ) | ✅ | Debounce F01 chưa có ngưỡng, ghi rõ mức thấp không chặn |
| 6 | §5 đã điền, mọi lệch Tồn tại/Hành vi có người quyết | ☐ | Đã điền đủ, nhưng 4 dòng còn ☐ chờ PO/Tech Lead — đây là kết quả thật của lần chạy này, không phải thiếu sót của WF |
| 7 | Tệp HTML mở được, mỗi `SCR` một `<section id>`, mỗi thành phần có `data-c` khớp C-id | ✅ | Xem `WF_US002-003_v1.0.html` |
| 8 | Kiểu trình bày chỉ dùng từ vựng `UICONV` §11 | ✅ | — |
| 9 | Có chữ ký Designer *(hoặc PO thay, `DEC-01`)* | ☐ | Chưa ký — chờ PO xác nhận thật ở G3 |
**Kết quả chạy thật tự kiểm C-id/F-id hai chiều** *(trích `[CF][0-9]{2}` từ `SRS` §2.A.3.1 và
từ `WF` .md §3.1.2 + `data-c` trong `.html`)*:
- Tập trong `SRS`: `C01, C02, C03, C04, C05, C06, F01, C07, C08, C09, C10, C11, C12, C13` (13 `C` + 1 `F` = 14)
- Tập trong `WF` .md §3.1.2: `C01, C02, C03, C04, C05, C06, F01, C07, C08, C09, C10, C11, C12, C13` (khớp)
- Tập `data-c` trong `.html`: `C01, C02, C03, C04, C05, C06, F01, C07, C08, C09, C10, C11, C12, C13` (khớp)
- **Kết luận: 0 lệch hai chiều.** Ba thành phần chỉ có ở prototype (checkbox chọn dòng, badge hết hàng, badge giá đổi) **không** được gán `C-id` và **không** xuất hiện trong `data-c` của HTML — đúng quy tắc "không tự thêm vào SRS", được mô tả riêng ở khối chú thích trực quan trong HTML (không có `data-c`).