# TRR-001　測試結果報告

| 項目 | 內容 |
|---|---|
| 文件編號 | TRR-001 |
| 版本 | **2.1** |
| 測試日期 | **2026-10-01**（**第 2 輪**；第 1 輪 2026-09-19） |
| 對應計畫 | `TRP-001`（**本版依 `TRP-001 §7` 之 6 項要求重構**，見 §9） |
| 測試範圍 | **17 個領域服務 ＋ 8 個平台模組 ＋ WebUI 26 頁**（第 1 輪僅 2 服務 ＋ 前端） |
| 測試環境 | 本機單機（Docker 容器 12 個 ＋ 本地服務） |
| 結果摘要 | **通過**（單元測試 **836 測 0 失敗**；品質關卡見 §7）；**⚠️ 效能與一致性測試尚未執行**（§5），**準出未達成**（§0.3） |

> **去識別化聲明**：本報告依專案規範，客戶名稱一律以代稱表示（`BEAM`／`迪艾克斯`），不含任何可識別客戶之資訊。

> ⚠️ **本版之證據性質（必讀）**：本報告**區分**兩類結果——
> **(A) 本輪（2026-10-01）實際重跑**：§0.2 之單元測試、§7 之品質關卡；
> **(B) 引用既有真機實測紀錄**：§2 之各服務劇本，來源為 `HANDOVER §3.A` 之 `#A-xx`
> （每列均附證據編號）。**(B) 不是本輪重跑**——**不得**當作「本次驗證」讀。

---

## 0. 執行摘要（`TRP-001 §7-1`）

### 0.1 通過／失敗／跳過數

| 項目 | 數量 | 說明 |
|---|---:|---|
| **單元／整合測試（自動）** | **836** | **失敗 0、錯誤 0、略過 0**（本輪重跑） |
| 真機端到端劇本（引用） | 見 §2 | 依服務分節，附 `#A-xx` 證據 |
| 前端頁面實測 | 26 頁已實作 | 其中 **多數具真實瀏覽器實測證據**（`docs/08-evidence/` 40 張） |
| 品質關卡 | 6 項 | **5 項通過、1 項待裁定**（§7） |

### 0.2 自動化測試（本輪重跑，逐模組）

| 模組 | 測 | 失 | 錯 | 略 |
|---|---:|---:|---:|---:|
| `platform/common-spring` | 95 | 0 | 0 | 0 |
| `platform/common-domain` | 55 | 0 | 0 | 0 |
| `platform/common-security` | 51 | 0 | 0 | 0 |
| `platform/common-saga` | 23 | 0 | 0 | 0 |
| `platform/common-event` | 18 | 0 | 0 | 0 |
| `platform/api-gateway` | 18 | 0 | 0 | 0 |
| `platform/bff-web` | 12 | 0 | 0 | 0 |
| `platform/common-batch` | 3 | 0 | 0 | 0 |
| `services/card-service` | 85 | 0 | 0 | 0 |
| `services/rewards-service` | 72 | 0 | 0 | 0 |
| `services/pricing-service` | 53 | 0 | 0 | 0 |
| `services/authorization-service` | 42 | 0 | 0 | 0 |
| `services/installment-service` | 38 | 0 | 0 | 0 |
| `services/payment-service` | 36 | 0 | 0 | 0 |
| `services/notification-service` | 35 | 0 | 0 | 0 |
| `services/statement-service` | 29 | 0 | 0 | 0 |
| `services/merchant-service` | 27 | 0 | 0 | 0 |
| `services/posting-service` | 27 | 0 | 0 | 0 |
| `services/clearing-service` | 24 | 0 | 0 | 0 |
| `services/dispute-service` | 19 | 0 | 0 | 0 |
| `services/party-service` | 19 | 0 | 0 | 0 |
| `services/product-service` | 18 | 0 | 0 | 0 |
| `services/migration-service` | 17 | 0 | 0 | 0 |
| `services/report-service` | 16 | 0 | 0 | 0 |
| `services/limit-service` | 4 | 0 | 0 | 0 |
| **合計** | **836** | **0** | **0** | **0** |

> **領域服務 561 測 ／ 平台模組 275 測**。

### 0.3 ★ 準出達成度（對照 `TRP-001 §6.2` 之 8 項）

| # | 準出條件 | 狀態 | 說明 |
|---:|---|---|---|
| 1 | 單元測試行覆蓋 ≥ 80%、分支 ≥ 70%、Mutation ≥ 75% | ⚪ **未量測** | 專案**未產出覆蓋率／Mutation 報告**（無 JaCoCo／PIT 設定）。**不得以「測試數多」推論覆蓋率** |
| 2 | 禁止模式掃描（scaffold／mockdata／faketest）0 命中 | ✅ **達成** | 本輪重跑：**3 支掃描器皆 0 命中**（§7） |
| 3 | 68 項 FR 功能劇本全部 Pass | 🟡 **部分** | **53 項程式承作類**已交付並有真機實測（§2）；**15 項 R0 流程／文件類**不產生程式碼，由 `TRP-001`／`BRD-001` 承作 |
| 4 | 17 項 POC 驗收全部 Pass | 🟡 **部分** | **12 ✅／4 🟡／1 ⚪＝82.4%**（`HANDOVER §1.2`） |
| 5 | 效能達標：授權 P95 ≤ 500ms、iECS ≥ 1,000 TPS、BASE24-mas > 2,000 TPS | ⚪ **未執行** | **無效能測試**（§5）——**SoW 門檻尚無任何實測數據** |
| 6 | 引擎一致率 ≥ 99.99%、差異率 < 0.01%、A 類差異 0、批次金額差異 0 | ⚪ **未執行** | 需與 Legacy ECS **並行比對**；**Legacy 資料源未接入**（`SCS-015 §5.1`） |
| 7 | 安全掃描無高／嚴重漏洞；個資遮蔽經滲透驗證 | ⚪ **未執行** | **未做安全掃描與滲透測試**；僅**個資保護機制**經實測（`KeyProvider`，`#A-24`～`#A-26`） |
| 8 | `TRR-001` 記載完整劇本、資料、缺陷狀態 | ✅ **本版達成** | 第 1 輪**不符**（缺 4 項，見 §9）；**本版首度符合 `TRP-001 §7`** |

