Giao diện
US-D14: Flow P2 — DTTH đảo buổi (story SAPP US-06 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-124). 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-06" ở đây là story phase 2 (chip id
us06-p2), khác "US-06 · CBE / Cert / Becker" phase 1 (US-D06).
| Field | Value |
|---|---|
| US ID | US-D14 |
| 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-06 · DTTH đảo buổi (id us06-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, DR-D-07 — 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 có buổi hôm nay đã được ghi nhận doanh thu, rồi dời (hoặc hủy) đúng buổi đó và đọc kết quả
So that kiểm được rằng một buổi đã ghi nhận doanh thu mà bị hủy hoặc dời lịch thì phần đã ghi cho buổi đó
bị đảo ngay, ghi vào nhóm cột đảo của chính dòng sổ cái gốc, không chờ lượt quét- Nguồn "So that":
shared/runbooks/sapp/sapp-26878/phase-2/us-06/README.md:6-7("Một buổi đã ghi nhận doanh thu mà bị hủy hoặc dời lịch thì phần đã ghi cho buổi đó bị đảo ngay, không chờ lượt quét"); hint luồngsapp-26878-flows.ts:5343. 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. Thêm (hint): chip chỉ chạy được trước 22:00 giờ VN (bộ sinh lịch đẩy buổi đầu sang tuần sau); thao tác dời đóng lúc 20:00, hủy đóng lúc 23:00 giờ VN (sapp-26878-flows.ts:5093,5189,5343).
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Luồng có 22 bước theo thứ tự ở §4a (một Deal, một hàng); 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:5345-5379 |
| BR-02 | "Kiểm buổi đã được ghi": câu SQL đọc tự chạy và điền sẵn id buổi (dòng đầu theo ngày) cho hai bước kích hoạt; kèm một kiểm chứng tự chấm | M2 - A17 | AC-M2.1 | sapp-26878-flows.ts:4982-5017 |
| BR-03 | "Tạo giáo viên" tạo một giáo viên dùng một lần; năm trường định danh bắt buộc, sinh từ mẫu | M1 - A18 | AC-M1.2 | sapp-26878-flows.ts:4939-4980 |
| BR-04 | "Kiểm buổi có học viên" là bước hướng dẫn chỉ đọc (đếm bản ghi buổi ↔ học viên), xong khi người dùng bấm xác nhận | M1 - A19 | AC-M1.3 | sapp-26878-flows.ts:5039-5072 |
| BR-05 | "Dời buổi" bắt buộc: id buổi, ngày mới (mặc định ngày mai 15:00Z), khung giờ, phòng, giáo viên (điền từ bước Tạo giáo viên), lý do (mặc định "Test US-06"); hình thức OFFLINE cố định; nội dung buổi để trống = giữ nguyên | M1 - A20 | AC-M1.4 | sapp-26878-flows.ts:5087-5167 |
| BR-06 | "Hủy buổi (trigger thay thế)" gửi id buổi và lý do (mặc định "Test US-06 — hủy buổi", được phép rỗng) | M1 - A21 | AC-M1.5 | sapp-26878-flows.ts:5183-5208 |
| BR-07 | Đọc kết quả lọc log SAP theo deal_id, tự chạy 6 kiểm chứng (§M2), luôn coi là xong; panel SQL 3 câu đọc + 1 câu ghi (xóa vết đảo phía sổ cái để dựng lại ca) | M2 - A22 | AC-M2.2 → AC-M2.8 | sapp-26878-flows.ts:5223-5329 |
| BR-08 | Mọi câu SQL ghi không tự chạy và phải qua hộp xác nhận | M2 | AC-M2.8 | fe/src/ui/components/works/sapp/sapp-26878-step-sql.tsx:200-213 |
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[Chip "US-06 · DTTH đảo buổi", portal Dev | Staging]
↓
[M1] U01:1 → U01:2 → U01:3 → U01:5 → U01:4 → U01:6 … U01:16 (dựng bút toán gốc)
↓
[M2] Kiểm buổi đã được ghi
↓
[M1] Tạo giáo viên → Kiểm buổi có học viên → Dời buổi ─┐ (chỉ MỘT trong hai mỗi lượt,
Hủy buổi ──────┘ bước còn lại "Bỏ qua")
↓
[M2] Đọc kết quảBảng bước (Fact: sapp-26878-flows.ts:5345-5379).
| # | 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 | U01:3 | Ops dev/staging | Gọi thành công |
| 4 | Gán phòng học | ops | U01:5 | Ops | Gọi thành công |
| 5 | Tạo buổi học | ops | U01:4 | 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 | Chạy lượt quét | scan | U01:16 | SAP service dev/staging | Gọi thành công |
| 17 | Kiểm buổi đã được ghi | trace + sql | riêng | Không ghi → bag class_schedule_id | Luôn xong |
| 18 | Tạo giáo viên | ops | riêng | Ops: giáo viên test → bag teacher_id | Gọi thành công |
| 19 | Kiểm buổi có học viên | guide + sql | riêng | Không ghi (SQL us06.link chỉ đọc) | Bấm "Đã có bản ghi buổi ↔ học viên" |
| 20 | Dời buổi | ops | riêng | Ops: sửa lịch buổi (theo hint: bắn sự kiện đảo ngay) | Gọi thành công, hoặc bỏ qua |
| 21 | Hủy buổi (trigger thay thế) | ops | riêng | Ops: hủy buổi (theo hint: cùng sự kiện đảo) | Gọi thành công, hoặc bỏ qua |
| 22 | Đọc kết quả | trace + sql | riêng | Không ghi, trừ câu SQL ④ (Ops DB) nếu 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 ✅ 6/6 trên dev 2026-09-18, lớp F103.215 (shared/runbooks/sapp/sapp-26878/phase-2/us-06/README.md:3-4) và một lượt trọn vẹn trên staging 2026-09-22 (.../phase-2/staging/README.md §6h).
b. Chi tiết từng màn ​
Màn M1 - Chuỗi bước dựng dữ liệu và kích hoạt (bước 1–16, 18–21) ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Chọn chip US-06 · DTTH đảo buổi (inventory E-07) |
| Mô tả ngắn | Dựng như US-01 để có bút toán gốc, rồi dời hoặc hủy chính buổi đó. |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Sitting mới | Bước 1 mở (→ US-D01) | N/A |
| Loading | Đang gọi Ops | Nút chạy ở trạng thái xử lý | N/A |
| Has data | Bước 18 xong | teacher_id vào bag, điền sẵn vào bước 20 | N/A |
| Empty | Staging, pool mã lớp rỗng | Như US-D09 EC-M1.2 | N/A |
| Error | Ops từ chối dời / hủy | Lỗi Ops (vd theo hint: ngày đã có buổi, quá giờ, thiếu giáo viên) | N/A |
| Disabled | Bước khóa; bước 7 trên Staging | Như US-D09 | N/A |
Fields ​
Chỉ field riêng (Nguồn sapp-26878-flows.ts:4946-5207).
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
B18 · full_name, email, username, phone, teacher_code | Yes | Text | sinh từ mẫu (cùng một số điện thoại) | — | BR-03 | Lỗi Ops (trùng) | Always | — |
B19 · class_schedule_id của buổi hôm nay | — | Text | — (nhập tay) | id | — | — | Always | Bước 17 |
B20 · class_schedule_id | Yes | Text | bag (bước 17) | id | BR-05 | Lỗi Ops | Always | Bước 17 |
B20 · lesson_date | Yes | Datetime ISO | ngày mai 15:00Z | ISO | Hint: khác ngày cũ, không ở quá khứ | Lỗi Ops | Always | — |
B20 · learning_mode | — | Text | OFFLINE | — | — | — | Readonly | — |
B20 · class_duration | Yes | JSON | 13:00–16:00 | JSON | — | — | Always | — |
B20 · classroom_id | Yes | Dropdown (phòng học) | — | id | — | Lỗi Ops | Always | Danh mục |
B20 · teacher_id | Yes | Text | bag teacher_id | id | BR-05 | Theo hint: thiếu → Ops 400/460404 | Always | Bước 18 |
B20 · course_section_ids | No | JSON | rỗng | mảng | — | — | Always | — |
B20 · reason | Yes | Text | "Test US-06" | — | BR-05 | Theo hint: rỗng → lỗi Ops | Always | — |
B21 · class_schedule_id | Yes | Text | bag (bước 17) | id | BR-06 | Lỗi Ops | Always | Bước 17 |
B21 · reason | No | Text | "Test US-06 — hủy buổi" | — | được phép rỗng | — | Always | — |
Actions ​
A18 - Tạo giáo viên (bước 18) ​
| Item | Description |
|---|---|
| Trigger | Bấm chạy |
| Behavior | Tạo giáo viên test trên Ops dev/staging (BR-03). Hint: không bỏ qua được vì buổi do bộ sinh lịch tạo không có giáo viên. |
| Success Result | Bag có teacher_id |
Error cases:
| Case | Expected Handling |
|---|---|
| Trùng định danh | Lỗi Ops |
A19 - Kiểm buổi có học viên (bước 19) ​
| Item | Description |
|---|---|
| Trigger | Nhập id buổi, chạy câu đếm, bấm xác nhận |
| Behavior | Chỉ đọc Ops DB (BR-04). Guide: bản ghi sinh bất đồng bộ, đếm lại vài lần; ra 0 thì lượt dời sau trả 200 mà không có gì xảy ra. |
| Success Result | Người dùng bấm "Đã có bản ghi buổi ↔ học viên" |
Error cases:
| Case | Expected Handling |
|---|---|
| Đếm ra 0 | Tool không chặn; guide yêu cầu đợi, không đi tiếp |
A20 / A21 - Dời buổi / Hủy buổi (bước 20, 21) ​
| Item | Description |
|---|---|
| Trigger | Bấm chạy một trong hai; bấm "Bỏ qua bước này" ở bước còn lại |
| Behavior | Ghi Ops dev/staging (BR-05, BR-06). Hint: một buổi chỉ nhận một trigger; muốn kiểm cả hai phải chạy chip hai lần. |
| Success Result | Gọi thành công; không cần lượt quét |
Error cases:
| Case | Expected Handling |
|---|---|
| Ngày mới đã có buổi của lớp | Ops từ chối (ClasScheduleExisted); chọn ngày trống |
| Hủy sau khi đã dời | Theo hint: Ops trả 200 nhưng không bắn sự kiện |
| Quá hạn giờ (dời sau 20:00 / hủy sau 23:00 giờ VN) | Ops từ chối |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Chuỗi 22 bước ​
gherkin
Given một sitting mới của luồng US-06 phase 2
When người dùng xem stepper
Then thấy 22 bước theo §4a trong một hàng; không có bước "Trả lại mã lớp"Maps to:
- Business Rule: BR-01
AC-M1.2 - Giáo viên test ​
gherkin
When mở bước 18
Then năm ô định danh đã điền sẵn từ mẫu; chạy thành công thì teacher_id vào bag và điền sẵn vào bước 20Maps to:
- Business Rule: BR-03
AC-M1.3 - Kiểm bản ghi buổi ↔ học viên ​
gherkin
When mở bước 19
Then chỉ có câu SQL đọc và nút xác nhận; bước xong khi bấm "Đã có bản ghi buổi ↔ học viên"Maps to:
- Business Rule: BR-04
AC-M1.4 - Dời buổi ​
gherkin
Given bag có class_schedule_id và teacher_id
When mở bước 20
Then các ô bắt buộc đã điền sẵn (ngày mới = ngày mai 15:00Z, lý do "Test US-06"), learning_mode = OFFLINE chỉ đọcMaps to:
- Business Rule: BR-05
AC-M1.5 - Hủy buổi thay thế ​
gherkin
Given bước 20 đã được bỏ qua
When chạy bước 21
Then yêu cầu hủy gửi id buổi và lý do (được phép rỗng)Maps to:
- Business Rule: BR-06
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 §6h 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 | ⚠️ Observed — sổ cái trao đổi với SAPP ghi "US-06 24 bước" | Code hiện có 22 bước (có thể do thay đổi sau ngày ghi) — DR-D-07 — xem 00-overview §6b |
| EC-M1.3 | Chạy cả bước 20 và 21 trong một lượt | Tool không chặn; theo hint, trigger thứ hai không bắn gì |
| EC-M1.4 | Staging — phòng học trùng lịch | Theo runbook staging §6h: Ops trả room_schedule_conflicted; chọn phòng khác |
| EC-M1.5 | ⚠️ Observed — "Dùng deal có sẵn" ở bước 8 | Như US-D09 EC-M1.3 — OQ-D-06 |
Màn M2 - Bước 17 "Kiểm buổi đã được ghi" và bước 22 "Đọc kết quả" ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Mở bước 17 / 22 |
| Mô tả ngắn | Hai bước đọc lọc theo deal_id (→ US-P05); bước 17 có 1 kiểm chứng, bước 22 có 6. |
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 | N/A |
| Loading | Đang tra | Trace đang tải | N/A |
| Has data | Có trail | Kết quả kiểm chứng | N/A |
| Empty | Không có lượt EVENT_RESCHEDULE | Hint: bị loại ở cổng (go-live / sửa ngày khai giảng), không phải sự kiện chưa tới | N/A |
| Error | Trace / SQL lỗi | → US-P05 / US-P09 | N/A |
| Disabled | N/A | N/A | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
B22 · class_schedule_id của buổi đã đảo | — | Text | — | id | Hint: cùng id đã dùng ở bước 20/21 | — | Always | Bước 17 |
Actions ​
A17 - Kiểm buổi đã được ghi (bước 17) ​
| Item | Description |
|---|---|
| Trigger | Mở bước (trace + SQL tự chạy) |
| Behavior | Đọc Ops DB + trace, điền class_schedule_id (BR-02). Không ghi. |
| Success Result | Bước luôn xong |
Error cases:
| Case | Expected Handling |
|---|---|
Không có dòng PER_LESSON | Kiểm chứng fail kèm giải thích (buổi hôm nay bị chốt sổ, hoặc chưa quét / chưa PUBLIC / chưa có học viên) |
A22 - Đọc kết quả (bước 22) ​
| Item | Description |
|---|---|
| Trigger | Mở bước (tự chạy); chạy tay SQL |
| Behavior | Trace + 6 kiểm chứng (BR-07). SQL ①–③ đọc (sổ cái lớp, nhóm cột đảo của buổi, lượt EVENT_RESCHEDULE); ④ ghi Ops DB xóa vết đảo để dựng lại ca (BR-08). Ghi chú ④: bút toán đảo đã tạo phía SAP vẫn còn. |
| 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:5006-5015,5223-5282).
AC-M2.1 - Buổi hôm nay được ghi như buổi thường (bước 17) ​
gherkin
When bước 17 chạy kiểm chứng "Buổi hôm nay được ghi như buổi thường"
Then pass khi có ít nhất một dòng sổ cái entry_type = PER_LESSONMaps to:
- Business Rule: BR-02
AC-M2.2 - Payload mang recognition_type = LESSON_REVERSAL ​
gherkin
When bước 22 chạy kiểm chứng tương ứng
Then pass khi phần tử cuối của payload có recognition_type = LESSON_REVERSALMaps to:
- Business Rule: BR-07
AC-M2.3 - Đảo trỏ thẳng vào bút toán gốc ​
gherkin
Then pass khi phần tử cuối của payload CÓ original_external_referenceMaps to:
- Business Rule: BR-07
AC-M2.4 - Đảo mang định danh buổi gốc ​
gherkin
Then pass khi phần tử cuối của payload CÓ lesson_idMaps to:
- Business Rule: BR-07
AC-M2.5 - document_date = u_lesson_date = ngày buổi bị hủy ​
gherkin
Then pass khi ở phần tử cuối, document_date bằng u_lesson_dateMaps to:
- Business Rule: BR-07
AC-M2.6 - Có khối batch ​
gherkin
Then pass khi phong bì (cấp ngang payloads) của lời gọi cuối CÓ khối batchMaps to:
- Business Rule: BR-07
AC-M2.7 - Có khối scope_evidence ​
gherkin
Then pass khi phong bì của lời gọi cuối CÓ khối scope_evidenceMaps to:
- Business Rule: BR-07
AC-M2.8 - Bước đọc không chặn · dựng lại ca ​
gherkin
Given một kiểm chứng fail hoặc unknown
Then bước 22 vẫn "xong"
When chạy câu SQL ④ và xác nhận
Then nhóm cột đảo của buổi đã chọn về rỗng và các lượt EVENT_RESCHEDULE bị xóaMaps to:
- Business Rule: BR-07, BR-08
Negative AC / Edge Cases của màn M2 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M2.1 | Không có kiểm chứng nào về số tiền | Theo code: đúng thiết kế — payload đảo không mang trường tiền, SAP tự tra (sapp-26878-flows.ts:5210-5222) |
| EC-M2.2 | ⚠️ Observed (OQ-D-19) — câu ④ xóa mọi lượt EVENT_RESCHEDULE của môi trường | Không lọc theo lớp (sapp-26878-flows.ts:5324) — đề xuất OQ "cố ý hay bug?" (cùng dạng US-D13 EC-M2.3) |
| 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 ​
gherkin
Given bước U01:1–16 thay đổi ở US-01
When mở luồng US-06 phase 2
Then luồng dùng đúng định nghĩa mớiMaps to:
- Liên quan nội bộ FS 26878 (không có mã REL) (US-D09)
AC-X.2 - Xóa buổi ở US-03 / US-04 cũng bắn sự kiện đảo ​
gherkin
Given một buổi đã có học viên
When bước "Xóa buổi đuôi" của US-03 / US-04 xóa buổi đó
Then theo hint, cùng sự kiện đảo của US-06 được bắn (không có bút toán gốc → ERR-03 + mail kế toán)Maps to:
- Liên quan nội bộ FS 26878 (không có mã REL) (US-D11, US-D12)