Giao diện
US-I06: Bulk product — tạo product và xem báo cáo kết quả ​
Thuộc FS: 00-overview.md — SAPP-24395 Contact / Deal instances & Bulk product creation Phần chung (tổng quan, roles, flow tổng, related features, NFR, Open Questions, References) xem ở Overview. File này chỉ chứa nội dung riêng của US. As-built tại commit
e77c47a— suy từ code, chưa chạy thử. Các mục⚠️ Observedvề hiển thị kết quả bước 3 là suy từ code, chưa chạy xác nhận.
| Field | Value |
|---|---|
| US ID | US-I06 |
| Role thực hiện | R1 - Người dùng tool (Assumption — OQ-I-16 về G-01) |
| Phase | As-built (đã triển khai) |
| Priority | N/A — as-built |
| Status | Draft |
| NFR liên quan | NFR-I-01, NFR-I-02, NFR-I-03, NFR-I-04, NFR-I-05, NFR-I-07 — xem Overview §5 |
| OQ liên quan | OQ-I-04, OQ-I-09, OQ-I-10, OQ-I-12, OQ-I-13, OQ-I-15, OQ-I-16, OQ-I-17 — xem Overview §6 |
Nguồn inventory: A-14, A-15. Ghi: SAPP Ops — môi trường theo SAPP_BASE_API_URL (❓ OQ-I-04); Redis mind_keep.
1. US Statement ​
text
As a Người dùng tool (Assumption — OQ-I-16)
I want chạy tạo toàn bộ payment product trong danh sách cố định trên SAPP Ops và xem dòng nào đã tạo, đã có sẵn, hay lỗi
So that [Assumption — OQ-I-15] SAPP Ops có đủ danh mục product mẫu để kiểm thử đồng bộ HubSpot ↔ Order, và chạy lại không sinh bản trùng2. Dependencies & Definition Of Ready ​
N/A — đã triển khai (Mode B). Dependency runtime:
| # | Cần sẵn sàng | Ai cung cấp | Trạng thái |
|---|---|---|---|
| D1 | Session đã nạp subjects (US-I05), còn hạn | Người dùng | N/A — runtime |
| D2 | Cấu hình SAPP_BASE_API_URL + SAPP_API_TOKEN (US-P04) | Admin CMS | N/A — runtime |
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Tạo product chỉ chạy khi session đã qua bước 2 và có ít nhất 1 subject; nếu không → 13018 (HTTP 409) | M1 - A1 | AC-M1.4 | be/libs/modules/src/lib/sapp/common.service.ts:2905-2910; be/libs/constants/src/lib/error-codes/error-codes.constants.ts:629-633 |
| BR-02 | Nguồn là danh sách cố định 102 dòng (category · subject code · hình thức học · giá): ACCA 49 · CFA 10 · CMA 12 · IFRS 10 · Short courses 18 · CGMA 3. Hình thức học ∈ OFFLINE / ONLINE / BLENDED / HYBRID / LIVE_ONLINE / OTHER | M1 - A1 | AC-M1.1 | be/libs/constants/src/lib/sapp/sapp-24395-products.constants.ts:14-137; be/libs/constants/src/lib/sapp/sapp.constants.ts:41-48 |
| BR-03 | Product được tạo với tên [SAPP-24395][AUTO] <category> <subject code> <hình thức học>, category và subject tra theo tên / mã từ session, giá từ danh sách, trạng thái ACTIVE | M1 - A1 | AC-M1.1 | be/libs/modules/src/lib/sapp/common.service.ts:2928, :2961-2968; be/libs/constants/src/lib/sapp/sapp.constants.ts:51-54 |
| BR-04 | Phân loại từng dòng (theo thứ tự): tên trùng (không phân biệt hoa thường) với product đang có trên SAPP Ops mang tiền tố [SAPP-24395][AUTO] → đã có sẵn (skipped) "Product already exists"; thiếu category và/hoặc subject → lỗi "Category and subject not found" / "Category not found" / "Subject not found"; SAPP Ops từ chối → lỗi với thông báo của SAPP Ops; còn lại → đã tạo. Nhờ vậy chạy lại không tạo trùng | M1 - A1 | AC-M1.1, AC-M1.2, AC-M1.3 | be/libs/modules/src/lib/sapp/common.service.ts:2921-2985, :2562-2581 |
| BR-05 | Tạo tuần tự từng dòng; một lượt có thể kéo dài vài phút (timeout — NFR-I-02) | M1 - A1 | AC-M1.1 (NFR-I-02) | be/libs/modules/src/lib/sapp/common.service.ts:2924-2985; be/apps/api/src/main.ts:104-109 |
| BR-06 | Giá product tính sẵn trong danh sách: trong cùng category, level cao hơn giá cao hơn, bắt đầu 3.000.000, bước 500.000; level không rõ coi như level 1 (theo chú thích code — chú thích ghi trần 15.000.000, dữ liệu thực tế tới 9.500.000) | M1 - A1 | AC-M1.1 | be/libs/constants/src/lib/sapp/sapp-24395-products.constants.ts:3-12 |
| BR-07 | Stepper: bước 1 luôn xem được; bước n (2, 3) xem được khi session đã đạt bước n-1; "Tiếp" bật khi session đã đạt bước đang xem; "Quay lại" bật khi không ở bước 1; mọi nút điều hướng khoá khi đang bận | M1 - A2 | AC-M1.5 | fe/src/ui/components/works/sapp/sapp-24395-products-tool.tsx:250-255, :411-456, :508-527 |
| BR-08 | Kết quả lượt tạo (đã tạo / đã có sẵn / lỗi) được lưu vào session và session chuyển bước 3; API trả về báo cáo kết quả (không phải session) | M1 - A1 | AC-M1.6 | be/libs/modules/src/lib/sapp/common.service.ts:2987-2989; be/apps/api/src/sapp/sapp.controller.ts:2558-2563 |
Không phải BR (⚠️ Observed → OQ): màn đọc sai kết quả bước 3 → luôn "0/0", không hiện kết quả, mất mã session (inventory R-33, DR-I-08 → OQ-I-09); màn không có danh sách "đã có sẵn" (R-35 → OQ-I-13); tạo thành công không kèm id vẫn tính "đã tạo" (R-32 → OQ-I-12); môi trường ghi ❓ (R-23 → OQ-I-04).
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[US-I05 Bước 2 đã nạp] ── "Tiếp" ──→ [M1: Bước 3 · Tạo products]
↓ "Tạo products"
(server chạy 102 dòng tuần tự → lưu kết quả vào session, session bước 3)
├─ Thiết kế màn: hiện "x tạo thành công · y lỗi", "Đã tạo (x)", "Xem chi tiết lỗi (y)" → nút "Chạy lại — Tạo products"
└─ ⚠️ Observed (suy từ code): popup "Tạo thành công 0, lỗi 0", khu kết quả trống, mã session trong trình duyệt hỏng (OQ-I-09)
"Quay lại" ──→ US-I05 · "Bắt đầu lại" ──→ US-I04 trốngLink flow chi tiết: sơ đồ trạng thái session ở inventory §5b.
b. Chi tiết từng màn ​
Màn M1 - Bước 3 · Tạo products (+ stepper điều hướng) ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | "Tiếp" từ bước 2, bấm "Create products" trên stepper, hoặc khôi phục session ở bước 3 |
| Mô tả ngắn | "Bước 3 · Tạo products" — "Chạy toàn bộ danh sách sản phẩm cố định và tạo từng product (resolve category / subject từ session). Dòng nào không resolve được hoặc lỗi sẽ nằm ở mục "lỗi"; phần còn lại là "tạo thành công"." Nút tạo + khu kết quả |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Session bước 2, chưa tạo | Nút "Tạo products" | N/A |
| Loading | Đang tạo (có thể vài phút) | Nút "Đang tạo…"; stepper, "Bắt đầu lại", "Quay lại", "Tiếp" khoá | N/A |
| Has data (thiết kế theo code) | Session bước 3 có kết quả | Thẻ "x tạo thành công" · "y lỗi"; "Đã tạo (x)" — tên + id product; "Xem chi tiết lỗi (y)" mở bảng Tên · Category · Subject · Mode · Lý do; nút "Chạy lại — Tạo products". Không có mục "đã có sẵn" | N/A |
| Has data (⚠️ Observed — suy từ code) | Ngay sau khi bấm tạo | Popup "Đã tạo products" — "Tạo thành công 0, lỗi 0."; khu kết quả không hiện; nút vẫn "Tạo products" (OQ-I-09) | N/A |
| Empty | Mọi dòng đã có sẵn | Thiết kế: "0 tạo thành công · 0 lỗi" (dòng "đã có sẵn" không hiển thị — OQ-I-13) | N/A |
| Error | API lỗi | Popup "Tạo products thất bại" — <message> (<code>) | N/A |
| Disabled | Session chưa đạt bước 2 | Bước 3 trên stepper khoá, không vào được | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
| (không có ô nhập) | — | — | — | — | — | — | — | — |
| Đếm "tạo thành công" / "lỗi" | — | Readonly | — | Số | — | — | Khi có kết quả | Session bước 3 |
| Danh sách "Đã tạo" | — | Readonly (tên + id) | — | Tên [SAPP-24395][AUTO] … | — | — | Khi x > 0 | Kết quả |
| Bảng lỗi | — | Readonly (Tên · Category · Subject · Mode · Lý do) | Thu gọn | — | — | — | Khi y > 0, bấm "Xem chi tiết lỗi" | Kết quả |
Filter / Search / Sort (chỉ màn List/Report — xóa nếu không phải) ​
N/A — báo cáo kết quả hiển thị toàn bộ, không lọc / tìm / sắp xếp; thứ tự theo danh sách cố định.
Actions ​
A1 - Tạo products (Bước 3) ​
| Item | Description |
|---|---|
| Trigger | Bấm "Tạo products" / "Chạy lại — Tạo products" |
| Behavior | BR-01 → nạp tên product đã có (tiền tố [SAPP-24395][AUTO]) → duyệt 102 dòng theo BR-04, tạo tuần tự (BR-03, BR-05, BR-06) → lưu kết quả vào session (BR-08). Ghi vào: SAPP Ops — payment product mới tại SAPP_BASE_API_URL (⚠️ môi trường ❓ — có thể là PROD, OQ-I-04) + Redis mind_keep. Màn: ⚠️ Observed (suy từ code) — màn coi báo cáo trả về là session, thay trạng thái session bằng báo cáo và lưu mã session không xác định vào trình duyệt (OQ-I-09) |
| Success Result | Server: kết quả lưu trong session. Màn: popup "Đã tạo products" — "Tạo thành công x, lỗi y." (⚠️ theo suy luận code, x = y = 0) |
Error cases:
| Case | Expected Handling |
|---|---|
| Chưa nạp subjects / không có subject | 13018 "SAPP-24395 product session subjects have not been loaded yet" |
| Session hết hạn | 13017 → xem OQ-I-10 |
| Không đọc được danh sách product đã có | 13021 "Failed to get SAPP payment products" |
| Lỗi chung | Popup "Tạo products thất bại" — "Failed to create SAPP-24395 products (13019)" |
| Một dòng bị SAPP Ops từ chối | Dòng vào "lỗi" với thông báo SAPP Ops; các dòng khác vẫn chạy |
A2 - Điều hướng bước ​
| Item | Description |
|---|---|
| Trigger | Bấm một bước trên stepper, "Quay lại" hoặc "Tiếp" |
| Behavior | BR-07. Chỉ đổi bước đang xem, không gọi API |
| Success Result | Hiện nội dung bước tương ứng (US-I04 / US-I05 / US-I06) |
Error cases:
| Case | Expected Handling |
|---|---|
| Bước chưa đạt | Nút bước khoá, không phản hồi |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Lần chạy đầu (phía server) ​
gherkin
Given session bước 2, đủ category + subject cho 100/102 dòng, SAPP Ops chưa có product "[SAPP-24395][AUTO] …" nào
When bấm "Tạo products"
Then SAPP Ops có 100 product mới (tên "[SAPP-24395][AUTO] <category> <subject> <mode>", giá theo danh sách, trạng thái ACTIVE)
And 2 dòng còn lại nằm trong "lỗi" với lý do "Category not found" / "Subject not found" / "Category and subject not found"
And session chuyển bước 3 và lưu kết quả { đã tạo 100, đã có sẵn 0, lỗi 2 }Maps to:
- Business Rule: BR-02, BR-03, BR-04, BR-05, BR-06, BR-08
- Field/Action: A1
AC-M1.2 - Chạy lại không tạo trùng ​
gherkin
Given lần chạy trước đã tạo 100 product
When bấm tạo lại
Then 100 dòng đó vào "đã có sẵn" với lý do "Product already exists"
And không có product trùng tên nào được tạo thêmMaps to:
- Business Rule: BR-04
AC-M1.3 - SAPP Ops từ chối một dòng ​
gherkin
Given SAPP Ops trả lỗi cho dòng "ACCA F1 BLENDED"
When chạy bước 3
Then dòng đó vào "lỗi" với thông báo SAPP Ops (hoặc "Create request failed" nếu không có)
And các dòng sau vẫn được xử lýMaps to:
- Business Rule: BR-04, BR-05
AC-M1.4 - Chưa nạp subjects ​
gherkin
Given session ở bước 1 (gọi API trực tiếp)
When gọi tạo products
Then trả 13018 (HTTP 409), không product nào được tạoMaps to:
- Business Rule: BR-01
AC-M1.5 - Stepper ​
gherkin
Given session đã đạt bước 2
When xem màn
Then bấm được "Categories", "Subjects", "Create products"
And đang ở bước 2 thì "Tiếp" bật; đang ở bước 3 mà session chưa đạt bước 3 thì "Tiếp" tắt (và đã là bước cuối)
And trong lúc đang tạo products, stepper, "Quay lại", "Tiếp", "Bắt đầu lại" đều khoáMaps to:
- Business Rule: BR-07
- Field/Action: A2
AC-M1.6 - ⚠️ Observed: màn hiển thị sai kết quả bước 3 (suy từ code, chưa chạy) ​
gherkin
Given server đã tạo xong và trả báo cáo { đã tạo 100, đã có sẵn 0, lỗi 2 }
When màn nhận phản hồi
Then (hành vi hiện tại, suy từ code) popup hiện "Tạo thành công 0, lỗi 0."
And khu kết quả không hiện, nút vẫn là "Tạo products"
And mã session lưu trong trình duyệt bị thay bằng giá trị không xác định
And mở lại màn sau đó không khôi phục được session (xem EC-M1.2)Maps to:
- Business Rule: N/A — ⚠️ Observed (inventory R-33, DR-I-08) → OQ-I-09; BR-08 (server lưu đúng)
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | Muốn xem dòng "đã có sẵn" | ⚠️ Observed — màn không hiển thị danh sách này (chỉ có trong API / session) (OQ-I-13) |
| EC-M1.2 | Mở lại màn sau bước 3 | ⚠️ Observed (suy từ code) — trình duyệt giữ mã session không hợp lệ → khôi phục lỗi, popup "Không khôi phục được session"; phải bấm "Bắt đầu lại" (OQ-I-09, OQ-I-10). Kết quả thật vẫn đọc được qua API GET session bằng mã session gốc |
| EC-M1.3 | SAPP Ops trả thành công không kèm id | ⚠️ Observed — dòng vào "đã tạo" với id rỗng (OQ-I-12) |
| EC-M1.4 | Subject tạo ở bước 2.5 có id rỗng | Dòng dùng subject đó có thể bị SAPP Ops từ chối → "lỗi" (liên quan OQ-I-12) |
| EC-M1.5 | Đóng tab trong lúc đang tạo | Server vẫn chạy tiếp và lưu kết quả vào session (suy từ code) |
| EC-M1.6 | Hai người cùng chạy bước 3 trên cùng SAPP Ops | Có thể tạo trùng tên (kiểm "đã có sẵn" chỉ làm một lần đầu lượt) |
| EC-M1.7 | Chạy vượt 10 phút | Request bị cắt ở server (NFR-I-02); product đã tạo không vào session → lần sau vào "đã có sẵn" |
5. Cross-feature AC ​
AC-X.1 - Product mẫu xuất hiện trên SAPP Ops ​
gherkin
Given bước 3 tạo thành công
When mở danh mục payment product trên SAPP Ops (môi trường tại SAPP_BASE_API_URL)
Then thấy các product tiền tố "[SAPP-24395][AUTO]" trạng thái ACTIVE — [Assumption — OQ-I-17] tiền tố dùng để nhận diện / dọn dữ liệu testMaps to:
- REL-07 (Be Affected - Danh mục SAPP Ops)
AC-X.2 - Cấu hình kết nối ​
gherkin
Given `SAPP_BASE_API_URL` đang trỏ tới môi trường production (chưa xác định — OQ-I-04)
When chạy bước 3
Then 102 product mẫu có thể được tạo trên productionMaps to:
- REL-02 (Affects - Nền tảng cấu hình env_systems)