> **結論**：**8 項中僅 2 項完全達成**。**不得**因單元測試全綠而宣稱「測試完成」——
> 效能量測、一致性比對、安全掃描**三項從未執行**，且**第 1 項（覆蓋率）從未量測**。

---

## 1. 測試環境

| 項目 | 版本／內容 |
|---|---|
| 資料庫（權威 OLTP） | Oracle Database 26ai Free 23.26.0.0（PDB `FREEPDB1`） |
| 資料庫（CQRS 讀模型／事件流） | PostgreSQL 18.6 |
| 訊息 | Kafka 4.3.1（KRaft）＋ Kafka UI |
| 快取 | Redis 8.8.2 |
| **物件儲存** | **Garage `v2.4.1`（S3 相容；2026-10-01 新增，`#A-106`／`#A-107`）** |
| 身分驗證 | Keycloak 26.4（realm `cardcore`；`SCS-022`） |
| 可觀測性 | OTel Collector 0.161.0 ＋ Jaeger 1.76.0 ＋ Prometheus 3.14.0 ＋ Grafana 12.4.11 ＋ Loki 3.7.8 |
| 執行環境 | Java 21.0.12.1 / Spring Boot 4.1.1 / Spring Cloud 2025.1.3 / Gradle 9.7.1 |
| 前端 | React 18 + Vite 5 + TypeScript 5（strict） |
| 容器 | Docker Compose（`ops/local/docker-compose.yml`），**12 個容器** |

**服務埠號**

| 服務 | 埠 | 服務 | 埠 |
|---|---:|---|---:|
| authorization-service | 8081 | statement-service | 8092 |
| card-service | 8082 | dispute-service | 8093 |
| limit-service | 8083 | clearing-service | 8094 |
| party-service | 8084 | merchant-service | 8095 |
| product-service | 8085 | migration-service | 8096 |
| pricing-service | 8086 | notification-service | 8097 |
| posting-service | 8087 | report-service | 8098 |
| payment-service | 8088 | api-gateway | 8100 |
| installment-service | 8089 | bff-web | 8101 |
| rewards-service | 8091 | cardcore-web（Vite） | 5173 |

---

## 2. 測試劇本清單（`TRP-001 §7-2`）

> ⚠️ **證據性質**：本節之「結果」為**引用** `HANDOVER §3.A` 之真機實測紀錄（附 `#A-xx`），
> **非本輪重跑**。劇本 ID 規則：`TR-<服務縮寫>-NN`。
> 「關聯」欄之 FR／POC 對應取自 **`GOV-004 §3`／`§4`**（權威追溯矩陣）。

### 2.1 `authorization-service`（8081）

關聯 FR：`AUT-1.1`／`AUT-1.2`／`AUT-1.3`　｜　POC：**13**（收單授權分流）、**15**（國際組織 compliance）、**17**（瞬間大量交易）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-AUTH-01 | 正常卡、額度充足 | APPROVED / `00` | ✅ | TRR 1.0 T-01 |
| TR-AUTH-02 | 額度不足 | DECLINED / `51 LIMIT` | ✅ | TRR 1.0 T-02 |
| TR-AUTH-03 | 鎖卡 | DECLINED / `51 CARD_STATUS` | ✅ | TRR 1.0 T-03 |
| TR-AUTH-04 | 13 項檢核（6 已實作） | 6 項如實回報、其餘標「未實作」**不造假通過** | ✅ | TRR 1.0 T-04／§5 L-1 |
| TR-AUTH-05 | Stand-in 降級閉環（停額度服務） | 不停機／`STANDIN`／flag=1／恢復後補送／`pending=0` | ✅ | TRR 1.0 T-12～T-15 |
| TR-AUTH-06 | 沖正（FULL／重複沖正） | 對稱釋放；重複沖正回 `CC-AUTH-3002` | ✅ | `#A-96`／`#A-97`；截圖 `webui-reversal-02` |
| TR-AUTH-07 | 授權策略檢核明細 | 檢核結果可查 | ✅ | `#A-95`／`#A-97`；截圖 `webui-policy-01` |
| TR-AUTH-08 | 稽核軌跡查詢（統一時間軸） | `OVERRIDE`／`REVERSAL` 合併排序；`actor` 對沖正如實 `null` | ✅ | `#A-102` |
| TR-AUTH-09 | 服務間 ACL（呼叫者身分） | 不符 `SAD-002 §5` 即 **403** | ✅ | `#A-63`／`#A-64` |
| TR-AUTH-10 | 認證 fail-closed | 無 token → **401**（17/17 服務） | ✅ | `#A-36`／`#A-41` |

### 2.2 `limit-service`（8083）

關聯 FR：`ISS-2.4`　｜　POC：**8**（專用額度）、**14**（授權額度更新）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-LIM-01 | 查詢永久額度 | 可用 = 10,000,000 分 | ✅ | TRR 1.0 T-07 |
| TR-LIM-02 | 臨時額度僅於有效期計入 | 100,000 + 50,000 = 150,000 | ✅ | TRR 1.0 T-08 |
| TR-LIM-03 | 建立佔用／釋放 | 9,700,000 → 10,000,000 | ✅ | TRR 1.0 T-09／T-10 |
| TR-LIM-04 | 佔用超過可用 | 拒絕 `CC-LIM-1001`，**不寫入佔用** | ✅ | TRR 1.0 T-11 |
| TR-LIM-05 | 專用額度查詢端點 | 4 端點；⚠️ SPECIAL **apply** 之資料模型待裁定 | ✅ | `#A-75` |
| TR-LIM-06 | 額度控管頁（兩維度並列） | 查詢＋建立佔用＋釋放 | ✅ | 截圖 `webui-limit-01`／`-02` |

