Project

General

Profile

CR #222 » CR-021_authorization-service三支契約端點完全未實作.md

內容更新:內部稱謂去識別化(2026-10-18) - Redmine Admin, 10/18/2026 05:32 AM

 

CR-021 authorization-service 三支契約端點完全未實作,與 SDD-007 §5.1.2 桶 A 之盤點錯誤

項目 內容
文件編號 CR-021
版本 1.0
提出日 2026-09-23
提出者 WorkBuddy AI(開發團隊)
緣起 C-14 桶 A 續作(授權策略檢核/離線授權與代授權/沖正機制三頁)之動工前查證:欲依 SDD-007 §5.1.2 桶 A 施作時,發現其依賴之三支端點程式完全不存在
影響範圍 contracts/openapi/authorization-service.yaml;SDD-007 §5.1.2(桶 A 盤點);CSP-001 §7.1(G-8 檢查點);tools/verify_contract_dto.py(新增端點存在性檢查)
關聯前例 CR-020 F1(契約宣告欄位、實作未接收)——同為「契約有、實作無」,本 CR 在端點層級;CR-016 §8(回應型別不符)

1. 問題定性:契約宣告了消費端打不到的端點

contracts/openapi/authorization-service.yaml 宣告 5 個端點,
而實作(AuthorizationController)只有 3 個:

# 契約端點 實作 判定
1 POST /api/v1/authorizations ✅ 有 —
2 GET /api/v1/authorizations ✅ 有 —
3 GET /api/v1/authorizations/{authNo} ✅ 有 —
4 POST /api/v1/authorizations/{authId}/reversals ❌ 無 未實作
5 POST /api/v1/authorizations/{authId}/advices ❌ 無 未實作
6 GET /api/v1/authorizations/{authId}/check-results ❌ 無 未實作

實測方式:全服務搜尋 RestController 僅得 1 支 AuthorizationController;
以 reversals/advices/check-results/CheckResult/ReversalRequest
為關鍵字搜尋 src/main/java 結果為 0(連 DTO 都沒有)。

⚠️ 契約對這三支還詳列了 requestBody schema、13 項檢核明細說明、錯誤碼
(如「已沖正回 CC-AUTH-3002(409)」「PARTIAL 必帶 amount≤原金額」),
消費端依契約開發將全部得到 404。


2. 連帶發現:SDD-007 §5.1.2 桶 A 之盤點方法錯誤(我方缺失)

§5.1.2(2026-09-23,SDD-007 1.10)當初之盤點方式為
「頁面所需功能 ↔ 該服務端點語意」做語意匹配,
但未驗證「該端點在契約與實作中確實存在」。

結果把下列三頁誤列為「桶 A 可立即實作」:

頁面 路徑 依賴端點 實況
授權策略檢核 /auth/policy GET /authorizations/{authId}/check-results 端點不存在
離線授權與代授權 /auth/stip POST /authorizations/{authId}/advices 端點不存在
沖正機制 /switch/auth/reversal POST /authorizations/{authId}/reversals 端點不存在

★ 教訓(已制度化,見 §4):

「服務有端點」≠「該頁有對應端點」——這是 §5.1.2 原本要解決的問題;
但本次暴露出更前一層的漏洞:
「契約有端點」≠「實作有端點」。
盤點時若只查契約(或只做語意匹配),即會把「不存在的端點」當成可用。


3. 併發現:limit-service 之契約/實作路徑寫法差異(1 則,需確認)

契約 實作 判定
GET /api/v1/cards/{cardId}/limits GET /api/v1/accounts/{accountId}/limits 路徑寫法差異(同 verb、同末端段 limits)

二者資源識別維度不同(cardId vs accountId),非單純別名——
若消費端依契約以 cardId 查額度將 404。待確認:係修契約(改為 accounts/{accountId})
或修實作(補一支 by-card 路徑)。


4. 制度化:G-8 新增「端點存在性」檢查面(不再只靠人工)

tools/verify_contract_dto.py 原已能偵測「契約有端點、Controller 無對應方法」,
但僅歸入 infos(不影響結論)→ 此類缺陷被靜默放過。

本期改為二分級,並納入結論:

情形 歸類 訊息
同服務無任何「同 verb 且同末端段」之實作路徑 hits(確定未實作) 「消費端依契約呼叫將 404」
同服務有「同 verb 且同末端段」之其他路徑 warns(疑似路徑寫法差異) 列出候選路徑,請人工確認

為何要分級:直接全部升為 hits 會對 limit-service 這類「路徑寫法差異」
產生偽陽性;本專案對偽陽性零容忍(會侵蝕工具可信度),故先比對末端段。

