Skip to content

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.

FieldValue
US IDUS-D11
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-03 · DTTH chốt sổ (id us03-p2)
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 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ồng sapp-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 ​

IDRuleÁp dụng ởĐã cover bởi (AC)Nguồn code (Mode B/C)
BR-01Luồ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ớpM1AC-M1.1fe/src/ui/components/works/sapp/sapp-26878-flows.ts:4044-4082
BR-02Form 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 - A3AC-M1.2sapp-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ầnM1 - A16AC-M1.3sapp-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 tayM1 - A17AC-M1.4sapp-26878-flows.ts:3877-3910
BR-05Hai bước 16, 17 là tùy chọn (bỏ qua được như mọi bước)M1 - A16, A17AC-M1.5sapp-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)M2AC-M2.1 → AC-M2.5sapp-26878-flows.ts:3934-4026; fe/src/ui/components/works/sapp/sapp-26878-tool.tsx:883-884
BR-07Mọi câu SQL ghi của luồng không tự chạy và phải qua hộp xác nhậnM1 - A17, M2AC-M1.4, AC-M2.5fe/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ướ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ớpops + sqlriêng (không có ô ngày kết thúc)Ops dev/stagingGọi thành công
4Tạo buổi họcopsU01:4OpsGọi thành công
5Gán phòng họcopsU01:5OpsGọi thành công
6Mở lớp (PUBLIC)opsU01:6OpsGọi thành công
7Thêm option mã lớpoptionU01:7HubSpot dev (staging: bỏ qua)Đủ 3 property / bỏ qua
8Tạo DealdealU01:8HubSpot (⚠️ portal prod khi Staging); Redis run historyCó deal
9Gán mã lớpclasscodeU01:9HubSpotGọi thành công
10Tạo đơn hàngopsU01:10OpsThành công, số tiền ≠ 0
11Soạn thảo hợp đồngstageU01:11HubSpotChuyển stage thành công
12Tạo giao dịchopsU01:12OpsGọi thành công
13Xác nhận giao dịchopsU01:13Ops → SAP (theo hint)Gọi thành công
14Kéo sang WonstageU01:14HubSpotChuyển stage thành công
15Hoàn thiện hồ sơstageU01:15HubSpotChuyển stage thành công
16Xóa buổi đuôi (tùy chọn)ops + sqlriê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ỉ đọcLần xóa đầu thành công, hoặc bỏ qua
17Kéo buổi về quá khứ (tùy chọn)guide + sqlriêngOps DB: us03.backdate.2 cập nhật ngày của buổi còn lạiBấm "Đã kéo buổi về quá khứ", hoặc bỏ qua
18Chạy lượt quétscanU01:16SAP service dev/stagingGọi thành công
19Đọc kết quảtrace + sqlriêngKhông ghi, trừ câu SQL ⑥ (xóa sổ cái của lớp, Ops DB) nếu người dùng chạyLuô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) ​

FieldValue
Figma frameN/A — as-built, không có Figma
Trigger vào mànChọn chip US-03 · DTTH chốt sổ (inventory E-07)
Mô tả ngắnDự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 ​
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 Ops / chạy SQLNút chạy ở trạng thái xử lýN/A
Has dataBước 16 vừa xóa một buổiCâu SQL đọc tự chạy lại, ô class_schedule_id đổi sang buổi cuối mớiN/A
EmptyStaging, pool mã lớp rỗngNhư US-D09 EC-M1.2N/A
ErrorOps trả class_schedule_not_foundLỗi của bước; ghi chú SQL khuyên đọc status / is_active / mode của buổiN/A
DisabledBước khóa; bước 7 trên StagingNhư US-D09N/A
Fields ​

Chỉ field riêng của luồng. Field của U01:x → US-D09.

FieldRequiredTypeDefaultFormatValidationError MessageVisibilityDepends On
B3 · (như U01:3, không có finished_at)————BR-02———
B16 · class_schedule_idYesTextid buổi cuối từ p2.deletetail.1id OpsBR-03class_schedule_not_found (Ops)Alwaysclass_id
B17 · Ngày kéo buổi về (date_past)—Datehôm nayYYYY-MM-DDHint: ≥ 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.1idBR-04—Readonly (điền sẵn)class_id
Actions ​
A16 - Xóa buổi đuôi (tùy chọn, bước 16) ​
ItemDescription
TriggerMở bước (SQL đọc tự chạy), bấm chạy; lặp tới khi lớp còn một buổi
BehaviorXó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 ResultBuổi bị xóa; câu SQL đọc tự chạy lại

Error cases:

CaseExpected Handling
Id buổi không còn / không thỏa điều kiện OpsOps 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) ​
ItemDescription
TriggerMở 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ứ"
BehaviorGhi 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 ResultLớp có đúng một buổi, ngày ≤ hôm nay

Error cases:

CaseExpected Handling
Còn hơn một buổiGhi 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_at

Maps 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ới

Maps 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ọn

Maps 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 ​
IDTình huốngHành vi mong đợi
EC-M1.1⚠️ Observed — chạy luồng trên StagingLuồ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.2Bước 15 "Hoàn thiện hồ sơ" bị bỏ qua rồi xóa buổi ở bước 16Tool 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 8Như US-D09 EC-M1.3 — OQ-D-06

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

FieldValue
Figma frameN/A — as-built, không có Figma
Trigger vào mànMở bước 19
Mô tả ngắnTrace 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 ​
StateKhi nàoHiển thịFigma frame
DefaultMở bướcHint + mã lớp + trace tự chạy + panel SQL us03.traceN/A
LoadingĐang traTrace đang tảiN/A
Has dataCó trailKết quả 4 kiểm chứngN/A
EmptyChưa có bút toánHint: đọc counters (true_ups_created = 0) và 3 nghi canN/A
ErrorTrace / SQL lỗi→ US-P05 / US-P09N/A
DisabledN/AN/AN/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 ​
ItemDescription
TriggerMở bước (trace tự chạy); chạy tay các câu SQL
BehaviorCâ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 ResultBước luôn xong

Error cases:

CaseExpected Handling
Không đọc được trườngKiể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_UP

Maps 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_hours

Maps 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_remaining

Maps 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_UP

Maps 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 ​
IDTình huốngHành vi mong đợi
EC-M2.1Bấm lại lượt quét (bước 18) mà không xóa sổ cáiTheo 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.2Dòng TRUE_UP có số tiền 0Theo hint: đúng thiết kế
EC-M2.3Kiểm chứng fail như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 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)