### 2.3 `card-service`（8082）

關聯 FR：`ISS-2.2`／`DEB-3.1`　｜　POC：**6**（信用卡快發快綁）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-CARD-01 | 發卡／快發快綁／Token 綁定（補齊 5 端點） | 12 情境全數符合 | ✅ | `#A-37` |
| TR-CARD-02 | `bindPlatform` 真正建立 Token | 不再只寫日誌 | ✅ | `#A-39` |
| TR-CARD-03 | 卡號加密（`KeyProvider`） | Oracle 密文往返 | ✅ | `#A-24`～`#A-26` |
| TR-CARD-04 | 卡片生命週期／Token 頁 | 兩維度並列；**同卡兩端點兩套錯誤碼**（4040 vs 3001）如實 | ✅ | 截圖 `webui-lifecycle-02`／`webui-token-01` |
| TR-CARD-05 | `CR-020` 四項缺陷修根因 | 解鎖後 `blockCode` 與 `status` 同步；無來源案件開卡遭拒 `CC-CARD-1002` | ✅ | `#A-92`；截圖 `webui-cr020-01`～`-03` |
| TR-CARD-06 | `ticketType` 補 DDL 並持久化 | 契約與 DDL 一致 | ✅ | `#A-42`／`#A-51` |
| TR-CARD-07 | 進件作業台（受理→送徵信→核准） | 全鏈路；**徵審未接上時顯示「轉人工核決」而非核准（fail-closed）** | ✅ | `#A-52`；截圖 `webui-applications-03` |
| TR-CARD-08 | 外部徵審介面（`SCS-025`） | 我方建議版；**未接上時 fail-closed 回 `REFER`** | 🟡 | `#A-48`（客戶規格未定） |

### 2.4 `party-service`（8084）

關聯 FR：`ISS-2.1`　｜　POC：**10**（市區停車）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-PTY-01 | 持卡人／歸戶查詢（4 端點） | 冪等 201／200／409 | ✅ | `#A-11` |
| TR-PTY-02 | 管制碼（`block_code`） | 設定後授權即時拒絕 | ✅ | `#A-10` |
| TR-PTY-03 | 個資加密（首個接 `KeyProvider` 之服務） | Oracle 密文往返 | ✅ | `#A-24`～`#A-26` |

### 2.5 `product-service`（8085）

關聯 FR：`COM-6.1`／`COM-6.2`

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-PRD-01 | 產品 CRUD（5 端點） | 真機 e2e 通過 | ✅ | `#A-76` |
| TR-PRD-02 | 參數版本化（熱更新） | 版本鏈正確；重疊回錯誤 | ✅ | `#A-76`；截圖 `webui-parameters-01` |
| TR-PRD-03 | 產品與費率設定頁 | 建立產品、狀態僅顯示 | ✅ | 截圖 `webui-product-01` |

### 2.6 `posting-service`（8087）

關聯 FR：`ACQ-4.5`／`ISS-2.3`／`ISS-2.12`／`DEB-3.2`／`DEB-3.5`　｜　POC：**9**（錯帳沖正、重覆入帳防範）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-POST-01 | 入帳＋沖正＋重複偵測 | 沖正、重複偵測皆正確 | ✅ | `#A-12` |
| TR-POST-02 | 計息串接（`pricing`） | 本金 67,845 × 18.5% × 30/365 = **1,032 分**入 `INTEREST`；重送不重複；**`pricing` 掛掉 → 503 `CC-PLT-5005` 且未入帳（無 fail-open）** | ✅ | `#A-31` |
| TR-POST-03 | 交易期間過濾（P0 修復） | `(上期結帳日, 本期結帳日]` 半開區間；**不再每期重複計收** | ✅ | `#A-33` |
| TR-POST-04 | Round-off／幣別一致性（三方） | 1,066 = 1,066 = 1,066 | ✅ | `#A-78` |
| TR-POST-05 | `UNMATCHED` 產生者（逾三日批次） | 逾時者轉換；**未逾時者不動** | ✅ | `#A-79`；**⚠️ 見 §4 DEF-06（時間炸彈測試）** |

### 2.7 `payment-service`（8088）

關聯 FR：`ISS-2.6`／`ISS-2.9`　｜　POC：**11**（繳款即時恢復額度）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-PAY-01 | 繳款分配不變式 | 10,000 分配正確 | ✅ | `#A-14` |
| TR-PAY-02 | 繳款即時恢復額度 | 額度回復 | ✅ | `#A-14` |
| TR-PAY-03 | 未匹配繳款逾時轉換 | 逾時者轉 `UNMATCHED` 並重新佔額；未逾時者不動 | ✅（**測試於 2026-10-01 修復，見 §4 DEF-06**） | 單測 |

### 2.8 `pricing-service`（8086）

關聯 FR：`ISS-2.5`／`DEB-3.3`　｜　POC：**1**（利息 & 違約金計算及查詢）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-PRC-01 | 利息／費用／違約金（3 端點） | 利息 796、費用 5 筆、違約金夾擠 3 期、預借現金拆分；**7 項錯誤路徑皆 4xx、0 筆 ERROR** | ✅ | `#A-28` |
| TR-PRC-02 | 規則選取維度（`TX_TYPE`） | `TIER` 挪用解除，回歸客層本義 | ✅ | `#A-77` |

### 2.9 `installment-service`（8089）

關聯 FR：`ISS-2.7`　｜　POC：**5**（分期）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-INST-01 | 建立分期與攤還表 | 1,000.00／3 期 → 333.33／333.33／**333.34**（尾差末期吸收）；剩餘本金收斂 0.00 | ✅ | `#A-67` |
| TR-INST-02 | 提前結清 | `EARLY` → `PRE_CLOSED`；DB `remaining_periods=0` | ✅ | `#A-67` |
| TR-INST-03 | 雙軸（`channel_type` × `business_type`） | 通路 7 值／業務型態 3 值＋「不指定」；空值顯示「**未記錄**」 | ✅ | `#A-60`／`#A-67` |
| TR-INST-04 | 總約未簽署 | `CC-INS-1002` | ✅ | `#A-67` |
| TR-INST-05 | 真實瀏覽器 ＋ Keycloak 登入 | **7 情境全數成立** | ✅ | `#A-67`；截圖 5 張 |

