Skip to content

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.

FieldValue
US IDUS-P06
Role thực hiệnR1 - 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
PhaseAs-built (đã triển khai — ⏸ bước bắn callback đang bị chặn phía SAPP, OQ-P-20)
PriorityN/A — as-built
StatusDraft
NFR liên quanNFR-P-01, NFR-P-03, NFR-P-04, NFR-P-05 — xem Overview §5
OQ liên quanOQ-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àngAi cung cấpTrạng thái
D1SAPP_SAP_{API_URL,CLIENT_ID,HMAC_SECRET}_{DEV,STAGING} (US-P04)Admin CMSTheo môi trường
D2Bộ 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 ​

IDRuleÁp dụng ởĐã cover bởi (AC)Nguồn code (Mode B/C)
BR-01Chỉ dựng được callback trên dev / staging: không có route prod, và dịch vụ từ chối prod (lỗi 13050)M1AC-M1.3be/apps/api/src/sapp/sapp.controller.ts:4017-4047, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:290-296
BR-02Ngườ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ệtM1AC-M1.1be/libs/modules/src/lib/sapp/sap-log.common.service.ts:286-315
BR-03Bắ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ọnM1 - fieldsAC-M1.1, AC-M1.2be/libs/interface/src/lib/dto/sapp/sap-log.dto.ts:158-189, be/apps/api/src/sapp/sapp.controller.ts:3964-3983
BR-04Chỉ 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)M1AC-M1.2be/apps/api/src/sapp/sapp.controller.ts:3964-3977
BR-05Kế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 credentialM1 - kết quảAC-M1.4be/libs/constants/src/lib/sapp/sap-log.constants.ts:54-64
BR-06BE 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.1be/libs/modules/src/lib/sapp/sap-log.common.service.ts:302-313
BR-07Thiếu URL / client id / HMAC secret của môi trường → lỗi 13037M1EC-M1.1be/libs/modules/src/lib/sapp/sap-log.common.service.ts:79-113, :298
BR-08Bộ ký lỗi → lỗi kèm thông điệp gốc của bộ kýM1EC-M1.2be/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 &ZeroWidthSpace;

Màn M1 - Dịch vụ dựng callback đã ký (gọi từ bước Ops của sub-tool 26878) &ZeroWidthSpace;

FieldValue
Figma frameN/A — as-built, không có Figma
Trigger vào mànNgười dùng chạy bước signSapCallback trong flow P2 US-09 của sapp.010
Mô tả ngắnKhô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 &ZeroWidthSpace;

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 &ZeroWidthSpace;
FieldRequiredTypeDefaultFormatValidationError MessageVisibilityDepends On
event_idYesTextTự điền từ SQL (FS 26878)REVENUE_RECOGNITION.…Chuỗi bắt buộcLỗi validate 400Always—
external_referenceYesTextTự điền = id dòng sổ cáiuuidChuỗi bắt buộcLỗi validate 400Always—
statusNoText / dropdownSUCCEEDEDSUCCEEDED / FAILED (UI 26878)——Always—
roleNoTextPOSITIVE———Always—
doc_num / trans_id / recognized_amount / baseline_3387NoTextrỗngSố tiền dạng chuỗiTrống = bỏ khỏi callback (BR-04)—Always—
Filter / Search / Sort &ZeroWidthSpace;

N/A — không phải màn List.

Actions &ZeroWidthSpace;
A1 - Dựng callback đã ký &ZeroWidthSpace;
ItemDescription
TriggerBước Ops signSapCallback được chạy
BehaviorBE 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 ResultLệnh gọi webhook đã ký + headers + chuỗi ký

Error cases:

CaseExpected Handling
prod13050 (không có route; dịch vụ cũng từ chối)
Thiếu cấu hình13037
Bộ ký lỗi13052 kèm thông điệp bộ ký (BR-08)
Acceptance Criteria của màn M1 &ZeroWidthSpace;
AC-M1.1 - Dựng callback thành công &ZeroWidthSpace;
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ệt

Maps to:

  • Business Rule: BR-02, BR-03, BR-06
AC-M1.2 - Trường để trống bị bỏ &ZeroWidthSpace;
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 &ZeroWidthSpace;
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ả 13050

Maps to:

  • Business Rule: BR-01
AC-M1.4 - Dùng một lần &ZeroWidthSpace;
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ới

Maps to:

  • Business Rule: BR-05
Negative AC / Edge Cases của màn M1 &ZeroWidthSpace;
IDTình huốngHành vi mong đợi
EC-M1.1Thiếu SAPP_SAP_CLIENT_ID_DEV13037
EC-M1.2⚠️ Observed — Bộ ký lỗiTrả 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/stagingBấ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.5external_reference không khớp dòng sổ cái nàoWebhook 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 &ZeroWidthSpace;

AC-X.1 - Flow US-09 của 26878 phụ thuộc dịch vụ này &ZeroWidthSpace;

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ả hai

Maps to:

  • REL-05 (Be Affected - FS 26878)
  • REL-08 (Affects - SAP service)