Giao diện
US-D16: Flow P2 — DTTH đồng bộ lại (story SAPP US-08 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-126). 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.⚠ Không nhầm với "đồng bộ lại theo story" US-08/09/10/12/14 của phase 1 (US-D18) — chip này là story US-08 phase 2 (id
us08-p2), gửi lại dòng sổ cái DTTH.
| Field | Value |
|---|---|
| US ID | US-D16 |
| 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-08 · DTTH đồng bộ lại (id us08-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 dòng sổ cái ở trạng thái lỗi, bấm gửi lại theo dòng và theo lớp, rồi dựng lần lượt sáu
trạng thái phải bị chặn
So that kiểm được rằng kế toán gửi lại được các dòng sổ cái bị lỗi mà tuyệt đối không sinh bút toán trùng- Nguồn "So that":
shared/runbooks/sapp/sapp-26878/phase-2/us-08/README.md:6-8("Kế toán bấm tay gửi lại các dòng sổ cái bị lỗi, và tuyệt đối không sinh bút toán trùng … Trọng tâm là những ca KHÔNG gửi lại"); hint luồngsapp-26878-flows.ts:5909. 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; hai thao tác gửi lại đi qua Ops passthrough (US-P08, inventory E-27 "sap-revenue resync").
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: U01:1 → U01:16 rồi 6 bước riêng theo thứ tự ở §4a; 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:5911-5947 |
| BR-02 | "Đọc sổ cái" là bước đọc không có kiểm chứng tự động (lọc theo deal_id), kèm 2 câu SQL chỉ đọc | M2 - A17 | AC-M2.1 | sapp-26878-flows.ts:5635-5662 |
| BR-03 | "Dựng dòng lỗi": câu đọc tự chạy và điền sẵn entry_id (dòng sớm nhất theo ngày buổi); câu ghi đưa dòng đó về FAILED · ERR-04 | M1 - A18 | AC-M1.2 | sapp-26878-flows.ts:5678-5714 |
| BR-04 | "Đồng bộ lại theo dòng" gửi lại đúng một dòng theo entry_id (không có thân request); bấm lặp được | M1 - A19 | AC-M1.3 | sapp-26878-flows.ts:5723-5742 |
| BR-05 | "Đồng bộ lại theo lớp" gửi lại mọi dòng chưa chốt của lớp theo class_id từ bag (không có thân request); bấm lặp được | M1 - A21 | AC-M1.4 | sapp-26878-flows.ts:5750-5761 |
| BR-06 | "Đọc kết quả gửi lại" lọc theo deal_id, tự chạy 3 kiểm chứng, luôn coi là xong | M2 - A20 | AC-M2.2 → AC-M2.5 | sapp-26878-flows.ts:5772-5812 |
| BR-07 | "Dựng sáu chốt chặn" là bước hướng dẫn, xong khi bấm xác nhận; panel SQL 6 câu đều ghi (5 câu dựng từng trạng thái chặn, 1 câu đưa dòng về trạng thái test được và xóa lượt chạy gửi lại) | M1 - A22 | AC-M1.5 | sapp-26878-flows.ts:5829-5894 |
| BR-08 | Câu SQL ghi không tự chạy và phải qua hộp xác nhận | M1 - A18, A22 | AC-M1.2, AC-M1.5 | 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-08 · DTTH đồng bộ lại", portal Dev | Staging]
↓
[M1] U01:1 → … → U01:16 (dựng dòng sổ cái)
↓
[M2] Đọc sổ cái → [M1] Dựng dòng lỗi → Đồng bộ lại theo dòng
↓
[M2] Đọc kết quả gửi lại → [M1] Đồng bộ lại theo lớp → Dựng sáu chốt chặn
(mỗi chốt: chạy 1 câu SQL → bấm lại "Đồng bộ lại theo dòng" → đọc lại)Bảng bước (Fact: sapp-26878-flows.ts:5911-5947).
| # | 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–16 | Kiểm tra kết nối Ops … Chạy lượt quét | như US-D09 | U01:1 → U01:16 (đúng thứ tự) | Như US-D09 §4a bước 1–16 (⚠️ HubSpot portal prod khi Staging) | Như US-D09 |
| 17 | Đọc sổ cái | trace + sql | riêng | Không ghi | Luôn xong |
| 18 | Dựng dòng lỗi | guide + sql | riêng | Ops DB: us08.seed.2 sửa trạng thái một dòng sổ cái → bag entry_id | Bấm "Đã dựng dòng lỗi" |
| 19 | Đồng bộ lại theo dòng | ops | riêng | Ops → gửi lại SAP một dòng (dev/staging) | Gọi thành công |
| 20 | Đọc kết quả gửi lại | trace | riêng | Không ghi | Luôn xong |
| 21 | Đồng bộ lại theo lớp | ops | riêng | Ops → gửi lại SAP các dòng chưa chốt của lớp | Gọi thành công |
| 22 | Dựng sáu chốt chặn | guide + sql | riêng | Ops DB: us08.guards.1–6 (chỉ khi người dùng chạy) | Bấm "Đã đọc sáu chốt chặn" |
⚠️ 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 ✅ 3/3 + 5/5 chốt chặn trên dev 2026-09-18, hai ca chưa dựng được (shared/runbooks/sapp/sapp-26878/phase-2/us-08/README.md:3-4); staging ✅ 2026-09-22 (.../phase-2/staging/README.md §6i).
b. Chi tiết từng màn ​
Màn M1 - Chuỗi bước dựng dữ liệu và gửi lại (bước 1–16, 18, 19, 21, 22) ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Chọn chip US-08 · DTTH đồng bộ lại (inventory E-07) |
| Mô tả ngắn | Dựng như US-01 để có dòng sổ cái, ép dòng về lỗi, gửi lại hai chế độ, rồi dựng các ca bị chặn. |
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 / chạy SQL | Nút chạy ở trạng thái xử lý | N/A |
| Has data | Bước 19 / 21 xong | Response (bước 21 có entries_queued) | N/A |
| Empty | Staging, pool mã lớp rỗng | Như US-D09 EC-M1.2 | N/A |
| Error | API gửi lại từ chối | Theo hint: dòng không tồn tại / đã SUCCESS / đã đảo → lỗi ngay; lớp không còn dòng chưa chốt → "không tìm thấy dòng sổ cái" | N/A |
| Disabled | Bước khóa; bước 7 trên Staging | Như US-D09 | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
B19 · entry_id | Yes | Text | bag entry_id (bước 18) | id dòng sổ cái | Hint: không phải id buổi / deal | Lỗi Ops | Always | Bước 18 |
Bước 21 không có field (dùng class_id từ bag). Field bước 1–16 → US-D09.
Actions ​
A18 - Dựng dòng lỗi (bước 18) ​
| Item | Description |
|---|---|
| Trigger | Mở bước (câu ① tự chạy), chạy câu ② (xác nhận), bấm "Đã dựng dòng lỗi" |
| Behavior | Ghi Ops DB dev/staging (BR-03, BR-08). Guide: chỉ FAILED và PENDING được gửi thẳng; không xóa mốc đã post của dòng SAP đã thật sự ghi. |
| Success Result | Dòng ở FAILED · ERR-04; entry_id trong bag |
Error cases:
| Case | Expected Handling |
|---|---|
| Lớp chưa có dòng sổ cái | Câu ① trả rỗng, entry_id trống |
A19 / A21 - Đồng bộ lại theo dòng / theo lớp (bước 19, 21) ​
| Item | Description |
|---|---|
| Trigger | Bấm chạy (lặp được) |
| Behavior | Gửi lại qua Ops dev/staging → SAP (BR-04, BR-05). Hint: gọi lần hai ngay sau lần một bị chặn vì dòng đã sang SENT (ca EC-M1.1 của story — kết quả đúng); entries_queued là số dòng được chọn (trần 200), không phải số đã gửi. |
| Success Result | Gọi thành công |
Error cases:
| Case | Expected Handling |
|---|---|
Dòng đã SUCCESS / đã đảo / không tồn tại | API trả lỗi ngay (hint) |
| Lớp không còn dòng chưa chốt | API trả lỗi "không tìm thấy dòng sổ cái" (hint: đúng thiết kế) |
A22 - Dựng sáu chốt chặn (bước 22) ​
| Item | Description |
|---|---|
| Trigger | Chạy một câu SQL (xác nhận) → quay lại bước 19 bấm gửi lại → đọc lại ở bước 20; lặp cho từng ca; bấm "Đã đọc sáu chốt chặn" |
| Behavior | Ghi Ops DB dev/staging (BR-07, BR-08): ① đã có bút toán trên SAP, ② đã bị đảo, ③ đã chốt SUCCESS, ④ ERR-05, ⑤ đang chờ SAP (SENT), ⑥ đưa dòng về trạng thái test được + xóa lượt EVENT_RESYNC. Guide: kết quả đúng của mọi ca chặn là "được chọn nhưng không gửi". |
| Success Result | Bước xong khi xác nhận |
Error cases:
| Case | Expected Handling |
|---|---|
| Chạy ⑥ khi SAP đã thật sự tạo bút toán | Guide cảnh báo: vô hiệu hóa chốt chặn chống trùng; tool không chặn |
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-08 phase 2
When người dùng xem stepper
Then bước 1–16 trùng US-01, bước 17–22 lần lượt "Đọc sổ cái", "Dựng dòng lỗi", "Đồng bộ lại theo dòng", "Đọc kết quả gửi lại", "Đồng bộ lại theo lớp", "Dựng sáu chốt chặn"
And không có bước "Trả lại mã lớp"Maps to:
- Business Rule: BR-01
AC-M1.2 - Ép dòng về lỗi ​
gherkin
Given lớp đã có dòng sổ cái
When mở bước 18
Then câu ① tự chạy và điền entry_id của dòng sớm nhất
When chạy câu ② và xác nhận
Then dòng đó có status = FAILED, error_code = ERR-04Maps to:
- Business Rule: BR-03, BR-08
AC-M1.3 - Gửi lại theo dòng ​
gherkin
Given bag có entry_id
When bấm chạy bước 19
Then tool gọi gửi lại đúng dòng đó, không kèm thân requestMaps to:
- Business Rule: BR-04
AC-M1.4 - Gửi lại theo lớp ​
gherkin
When bấm chạy bước 21
Then tool gọi gửi lại theo class_id của lượt, không kèm thân request, và hiện entries_queued trong responseMaps to:
- Business Rule: BR-05
AC-M1.5 - Dựng chốt chặn ​
gherkin
When mở bước 22
Then thấy 6 câu SQL đều là câu ghi (tô đỏ, cần xác nhận) và checklist các ca chặnMaps to:
- Business Rule: BR-07, BR-08
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 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 (OQ-D-18) — guide bước 18 ghi "⚠ Chỉ làm trên dev" | Bước không bị khóa trên Staging; runbook §6i ghi đã chạy US-08 trên staging. Đề xuất OQ — điều phối viên cấp mã |
| EC-M1.3 | ⚠️ Observed (OQ-D-19) — câu ⑥ bước 22 xóa mọi lượt EVENT_RESYNC của môi trường | Không lọc theo lớp (sapp-26878-flows.ts:5866) — cùng dạng US-D13 EC-M2.3; đề xuất OQ |
| EC-M1.4 | Ca "kỳ đã đóng sổ" (checklist ⑤) | Không có câu SQL dựng; guide: chọn dòng thuộc tháng đã qua mốc đóng sổ, chỉ chạy đúng khi đã nạp lịch nghỉ lễ |
| 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 "Đọc sổ cái" và bước 20 "Đọc kết quả gửi lại" ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Mở bước 17 / 20 |
| Mô tả ngắn | Hai bước đọc lọc theo deal_id (→ US-P05); bước 17 không có kiểm chứng, bước 20 có 3. |
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 us08.read ở bước 17) | N/A |
| Loading | Đang tra | Trace đang tải | N/A |
| Has data | Có trail | Bước 20: kết quả 3 kiểm chứng | N/A |
| Empty | Chưa có lượt gửi lại | Trace không có phần gửi lại | N/A |
| Error | Trace lỗi | → US-P05 | N/A |
| Disabled | N/A | N/A | N/A |
Fields ​
N/A — bước chỉ đọc.
Actions ​
A17 / A20 - Đọc sổ cái / Đọc kết quả gửi lại ​
| Item | Description |
|---|---|
| Trigger | Mở bước (tự chạy) |
| Behavior | Bước 17: trace + 2 câu SQL đọc (sổ cái lớp; dấu vết lượt gửi lại trong log) (BR-02). Bước 20: trace + 3 kiểm chứng (BR-06). Không ghi. |
| 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-M2.2 → AC-M2.4 = kiểm chứng tự chấm của bước 20 (sapp-26878-flows.ts:5772-5800).
AC-M2.1 - Đọc sổ cái không chấm ​
gherkin
When mở bước 17
Then trace tự chạy, không có kiểm chứng tự động, và panel có 2 câu SQL chỉ đọcMaps to:
- Business Rule: BR-02
AC-M2.2 - Gửi lại mang ngày gửi lại, giữ nguyên ngày buổi ​
gherkin
Then pass khi có ít nhất một phần tử payload có document_date khác u_lesson_dateMaps to:
- Business Rule: BR-06
AC-M2.3 - Giữ nguyên công thức của dòng gốc ​
gherkin
Then pass khi phần tử cuối của payload có recognition_type = PER_LESSONMaps to:
- Business Rule: BR-06
AC-M2.4 - Giữ nguyên khóa của dòng cũ ​
gherkin
Then pass khi phần tử cuối của payload CÓ external_referenceMaps to:
- Business Rule: BR-06
AC-M2.5 - Bước đọc không chặn ​
gherkin
Given một kiểm chứng fail hoặc unknown
Then bước 20 vẫn "xong" và bước 21 mởMaps to:
- Business Rule: BR-06
Negative AC / Edge Cases của màn M2 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M2.1 | Gửi lại một dòng không phải buổi thường | Kiểm chứng "Giữ nguyên công thức" cố định PER_LESSON → fail; theo hint, người dùng tự đổi giá trị mong đợi theo loại dòng |
| EC-M2.2 | Ca chặn: "được chọn" > 0 mà "đã gửi" = 0 | Theo hint: kết quả đúng; tool không tự chấm các ca chặn — người dùng đọc counters.skipped — 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-08 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 - Gửi lại thô cùng thao tác Ops ​
gherkin
Given chip Trace "Gửi lại bút toán (P2)" / "Gửi lại lớp (P2)"
When người dùng gửi lại theo id ở đó
Then đó là cùng loại thao tác gửi lại dòng / lớp qua Ops như bước 19 / 21, không qua stepper (inventory A-91 → US-D18)Maps to:
- Liên quan nội bộ FS 26878 (không có mã REL) (US-D18)
AC-X.3 - US-09 chặn gửi lại dòng ERR-05 ​
gherkin
Given US-D17 dựng dòng thiếu trường (SENT + ERR-05, có mốc đã post)
When gửi lại dòng đó ở bước 19
Then theo guide US-09, dòng bị chặn (skipped.ALREADY_POSTED)Maps to:
- Liên quan nội bộ FS 26878 (không có mã REL) (US-D17)