### 2.10 `rewards-service`（8091）

關聯 FR：`RWD-5.1`／`RWD-5.2`／`RWD-5.3`　｜　POC：**2**（點數）、**4**（ONLINE REDEEM）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-RWD-01 | 三層點數（帳戶／到期桶／明細） | 三層皆可查 | ✅ | `#A-16`；截圖 `webui-rewards-01` |
| TR-RWD-02 | 兌換後自動重查 | 即時反映新餘額（**非讀快取**） | ✅ | 截圖 `webui-rewards-02` |
| TR-RWD-03 | 併發兌換 | 6 筆併發**無遺失更新** | ✅ | `#A-16` |
| TR-RWD-04 | 兌換雙欄位（標的類別 × 折抵方式） | 「點數＋現金換哩程」兩者並存 | ✅ | `#A-70` |
| TR-RWD-05 | 現金價值由折算率計算 | `CASH_VALUE` 不再恆 0 | ✅ | `#A-72` |
| TR-RWD-06 | 驗證層次對齊（分層並存） | 控制器層管形狀→平台碼；應用層管語意→服務碼 | ✅ | `#A-58`（55 測 0 失敗） |

### 2.11 `statement-service`（8092）

關聯 FR：`ISS-2.8`　｜　POC：**16**（帳單批次執行）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-STM-01 | 結帳公式 | `new_balance` 43,455 正確 | ✅ | `#A-13` |
| TR-STM-02 | 結帳前觸發計息 | 計息先於結帳 | ✅ | `#A-32` |
| TR-STM-03 | 帳單環境重建（10／11 月） | 10 月 `new_balance` 57,898 → **70,243**；11 月 `prev_balance` = 70,243；明細各期**互斥** | ✅ | `#A-61` |
| TR-STM-04 | 計息幣別與帳單同源 | 非 TWD 帳戶不再「以 TWD 入息、帳單標他幣」 | ✅ | `#A-78` |
| TR-STM-05 | 批次清單端點 | `GET /statement-runs?limit=N` 200／5 筆 | ✅ | `#A-104` |
| TR-STM-06 | 帳單 PDF（`PDF_REF`） | ⚠️ **未實作**（產生器需額外函式庫） | ⚪ | `SCS-011 §10` |

### 2.12 `clearing-service`（8094）

關聯 FR：`ACQ-4.6`／`ISS-2.13`／`DEB-3.6`　｜　POC：**3**（收單）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-CLR-01 | 清算執行／對帳查詢／結算（3 端點） | 3 端點 e2e 通過 | ✅ | `#A-81` |
| TR-CLR-02 | 差異判定 | `DIFFERENCE` 如實；差異未歸零**不得結案** | ✅ | `#A-81`；截圖 `webui-clearing-01` |
| TR-CLR-03 | 清算執行清單端點 | 200／2 筆；**如實回 `createdAt`／`updatedAt`（無 `startedAt` 欄位，不臆造）** | ✅ | `#A-104` |

### 2.13 `dispute-service`（8093）

關聯 FR：⚠️ **`GOV-004 §3` 未列本服務**（見 §6 U-01）　｜　POC：**3**（收單，部分）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-DSP-01 | 爭議受理／查詢／扣款仲裁（3 端點） | 3 端點 e2e 通過 | ✅ | `#A-82` |
| TR-DSP-02 | 雙軸拆分（`DISPUTE_REASON` × `WORKFLOW_STAGE`） | 兩軸分列 | ✅ | `#A-82`；截圖 `webui-dispute-01` |
| TR-DSP-03 | 跳號 | 如實回 `CC-DSP-3001` | ✅ | `#A-86` |
| TR-DSP-04 | 拒付時限與舉證規範 | ⚠️ **真阻塞**（卡組織文件未提供） | ⛔ | `§3.D D-1` |

### 2.14 `merchant-service`（8095）

關聯 FR：`ACQ-4.1`／`ACQ-4.2`／`ACQ-4.3`　｜　POC：**3**（收單）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-MCH-01 | 商戶建檔／查詢／請款（3 端點） | e2e 通過；請款淨額 **9,790 元** | ✅ | `#A-80`／`#A-87` |
| TR-MCH-02 | 雙軸拆分（商店型態 × 業別） | 兩軸分列 | ✅ | `#A-80`；截圖 `webui-merchant-01` |
| TR-MCH-03 | `merchantId` 語意（對外即業務代碼） | 往返回查 **200**（修正前 404） | ✅ | `#A-88` |
| TR-MCH-04 | 收單帳戶金鑰管理（KMC） | ⚠️ HSM／KMS 未提供；`KeyProvider` 機制已就緒 | 🟡 | `§3.D D-5`／`§3.E W-1` |

### 2.15 `migration-service`（8096）

關聯 FR：`SYS-2.8`／`SYS-3`　｜　POC：**12**（系統功能，部分）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-MIG-01 | 遷移作業受理／舊帳查詢（2 端點） | 兩層 `WAVE`＋`JOB` | ✅ | `#A-84` |
| TR-MIG-02 | 試跑（`dryRun`） | 僅計數、**不變更任何列** | ✅ | 截圖 `webui-migration-01` |
| TR-MIG-03 | 遷移作業清單端點 | 200／3 筆；`jobNo`／`waveCode`／`dryRun` 正確 | ✅ | `#A-104` |
| TR-MIG-04 | 帳務資料搬移 | ⚠️ **舊系統資料源未接入 → 不搬移任何帳務資料**（計數為「對映處理數」） | ⛔ | `SCS-015 §5.1` |

### 2.16 `notification-service`（8097）

