Giao diện
US-I03: Tạo deal test theo 14 deal case và gắn contact ​
Thuộc FS: 00-overview.md — SAPP-24395 Contact / Deal instances & Bulk product creation 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. As-built tại commit
e77c47a— suy từ code, chưa chạy thử.
| Field | Value |
|---|---|
| US ID | US-I03 |
| Role thực hiện | R1 - Người dùng tool (Assumption — OQ-I-16 về G-01) |
| Phase | As-built (đã triển khai) |
| Priority | N/A — as-built |
| Status | Draft |
| NFR liên quan | NFR-I-01, NFR-I-04, NFR-I-05, NFR-I-06, NFR-I-07 — xem Overview §5 |
| OQ liên quan | OQ-I-01, OQ-I-02, OQ-I-03, OQ-I-06, OQ-I-07, OQ-I-16, OQ-I-17, OQ-I-19 — xem Overview §6 |
Nguồn inventory: A-05, A-06, A-07. Ghi: HubSpot dev · HubSpot PROD (qua tab "Staging").
1. US Statement ​
text
As a Người dùng tool (Assumption — OQ-I-16)
I want chọn một trong 14 deal case, điền các trường của case, gắn các contact đã tạo và tạo deal trên HubSpot của môi trường đang chọn
So that [Assumption — OQ-I-01] tôi có deal đầu vào đúng pipeline / stage / thuộc tính của từng tình huống để kiểm thử luồng tự động ghi nhận doanh thu2. Dependencies & Definition Of Ready ​
N/A — đã triển khai (Mode B). Dependency runtime:
| # | Cần sẵn sàng | Ai cung cấp | Trạng thái |
|---|---|---|---|
| D1 | Token HubSpot dev / prod trong env_systems (US-P04) | Admin CMS | N/A — runtime |
| D2 | Pipeline / dealstage ghi cứng (bảng §4.b) còn tồn tại trên portal tương ứng | Owner HubSpot | N/A — runtime (không kiểm được từ code) |
| D3 | Contact cần gắn đã có trong danh sách tool (US-I02) | Người dùng | N/A — tuỳ chọn |
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Deal được gắn với các contact đang tick ở mục 1 (US-I01); dòng tóm tắt hiện "Sẽ gán n contact: <ids>". Không tick contact nào vẫn tạo được deal — dòng tóm tắt hiện "Chưa chọn contact nào — deal sẽ được tạo mà không gán contact." | M1 - A1 | AC-M1.1, AC-M1.2 | fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:363-381, :598-601; be/libs/modules/src/lib/hubspot/common.service.ts:542-557 |
| BR-02 | Có đúng 14 deal case (bảng §4.b); mặc định chọn "Deal Lost". Case không thuộc danh sách → lỗi 13011 "Invalid SAPP-24395 deal case" | M1 - field Deal case | AC-M1.1, AC-M1.7 | be/libs/constants/src/lib/sapp/sapp.constants.ts:274-289; be/apps/api/src/sapp/sapp.controller.ts:2034-2046; fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:100-136, :398 |
| BR-03 | Tên deal do hệ thống đặt, người dùng không đặt được: [IT TEST][SAPP-24395] <nhãn case> <n>, với n = số deal tool đã tạo trong môi trường đó + 1 (đếm chung mọi case) | M1 - A1 | AC-M1.1 | be/apps/api/src/sapp/sapp.controller.ts:2325-2327; be/libs/modules/src/lib/sapp/common.service.ts:1624-1634 |
| BR-04 | Pipeline và dealstage (và ở staging / dev: loại phí dịch vụ) được hệ thống gắn cố định theo cặp (môi trường, case) theo bảng §4.b; người dùng không đổi được pipeline / dealstage | M1 - A1 | AC-M1.3, AC-M1.4 | be/apps/api/src/sapp/sapp.controller.ts:1739-2032 |
| BR-05 | "Tài khoản nhận phí dịch vụ": danh sách lựa chọn lấy từ HubSpot của môi trường; mặc định "ACCA - Kể từ 01/01/2026"; nếu giá trị đang chọn không có trong danh sách thì quay về mặc định, không có mặc định thì lấy lựa chọn đầu tiên. Màn luôn gửi giá trị này và nó thắng mọi giá trị khác của cùng thuộc tính | M1 - field Tài khoản nhận phí dịch vụ | AC-M1.5 | fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:95-98, :435-457, :517-523; be/libs/constants/src/lib/sapp/sapp.constants.ts:243-247; be/apps/api/src/sapp/sapp.controller.ts:2080-2083 |
| BR-06 | CCCD / Hộ chiếu áp dụng cho mọi case, được ghi lên deal (thuộc tính "[TVTS] CCCD/Hộ chiếu"), chỉ gửi khi có giá trị | M1 - field CCCD/Hộ chiếu | AC-M1.1 | be/apps/api/src/sapp/sapp.controller.ts:2084-2086; fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:519, :684-697 |
| BR-07 | Mỗi case có bộ trường riêng (bảng §4.b cột "Trường riêng trên màn"); chỉ các trường của case đang chọn và có giá trị mới được gửi | M1 - trường riêng | AC-M1.6 | fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:203-224, :487-516 |
| BR-08 | Deal Lost: người dùng chọn một loại thanh toán — Học phí (tối đa 3 đợt: số tiền, ngày, phương thức) hoặc Phí dịch vụ (Loại phí dịch vụ + tối đa 2 đợt); chỉ gửi trường của loại đang chọn. 5 số tiền đợt (3 học phí + 2 phí DV) mặc định 0 nếu không nhập | M1 - Deal Lost | AC-M1.3 | fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:148-194, :501-516; be/apps/api/src/sapp/sapp.controller.ts:2068-2073; be/libs/constants/src/lib/sapp/sapp.constants.ts:253-259 |
| BR-09 | Thứ tự ưu tiên khi ghép thuộc tính deal (thấp → cao): số tiền đợt mặc định 0 (Deal Lost) → loại phí dịch vụ cố định được phép ghi đè (chỉ Deal Lost) → trường người dùng gửi → giá trị cố định được bảo vệ (pipeline, dealstage, loại phí của case khác, tài khoản mặc định) → Tài khoản nhận phí dịch vụ đã chọn → CCCD/Hộ chiếu | M1 - A1 | AC-M1.3, AC-M1.4 | be/apps/api/src/sapp/sapp.controller.ts:2048-2088; be/libs/constants/src/lib/sapp/sapp.constants.ts:261-267 |
| BR-10 | Đổi deal case: xoá các trường riêng đã nhập và đưa Deal Lost về tab "Học phí"; CCCD và Tài khoản nhận phí được giữ | M1 - field Deal case | AC-M1.6 | fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:413-432 |
| BR-11 | Tạo thành công: deal (id + tên) được thêm vào danh sách của môi trường; popup "Đã tạo deal instance" — "Deal "<tên>" (id: <id>) đã được tạo trong portal <env>." | M1 - A1 | AC-M1.1 | be/libs/modules/src/lib/sapp/common.service.ts:1636-1650; fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:481-491 |
| BR-12 | Môi trường ghi theo tab như US-I02 BR-05: Dev → HubSpot dev; Staging → HubSpot production (cố ý theo comment code); Prod → production (chỉ qua API) | M1 - A1 | AC-M1.4 | be/libs/constants/src/lib/hubspot/hubspot.constants.ts:19-26; be/apps/api/src/sapp/sapp.controller.ts:1829-1831 |
Không phải BR (⚠️ Observed → OQ): prod không có loại phí dịch vụ cố định cho case nào, client ghi được cho mọi case (inventory R-14 → OQ-I-03); trường tự do không whitelist (R-12 → OQ-I-07); bộ đếm tên không khoá khi tạo đồng thời (R-09 → OQ-I-06); Staging ghi production (R-19 → OQ-I-02); chữ hướng dẫn Deal Lost lệch hành vi (OQ-I-19).
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[M1: mục "2. Tạo HubSpot deal instance theo case" (trong màn US-I01)]
↓ (tuỳ chọn) tick contact ở mục 1
↓ chọn case ở danh sách trái → trường của case hiện bên phải
↓ chọn Tài khoản nhận phí, nhập CCCD, nhập trường riêng (Deal Lost: chọn tab Học phí / Phí dịch vụ)
↓ bấm "Tạo deal"
├─ OK ─────────────→ popup "Đã tạo deal instance", "Deal đã tạo (n+1)"
└─ lỗi ────────────→ popup "Tạo deal instance thất bại", ở lại M1Link flow chi tiết: N/A.
b. Chi tiết từng màn ​
Bảng 14 deal case (Fact từ code; ý nghĩa nghiệp vụ = Assumption) ​
Nguồn: nhãn be/libs/constants/src/lib/sapp/sapp.constants.ts:292-314; nhãn trên màn fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:100-136; cấu hình be/apps/api/src/sapp/sapp.controller.ts:1739-2032 (prod :1743-1828, staging :1832-1931, dev :1932-2031); trường riêng fe/src/ui/components/works/sapp/sapp-24395-tool.tsx:203-224. Mọi case, mọi môi trường còn gắn "Tài khoản nhận phí dịch vụ" = "ACCA - Kể từ 01/01/2026" (bị thay bởi giá trị người dùng chọn — BR-05). Chú thích trong code: pipeline 877604025 = "Pipeline test UAT environment"; 882511134 = "IT test đóng tiền chuyển đổi học phí" (be/apps/api/src/sapp/sapp.controller.ts:1775, :1781). Pipeline dev không có chú thích tên.
| # | Case (mã đường dẫn) | Nhãn trên màn | Nhãn trong tên deal | Prod & Staging: pipeline / dealstage | Dev: pipeline / dealstage | Loại phí dịch vụ — Staging & Dev | Loại phí dịch vụ — Prod | Trường riêng trên màn | Ý nghĩa nghiệp vụ |
|---|---|---|---|---|---|---|---|---|---|
| 1 | lost | Deal Lost | Deal Lost | 877604025 / 1316240409 | 836815496 / 1244260910 | Rỗng — người dùng ghi đè được (tab Phí dịch vụ) | Không gửi | Tab Học phí (3 đợt) hoặc Phí dịch vụ (Loại phí DV + 2 đợt) — BR-08 | [Assumption] deal bị lost có các đợt đã đóng — OQ-I-01 |
| 2 | cbe | Deal CBE | Deal CBE | 877604025 / 1316240409 | 836815496 / 1244260910 | Phí đăng ký thi CBE | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí đăng ký thi CBE — OQ-I-01 |
| 3 | cert | Deal CERT | Deal CERT | 877604025 / 1316240409 | 836815496 / 1244260910 | Phí tài khoản Cert | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí tài khoản Cert — OQ-I-01 |
| 4 | becker | Deal BECKER | Deal BECKER | 877604025 / 1316240409 | 836815496 / 1244260910 | Phí tài khoản Becker | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí tài khoản Becker — OQ-I-01 |
| 5 | gia-han | Deal Gia hạn | Deal Gia hạn | 877604025 / 1316240409 | 836815496 / 1244260910 | Phí gia hạn | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí gia hạn khoá học — OQ-I-01 |
| 6 | bao-luu | Deal Bảo lưu | Deal Bảo lưu | 877604025 / 1316240409 | 836815496 / 1244260910 | Phí bảo lưu | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí bảo lưu — OQ-I-01 |
| 7 | chuyen-doi-ghi-nhan-doanh-thu | Deal Chuyển đổi - Ghi nhận doanh thu | Deal Chuyển đổi - Ghi nhận doanh thu | 882511134 / 1325314701 | 878176910 / 1317215384 | Chuyển đổi | Không gửi | Deal ID bị lost; Deal ID đã thanh toán phí | [Assumption] chuyển đổi có ghi nhận doanh thu — OQ-I-01 |
| 8 | chuyen-nhuong-hv-chuyen-nhuong | Deal Chuyển nhượng - HV Chuyển nhượng | Deal Chuyển nhượng - HV Chuyển nhượng | 877604025 / 1316240409 | 878343020 / 1317287583 | Chuyển nhượng | Không gửi | Không có | [Assumption] phía học viên chuyển nhượng — OQ-I-01 |
| 9 | chuyen-doi-khong-ghi-nhan-phi | Deal Chuyển đổi - Không ghi nhận phí | Deal Chuyển đổi - Không ghi nhận phí | 882511134 / 1325314701 | 878176910 / 1317215384 | Không ghi nhận phí | Không gửi | Không có | [Assumption] chuyển đổi không ghi nhận phí — OQ-I-01 |
| 10 | chuyen-nhuong-hv-nhan-chuyen-nhuong | Deal Chuyển nhượng - HV Nhận Chuyển nhượng | Deal Chuyển nhượng - HV Nhận Chuyển nhượng | 877604025 / 1316240409 | 878343020 / 1317287583 | Không ghi nhận phí | Không gửi | Không có | [Assumption] phía học viên nhận chuyển nhượng — OQ-I-01 |
| 11 | tu-van-khoa-hoc | Deal Tư vấn khóa học | Deal Tư vấn khóa học | 877604025 / 1316240409 | 836815496 / 1244260910 | Tư vấn khóa học | Không gửi | Deal ID đã thanh toán phí | [Assumption] phí tư vấn khoá học — OQ-I-01 |
| 12 | chuyen-doi-dieu-chinh-giam-original | Original Deal – Chuyển đổi điều chỉnh giảm | Original Deal dành cho Chuyển đổi điều chỉnh giảm | 882511134 / 1325314701 | 878176910 / 1317215384 | Chuyển đổi | Không gửi | Học phí gốc; Amount; Gói khoá học | [Assumption] deal gốc trước khi chuyển đổi điều chỉnh giảm — OQ-I-01 |
| 13 | chuyen-nhuong-hv-nhan-chuyen-nhuong-tru | Deal trừ – Chuyển nhượng HV nhận chuyển nhượng | Deal trừ dành cho Chuyển nhượng HV nhận chuyển nhượng | 877604025 / 1316240409 | 878343020 / 1317287583 | Chuyển nhượng | Không gửi | Gói khoá học chuyển nhượng; Amount | [Assumption] deal trừ cho học viên nhận chuyển nhượng — OQ-I-01 |
| 14 | chuyen-doi-tang-doanh-thu-deal-tru | Deal trừ – Chuyển đổi tăng doanh thu | Deal trừ dành cho Deal Chuyển đổi ghi nhận doanh thu | 882511134 / 1325314701 | 878176910 / 1317215384 | Chuyển đổi | Không gửi | Khoá học đem chuyển đổi; Amount | [Assumption] deal trừ cho chuyển đổi tăng doanh thu — OQ-I-01 |
Khác biệt tóm tắt (in đậm ở bảng):
- 4 case "Chuyển đổi" (7, 9, 12, 14) dùng pipeline riêng ở prod/staging (882511134) và ở dev (878176910).
- 3 case "Chuyển nhượng" (8, 10, 13) chỉ ở dev dùng pipeline riêng (878343020); ở prod/staging vẫn dùng pipeline chung 877604025.
- Prod không gửi loại phí dịch vụ cho case nào (⚠️ Observed — OQ-I-03, DR-I-02, DR-I-04), trong khi staging (cùng portal production) có → cùng một case trên cùng portal cho ra deal khác nhau tuỳ gọi "prod" hay "staging".
- Nhãn trên màn của case 12–14 ngắn hơn nhãn nằm trong tên deal.
Tên nội bộ HubSpot của trường riêng: Deal ID đã thanh toán phí = deal_id_da_thanh_toan_phi; Deal ID bị lost = deal_id_bi_lost; Học phí gốc = hoc_phi_goc; Amount = amount; Gói khoá học = goi_khoa_hoc; Gói khoá học chuyển nhượng = goi_khoa_hoc_chuyen_nhuong; Khoá học đem chuyển đổi = khoa_hoc_dem_chuyen_doi (nhãn hiển thị lấy từ định nghĩa property trên HubSpot — tên tiếng Việt ở trên là diễn giải từ tên nội bộ).
Màn M1 - Form "2. Tạo HubSpot deal instance theo case" ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | Mở màn Contact / Deal instances (US-I01), chọn tab môi trường |
| Mô tả ngắn | Trái: danh sách 14 case (dọc, cuộn). Phải: Tài khoản nhận phí dịch vụ, CCCD/Hộ chiếu, trường riêng của case, nút "Tạo deal", dòng tóm tắt contact + tài khoản. Dưới: "Deal đã tạo (n)" + icon lịch sử (US-I01 M2). Mô tả: "Chọn case và (tùy chọn) các contact để gán vào deal. Contact được chọn ở mục 1 (<đã chọn>/<tổng>)." |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Vừa vào | Case "Deal Lost" được chọn, tab "Học phí" với 3 đợt; Tài khoản nhận phí đang tải | N/A |
| Loading | Đang tải lựa chọn tài khoản | Ô chọn tài khoản khoá, placeholder "Đang tải…" | N/A |
| Loading (tạo) | Đang tạo deal | Nút "Đang tạo…"; danh sách case và các ô bị khoá | N/A |
| Has data | Tạo xong | Popup thành công; số "Deal đã tạo" tăng 1; form không bị xoá | N/A |
| Empty | Không có lựa chọn tài khoản từ HubSpot | Ô chọn khoá, placeholder "ACCA - Kể từ 01/01/2026 (mặc định)" — vẫn gửi giá trị mặc định | N/A |
| Error | Tải tài khoản lỗi / tạo lỗi | Popup "Không tải được danh sách tài khoản nhận phí" / "Tạo deal instance thất bại" | N/A |
| Disabled | Đang tạo | Như Loading (tạo) | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
| Deal case | Yes | Danh sách chọn 1 (14 mục) | Deal Lost | Bảng trên | BR-02 | "Invalid SAPP-24395 deal case (13011)" (chỉ khi gọi API sai) | Always | — |
Tài khoản nhận phí dịch vụ (tai_khoan_nhan_phi_dich_vu) | Yes (luôn gửi) | Dropdown — lựa chọn từ HubSpot | ACCA - Kể từ 01/01/2026 | — | BR-05 | "Không tải được danh sách tài khoản nhận phí" | Always | Tab môi trường |
CCCD / Hộ chiếu (cccd_ho_chieu — deal) | No | Theo định nghĩa HubSpot | Rỗng | — | BR-06 | — | Always | — |
| Trường riêng theo case | No | Theo định nghĩa HubSpot | Rỗng | — | BR-07 | Lỗi HubSpot → A1 | Theo case (bảng trên) | Deal case |
| Deal Lost — Loại thanh toán | Yes (khi Deal Lost) | Tab "Học phí" / "Phí dịch vụ" | Học phí | — | BR-08 | — | Chỉ Deal Lost | Deal case = lost |
Deal Lost — Loại phí dịch vụ (loai_phi_dich_vu) | No | Theo HubSpot | Rỗng | — | BR-08, BR-09 | — | Chỉ tab Phí dịch vụ | Loại thanh toán |
| Deal Lost — Đợt i: Số tiền / Ngày / Phương thức | No | Theo HubSpot | Số tiền: "0 (mặc định)" | Học phí: so_tien_hoc_vien_thanh_toan_lan_i, ngay_thanh_toan_hoc_phi_lan_i, phuong_thuc_thanh_toan_lan_i (i=1..3). Phí DV: phi_dich_vu_dong_lan_i, ngay_thanh_toan_phi_dv_lan_1 / ngay_thanh_toan_phi_lan_2, phuong_thuc_thanh_toan_phi_lan_i (i=1..2) | BR-08 | — | Theo tab | Loại thanh toán |
Ghi chú trên màn Deal Lost: "Điền lần lượt từ đợt 1; các trường đều tùy chọn (số tiền bỏ trống mặc định là 0). Đổi tab sẽ xóa dữ liệu đã nhập ở tab trước." — phần sau lệch hành vi (OQ-I-19).
Filter / Search / Sort (chỉ màn List/Report — xóa nếu không phải) ​
N/A — màn form. Danh sách case cố định 14 mục, không lọc.
Actions ​
A1 - Tạo deal ​
| Item | Description |
|---|---|
| Trigger | Bấm "Tạo deal" |
| Behavior | Gom trường của case đang chọn có giá trị (BR-07, BR-08) + Tài khoản nhận phí (BR-05) + CCCD (BR-06) + danh sách contact đã tick (BR-01) → BE kiểm case (BR-02), ghép thuộc tính theo BR-09 với giá trị cố định của (môi trường, case) (BR-04), đặt tên (BR-03), tạo deal và liên kết deal → contact trong cùng một lệnh HubSpot, rồi thêm {id, tên} vào danh sách Redis (BR-11). Ghi vào: HubSpot (dev hoặc production theo BR-12) + Redis mind_keep. ⚠️ Ghi PROD (qua Staging): ở tab Staging, deal được tạo trên portal HubSpot production (pipeline test 877604025 / 882511134) và liên kết với contact production |
| Success Result | Popup "Đã tạo deal instance"; "Deal đã tạo (n)" tăng 1 |
Error cases:
| Case | Expected Handling |
|---|---|
| Case không hợp lệ (chỉ khi gọi API trực tiếp) | 13011 "Invalid SAPP-24395 deal case" |
| HubSpot từ chối (giá trị thuộc tính sai, contact id không tồn tại, pipeline không có…) | Popup "Tạo deal instance thất bại" với lỗi tạo đối tượng HubSpot (12006) |
| Lỗi khác | Popup "Tạo deal instance thất bại" — "Failed to create SAPP deal instance (13009)" |
A2 - Chọn case / đổi loại thanh toán Deal Lost ​
| Item | Description |
|---|---|
| Trigger | Bấm một case ở danh sách trái; hoặc bấm tab "Học phí" / "Phí dịch vụ" khi đang ở Deal Lost |
| Behavior | Đổi case: BR-10. Đổi tab Deal Lost: chỉ đổi nhóm trường hiển thị và nhóm được gửi; giá trị tab kia vẫn giữ trong màn nhưng không gửi (OQ-I-19) |
| Success Result | Trường của case / tab mới hiện |
Error cases:
| Case | Expected Handling |
|---|---|
| — | Không có (thao tác cục bộ) |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Tạo deal CBE gắn contact ở Dev ​
gherkin
Given tab Dev, tool đã tạo 4 deal ở Dev, đã tick contact 101 và 102
And chọn case "Deal CBE", nhập CCCD "012345678901", Deal ID đã thanh toán phí "999"
When bấm "Tạo deal"
Then HubSpot dev có deal "[IT TEST][SAPP-24395] Deal CBE 5" liên kết contact 101, 102
And deal có pipeline 836815496, dealstage 1244260910, loại phí dịch vụ "Phí đăng ký thi CBE", tài khoản nhận phí = giá trị đang chọn, CCCD = "012345678901", Deal ID đã thanh toán phí = "999"
And popup "Đã tạo deal instance"; "Deal đã tạo (5)"Maps to:
- Business Rule: BR-01, BR-03, BR-04, BR-05, BR-06, BR-11
- Field/Action: A1
AC-M1.2 - Tạo deal không gắn contact ​
gherkin
Given không tick contact nào
When bấm "Tạo deal"
Then dòng tóm tắt trước đó hiện "Chưa chọn contact nào — deal sẽ được tạo mà không gán contact."
And deal được tạo không có liên kết contactMaps to:
- Business Rule: BR-01
AC-M1.3 - Deal Lost tab Phí dịch vụ ​
gherkin
Given tab Dev, case "Deal Lost", tab "Phí dịch vụ"
And nhập Loại phí dịch vụ "Phí bảo lưu", Đợt 1 số tiền "1500000", để trống Đợt 2
When bấm "Tạo deal"
Then deal có loại phí dịch vụ "Phí bảo lưu" (ghi đè giá trị rỗng mặc định), phí dịch vụ đợt 1 = 1500000
And phí dịch vụ đợt 2 và cả 3 số tiền học phí đều = "0" (mặc định)
And không có trường ngày / phương thức nào của tab "Học phí" được gửiMaps to:
- Business Rule: BR-08, BR-09
AC-M1.4 - ⚠️ Ghi PROD qua Staging, pipeline riêng cho Chuyển đổi ​
gherkin
Given tab Staging, case "Deal Chuyển đổi - Ghi nhận doanh thu"
When bấm "Tạo deal"
Then deal được tạo trên portal HubSpot **production** với pipeline 882511134, dealstage 1325314701, loại phí dịch vụ "Chuyển đổi"
And người dùng không thể đổi pipeline / dealstage kể cả khi gửi thuộc tính cùng tênMaps to:
- Business Rule: BR-04, BR-09, BR-12 — OQ-I-02
AC-M1.5 - Tài khoản nhận phí mặc định / dự phòng ​
gherkin
Given danh sách lựa chọn "Tài khoản nhận phí dịch vụ" từ HubSpot không chứa "ACCA - Kể từ 01/01/2026"
When danh sách tải xong
Then ô chọn tự chuyển sang lựa chọn đầu tiên của danh sách
And giá trị này được gửi khi tạo dealMaps to:
- Business Rule: BR-05
AC-M1.6 - Đổi case xoá trường riêng ​
gherkin
Given case "Deal trừ – Chuyển đổi tăng doanh thu" đã nhập Amount "5000000" và CCCD "0123"
When chọn case "Deal CBE" rồi quay lại case cũ
Then Amount trống, CCCD vẫn là "0123"
And khi tạo deal ở case "Deal CBE", Amount không được gửiMaps to:
- Business Rule: BR-07, BR-10
- Field/Action: A2
AC-M1.7 - Case không hợp lệ qua API ​
gherkin
Given gọi POST /api/v1/sapp/dev/sapp-24395/deals/abc
When BE xử lý
Then trả lỗi 13011 "Invalid SAPP-24395 deal case" (HTTP 400), không tạo dealMaps to:
- Business Rule: BR-02
AC-M1.8 - ⚠️ Observed: prod không có loại phí dịch vụ cố định ​
gherkin
Given gọi trực tiếp POST /api/v1/sapp/prod/sapp-24395/deals/cbe (tab Prod bị tắt trên màn)
When BE tạo deal
Then (hành vi hiện tại) deal trên production không có loại phí dịch vụ "Phí đăng ký thi CBE"
And nếu client gửi loại phí dịch vụ trong trường tự do thì giá trị đó được ghiMaps to:
- Business Rule: N/A — ⚠️ Observed (inventory R-14, R-20) → OQ-I-03, OQ-I-02, NFR-I-01
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | Hai người / hai tab bấm "Tạo deal" cùng lúc trong cùng môi trường | ⚠️ Observed — hai deal có thể trùng số thứ tự trong tên, danh sách tool mất một mục (inventory R-09 → OQ-I-06) |
| EC-M1.2 | Gọi API với trường tự do chứa thuộc tính bất kỳ (ví dụ amount cho case CBE) | ⚠️ Observed — được chuyển thẳng sang HubSpot, không có whitelist (trừ khoá cố định của case) (inventory R-12 → OQ-I-07) |
| EC-M1.3 | Tick contact rồi đổi tab môi trường | Lựa chọn bị xoá (US-I01 BR-02) — không thể gắn contact của môi trường khác |
| EC-M1.4 | Contact đã tick bị xoá trên HubSpot | HubSpot từ chối liên kết → popup "Tạo deal instance thất bại" |
| EC-M1.5 | Đổi tab Deal Lost Học phí → Phí dịch vụ → Học phí | Số liệu tab Học phí đã nhập vẫn còn (ghi chú trên màn nói bị xoá — OQ-I-19) |
| EC-M1.6 | Bấm "Tạo deal" hai lần nhanh | Nút khoá trong lúc tạo |
| EC-M1.7 | Mất mạng giữa chừng | Popup lỗi chung; nếu HubSpot đã tạo xong nhưng phản hồi mất, deal tồn tại trên HubSpot mà không vào danh sách tool (suy từ trình tự: tạo HubSpot trước, ghi Redis sau) |
5. Cross-feature AC ​
AC-X.1 - Deal test nằm trong portal production ​
gherkin
Given tab Staging
When tạo deal bất kỳ case
Then deal tên "[IT TEST][SAPP-24395] …" xuất hiện trên portal HubSpot production, trong pipeline test, liên kết với contact production đã chọnMaps to:
- REL-05 (Be Affected - Dữ liệu HubSpot portal production)
AC-X.2 - Deal là đầu vào luồng ghi nhận doanh thu ​
gherkin
Given deal được tạo ở pipeline / dealstage của case
When workflow hạ nguồn trên HubSpot / SAP xử lý pipeline đó
Then [Assumption — OQ-I-01] luồng tự động ghi nhận doanh thu được kích hoạt theo case (không truy vết trong code mind_keep)Maps to:
- REL-06 (Be Affected - Luồng tự động ghi nhận doanh thu)
AC-X.3 - Logic tạo deal dùng chung với SAPP-26878 ​
gherkin
Given tool SAPP-26878 chạy bước tạo deal
When cách đặt tên / đếm / lưu danh sách deal của 24395 thay đổi
Then bước tạo deal của 26878 chịu ảnh hưởng tương ứngMaps to:
- REL-04 (Be Affected - SAPP-26878 US-D03)