# GOV-007　BEAM PMO 裁定清單（待裁定項之裁定與執行）

| 項目 | 內容 |
|---|---|
| 文件編號 | GOV-007 |
| 版本 | **1.2** |
| 日期 | 2026-10-01 |
| 裁定者 | BEAM PMO |
| 記錄者 | WorkBuddy AI（開發團隊） |
| 緣起 | `#A-113` 後 BEAM PMO 指示「清掉幾項待我裁定的卡點」。本清單逐項列**議題／選項／建議／BEAM PMO 裁定／依裁定之執行**，備查 |
| 狀態 | 裁定已收；**執行狀態見各節** |

> ⚠️ **本清單為「裁定之紀錄」**，非規格。各項之規格變更仍依 `GOV-003`（先規格後程式）於對應文件為之。

---

## 裁定總表

| # | 議題 | BEAM PMO 裁定 | 執行狀態 |
|---:|---|---|---|
| 1 | SSO 是否改 fail-closed | **同意（有條件）**：若會影響開發測試則先不改 | ✅ **已釐清：機制早已實作；依條件「先不改」**（見 §1） |
| 2 | `CorrelationIdFilter` 註冊或退役 | **註冊** | ✅ **早已實作**（`CorrelationIdAutoConfiguration`；見 §2） |
| 3 | 日誌 `total-size-cap` | **限制 5GB** | ✅ **已執行**（19 檔＋產生器模板；見 §3） |
| 4 | 報表下載 `409` 語意 | **另立 `CC-PLT-3003`** | ✅ **已執行**（`SDD-006` 1.10／`SCS-017` 1.6；見 §4） |
| 5 | `statement` 帳單 PDF 產生器 | **必做**（現行系統有，微服務不能少） | ✅ **已執行**（PDFBox 3.0.8；真機驗證通過；見 §5） |

---

## 1. SSO 是否改 fail-closed

**議題**：`cardcore.security.enabled` 是否改為 fail-closed（預設要求認證）。

**現況（2026-10-01 實測）**：

| 層次 | 現值 | 來源 |
|---|---|---|
| Java 預設 | **`true`（fail-closed）** | `SecurityProperties.enabled`（`common-spring`） |
| 本地 profile | `${CARDCORE_SECURITY_ENABLED:false}`（**預設關閉**） | `application-local.yml`（17/17 服務皆已宣告） |
| 本地 env | `true` | `ops/local/sso.env`（`sso.sh` 產生，`env.sh` 載入） |

> ★ **重要更正（誠實揭露）**：`SecurityProperties.enabled` 之 fail-closed 預設**早已於 2026-09-20（`SCS-022` v1.7，`§10 #12`）由 BEAM PMO 核定並實作**。
> `HANDOVER` 之 `C-34`／`W-3` 註記「**預設仍 false…是否改 fail-closed 待 BEAM PMO 定奪**」係**過期記載**（該註記早於 v1.7 之變更）→ **應予更正**。

**選項**：

| 選項 | 內容 |
|---|---|
| **(a) 維持現狀** | Java 預設 `true`（正式環境 fail-closed）＋ 本地 `application-local.yml` 顯式 `false` |
| **(b) 本地亦 fail-closed** | 移除本地之 `:false`（改依 Java 預設 `true`）→ 本地未設環境變數即**要求認證** |

**影響評估（回應 BEAM PMO 之關切「開發測試階段會不會無法繼續」）**：

- 採 (b) 後，本地預設為**要求認證**。惟：
  - 走 `ops/local/env.sh` 時，`sso.env` 已載入 `true` → **現況即為開啟**，服務可正常啟動（`#A-36` 已 **17/17** 實測）。
  - 未帶 token 之 `curl` 驗證（`#A-111`／`#A-113`／`#A-114` 之作法）需**顯式覆寫** `CARDCORE_SECURITY_ENABLED=false`——**此為既有慣例，非新增障礙**。
- **⚠️ 但確有一處會「影響開發」**：若開發者**不經 `env.sh`**（如 IDE 直接啟動）且未提供 `m2m.env`，服務將因「入站啟用＋出站憑證未設定」而**啟動失敗**（`SCS-022 §7.6` 之刻意 fail-closed）。

**建議**：**採 (a) 維持現狀**——理由：fail-closed 之**實質目的（正式環境不靜默放行）已達成**（Java 預設 `true`）；而本地之顯式停用係 `SCS-022 §10 #12` 之**既定設計**，強改為 (b) 只會讓「不經 `env.sh` 之開發」啟動失敗，屬「影響開發」。

**BEAM PMO 裁定**：**同意（有條件）**——「是，但若會影響開發測試則先不改」。

**依裁定之執行**：因 (b) **確會影響**（不經 `env.sh` 之開發將啟動失敗）→ **先不改（維持 (a)）**；並**更正 `HANDOVER` 之過期註記**（載明 fail-closed 已於 v1.7 實作）。

---

## 2. `CorrelationIdFilter` 註冊或退役

