Giao diện
US-P06: Đóng vai SAP — dựng callback đã ký ​
Thuộc FS: 00-overview.md — Nền tảng dùng chung của cụm tool SAPP (as-built @
e77c47a) 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.
| Field | Value |
|---|---|
| US ID | US-P06 |
| Role thực hiện | R1 - Người dùng tool (qua sub-tool sapp.010 — SAPP 26878, flow phase 2 US-09) — Assumption (OQ về G-01), xem OQ-P-13 |
| Phase | As-built (đã triển khai — ⏸ bước bắn callback đang bị chặn phía SAPP, OQ-P-20) |
| Priority | N/A — as-built |
| Status | Draft |
| NFR liên quan | NFR-P-01, NFR-P-03, NFR-P-04, NFR-P-05 — xem Overview §5 |
| OQ liên quan | OQ-P-09, OQ-P-20, OQ-P-22 — xem Overview §6 |
Nguồn inventory: A-16.
Sub-tool đang dùng dịch vụ này (Fact): chỉ sapp.010 (FS 26878), bước Ops signSapCallback của flow phase 2 US-09 "DTTH đồng bộ ngược" (fe/src/ui/components/works/sapp/sapp-26878-flows.ts:5991-6030, fe/src/ui/components/works/sapp/sapp-26878-step-ops.tsx:53, :1060-1063) → FS 26878 US-D17. Màn nhập liệu của bước đó thuộc FS 26878; US này mô tả dịch vụ phía sau.
1. US Statement ​
text
As a Người dùng tool (qua sub-tool 26878) [Assumption — OQ-P-13 / G-01]
I want nhận một callback SAP đã được ký sẵn (lệnh gọi webhook) cho một dòng sổ cái, với kết quả tôi chọn (thành công / thất bại, có hoặc thiếu trường)
So that dựng được callback mà SAP gửi về, "vì không thể yêu cầu SAP thật trả lời theo kịch bản" — nguồn: `shared/external/sapp/sapp-26878/2026-09-22-mind-sign-callback-lech-dto.md:12-13`2. 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 | SAPP_SAP_{API_URL,CLIENT_ID,HMAC_SECRET}_{DEV,STAGING} (US-P04) | Admin CMS | Theo môi trường |
| D2 | Bộ ký của SAP service và webhook nhận callback chấp nhận body do bộ ký dựng | Đội SAPP | ⏸ Webhook trả 400 với body bộ ký dựng (đo 2026-09-22) — OQ-P-20 |
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Chỉ dựng được callback trên dev / staging: không có route prod, và dịch vụ từ chối prod (lỗi 13050) | M1 | AC-M1.3 | be/apps/api/src/sapp/sapp.controller.ts:4017-4047, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:290-296 |
| BR-02 | Người dùng chỉ gửi nội dung callback; client id và secret được BE lấy từ env_systems rồi đưa vào yêu cầu gửi bộ ký — không đi qua trình duyệt | M1 | AC-M1.1 | be/libs/modules/src/lib/sapp/sap-log.common.service.ts:286-315 |
| BR-03 | Bắt buộc event_id và external_reference (id dòng sổ cái); status mặc định SUCCEEDED; role mặc định POSITIVE; doc_num, trans_id, recognized_amount, baseline_3387 tuỳ chọn | M1 - fields | AC-M1.1, AC-M1.2 | be/libs/interface/src/lib/dto/sapp/sap-log.dto.ts:158-189, be/apps/api/src/sapp/sapp.controller.ts:3964-3983 |
| BR-04 | Chỉ trường người dùng thực sự nhập mới được đưa vào callback — trường để trống bị bỏ hẳn (để dựng được ca thiếu trường, vd thiếu baseline_3387) | M1 | AC-M1.2 | be/apps/api/src/sapp/sapp.controller.ts:3964-3977 |
| BR-05 | Kết quả trả về (lệnh gọi đã ký, headers, chuỗi ký) dùng được đúng một lần trong khoảng 300 giây; dùng lại → 401 về nonce, không phải lỗi credential | M1 - kết quả | AC-M1.4 | be/libs/constants/src/lib/sapp/sap-log.constants.ts:54-64 |
| BR-06 | BE gửi kèm địa chỉ SAP service của môi trường để lệnh trả về trỏ tới host gọi được từ ngoài (không phải địa chỉ nội bộ của SAP service) | M1 - kết quả | AC-M1.1 | be/libs/modules/src/lib/sapp/sap-log.common.service.ts:302-313 |
| BR-07 | Thiếu URL / client id / HMAC secret của môi trường → lỗi 13037 | M1 | EC-M1.1 | be/libs/modules/src/lib/sapp/sap-log.common.service.ts:79-113, :298 |
| BR-08 | Bộ ký lỗi → lỗi kèm thông điệp gốc của bộ ký | M1 | EC-M1.2 | be/libs/modules/src/lib/sapp/sap-log.common.service.ts:318-328 |
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[FS 26878 · flow P2 US-09 · bước "sign"] (câu SQL tự điền event_id + id dòng sổ cái — US-P09)
↓ người dùng chọn status / nhập doc_num, trans_id, recognized_amount, baseline_3387
[M1: Dịch vụ dựng callback đã ký] POST /api/v1/sapp/<dev|staging>/sap-log/sign-callback
├─ OK → lệnh gọi webhook đã ký (dùng 1 lần, ~300 s) → người dùng tự chạy lệnh
└─ lỗi → 13037 / 13050 / 13052 kèm thông điệp bộ kýb. Chi tiết từng màn ​
Màn M1 - Dịch vụ dựng callback đã ký (gọi từ bước Ops của sub-tool 26878) ​
| Field | Value |
|---|---|
| Figma frame | N/A — as-built, không có Figma |
| Trigger vào màn | Người dùng chạy bước signSapCallback trong flow P2 US-09 của sapp.010 |
| Mô tả ngắn | Không có màn riêng ở nền tảng — dịch vụ API; UI là khung bước Ops của 26878 (FS 26878 US-D03 / US-D17) |
UI States ​
N/A — dịch vụ không có màn riêng; trạng thái hiển thị do bước Ops của FS 26878 đặc tả (US-D03).
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
| event_id | Yes | Text | Tự điền từ SQL (FS 26878) | REVENUE_RECOGNITION.… | Chuỗi bắt buộc | Lỗi validate 400 | Always | — |
| external_reference | Yes | Text | Tự điền = id dòng sổ cái | uuid | Chuỗi bắt buộc | Lỗi validate 400 | Always | — |
| status | No | Text / dropdown | SUCCEEDED | SUCCEEDED / FAILED (UI 26878) | — | — | Always | — |
| role | No | Text | POSITIVE | — | — | — | Always | — |
| doc_num / trans_id / recognized_amount / baseline_3387 | No | Text | rỗng | Số tiền dạng chuỗi | Trống = bỏ khỏi callback (BR-04) | — | Always | — |
Filter / Search / Sort ​
N/A — không phải màn List.
Actions ​
A1 - Dựng callback đã ký ​
| Item | Description |
|---|---|
| Trigger | Bước Ops signSapCallback được chạy |
| Behavior | BE ghép callback theo BR-03/BR-04, lấy credential (BR-02), gửi bộ ký của SAP service dev hoặc staging (BR-06). Bản thân lời gọi này không ghi dữ liệu; việc chạy lệnh trả về mới ghi kết quả SAP vào sổ doanh thu của môi trường đó. Không có đường ghi PROD (BR-01) |
| Success Result | Lệnh gọi webhook đã ký + headers + chuỗi ký |
Error cases:
| Case | Expected Handling |
|---|---|
| prod | 13050 (không có route; dịch vụ cũng từ chối) |
| Thiếu cấu hình | 13037 |
| Bộ ký lỗi | 13052 kèm thông điệp bộ ký (BR-08) |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Dựng callback thành công ​
gherkin
Given staging có đủ SAPP_SAP_*_STAGING
When người dùng gửi event_id + external_reference, để status trống
Then nhận lệnh gọi đã ký với status = SUCCEEDED, role = POSITIVE, trỏ tới host SAP service staging
And client id / secret không xuất hiện trong yêu cầu từ trình duyệtMaps to:
- Business Rule: BR-02, BR-03, BR-06
AC-M1.2 - Trường để trống bị bỏ ​
gherkin
Given người dùng nhập doc_num, trans_id, recognized_amount nhưng để trống baseline_3387
When dựng callback
Then callback không có trường baseline_3387 (không phải chuỗi rỗng)Maps to:
- Business Rule: BR-03, BR-04
AC-M1.3 - Prod bị từ chối ​
gherkin
Given ai đó gọi dịch vụ với môi trường prod
When dựng callback
Then không có route prod; tầng dịch vụ trả 13050Maps to:
- Business Rule: BR-01
AC-M1.4 - Dùng một lần ​
gherkin
Given người dùng đã chạy lệnh đã ký một lần
When chạy lại đúng lệnh đó
Then webhook trả 401 về nonce; cần chạy lại bước để lấy lệnh mớiMaps 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 | Thiếu SAPP_SAP_CLIENT_ID_DEV | 13037 |
| EC-M1.2 | ⚠️ Observed — Bộ ký lỗi | Trả mã 13052 "Failed to trigger the manual revenue-recognition sweep" (tên lỗi của quét thủ công) kèm thông điệp gốc — be/libs/modules/src/lib/sapp/sap-log.common.service.ts:318-328; OQ-P-22 |
| EC-M1.3 | ⚠️ Observed — Route public trên dev/staging | Bất kỳ ai gọi được API đều dựng được callback SAP hợp lệ cho dev/staging (OQ-P-09, NFR-P-01) |
| EC-M1.4 | ⏸ Webhook staging từ chối body bộ ký dựng (400) | Bước dựng chạy được (201) nhưng callback không áp được — trạng thái "đã triển khai, chưa chạy được" (OQ-P-20; shared/external/sapp/sapp-26878/2026-09-22-mind-sign-callback-lech-dto.md:15-18) |
| EC-M1.5 | external_reference không khớp dòng sổ cái nào | Webhook trả 200 và không dòng nào đổi (theo gợi ý bước trong fe/src/ui/components/works/sapp/sapp-26878-flows.ts:6008) |
5. Cross-feature AC ​
AC-X.1 - Flow US-09 của 26878 phụ thuộc dịch vụ này ​
gherkin
Given FS 26878 US-D17 (DTTH đồng bộ ngược)
When đặc tả bước dựng callback
Then FS 26878 tham chiếu US-P06, và trạng thái chặn (OQ-P-20) áp cho cả haiMaps to:
- REL-05 (Be Affected - FS 26878)
- REL-08 (Affects - SAP service)