關聯 FR：`ISS-2.10`　｜　POC：**7**（消費通知）

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-NOTIF-01 | 通知發送／查詢（2 端點） | 通道抽象先行（本地 Log 通道 stand-in） | ✅ | `#A-85` |
| TR-NOTIF-02 | 實際發送通道 | ⚠️ **真阻塞**（簡訊／Email／推播供應商未定） | ⛔ | `§3.D D-3` |

### 2.17 `report-service`（8098）

關聯 FR：`SYS-1`／`ACQ-4.4`／`ISS-2.11`／`DEB-3.4`

| 劇本 ID | 情境 | 預期 | 結果 | 證據 |
|---|---|---|---|---|
| TR-RPT-01 | 報表作業受理／查詢（2 端點） | 非同步；`QUEUED` → `COMPLETED` | ✅ | `#A-83` |
| TR-RPT-02 | **CQRS 讀模型**（Oracle → Postgres 投影） | 讀側首例；投影追趕 | ✅ | `#A-83` |
| TR-RPT-03 | `XLSX`／`PDF` 未支援 | 作業 `FAILED` 並**載明原因**（**不產空檔**） | ✅ | `#A-83`；截圖 `webui-reports-01` |
| TR-RPT-04 | 報表作業清單端點 | 200／4 筆 | ✅ | `#A-104` |
| TR-RPT-05 | **輸出改走物件儲存** | `DOWNLOAD_URL` 存**物件鍵**；物件確實可自 Garage 取回；**本機不留檔** | ✅ | **`#A-107`（本輪）** |
| TR-RPT-06 | 報表檔案下載（**代理端點**） | 200 且**內容與物件逐位元組一致**；QUEUED→409、不存在→404 | ✅ | **`#A-109`（本輪）** |

### 2.18 平台模組（8 個）

| 劇本 ID | 模組 | 情境 | 結果 | 證據 |
|---|---|---|---|---|
| TR-PLT-01 | `api-gateway` | 路由（17 服務）＋ Redis 限流 ＋ 分流熱更新 | ✅ | `#A-73` |
| TR-PLT-02 | `api-gateway` | 唯讀路由端點（`/api/v1/gateway/routes`） | ✅ | `#A-103` |
| TR-PLT-03 | `bff-web` | 三域聚合 ＋ token-relay 端到端 | ✅ | `#A-74` |
| TR-PLT-04 | `bff-web` | 健康聚合（並行探測；`SecurityContext` 傳遞） | ✅ | `#A-101` |
| TR-PLT-05 | `bff-web` | 批次聚合（四服務；`DIFFERENCE`→`WARNING` 非 `SUCCEEDED`） | ✅ | `#A-104` |
| TR-PLT-06 | `common-spring` | 全域例外處理（7 handler、9 例外型別） | ✅ | `#A-22`／`#A-23` |
| TR-PLT-07 | `common-security` | `KeyProvider` 機制化（**生產 profile 拒絕啟動**） | ✅ | `#A-24`～`#A-26` |
| TR-PLT-08 | 全平台 | 服務間出站憑證（`client_credentials`） | ✅ | `#A-62` |
| TR-PLT-09 | 全平台 | 服務對服務 ACL（不符即 403） | ✅ | `#A-64` |
| TR-PLT-10 | 全模組 | 監控三支柱（19/19 模組） | ✅ | `#A-27`／`#A-38` |

### 2.19 WebUI（26 頁）

| 劇本 ID | 項目 | 結果 | 證據 |
|---|---|---|---|
| TR-UI-01 | 26 頁已實作（側欄／路由／頁首同源） | ✅ | `HANDOVER §2.3` |
| TR-UI-02 | TypeScript 型別檢查 | ✅ **0 錯誤**（本輪重跑） | §7 |
| TR-UI-03 | 正式建置 | ✅ `vite build` 成功（392.69 kB） | 本輪 |
| TR-UI-04 | 真實瀏覽器實測 | 🟡 **多數頁有截圖證據（40 張）；非全部** | `docs/08-evidence/README.md` |
| TR-UI-05 | SSO 啟用後帶 token 操作 | ✅ | 截圖 `webui-applications-05` |

---

## 3. 測試資料清單（`TRP-001 §7-3`）

| # | 資料集 | 來源 | 遮蔽狀態 | 用途 |
|---:|---|---|---|---|
| DS-1 | 持卡人／歸戶／卡片／額度 | **SQL 種子寫入真實 Oracle**（非程式內建假資料） | 測試資料，**無真實個資** | TR-AUTH／TR-PTY／TR-CARD |
| DS-2 | 授權交易與檢核結果 | 授權 API 產生 → 落 Oracle `CC_AUTH` | 同上 | TR-AUTH-01～04 |
| DS-3 | 帳單與明細 | 帳單批次產生（`#A-61` 重建後） | 同上 | TR-STM-01～04 |
| DS-4 | 分期／攤還表 | 分期 API 產生 | 同上 | TR-INST-01～04 |
| DS-5 | 點數帳戶／到期桶／異動 | 紅利 API 產生 | 同上 | TR-RWD-01～05 |
| DS-6 | 清算明細／對帳結果 | 清算 API ＋ 種子 | 同上 | TR-CLR-01～03 |
| DS-7 | 爭議案件 | 爭議 API 產生 | 同上 | TR-DSP-01～03 |
| DS-8 | 商店／請款 | 商店 API 產生 | 同上 | TR-MCH-01～03 |
| DS-9 | 報表讀模型（Postgres `rpt`） | Oracle 投影批次 | 同上 | TR-RPT-02 |
| DS-10 | 遷移對映註冊表 | 種子（`LEGACY_ACCOUNT_MAP`） | 同上 | TR-MIG-01～02 |
| DS-11 | **個資加密欄位** | `KeyProvider`（本地靜態金鑰） | **密文儲存**；金鑰不入版控 | TR-CARD-03／TR-PTY-03 |
| DS-12 | Stripe 測試卡（`sk_test_`） | 客戶提供，置 `~/.config/cardcore/stripe-test.env`（**repo 之外**、權限 600） | **測試金鑰** | `#A-44`／`#A-55` |
| DS-13 | 物件儲存（報表輸出） | 報表產生 → Garage `cardcore-artifacts` | 測試資料 | TR-RPT-05 |

