Giao diện
US-D11: Flow P2 — DTTH chốt sổ (story SAPP US-03 phase 2) ​
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-121). 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 ở US-D09 §4a.⚠ "US-03" ở đây là story phase 2 (chip id
us03-p2), khác hẳn "US-03 · Học phí thường" phase 1 (US-D04) —shared/runbooks/sapp/sapp-26878/README.md:12-13.
| Field | Value |
|---|---|
| US ID | US-D11 |
| Role thực hiện | Người dùng tool — Assumption (OQ về G-01 · inventory Q-05 — xem 00-overview §6) |
| Phase | Phase 2 của SAPP-26878 (DTTH) · chip US-03 · DTTH chốt sổ (id us03-p2) |
| Priority | N/A — as-built, đã triển khai (backlog R2: không xếp Priority) |
| Status | Draft |
| NFR liên quan | NFR-P-01 (quyền, FS nền tảng) · NFR của 26878 — xem 00-overview §5 |
| OQ liên quan | OQ-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 chỉ còn đúng một buổi đã diễn ra (buổi đó vừa là buổi đầu vừa là buổi chốt sổ),
chạy lượt quét rồi đọc kết quả
So that kiểm được rằng tại buổi cuối của lớp, hệ thống ghi toàn bộ doanh thu chờ phân bổ còn lại để số
dư 3387 của môn về 0 (chốt sổ / true-up)- Nguồn "So that":
shared/runbooks/sapp/sapp-26878/phase-2/us-03/README.md:5-6("Tại buổi cuối của lớp, ghi toàn bộ doanh thu chờ phân bổ còn lại để số dư 3387 của môn về 0 và hấp thụ hết sai số làm tròn tích lũy"); hint luồngsapp-26878-flows.ts:4042. Tiêu chí nghiệm thu của tool:[Assumption](OQ-D-13).
2. Dependencies & Definition Of Ready ​
N/A — đã triển khai (Mode B). Dependency runtime như US-D09 §2; luồng này dùng thêm nhiều câu SQL ghi qua US-P09 và thao tác xóa buổi qua US-P08.
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Luồng có 19 bước theo thứ tự ở §4a; bước "Xóa buổi đuôi" và "Kéo buổi về quá khứ" nằm sau "Hoàn thiện hồ sơ" và trước "Chạy lượt quét"; không có bước trả lại mã lớp | M1 | AC-M1.1 | fe/src/ui/components/works/sapp/sapp-26878-flows.ts:4044-4082 |
| BR-02 | Form Tạo lớp của luồng không có ô ngày kết thúc lớp (ngày kết thúc do hệ thống tự tính từ buổi học) | M1 - A3 | AC-M1.2 | sapp-26878-flows.ts:3677-3796 |
| BR-03 | "Xóa buổi đuôi" xóa một buổi của lớp theo id; id buổi cuối còn lại được điền sẵn từ câu SQL đọc (tự chạy, và tự chạy lại sau mỗi lần xóa); bước bấm lặp được nhiều lần | M1 - A16 | AC-M1.3 | sapp-26878-flows.ts:3829-3865 |
| BR-04 | "Kéo buổi về quá khứ": câu đọc tự chạy và điền sẵn id lịch của buổi còn lại; ngày kéo về mặc định hôm nay; câu ghi cập nhật ngày bắt đầu và ngày kết thúc của buổi; câu kiểm lại chạy tay | M1 - A17 | AC-M1.4 | sapp-26878-flows.ts:3877-3910 |
| BR-05 | Hai bước 16, 17 là tùy chọn (bỏ qua được như mọi bước) | M1 - A16, A17 | AC-M1.5 | sapp-26878-flows.ts:3846,4074 |
| BR-06 | Đọc kết quả lọc log SAP theo deal_id, tự chạy 4 kiểm chứng (§M2), luôn coi là xong; kèm 6 câu SQL (5 đọc, 1 ghi xóa sổ cái của lớp) | M2 | AC-M2.1 → AC-M2.5 | sapp-26878-flows.ts:3934-4026; fe/src/ui/components/works/sapp/sapp-26878-tool.tsx:883-884 |
| BR-07 | Mọi câu SQL ghi của luồng không tự chạy và phải qua hộp xác nhận | M1 - A17, M2 | AC-M1.4, AC-M2.5 | fe/src/ui/components/works/sapp/sapp-26878-step-sql.tsx:200-213; inventory R-26 |
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[Chip "US-03 · DTTH chốt sổ", portal Dev | Staging]
↓
[M1] U01:1 → U01:2 → Tạo lớp (riêng) → U01:4 … U01:15
→ Xóa buổi đuôi (tùy chọn, lặp tới khi còn 1 buổi) → Kéo buổi về quá khứ (tùy chọn) → U01:16
↓
[M2] Đọc kết quả (luôn "xong")Bảng bước (Fact: sapp-26878-flows.ts:4044-4082).
| # | Tên bước | Loại | Tái dùng | Ghi gì (hệ thống · môi trường) | Điều kiện chuyển (xong) |
|---|---|---|---|---|---|
| 1 | Kiểm tra kết nối Ops | ops + sql | U01:1 | Không ghi | Ping thành công |
| 2 | Đếm lớp của môn | ops | U01:2 | Không ghi | Gọi thành công |
| 3 | Tạo lớp | ops + sql | riêng (không có ô ngày kết thúc) | Ops dev/staging | Gọi thành công |
| 4 | Tạo buổi học | ops | U01:4 | Ops | Gọi thành công |
| 5 | Gán phòng học | ops | U01:5 | Ops | Gọi thành công |
| 6 | Mở lớp (PUBLIC) | ops | U01:6 | Ops | Gọi thành công |
| 7 | Thêm option mã lớp | option | U01:7 | HubSpot dev (staging: bỏ qua) | Đủ 3 property / bỏ qua |
| 8 | Tạo Deal | deal | U01:8 | HubSpot (⚠️ portal prod khi Staging); Redis run history | Có deal |
| 9 | Gán mã lớp | classcode | U01:9 | HubSpot | Gọi thành công |
| 10 | Tạo đơn hàng | ops | U01:10 | Ops | Thành công, số tiền ≠ 0 |
| 11 | Soạn thảo hợp đồng | stage | U01:11 | HubSpot | Chuyển stage thành công |
| 12 | Tạo giao dịch | ops | U01:12 | Ops | Gọi thành công |
| 13 | Xác nhận giao dịch | ops | U01:13 | Ops → SAP (theo hint) | Gọi thành công |
| 14 | Kéo sang Won | stage | U01:14 | HubSpot | Chuyển stage thành công |
| 15 | Hoàn thiện hồ sơ | stage | U01:15 | HubSpot | Chuyển stage thành công |
| 16 | Xóa buổi đuôi (tùy chọn) | ops + sql | riêng (dùng chung với US-04) | Ops: xóa một buổi của lớp (lặp được). SQL p2.deletetail chỉ đọc | Lần xóa đầu thành công, hoặc bỏ qua |
| 17 | Kéo buổi về quá khứ (tùy chọn) | guide + sql | riêng | Ops DB: us03.backdate.2 cập nhật ngày của buổi còn lại | Bấm "Đã kéo buổi về quá khứ", hoặc bỏ qua |
| 18 | Chạy lượt quét | scan | U01:16 | SAP service dev/staging | Gọi thành công |
| 19 | Đọc kết quả | trace + sql | riêng | Không ghi, trừ câu SQL ⑥ (xóa sổ cái của lớp, Ops DB) nếu người dùng chạy | Luôn xong |
⚠️ Ghi PROD — trên Staging, bước 8, 9, 11, 14, 15 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 ✅ 4/4 trên dev 2026-09-18 (shared/runbooks/sapp/sapp-26878/phase-2/us-03/README.md:3) và một lượt trọn vẹn trên staging 2026-09-22 (.../phase-2/staging/README.md §6e).
b. Chi tiết từng màn ​
Màn M1 - Chuỗi bước dựng dữ liệu (bước 1–18) ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Chọn chip US-03 · DTTH chốt sổ (inventory E-07) |
| Mô tả ngắn | Dựng như US-01, rồi rút lớp về đúng một buổi đã diễn ra trước khi quét. |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Sitting mới | Bước 1 mở, còn lại khóa (→ US-D01) | N/A |
| Loading | Đang gọi Ops / chạy SQL | Nút chạy ở trạng thái xử lý | N/A |
| Has data | Bước 16 vừa xóa một buổi | Câu SQL đọc tự chạy lại, ô class_schedule_id đổi sang buổi cuối mới | N/A |
| Empty | Staging, pool mã lớp rỗng | Như US-D09 EC-M1.2 | N/A |
| Error | Ops trả class_schedule_not_found | Lỗi của bước; ghi chú SQL khuyên đọc status / is_active / mode của buổi | N/A |
| Disabled | Bước khóa; bước 7 trên Staging | Như US-D09 | N/A |
Fields ​
Chỉ field riêng của luồng. Field của U01:x → US-D09.
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
B3 · (như U01:3, không có finished_at) | — | — | — | — | BR-02 | — | — | — |
B16 · class_schedule_id | Yes | Text | id buổi cuối từ p2.deletetail.1 | id Ops | BR-03 | class_schedule_not_found (Ops) | Always | class_id |
B17 · Ngày kéo buổi về (date_past) | — | Date | hôm nay | YYYY-MM-DD | Hint: ≥ go-live (dev 2026-09-14, staging 2026-09-17) và ≥ ngày khai giảng | — | Always | — |
B17 · survivor_schedule_id | — | Text (bag) | từ us03.backdate.1 | id | BR-04 | — | Readonly (điền sẵn) | class_id |
Actions ​
A16 - Xóa buổi đuôi (tùy chọn, bước 16) ​
| Item | Description |
|---|---|
| Trigger | Mở bước (SQL đọc tự chạy), bấm chạy; lặp tới khi lớp còn một buổi |
| Behavior | Xóa buổi trên Ops dev/staging (BR-03). Theo hint: End date của lớp tự co về buổi còn lại; ở US-03 phải xóa sau bước Hoàn thiện hồ sơ vì xóa trước làm lớp kết thúc và học viên không được thêm vào; xóa buổi đã có học viên bắn sự kiện đảo (US-06) và có thể sinh mail ERR-03 cho kế toán mỗi buổi (sapp-26878-flows.ts:3852). |
| Success Result | Buổi bị xóa; câu SQL đọc tự chạy lại |
Error cases:
| Case | Expected Handling |
|---|---|
| Id buổi không còn / không thỏa điều kiện Ops | Ops trả class_schedule_not_found; tool hiện lỗi |
A17 - Kéo buổi về quá khứ (tùy chọn, bước 17) ​
| Item | Description |
|---|---|
| Trigger | Mở bước (câu ① tự chạy), chọn ngày, bấm "Chạy" câu ② (xác nhận), chạy câu ③, bấm "Đã kéo buổi về quá khứ" |
| Behavior | Ghi Ops DB dev/staging qua SQL runner (BR-04, BR-07). Guide: bỏ qua nếu buổi còn lại đã ở hôm nay hoặc sớm hơn; không sửa ngày kết thúc lớp. |
| Success Result | Lớp có đúng một buổi, ngày ≤ hôm nay |
Error cases:
| Case | Expected Handling |
|---|---|
| Còn hơn một buổi | Ghi chú câu ①: quay lại bước 16 |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Chuỗi 19 bước ​
gherkin
Given một sitting mới của luồng US-03 phase 2
When người dùng xem stepper
Then thấy 19 bước theo §4a; "Xóa buổi đuôi (tùy chọn)" và "Kéo buổi về quá khứ (tùy chọn)" nằm giữa "Hoàn thiện hồ sơ" và "Chạy lượt quét"
And không có bước "Trả lại mã lớp"Maps to:
- Business Rule: BR-01
AC-M1.2 - Không gửi ngày kết thúc lớp ​
gherkin
When mở bước 3 "Tạo lớp"
Then form không có ô finished_atMaps to:
- Business Rule: BR-02
AC-M1.3 - Xóa dần buổi đuôi ​
gherkin
Given lớp có N buổi
When mở bước 16
Then ô class_schedule_id điền sẵn id buổi cuối
And sau mỗi lần xóa thành công, danh sách buổi tự đọc lại và ô được điền id buổi cuối mớiMaps to:
- Business Rule: BR-03
AC-M1.4 - Kéo buổi còn lại về quá khứ ​
gherkin
Given lớp còn một buổi
When mở bước 17
Then câu ① tự chạy và điền survivor_schedule_id; ngày mặc định hôm nay
When chạy câu ② và xác nhận
Then ngày bắt đầu và ngày kết thúc của buổi đổi sang ngày đã chọnMaps to:
- Business Rule: BR-04, BR-07
AC-M1.5 - Hai bước tùy chọn ​
gherkin
Given buổi do bộ sinh lịch tạo đã nằm ở hôm nay và lớp chỉ có một buổi
When người dùng bấm "Bỏ qua bước này" ở bước 16 và 17
Then luồng đi tiếp tới "Chạy lượt quét"Maps to:
- Business Rule: BR-05
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | ⚠️ Observed — chạy luồng trên Staging | Luồng không có bước "Trả lại mã lớp" (chỉ US-01 có), trong khi runbook staging §0.1 và lượt §6e ghi mọi lượt đều trả mã. Mỗi lượt giữ vĩnh viễn một mã của pool staging; cạn pool → bước Tạo lớp của mọi luồng phase 2 bị chặn. OQ-D-07 · DR-D-06 — xem 00-overview §6 / §6b |
| EC-M1.2 | Bước 15 "Hoàn thiện hồ sơ" bị bỏ qua rồi xóa buổi ở bước 16 | Tool không kiểm lớp đã có học viên trước khi xóa — bước 16 vẫn chạy. Theo hint: xóa khi lớp chưa có học viên làm lớp kết thúc sớm và học viên không được thêm vào, im lặng, phải tạo Deal mới (sapp-26878-flows.ts:4067-4071) |
| EC-M1.3 | ⚠️ Observed (OQ-D-18) — guide bước 17 ghi "⚠ Chỉ làm trên dev" | Hành vi hiện tại: bước không bị khóa trên Staging, và runbook staging §6e ghi đã chạy US-03 trên staging. Đề xuất OQ "hướng dẫn cũ hay giới hạn thật?" — điều phối viên cấp mã |
| EC-M1.4 | ⚠️ Observed — "Dùng deal có sẵn" ở bước 8 | Như US-D09 EC-M1.3 — OQ-D-06 |
Màn M2 - Bước 19 "Đọc kết quả" ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Mở bước 19 |
| Mô tả ngắn | Trace log SAP theo deal_id + 4 kiểm chứng; panel 6 câu SQL đối chiếu tay / dọn dữ liệu. |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Mở bước | Hint + mã lớp + trace tự chạy + panel SQL us03.trace | N/A |
| Loading | Đang tra | Trace đang tải | N/A |
| Has data | Có trail | Kết quả 4 kiểm chứng | N/A |
| Empty | Chưa có bút toán | Hint: đọc counters (true_ups_created = 0) và 3 nghi can | N/A |
| Error | Trace / SQL lỗi | → US-P05 / US-P09 | N/A |
| Disabled | N/A | N/A | N/A |
Fields ​
N/A — bộ lọc lấy từ bag; câu SQL dùng class_id / class_code từ bag.
Actions ​
A19 - Đọc kết quả + SQL đối chiếu ​
| Item | Description |
|---|---|
| Trigger | Mở bước (trace tự chạy); chạy tay các câu SQL |
| Behavior | Câu ①–⑤ chỉ đọc (End date lớp, sổ cái lớp, cờ buổi bù, cửa sổ lượt quét, 10 dòng sổ cái gần nhất toàn môi trường). Câu ⑥ ghi Ops DB: xóa sổ cái của lớp để chạy lại (BR-06, BR-07). |
| Success Result | Bước luôn xong |
Error cases:
| Case | Expected Handling |
|---|---|
| Không đọc được trường | Kiểm chứng = unknown |
Acceptance Criteria của màn M2 ​
AC = kiểm chứng tự chấm (sapp-26878-flows.ts:3934-3965).
AC-M2.1 - Bút toán cuối là chốt sổ ​
gherkin
When chạy kiểm chứng "Bút toán cuối là chốt sổ"
Then pass khi phần tử CUỐI của payload có recognition_type = TRUE_UPMaps to:
- Business Rule: BR-06
AC-M2.2 - Chốt sổ không gửi lesson_hours ​
gherkin
When chạy kiểm chứng "Chốt sổ không gửi lesson_hours"
Then pass khi phần tử cuối của payload KHÔNG có lesson_hoursMaps to:
- Business Rule: BR-06
AC-M2.3 - Chốt sổ không gửi standard_hours_remaining ​
gherkin
When chạy kiểm chứng "Chốt sổ không gửi standard_hours_remaining"
Then pass khi phần tử cuối của payload KHÔNG có standard_hours_remainingMaps to:
- Business Rule: BR-06
AC-M2.4 - Dòng sổ cái TRUE_UP ​
gherkin
When chạy kiểm chứng "Dòng sổ cái mang entry_type = TRUE_UP"
Then pass khi các dòng sổ cái có entry_type = TRUE_UPMaps to:
- Business Rule: BR-06
AC-M2.5 - Xóa sổ cái để chạy lại ​
gherkin
Given người dùng muốn quét lại từ đầu
When chạy câu SQL ⑥ và xác nhận hộp thoại
Then sổ cái của lớp bị xóa; bước 19 vẫn "xong"Maps to:
- Business Rule: BR-06, BR-07
Negative AC / Edge Cases của màn M2 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M2.1 | Bấm lại lượt quét (bước 18) mà không xóa sổ cái | Theo hint: buổi đã có dòng bị bỏ qua (ALREADY_RECORDED), không sinh dòng thứ hai — tool không tự kiểm, người dùng đọc tay |
| EC-M2.2 | Dòng TRUE_UP có số tiền 0 | Theo hint: đúng thiết kế |
| EC-M2.3 | Kiểm chứng fail nhưng đi tiếp | Không có gate — OQ-D-15 |
5. Cross-feature AC ​
AC-X.1 - Dùng lại bước US-01 và bước "Xóa buổi đuôi" với US-04 ​
gherkin
Given bước U01:x hoặc bước "Xóa buổi đuôi (tùy chọn)" thay đổi
When mở luồng US-03 phase 2 hoặc US-04
Then cả hai luồng dùng cùng định nghĩa bước "Xóa buổi đuôi" (US-D12 bước 7)Maps to:
- Liên quan nội bộ FS 26878 (không có mã REL) (US-D09, US-D12)