Skip to content

US-D10: Flow P2 — DTTH lớp online (story SAPP US-02) ​

Thuộc FS: 00-overview.md — SAPP-26878 · Tạo dữ liệu test doanh thu (Ops → HubSpot → SAP) 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.

Mode B – As-built tại commit e77c47a · nguồn Fact: inventory 26878 §3.3 (A-120). Khung stepper → US-D01 · lịch sử / log SAP → US-D02 · loại bước → US-D03. U01:x = bước x của luồng US-01, mô tả đầy đủ ở US-D09 §4a — file này không lặp lại.

FieldValue
US IDUS-D10
Role thực hiệnNgười dùng tool — Assumption (OQ về G-01 · inventory Q-05 — xem 00-overview §6)
PhasePhase 2 của SAPP-26878 (DTTH) · chip US-02 · DTTH lớp online (id us02)
PriorityN/A — as-built, đã triển khai (backlog R2: không xếp Priority)
StatusDraft
NFR liên quanNFR-P-01 (quyền, FS nền tảng) · NFR của 26878 — xem 00-overview §5
OQ liên quanOQ-D-07, OQ-D-06, OQ-D-13, OQ-D-15 — xem 00-overview §6 · DR-D-06 — xem 00-overview §6b

1. US Statement ​

text
As a Người dùng tool (Assumption — OQ về G-01)
I want dựng một lớp Recorded Online (không có buổi học) cùng Deal, đơn hàng và giao dịch, chạy lượt
       quét rồi đọc kết quả
So that kiểm được rằng với lớp online, hệ thống ghi trọn số dư doanh thu của môn đúng một lần, chọn
        phạm vi theo ngày kích hoạt của học viên chứ không theo ngày buổi
  • Nguồn "So that": hint luồng fe/src/ui/components/works/sapp/sapp-26878-flows.ts:3626 và runbook shared/runbooks/sapp/sapp-26878/phase-2/README.md ("US-02 · Lớp Recorded Online (FULL_REMAINING)"). Ý đồ story gốc / tiêu chí nghiệm thu của tool là [Assumption] (OQ-D-13).

2. Dependencies & Definition Of Ready ​

N/A — đã triển khai (Mode B). Dependency runtime giống US-D09 §2 (env_systems, danh mục phase 2, Ops passthrough US-P08, SQL runner US-P09, option US-P07, quét/trace US-P05), thêm: danh mục sản phẩm phải có sản phẩm mã ONLINE.

3. Business Rules ​

IDRuleÁp dụng ởĐã cover bởi (AC)Nguồn code (Mode B/C)
BR-01Luồng có 15 bước theo thứ tự ở §4a; không có bước tạo buổi học, gán phòng học và trả lại mã lớpM1AC-M1.1fe/src/ui/components/works/sapp/sapp-26878-flows.ts:3628-3648
BR-02Lớp của luồng có hình thức ONLINE và thời lượng FIXED — cả hai cố định, không sửa được trên formM1 - A3 Tạo lớpAC-M1.2sapp-26878-flows.ts:3490-3503
BR-03Lớp online gửi cả ngày bắt đầu và ngày kết thúc, cả hai mặc định 00:00 hôm nay giờ VN và bắt buộc; gửi thêm flexible_days mặc định 100M1 - A3 Tạo lớpAC-M1.2sapp-26878-flows.ts:3504-3530
BR-04Mã lớp / tên lớp / pool mã staging giống US-01 (US-D09 BR-03 → BR-05)M1 - A3 Tạo lớpAC-M1.2sapp-26878-flows.ts:3442-3457
BR-05Bước Tạo đơn hàng dùng lại bước của US-01 nhưng chọn sẵn sản phẩm mã ONLINE (vẫn đổi được)M1 - A8 Tạo đơnAC-M1.3sapp-26878-flows.ts:3637-3640
BR-06Bước Đọc kết quả lọc log SAP theo deal_id, tự chạy 5 kiểm chứng (§M2) và luôn coi là xongM2AC-M2.1 → AC-M2.6sapp-26878-flows.ts:3563-3614; fe/src/ui/components/works/sapp/sapp-26878-tool.tsx:883-884