> ⚠️ **遮蔽狀態之誠實揭露**：本案為**本地開發環境**，資料全為**自建測試資料**，
> **未使用任何客戶真實資料**。故「個資遮蔽」在此階段**無從驗證**——
> **不得**據此宣稱「已通過個資驗證」（`TRP-001 §6.2 #7` 仍未達成）。

---

## 4. 缺陷清單（`TRP-001 §7-4`）

> 嚴重度：**S1**（阻斷／資安）／**S2**（主要功能）／**S3**（次要）／**S4**（介面）。
> DEF-01～DEF-05 為第 1 輪既有；**DEF-06 為本輪（2026-10-01）新發現**。

| DEF-ID | 缺陷 | 嚴重度 | 狀態 | 關聯 | 修復說明 |
|---|---|---|---|---|---|
| DEF-01 | Flyway 從未執行（缺 `spring-boot-flyway`） | **S1** | ✅ 已修 | 全 17 服務 | 補 `spring-boot-flyway` 依賴；**Spring Boot 4 模組化之「靜默不做」型缺陷**（無任何錯誤訊息） |
| DEF-02 | 共用例外處理器未註冊（套件掃描範圍） | **S1** | ✅ 已修 | `common-spring` | 領域例外噴 500 → 修正掃描範圍，客戶端可取 `CC-*` 錯誤碼 |
| DEF-03 | OpenAPI `operationId` 產生邏輯撞號 | S3 | ✅ 已修 | `gen_openapi.py` | 集合端點與單一資源端點同名 → 修正唯一性 |
| DEF-04 | `SPECIAL_LIMITS` 無法充當信用額度（`ORA-02290`） | **S2** | ✅ 已修 | `limit-service` | `CR-001` |
| DEF-05 | 信用額度主檔缺口 | **S2** | ✅ 已修 | `limit-service` | `CR-001` |
| **DEF-06** | **★ `PaymentUnmatchedServiceTest` 為「時間炸彈測試」——fixture 用固定日期、受測程式用真實時鐘** | **S2**（測試可信度） | ✅ **本輪已修** | `payment-service` | **根因**：`NOW = Instant.parse("2026-09-22T08:00:00Z")`（固定），而 `PaymentUnmatchedService` 以**真實** `Instant.now() − 3 日` 計算 cutoff → 真實日期一過 fixture 3 日，連「剛受理」之候選也變逾時 → `transitioned` 由 1 變 2 → **斷言必然失敗**。**實測：2026-09-25 起即紅**，惟先前僅**逐模組**跑測試而未察覺；**2026-10-01 首次全量 `./gradlew test` 才發現**。**修法**：`NOW` 改為 `Instant.now()`（所有 `NOW.minus(...)` 之相對關係不變）。**併載教訓**：**逐模組跑測試會漏掉「跨模組才暴露」的問題**；且**「561 測 0 失敗」之記載在當時即不成立** |
| **DEF-07** | `validate_sql` 全庫掃描有 **5 處違規**（全在 `db/migration-postgres/V1__rpt_read_model.sql` 之 `daily_auth_summary`：SQL-04 表名非複數 ＋ SQL-05 缺 `id`／`created_at`／`updated_at`／`version`） | **S3** | ✅ **已結案**（`#A-109`，採 (c)） | `report-service`／`tools` | **根因＝工具適用範圍未界定**：該表為 **Postgres 讀模型投影表**（CQRS 讀側），**非** Oracle 權威 OLTP schema；SQL-01～09 係為 **Oracle** 設計。**修法（BEAM PMO 裁定 (c)）**：`validate_sql` **目錄掃描只納入 `<...>/db/migration/`**；`migration-postgres` **略過並明示**；**單檔明示不受限**；**併修「靜默 0 檔」→ 印警告**。**驗證**：掃 `backend` → **48 檔、0 違規**。⚠️ **不修表**（對投影表硬補 `version` ＝ **無意義欄位＝假綠**，`#C-36` 之教訓） |

---

## 5. 效能與一致性測試對照 SoW 門檻（`TRP-001 §7-5`）

> ⚠️ **本節為空——該類測試從未執行。** 誠實列出門檻與現況，**不以任何推論填補**。

| SoW 門檻 | 現況 | 判定 |
|---|---|---|
| 授權端到端 **P95 ≤ 500ms** | **未量測** | ⚪ **未執行** |
| **iECS ≥ 1,000 TPS** | **未量測** | ⚪ **未執行** |
| **BASE24-mas > 2,000 TPS** | **未量測** | ⚪ **未執行** |
| 引擎一致率 **≥ 99.99%** | **未比對**（需與 Legacy ECS 並行） | ⚪ **未執行** |
| 差異率 **< 0.01%** | **未比對** | ⚪ **未執行** |
| **A 類差異 0** | **未比對** | ⚪ **未執行** |
| 批次金額差異 **0** | **未比對** | ⚪ **未執行** |

**為何未執行（誠實說明）**：

1. **一致性比對需 Legacy 資料源**——`migration-service` 之舊系統資料源**未接入**
   （`SCS-015 §5.1`，真阻塞 `§3.D D-4`）。
2. **效能測試需壓測環境**——本案為**本機單機（4 核／32GB）**，
   且 `TRP-001 §6.2` 之 TPS 門檻為**生產級**，本機數據**不具代表性**。
3. **本機服務以 `--profile` 分層啟動**（`ops/local/docker-compose.yml`），
   非全量常駐，**不構成壓測條件**。

> **建議**：效能與一致性測試**須於 SIT 環境執行**，並納入 G4／G5 關卡；
> 在此之前，**NFR 之效能相關小節（NFR 60 小節中絕大多數）不得宣稱已驗證**。

---

## 6. 未決事項與風險（`TRP-001 §7-6`）

