Giao diện
US-I05: Bulk product — nạp và tạo subject còn thiếu ​
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ử.
| Field | Value |
|---|---|
| US ID | US-I05 |
| 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-03, NFR-I-04, NFR-I-05, NFR-I-07 — xem Overview §5 |
| OQ liên quan | OQ-I-04, OQ-I-10, OQ-I-12, OQ-I-13, OQ-I-16 — xem Overview §6 |
Nguồn inventory: A-12, A-13. 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 nạp toàn bộ subject của SAPP Ops vào session, xem subject code nào trong danh sách sản phẩm cố định còn thiếu, và tạo các subject thiếu (chọn một phần hoặc tất cả)
So that [Assumption] bước tạo product (US-I06) tìm được subject cho mọi dòng sản phẩm2. 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 đã bắt đầu (US-I04) và 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 | Nạp subjects: nạp lại toàn bộ subject (mã → id) của SAPP Ops vào session (theo trang 100 dòng), tính lại danh sách subject code thiếu, đưa session về bước 2 — kể cả khi session đã ở bước 3 (kết quả tạo trước đó vẫn được giữ) | M1 - A1 | AC-M1.1, EC-M1.3 | be/libs/modules/src/lib/sapp/common.service.ts:2703-2728, :2527-2548 |
| BR-02 | Subject code "thiếu" = mã trong danh sách sản phẩm cố định không khớp (không phân biệt hoa thường, bỏ khoảng trắng đầu cuối) với subject nào trên SAPP Ops; mỗi mục thiếu kèm category mà nó thuộc về | M1 - danh sách thiếu | AC-M1.1 | be/libs/modules/src/lib/sapp/common.service.ts:2640-2696 |
| BR-03 | Tạo subject thiếu: tick chọn một số mã, hoặc không tick gì = tạo tất cả mã thiếu; mã không nằm trong danh sách thiếu bị bỏ qua; lỗi từng mục ghi vào "lỗi" kèm lý do, không dừng cả lượt | M1 - A2 | AC-M1.2, AC-M1.3 | be/libs/modules/src/lib/sapp/common.service.ts:2810-2867; fe/src/ui/components/works/sapp/sapp-24395-products-tool.tsx:296-321 |
| BR-04 | Subject mới được tạo với tên = mã, dưới category tra theo tên từ session; không tìm thấy category trong session → mục đó lỗi "Category not found" | M1 - A2 | AC-M1.4 | be/libs/modules/src/lib/sapp/common.service.ts:2838-2853 |
| BR-05 | Sau khi tạo: subject tạo được thêm vào session và bỏ khỏi danh sách thiếu; bước session giữ nguyên; kết quả lượt tạo (đã tạo / lỗi) lưu trong session | M1 - A2 | AC-M1.2 | be/libs/modules/src/lib/sapp/common.service.ts:2869-2877 |
| BR-06 | Tạo subject thiếu yêu cầu session đã qua bước 2 (đã nạp subjects); nếu chưa → 13018 "SAPP-24395 product session subjects have not been loaded yet" (HTTP 409) | M1 - A2 | AC-M1.5 | be/libs/modules/src/lib/sapp/common.service.ts:2816-2821; be/libs/constants/src/lib/error-codes/error-codes.constants.ts:629-633 |
| BR-07 | Mỗi lần nạp lại subjects, lựa chọn đang tick bị xoá và phần chi tiết lỗi được thu gọn | M1 - A1 | AC-M1.6 | fe/src/ui/components/works/sapp/sapp-24395-products-tool.tsx:275-280 |
Không phải BR (⚠️ Observed → OQ): tạo thành công không kèm id vẫn tính "đã tạo" với id rỗng (inventory R-32 → OQ-I-12); category thiếu không tạo được trên màn nên subject của category đó lỗi (OQ-I-13); nhận diện hết hạn session (OQ-I-10); môi trường ghi ❓ (OQ-I-04).
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[US-I04 Bước 1 đã nạp] ── "Tiếp" ──→ [M1: Bước 2 · Nạp subjects]
↓ "Nạp subjects"
[Có n subjects; "Subject còn thiếu (m)"]
├─ m = 0 → "Không thiếu subject nào — có thể sang bước 3 để tạo products." ── "Tiếp" ──→ [US-I06]
└─ m > 0 → tick (hoặc không) → "Tạo k subject đã chọn" / "Tạo tất cả (m) subject thiếu"
↓
[Kết quả: x tạo thành công · y lỗi; "Đã tạo: …"; "Xem chi tiết lỗi (y)"]
↓ "Tiếp" ──→ [US-I06]Link 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 2 · Nạp subjects (+ tạo subject thiếu) ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | Bấm "Tiếp" từ bước 1, bấm "Subjects" trên stepper, hoặc khôi phục session ở bước 2 |
| Mô tả ngắn | Khối 1: "Bước 2 · Nạp subjects" — "Nạp toàn bộ subject (code → id) vào session và tính các subject code còn thiếu so với danh sách sản phẩm." + nút nạp. Khối 2 (sau khi nạp): "Subject còn thiếu (m)", danh sách checkbox (mã + category), nút tạo, kết quả tạo |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Session ở bước 1 | Nút "Nạp subjects"; khối 2 ẩn | N/A |
| Loading | Đang nạp / đang tạo | "Đang nạp…" / "Đang tạo…"; mọi nút khoá | N/A |
| Has data | Đã nạp | Nút đổi "Nạp lại subjects"; nhãn "n subjects"; khối "Subject còn thiếu (m)" | N/A |
| Empty | m = 0 | "Không thiếu subject nào — có thể sang bước 3 để tạo products." | N/A |
| Result | Sau khi tạo | Thẻ "x tạo thành công" · "y lỗi" (tô đỏ nếu y > 0); "Đã tạo: <mã>, …"; "Xem chi tiết lỗi (y)" mở danh sách mã (category) — lý do | N/A |
| Error | API lỗi | Popup "Nạp subjects thất bại" / "Tạo subject thất bại" — <message> (<code>) | N/A |
| Disabled | Đang bận | Nút khoá | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
| Danh sách "Subject còn thiếu" | No | Checkbox list (mã + category) | Không tick | — | BR-03 | — | Sau khi nạp, m > 0 | Session bước ≥ 2 |
| Chọn tất cả / Bỏ chọn tất cả | No | Link | "Chọn tất cả" | — | — | — | m > 0 | Danh sách thiếu |
| Nút tạo | — | Button | "Tạo tất cả (m) subject thiếu" khi không tick; "Tạo k subject đã chọn" khi tick k | — | — | — | m > 0 | Lựa chọn |
Filter / Search / Sort (chỉ màn List/Report — xóa nếu không phải) ​
N/A — danh sách chọn ngắn, không có lọc / tìm / sắp xếp; thứ tự theo danh sách sản phẩm cố định.
Actions ​
A1 - Nạp subjects / Nạp lại subjects ​
| Item | Description |
|---|---|
| Trigger | Bấm "Nạp subjects" / "Nạp lại subjects" |
| Behavior | BR-01, BR-02, BR-07. Chỉ đọc SAPP Ops; ghi session Redis mind_keep (đặt lại hạn 6 giờ) |
| Success Result | Popup "Đã nạp subjects" — "Đã nạp n subjects. Thiếu m subject code." |
Error cases:
| Case | Expected Handling |
|---|---|
| Session hết hạn | 13017 → xem OQ-I-10 (có thể chỉ hiện popup lỗi chung "Nạp subjects thất bại") |
| SAPP Ops lỗi | Popup "Nạp subjects thất bại" — "Failed to get SAPP subjects (13014)" |
| Thiếu cấu hình | 13012 |
A2 - Tạo subject thiếu (Bước 2.5) ​
| Item | Description |
|---|---|
| Trigger | Bấm "Tạo k subject đã chọn" hoặc "Tạo tất cả (m) subject thiếu" |
| Behavior | Không tick → gửi yêu cầu rỗng = tạo tất cả (BR-03); tạo từng subject tuần tự (BR-04); cập nhật session (BR-05). Ghi vào: SAPP Ops — subject mới tại SAPP_BASE_API_URL (⚠️ môi trường ❓ — có thể là PROD, OQ-I-04) + Redis mind_keep |
| Success Result | Popup "Đã tạo subject" — "Tạo thành công x, lỗi y. Còn thiếu z subject."; lựa chọn bị xoá |
Error cases:
| Case | Expected Handling |
|---|---|
| Chưa nạp subjects (gọi API trực tiếp) | 13018 (HTTP 409) |
| Một mục lỗi | Vào danh sách lỗi kèm lý do; các mục khác vẫn chạy |
| Lỗi chung | Popup "Tạo subject thất bại" — "Failed to create SAPP subject (13015)" |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Nạp subjects ​
gherkin
Given session ở bước 1; SAPP Ops có 200 subject; danh sách cố định có 3 mã không khớp (không phân biệt hoa thường)
When bấm "Nạp subjects"
Then session chuyển bước 2 với 200 subject
And popup "Đã nạp subjects" — "Đã nạp 200 subjects. Thiếu 3 subject code."
And "Subject còn thiếu (3)" liệt kê 3 mã kèm categoryMaps to:
- Business Rule: BR-01, BR-02
- Field/Action: A1
AC-M1.2 - Tạo một phần ​
gherkin
Given "Subject còn thiếu (3)": F1, F2, F3
When tick F1, F2 và bấm "Tạo 2 subject đã chọn"
Then SAPP Ops có subject F1, F2 (tên = mã) dưới category tương ứng
And popup "Tạo thành công 2, lỗi 0. Còn thiếu 1 subject."
And danh sách thiếu còn F3, lựa chọn bị xoá, "Đã tạo: F1, F2"Maps to:
- Business Rule: BR-03, BR-04, BR-05
- Field/Action: A2
AC-M1.3 - Không tick = tạo tất cả ​
gherkin
Given "Subject còn thiếu (3)", không tick mục nào
When bấm "Tạo tất cả (3) subject thiếu"
Then hệ thống thử tạo cả 3 mãMaps to:
- Business Rule: BR-03
AC-M1.4 - Category không có trong session ​
gherkin
Given mã thiếu F9 thuộc category "CGMA" nhưng session không có category "CGMA"
When tạo subject F9
Then F9 nằm trong danh sách lỗi với lý do "Category not found"
And các mã khác vẫn được tạoMaps to:
- Business Rule: BR-04 — liên quan OQ-I-13 (không tạo được category thiếu trên màn)
AC-M1.5 - Tạo khi chưa nạp subjects (API) ​
gherkin
Given session ở bước 1
When gọi trực tiếp API tạo subject thiếu
Then trả 13018 "SAPP-24395 product session subjects have not been loaded yet" (HTTP 409)Maps to:
- Business Rule: BR-06
AC-M1.6 - Nạp lại xoá lựa chọn ​
gherkin
Given đang tick 2 mã và đang mở "Xem chi tiết lỗi"
When bấm "Nạp lại subjects"
Then không còn mã nào được tick và phần chi tiết lỗi được thu gọnMaps to:
- Business Rule: BR-07
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | SAPP Ops trả thành công nhưng không có id | ⚠️ Observed — mục vẫn tính "tạo thành công" với id rỗng; bước 3 có thể dùng id rỗng (OQ-I-12) |
| EC-M1.2 | Session hết hạn giữa bước 2 | ⚠️ Observed — có thể chỉ hiện lỗi chung, màn không tự reset (OQ-I-10) |
| EC-M1.3 | Nạp lại subjects khi session đã ở bước 3 | Session về bước 2; stepper bước 3 vẫn xem được (đạt bước 2); kết quả tạo subject / product cũ vẫn còn trong session |
| EC-M1.4 | Hai tab cùng tạo subject | Có thể tạo trùng trên SAPP Ops (không có khoá); lượt ghi sau ghi đè session của lượt trước (suy từ code: đọc-rồi-ghi session không khoá) |
| EC-M1.5 | Trình duyệt mất mạng giữa lượt tạo | Popup lỗi trên màn; phía server lượt tạo vẫn chạy tiếp và ghi session (suy từ code — server không theo dõi việc trình duyệt ngắt). Mở lại màn (khôi phục) để thấy kết quả; nếu lượt tạo lỗi giữa chừng ở server thì subject đã tạo không vào session, lần "Nạp lại subjects" sẽ thấy chúng không còn thiếu |
5. Cross-feature AC ​
AC-X.1 - Subject mới xuất hiện trên SAPP Ops ​
gherkin
Given tạo subject thiếu thành công
When mở danh mục subject trên SAPP Ops (môi trường tại SAPP_BASE_API_URL)
Then thấy subject có tên = mã, thuộc category tương ứngMaps 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` đổi giữa bước 1 và bước 2
When nạp subjects
Then subject được nạp từ URL mới trong khi category trong session là của URL cũ (session không ghi URL)Maps to:
- REL-02 (Affects - Nền tảng cấu hình env_systems)