4. Design ​

a. Mối liên hệ giữa các màn & User Flow ​

text
[Chip "US-02 · DTTH lớp online", portal Dev | Staging]
  ↓
[M1] U01:1 → U01:2 → Tạo lớp ONLINE → U01:6 → U01:7 → U01:8 → U01:9 → U01:10 (sản phẩm ONLINE)
     → U01:11 → U01:12 → U01:13 → U01:14 → U01:15 → U01:16
  ↓
[M2] Đọc kết quả (luôn "xong") — hết luồng, không có bước trả mã lớp

Bảng bước (Fact: sapp-26878-flows.ts:3628-3648).

#Tên bướcLoạiTái dùngGhi gì (hệ thống · môi trường)Điều kiện chuyển (xong)
1Kiểm tra kết nối Opsops + sqlU01:1Không ghiPing thành công
2Đếm lớp của mônopsU01:2Không ghiGọi thành công
3Tạo lớpopsriêng (lớp ONLINE)Ops dev/staging: lớp DRAFT, ONLINE, FIXED, có ngày kết thúcGọi thành công
4Mở lớp (PUBLIC)opsU01:6OpsGọi thành công
5Thêm option mã lớpoptionU01:7HubSpot dev (staging: bỏ qua)Đủ 3 property / bỏ qua
6Tạo DealdealU01:8HubSpot deal + contact (⚠️ portal prod khi Staging); Redis run historyCó deal
7Gán mã lớpclasscodeU01:9HubSpot deal + contactGọi thành công
8Tạo đơn hàngopsU01:10 (ghi đè: sản phẩm mặc định ONLINE)Ops: đơn hàngThành công và số tiền ≠ 0
9Soạn thảo hợp đồngstageU01:11HubSpot dealstageChuyển stage thành công
10Tạo giao dịchopsU01:12OpsGọi thành công
11Xác nhận giao dịchopsU01:13Ops → SAP (theo hint)Gọi thành công
12Kéo sang WonstageU01:14HubSpot dealstageChuyển stage thành công
13Hoàn thiện hồ sơstageU01:15HubSpot dealstageChuyển stage thành công
14Chạy lượt quétscanU01:16SAP service dev/stagingGọi thành công
15Đọc kết quảtraceriêngKhông ghiLuôn xong

⚠️ Ghi PROD — trên Staging, bước 6, 7, 9, 12, 13 ghi HubSpot portal production (như US-D09 §4a).

Tình trạng nghiệm thu gần nhất (nguồn ngoài code, chưa kiểm chứng ở R3): runbook ghi US-02 ✅ 5/5 trên dev 2026-09-18 (shared/runbooks/sapp/sapp-26878/phase-2/README.md) và một lượt trọn vẹn trên staging 2026-09-22 (.../phase-2/staging/README.md §6d).

b. Chi tiết từng màn ​

Màn M1 - Chuỗi bước dựng dữ liệu (bước 1–14) ​

FieldValue
Figma frameN/A — as-built, không có Figma
Trigger vào mànChọn chip US-02 · DTTH lớp online (inventory E-07)
Mô tả ngắnStepper 15 bước; bước 1–14 dựng lớp online, Deal và giao dịch rồi chạy lượt quét.
UI States ​
StateKhi nàoHiển thịFigma frame
DefaultSitting mớiBước 1 mở, còn lại khóa (→ US-D01)N/A
LoadingĐang gọi hệ ngoàiNút chạy bước ở trạng thái xử lýN/A
Has dataBước xongResponse + id vào bag, tự sang bước kếN/A
EmptyStaging, pool mã lớp rỗngNhư US-D09 EC-M1.2N/A
ErrorHệ ngoài trả lỗiLỗi của bước, bước không xongN/A
DisabledBước khóa; bước 5 trên StagingNhư US-D09N/A
Fields ​