| U-ID | 項目 | 類型 | 說明／建議 |
|---|---|---|---|
| ~~**U-01**~~ | ~~**`GOV-004 §3` 未列 `dispute-service`**~~ → ✅ **已結案（`#A-109`）** | 文件缺口 | **【2026-10-01 查證後結案】**：★ **查明「未列」之原因為「需求側缺口」，非漏列**——`BRD-002` 之 FR 編號群**無任何爭議／拒付前綴**（`DEB-3.x` 六項**全為 DEBIT 卡**）、`BRD-001` **僅文字**提及「爭議帳款」、**`SCS-012 §1` 早已自行揭露**並建議補 `DIS-*`。→ **`GOV-004 §3` 已補該服務列，FR 欄以「0」如實呈現（不捏造歸屬）**；§6 新增「17 服務皆納入矩陣」檢核列（差額 1 即該服務）。`GOV-004` → **1.1**。**遺留**：`DIS-*` FR **待 SA 補** |
| ~~**U-02**~~ | ~~**報表下載呈現方式**~~ → ✅ **已結案（`#A-109`，採方案 B）** | 待裁定 | **【2026-10-01 BEAM PMO 裁定採 B（代理端點）】**：`SCS-017 §6.2` 立規格 → 契約 **86 端點 0 錯誤** → 實作 → 前端下載鈕 → **真機驗證**：QUEUED → **409 `CC-PLT-3001`**、完成後 → **200** 且**下載內容與物件儲存內之原始檔逐位元組一致（SHA-256 相同）**、作業不存在 → `404`、非 UUID → `400`。**設計要點**：**全案唯一非封套回應**；追蹤碼改以 **`X-Trace-Id` 標頭**回傳；**三種「沒有檔案」分開講**（404／409／**物件查無→404 如實回報**，不回空檔）。**遺留**：**無 Range 支援**、**無下載稽核留痕**（建議另立 CR） |
| ~~**U-03**~~ | ~~**`validate_sql` 之適用範圍**~~ → ✅ **已結案（`#A-109`，採 (c)）** | 待裁定 | **【2026-10-01 BEAM PMO 裁定採 (c)「界定工具範圍」】**：目錄掃描**只納入 `<...>/db/migration/`**（Oracle 遷移）；`db/migration-postgres/` **略過並明示**；**單檔明示傳入不受限**；**併修「靜默 0 檔」→ 印警告**。**驗證**：掃 `backend` → **48 檔、0 違規**（原 49 檔、5 違規）。**根因**：SQL-01～09 係為 **Oracle 權威 OLTP schema** 設計，對 **Postgres 讀模型投影表不適用**（硬補 `version` ＝ 無意義欄位＝**假綠**） |
| **U-04** | **`verify_contract_dto` 4 處不符 ＋ 2 則需確認** | 既有 | 全在 `authorization-service`（`AuthorizeResponse` vs `ReversalResult`／`OverrideResult`；`AuthorizeRequest` 3 欄）與 `installment-service`（`InstallmentPeriod.principalAmount`）；另有 `limit-service` 之路徑寫法差異待人工確認。**與本輪無關**（既有），列此供追蹤 |
| **U-05** | **NFR 60 小節僅 2 項經實測** | 風險 | 「設計 100%／**驗證 3.3%**」。其餘 58 項須待 **G4／G5 關卡**（效能壓測、資安測試、災難復原演練）——**未驗證不等於未完成，但也不等於完成** |
| **U-06** | **POC 17 項之 4 🟡／1 ⚪** | 風險 | 見 `HANDOVER §1.2`；建議逐項確認缺口 |
| **U-07** | 真阻塞 6 項（`§3.D`） | 外部依賴 | 卡組織規範文件、收單資料源、通知發送通道——**骨架／契約／狀態機可先做，業務參數與實際連線必須等** |
| **U-08** | 覆蓋率與 Mutation 從未量測 | 風險 | `TRP-001 §6.2 #1` 之門檻**無工具支援**（無 JaCoCo／PIT）。**建議**：納入 CI（`CSP-001 §7` 之關卡） |
| **U-09** | ⚠️ **`409` 之錯誤碼語意落差**（`#A-109` 併發現） | 待日後處理 | `SDD-006 §3.4` 之 **409 平台碼皆為「狀態機轉換」語意**（`CC-PLT-2001`／`2002`／`3001`／`3002`），但「**資源當前狀態不允許此操作**」（如「作業未完成故無檔案可下載」）**並非狀態機轉換** → 本輪以最接近之 `CC-PLT-3001` 表達，**不為單一端點擴充登錄表**。**建議**：若此類情境增多，**另立 `CC-PLT-3003`**（409「資源狀態不允許此操作」）並回填登錄表 |

---

## 7. 品質關卡（本輪重跑，2026-10-01）

| 檢查 | 指令 | 結果 |
|---|---|---|
| 空殼／佔位掃描 | `scan_scaffold.py backend` | ✅ **0 命中** |
| mock data 掃描 | `scan_mockdata.py backend` | ✅ **0 命中** |
| 假測試掃描 | `scan_faketest.py backend` | ✅ **0 命中** |
| SQL 規則 | `validate_sql.py backend` | ✅ **0 違規**（**48 檔**＝Oracle 遷移；`migration-postgres` 已依 `#A-109` 界定為**不適用**並略過，**不靜默**） |
| Mermaid 語法 | `validate_mermaid.py docs` | ✅ **0 錯誤**（117 區塊） |
| OpenAPI 契約 | `gen_openapi.py` | ✅ **0 錯誤**（17 服務 ＋ `bff-web`，**85 端點**） |
| 契約 ↔ DTO 比對 | `verify_contract_dto.py` | ⚠️ **不符 4 處、需確認 2 則**（既有，見 **U-04**） |
| 單元／整合測試 | `./gradlew test` | ✅ **836 測、0 失敗**（**修 DEF-06 後**） |
| 前端型別檢查 | `npm run typecheck` | ✅ **0 錯誤** |
| 前端正式建置 | `npm run build` | ✅ 成功（392.69 kB） |