**議題**：`CorrelationIdFilter`（`common-spring`）**從未被註冊為 bean**（`#A-59` 之根因），致 `MDC` 恆空、`TraceContext.currentTraceId()` 每次現產亂數——回應看似帶合法追蹤碼，實則與日誌對不上（**「靜默不做」型缺陷**）。現由 `TraceContext` 改以 **OTel traceId 為權威**（`#A-59`）緩解，但**該 filter 本身之去留未定**。

**選項**：

| 選項 | 內容 | 影響 |
|---|---|---|
| **(a) 註冊** | 將 filter 註冊為 bean（`@Component` 或 `FilterRegistrationBean`），於**無 OTel 情境**提供 `correlationId`（如 `X-Correlation-Id` 入站沿用） | 補齊「無 OTel 時之追蹤」；⚠️ 須避免與 OTel 之 `trace_id` **產生兩套值**（`#A-59` 之顧慮） |
| **(b) 退役** | 刪除 filter，追蹤**一律**以 OTel 為準 | 簡化；但**無 OTel 情境**（如未接 collector 之單元／本機）將無入站關聯碼 |

**建議**：採 **(a) 註冊**，但**明確分工**——`correlationId` 僅在**無 OTel span** 時作為**降級值**（`TraceContext` 之既有優先序：OTel traceId → MDC → 臨時值）；且**沿用入站 `X-Correlation-Id`**（若帶）以支援跨系統追蹤。

**BEAM PMO 裁定**：**註冊**。

**依裁定之執行**：✅ **早已實作（2026-09-21／22）**——`CorrelationIdAutoConfiguration`（`@ConditionalOnWebApplication(SERVLET)`）以 `FilterRegistrationBean` 註冊 filter，**顯式**指定 `ORDER`（`LOWEST_PRECEDENCE - 100`）確保晚於 OTel 觀測範圍；已登錄於 `AutoConfiguration.imports`；測試 `CorrelationIdFilterTest`／`TraceContextTest` 齊備；啟動日誌可見 `Filter 'correlationIdFilter' configured for use`。
⚠️ **本輪僅更正**：`CorrelationIdFilter` 之 javadoc 原仍寫「🔴 未被註冊」（**過時且與實作矛盾**）→ 已更正為「已註冊並生效（附歷史）」；`SCS-020 §9.5 #3` 之「待裁定／未擅自註冊」亦已更正。

---

## 3. 日誌 `total-size-cap`

**議題**：結構化日誌（ECS JSON）之**輪轉**中，`max-file-size`（預設 10MB）與 `max-history`（預設 7）皆已生效，惟 **`total-size-cap` 預設 `0B`＝無上限** → 日誌**總量不受總額約束**（`C-30` 之真實殘留顧慮）。

**現況（實測）**：Spring Boot 4.1.1 提供 `logging.logback.rollingpolicy.*`；`total-size-cap` 預設 **`0B`**（無上限）。

**選項**：

| 選項 | 內容 |
|---|---|
| (a) 不設 | 維持無上限（僅受單檔／份數約束） |
| **(b) 設上限** | `logging.logback.rollingpolicy.total-size-cap: 5GB` |

**建議**：採 **(b)**——設 `5GB`，避免長期運行時日誌佔滿磁碟（尤以本機 SSD 為然）。

**BEAM PMO 裁定**：**限制在 5GB SSD 空間**。

**依裁定之執行**：✅ **已執行**——**19 個** `application.yml` 均設 `logging.logback.rollingpolicy.total-size-cap: 5GB`；產生器模板（`gen_service_skeleton.py` 之 `T_APP_YML`／`T_APP_YML_CORE`）同步；`SCS-020` → **1.10**（§9.5 #5，**併更正原建議之錯誤屬性名** `logging.file.total-size-cap` → `logging.logback.rollingpolicy.total-size-cap`）。**19 檔 YAML 解析驗證通過（0 錯誤）**。

---

## 4. 報表下載 `409` 語意

**議題**：報表下載端點（`#A-109` 之代理端點）於「作業未完成／失敗」時回 **`409`**，但暫用 `CC-PLT-3001`（**非法狀態轉換**，`SDD-006 §3.4`）——**語意不完全吻合**（該碼係為 `SDD-005` 之狀態機轉換設計）。`SDD-006 §3.4` 現有 `409` 平台碼僅 **`CC-PLT-2002`（狀態版本衝突）／`CC-PLT-3001`（非法狀態轉換）／`CC-PLT-3002`（終態不可轉換）**。

**選項**：

| 選項 | 內容 |
|---|---|
| (a) 沿用 `CC-PLT-3001` | 不改碼表；語意以訊息補充 |
| **(b) 另立 `CC-PLT-3003`** | 新增「**資源尚未就緒**」語意之 `409` 平台碼 |

**建議**：採 **(b)**——「檔案尚未就緒（`QUEUED`／`RUNNING`／`FAILED`）」與「狀態機非法轉換」**語意不同**；混用會使錯誤處理與告警失準。

**BEAM PMO 裁定**：**是（另立 `CC-PLT-3003`）**。