Chỉ field khác US-01 (bước 3 và bước 8). Field còn lại → US-D09 §M1 Fields.

FieldRequiredTypeDefaultFormatValidationError MessageVisibilityDepends On
B3 · instruction_mode—TextONLINE—BR-02—Readonly—
B3 · duration_type—TextFIXED—BR-02—Readonly—
B3 · flexible_daysNoNumber100số——Always—
B3 · started_atYesDatetime ISO00:00 hôm nay giờ VNISOBR-03Lỗi của OpsAlways—
B3 · finished_atYesDatetime ISO00:00 hôm nay giờ VNISOBR-03Lỗi của OpsAlways—
B3 · facility_idYesDropdown—id——AlwaysHint: vẫn gửi dù Center = ALL
B8 · product_ids—Dropdown (danh mục sản phẩm)sản phẩm mã ONLINE—BR-05—AlwaysDanh mục
Actions ​
A3 - Tạo lớp ONLINE (bước 3) ​
ItemDescription
TriggerKiểm/chọn mã lớp, bấm chạy
BehaviorTạo lớp trên Ops dev/staging với hình thức ONLINE, FIXED, có ngày bắt đầu + kết thúc (BR-02, BR-03, BR-04).
Success ResultBag có class_id, class_code

Error cases:

CaseExpected Handling
Pool mã staging rỗng / mã trùngNhư US-D09 EC-M1.1, EC-M1.2
A8 - Tạo đơn hàng với sản phẩm ONLINE (bước 8) ​
ItemDescription
TriggerMở bước (sản phẩm ONLINE đã chọn sẵn), bấm chạy
BehaviorNhư U01:10, riêng sản phẩm mặc định ONLINE (BR-05).
Success ResultBag có order_id, order_amount

Error cases:

CaseExpected Handling
Người dùng đổi sang sản phẩm BLENDEDTool không chặn; theo hint, luồng chạy tới Won rồi hỏng ở lượt quét với ERR-01 (sapp-26878-flows.ts:3639)
Acceptance Criteria của màn M1 ​
AC-M1.1 - Chuỗi 15 bước không có buổi học ​
gherkin
Given một sitting mới của luồng US-02
When người dùng xem stepper
Then thấy 15 bước theo §4a; không có bước "Tạo buổi học", "Gán phòng học", "Trả lại mã lớp"

Maps to:

  • Business Rule: BR-01
AC-M1.2 - Lớp online cố định ​
gherkin
Given bước 3 "Tạo lớp" của US-02
When mở form
Then instruction_mode = ONLINE và duration_type = FIXED ở chế độ chỉ đọc
And started_at, finished_at bắt buộc, mặc định 00:00 hôm nay giờ VN

Maps to:

  • Business Rule: BR-02, BR-03, BR-04
AC-M1.3 - Sản phẩm ONLINE chọn sẵn ​
gherkin
Given danh mục sản phẩm của môi trường có sản phẩm mã ONLINE
When mở bước 8 "Tạo đơn hàng"
Then ô sản phẩm đã chọn sẵn sản phẩm ONLINE

Maps to:

  • Business Rule: BR-05
Negative AC / Edge Cases của màn M1 ​
IDTình huốngHành vi mong đợi
EC-M1.1⚠️ Observed — chạy luồng trên StagingHành vi hiện tại: luồng không có bước "Trả lại mã lớp" (chỉ US-01 có, US-D09 bước 18), trong khi runbook staging §0.1 "Vòng đời một mã lớp" và lượt §6d ghi mọi lượt đều trả mã. Mỗi lượt giữ vĩnh viễn một mã của pool staging; tool không có đường nào trả mã của lớp do luồng này tạo. Pool cạn → bước Tạo lớp của mọi luồng phase 2 bị chặn (US-D09 EC-M1.2). OQ-D-07 · DR-D-06 — xem 00-overview §6 / §6b
EC-M1.2⚠️ Observed — bước 6 chọn "Dùng deal có sẵn"Như US-D09 EC-M1.3: mọi bước còn lại bị đánh dấu xong — OQ-D-06
EC-M1.3Đổi sản phẩm đơn hàng khác ONLINETool không chặn (A8 Error cases)