回測(--selftest)由 4/4 擴充為 6/6,新增兩個人工樣本:

  • EXPECT-HIT-missing-endpoint:契約有、Controller 完全無 → 必須命中
  • EXPECT-WARN-path-alias:契約 cards/{cardId}/limits vs 實作 accounts/{accountId}/limits
    → 必須為 warn 且不得為 hit(證明不會偽陽性)

5. 待裁定

# 議題 選項
1 三支未實作端點 (a) 本期補實作(建議——契約已詳載語意,且 SDD-005/SCS 應有對應設計);(b) 自契約移除並加註「本期不提供」
2 三頁之處置 移至桶 C(待後端)——不造空殼(客戶硬性要求)
3 limit-service 路徑差異 修契約(改 accounts/{accountId})/修實作(補 by-card)

我方建議:先做 (1)-(a)。理由:契約對這三支之語意已相當完整
(13 項檢核明細、FULL/PARTIAL 沖正、強制授權軌跡),
且「沖正」在信用卡業務為必要功能(SDD-005 §3 已有佔用狀態機之
HELD --取消/沖正--> RELEASED 轉換),不是可省略的項目。
若採 (b),等於宣告「本期不做沖正」,恐與 RFP 需求不符。


6. 誠實揭露

  1. 本 CR 之盤點錯誤源自我方(§5.1.2 於 SDD-007 1.10 建立時未驗證端點存在),
    非既有程式缺陷——程式缺陷(三支未實作)則是本次查證所發現。
  2. 尚未動工:本輪僅查證與制度化,未開始撰寫這三頁(避免造空殼)。
  3. 未驗證範圍:advices 之語意(契約載「人工授權/強制授權(Override)」)
    與頁面名「離線授權與代授權(STIP)」是否為同一件事,尚待確認
    ——契約描述回 APPROVED/STANDIN,似同時涵蓋兩者,但語意不完全相同,
    頁面命名與歸屬建議於補實作時一併釐清。

7. 執行結果(2026-09-23,BEAM PMO「請繼續」→ 採 §5 (a) 補實作)

端點 狀態 真機驗證
GET …/{authNo}/check-results ✅ 已實作 回契約形狀陣列(AMOUNT/CURRENCY/CARD_STATUS/… 逐項 PASS+reasonCode);併修正契約陣列性(原誤宣告單一物件);查無 → CC-AUTH-4040/404(初版 ResponseStatusException 落兜底 500,已改)
POST …/{authNo}/reversals ✅ 已實作(** Stand-in 佔用除外**) 實測發現 runtime 掛載 StandInLimitPort(種子授權皆為 Stand-in 本地佔用)→ 初版 500,已改為明確業務拒絕(CC-AUTH-3001/422)。FULL 沖正 happy path 待「Stand-in 佔用沖正設計」裁定後方可真機驗證
POST …/{authNo}/advices ⬜ 語意待裁定(SCS-001 §7.7:(a) 後送 vs (b) 人工覆核) 未實作(不猜語意);/auth/stip 頁續留桶 C

落地:V5__auth_reversals.sql(AUTH_REVERSALS+AUTHORIZATIONS.REVERSED_AT);LimitPort.release(Remote 轉呼 limit-service/StandIn、Jdbc fail-loud);ReversalService(已沖正→CC-AUTH-3002、查無→CC-AUTH-4040、PARTIAL≤holdAmount、釋放+紀錄同交易;決策欄不修改)。SCS-001 → 1.1、SDD-006 → 1.9(CC-AUTH-4040,123 碼)。
誠實揭露:①查無授權初版 500(ResponseStatusException 未被 handler 映射)→ 已改 CC-AUTH-4040,連既有明細端點一併修正(同服務不得兩套真相);②檢核視圖初版誤沿用 AuthorizeResponse.CheckResultView(新落差),真機實測後改為契約形狀。


8. 修訂記錄

版本 日期 修訂內容
1.1 2026-09-23 BEAM PMO「請繼續」→ 採 §5 (a) 補實作:check-results ✅/reversals ✅(** Stand-in 佔用除外**,待裁定)/advices ⬜(§7.7 兩語意待裁定)。新增 §7 執行結果(含兩項誠實揭露)。SCS-001 → 1.1、SDD-006 → 1.9、HANDOVER → 1.73(#A-95)
1.0 2026-09-23 初版:authorization-service 三支契約端點完全未實作之實測證據;SDD-007 §5.1.2 桶 A 盤點方法錯誤之更正;limit-service 路徑寫法差異;tools/verify_contract_dto.py 新增「端點存在性」檢查(二分級、回測 6/6)
    (1-1/1)