> ⚠️ **掃描器之範圍（避免誤讀「0 命中」）**：三支 `scan_*` 以 **`backend`** 為範圍；
> `validate_sql` **無內建 `db/migration` 過濾**（會掃到 `migration-postgres`）；
> `validate_mermaid` 以 `docs` 為範圍。**範圍不同，不可互相推論**。

---

## 8. 結論

1. **單元／整合測試**：**836 測 0 失敗**（本輪重跑，**修復 DEF-06 後**）。
2. **品質關卡**：**3 支掃描器 0 命中**、Mermaid 0 錯誤、契約 0 錯誤；**2 項待處理**（DEF-07／U-03、U-04）。
3. **真機實測**：**17 個領域服務 ＋ 8 個平台模組 ＋ 26 頁 WebUI** 皆有實測證據（§2，附 `#A-xx`）。
4. ⚠️ **準出未達成**（`TRP-001 §6.2`）：**8 項中僅 2 項完全達成**；
   **效能、一致性、安全掃描三項從未執行**；**覆蓋率從未量測**。

**建議（依優先序）**：

1. **裁定 U-03**（`validate_sql` 範圍）與 **U-02**（報表下載方式）——兩者皆已有建議方案。
2. **補 `GOV-004 §3` 之 `dispute-service`**（U-01）——追溯矩陣之第 1 問缺口。
3. **將覆蓋率納入 CI**（U-08）——目前 `TRP-001 §6.2 #1` 無從量測。
4. **規劃 SIT 環境**以執行效能與一致性測試（§5）——**本機無法代表生產**。
5. 處理 U-04 之 4 處契約↔實作不符（既有）。

---

## 9. 與第 1 輪之差異（`TRP-001 §7` 符合性）

| `TRP-001 §7` 要求 | 第 1 輪（v1.0） | **本版（v2.0）** |
|---|---|---|
| 1. 執行摘要（通過／失敗／跳過、覆蓋率、**準出達成度**） | ❌ 僅有測試數，**無準出達成度** | ✅ **§0**（含對照 `§6.2` 8 項之達成度） |
| 2. **測試劇本清單**（劇本 ID、**關聯 FR/POC/NFR**、步驟、預期） | 🟡 有情境，**但無劇本 ID、無 FR/POC 關聯** | ✅ **§2**（`TR-*` 劇本 ID ＋ `GOV-004` 之 FR／POC 關聯 ＋ 證據） |
| 3. **測試資料清單**（資料集、來源、遮蔽狀態） | ❌ **完全沒有** | ✅ **§3**（13 個資料集 ＋ 誠實揭露「無從驗證遮蔽」） |
| 4. 缺陷清單（**DEF-ID、嚴重度**、狀態、關聯、修復） | 🟡 有缺陷，**但無 DEF-ID、無嚴重度** | ✅ **§4**（DEF-01～07，含嚴重度；**新增 DEF-06**） |
| 5. **效能與一致性對照 SoW 門檻** | ❌ **完全沒有** | ✅ **§5**（**誠實標示「未執行」**，並說明原因） |
| 6. 未決事項與風險 | 🟡 有「已知限制」，但**未含未決事項** | ✅ **§6**（U-01～U-08） |

**併載之範圍擴充**：測試範圍由 **2 服務 ＋ 前端** → **17 領域服務 ＋ 8 平台模組 ＋ 26 頁 WebUI**。

---

## 10. 修訂記錄

| 版本 | 日期 | 修訂者 | 說明 |
|---|---|---|---|
| **2.1** | **2026-10-01** | WorkBuddy AI | **BEAM PMO 三裁定之執行結果回寫（`HANDOVER #A-109`）**。**U-03 結案**（採 (c)）：`validate_sql` **界定適用範圍**——目錄掃描只納入 `<...>/db/migration/`（Oracle 遷移）、`migration-postgres` 略過並**明示**、單檔明示不受限、**併修「靜默 0 檔」→ 印警告** → **DEF-07 結案**，§7 之 SQL 規則由「違規 5 處」改為 **0 違規（48 檔）**。**U-01 結案**：★ 查明「`GOV-004 §3` 未列 dispute」**係需求側缺口、非漏列**（`BRD-002` 無任何爭議／拒付 FR）→ 以「0」如實呈現，`GOV-004` → **1.1**。**U-02 結案**（採代理端點 B）：新增 **TR-RPT-06**（下載）為 ✅——**真機驗證**：200 且**內容與物件逐位元組一致**、QUEUED→**409**、不存在→404。★ **新增 U-09**：`409` 之**錯誤碼語意落差**（既有平台 409 碼皆為狀態機轉換語意）——本輪以 `CC-PLT-3001` 表達並明載，**建議日後另立 `CC-PLT-3003`** |
| **2.0** | **2026-10-01** | WorkBuddy AI | **依 `TRP-001 §7` 重構 ＋ 範圍擴充（`HANDOVER #A-108`）**。**範圍**：2 服務 ＋ 前端 → **17 領域服務 ＋ 8 平台模組 ＋ 26 頁 WebUI**。**新增 §0 準出達成度**（對照 `TRP-001 §6.2` 8 項：**僅 2 項達成**）、**§2 測試劇本清單**（`TR-*` ID ＋ `GOV-004` 之 FR／POC 關聯 ＋ `#A-xx` 證據）、**§3 測試資料清單**（13 資料集）、**§5 效能對照**（**誠實標示未執行**）、**§6 未決事項**（U-01～U-08）。**缺陷清單**加 DEF-ID 與嚴重度，**新增 DEF-06**（時間炸彈測試，已修）與 **DEF-07**（`validate_sql` 5 處）。★ **本輪實測**：`./gradlew test` **836 測 0 失敗**（修 DEF-06 後）。⚠️ **未竟**：效能／一致性／安全掃描**從未執行**（§5）；覆蓋率**從未量測** |
| 1.0 | 2026-09-19 | WorkBuddy AI | 初版：2026-09-19 實測結果（範圍：`authorization-service`、`limit-service`、WebUI 授權作業台） |