Màn M2 - Bước 15 "Đọc kết quả" ​

FieldValue
Figma frameN/A — as-built, không có Figma
Trigger vào mànMở bước 15
Mô tả ngắnTrace log SAP theo deal_id (→ US-P05) + 5 kiểm chứng tự chấm.
UI States ​
StateKhi nàoHiển thịFigma frame
DefaultMở bướcHint + mã lớp + trace tự chạy (lọc deal_id)N/A
LoadingĐang traTrace đang tảiN/A
Has dataCó trailKết quả 5 kiểm chứng pass / fail / unknownN/A
EmptyChưa có dòng nàoTheo hint: số dư 3387 bằng 0 thì không có bút toán — "không có dòng" có thể là đúngN/A
ErrorTrace lỗi→ US-P05N/A
DisabledN/AN/AN/A
Fields ​

N/A — bước chỉ đọc.

Actions ​
A15 - Đọc kết quả ​
ItemDescription
TriggerMở bước (tự chạy)
BehaviorTra log theo deal_id, chạy 5 kiểm chứng (BR-06). Không ghi.
Success ResultBước luôn xong

Error cases:

CaseExpected Handling
Không đọc được trườngKiểm chứng = unknown (US-D09 BR-17)
Acceptance Criteria của màn M2 ​

AC = kiểm chứng tự chấm (sapp-26878-flows.ts:3563-3602).

AC-M2.1 - Ghi trọn số dư một lần ​
gherkin
Given lượt quét đã gửi bút toán của lớp online
When chạy kiểm chứng "Ghi trọn số dư một lần"
Then pass khi recognition_type trong payload = FULL_REMAINING

Maps to:

  • Business Rule: BR-06
AC-M2.2 - Không mang tiến trình buổi học ​
gherkin
When chạy kiểm chứng "Không mang tiến trình buổi học"
Then pass khi payload KHÔNG có lesson_hours

Maps to:

  • Business Rule: BR-06
AC-M2.3 - Không mang số dư theo buổi ​
gherkin
When chạy kiểm chứng "Không mang số dư theo buổi"
Then pass khi payload KHÔNG có standard_hours_remaining

Maps to:

  • Business Rule: BR-06
AC-M2.4 - Trung tâm cố định ALL ​
gherkin
When chạy kiểm chứng "Trung tâm cố định ALL"
Then pass khi dimensions.center = ALL

Maps to:

  • Business Rule: BR-06
AC-M2.5 - Dòng sổ cái đúng loại ​
gherkin
When chạy kiểm chứng "Dòng sổ cái đúng loại"
Then pass khi dòng sổ cái có entry_type = RECORDED_ONLINE

Maps to:

  • Business Rule: BR-06
AC-M2.6 - Bước đọc không chặn ​
gherkin
Given một kiểm chứng fail hoặc unknown
Then bước 15 vẫn là "xong"

Maps to:

  • Business Rule: BR-06
Negative AC / Edge Cases của màn M2 ​
IDTình huốngHành vi mong đợi
EC-M2.1Chạy lại lượt quét trên lớp đã ghiTheo hint: lớp không vào lượt quét nữa; muốn test lại phải xóa dòng sổ cái bằng SQL ngoài tool — luồng không cung cấp câu SQL này
EC-M2.2Kiểm chứng fail nhưng người dùng đi tiếpKhông có gate — OQ-D-15

5. Cross-feature AC ​

AC-X.1 - Dùng lại bước US-01 ​

gherkin
Given bước U01:1, 2, 6–16 thay đổi ở US-01
When mở luồng US-02
Then luồng dùng đúng định nghĩa mới, trừ ô sản phẩm của bước 8 (ghi đè riêng)

Maps to:

  • Liên quan nội bộ FS 26878 (không có mã REL) (US-D09, AC-X.1)