**依裁定之執行**：✅ **已執行**——`SDD-006 §3.4` 新增 `CC-PLT-3003`（`409` 資源尚未就緒）→ `SDD-006` → **1.10**；`gen_error_codes.py --force` 重生 `ErrorCodes.java`（**錯誤碼 123 → 124**）；`SCS-017` → **1.6**（§6.2 改用 `CC-PLT-3003`）；`ReportJobService.download` 與 `ReportJobServiceTest` 同步；`:services:report-service:test` **BUILD SUCCESSFUL**。

---

## 5. `statement` 帳單 PDF 產生器

**議題**：帳單 PDF（`PDF_REF`）之**儲存媒體已定**（S3 API／本地 Garage，`SAD-006 §3.2`，`#A-106`／`#A-107`），惟 **PDF 產生器本身尚未實作**（需額外函式庫，`SCS-011 §10`）→ 帳單**尚無法產生 PDF**。

**現況**：`report-service` 之物件儲存接線已完成（`#A-107`）；`statement-service` 之**帳單 PDF 產生器未實作**（`SCS-011 §10` 明載）。

**選項（產生器之技術路徑）**：

| 選項 | 內容 | 授權 | 備註 |
|---|---|---|---|
| **(a) Apache PDFBox** | 純 Java、Apache 2.0 | ✅ 寬鬆 | 低階、需自行排版 |
| (b) OpenPDF | `com.github.librepdf:openpdf`，LGPL/MPL | ✅ 可用 | iText 分支、API 較高階 |
| (c) iText 7 | 功能強 | ⚠️ **AGPL／商業** | **銀行案授權風險** |
| (d) HTML→PDF | 以範本轉檔 | 視引擎 | 需額外引擎／字型 |

**建議**：採 **(a) Apache PDFBox**（或 (b) OpenPDF）——**授權寬鬆**、無 AGPL 風險；先出「**帳單摘要 PDF**」（客戶基本資料、帳期、應繳金額、繳費期限、明細條列），**字型須內嵌中文**（否則中文變方框）。**依 `version-compat-verification`** 先查證版本與 Spring Boot 4.1.1 之相容性再鎖版。

**BEAM PMO 裁定**：**必做**——「現有的系統有，微服務的不能少」。

**依裁定之執行**：✅ **已完成（`#A-116`）**——**規格先行**：`SCS-011` → **1.8**（新增 **§8.2 帳單 PDF 產生與物件儲存**）→ **依賴查證**（`version-compat-verification`；Maven Central 實查採 **Apache PDFBox 3.0.8**，Apache 2.0，**避 iText AGPL**）→ 加依賴（`libs.versions.toml` ＋ `statement-service`）→ **實作**（`StatementPdfPort`＋`PdfBoxStatementPdfAdapter`；`ObjectStoragePort`＋`S3StorageConfig`＋`S3ObjectStorageAdapter`；`Statement.withPdfRef`；接線 `StatementGenerationService`）→ **真機驗證**（產生 **35,471 bytes** PDF → 上傳真實 **Garage** → 取回**逐位元組一致**、含中文）。
**併載**：PDF 為衍生物——**失敗不擋帳單**（fail-soft 但不靜默，`§8.2.2`）。
**未竟**：**電子帳單寄送通道**仍為**真阻塞**（供應商未定）。

---

## 附註：後續

- 本清單之 **#2／#3／#4** 為**小而明確**之變更，可**逐項執行**（規格 → 程式 → 測試 → 真機 → 文件 → commit）。
- **#5** 工作量較大，建議**另立交付單元**（比照 `#A-101`／`#A-107` 模式：規格先行 → 依賴查證 → 實作 → 真機驗證）。
- **#1** 依裁定**先不改**，惟須**更正 `HANDOVER` 之過期註記**。

## 修訂記錄

| 版本 | 日期 | 說明 |
|---|---|---|
| 1.2 | 2026-10-01 | **#5 執行完成**——`statement` 帳單 PDF 產生器：`SCS-011` → 1.8（§8.2）；依賴實查採 **Apache PDFBox 3.0.8**（避 iText AGPL）；實作 `StatementPdfPort`／`PdfBoxStatementPdfAdapter` ＋ `ObjectStoragePort`／`S3StorageConfig`／`S3ObjectStorageAdapter`；真機驗證（產生 35,471 bytes → 上傳 Garage → 取回逐位元組一致、含中文）。**5 項裁定全數執行完畢**。 |
| 1.1 | 2026-10-01 | **#2／#3／#4 執行完成**：②`CorrelationIdFilter` **早已實作**（僅更正過時 javadoc）；③19 檔 `application.yml` 設 `total-size-cap: 5GB`（＋產生器模板；`SCS-020` 1.10）；④`CC-PLT-3003` 立碼（`SDD-006` 1.10／`SCS-017` 1.6；錯誤碼 124）。 |
| 1.0 | 2026-10-01 | 初版：BEAM PMO 5 項裁定之紀錄（含選項、建議、影響評估、執行狀態）；併更正 `HANDOVER`「fail-closed 待定奪」之過期記載 |
