# CR-053　卡片級獨立主額度之**參數化額度維度**資料模型

| 項目 | 內容 |
|---|---|
| 文件編號 | CR-053 |
| 版本 | **1.1** |
| 狀態 | **D-1／D-4／D-5 已落地並真機驗證**（2026-10-17，BEAM PMO 授權自主推進）；**D-2 部分**（維度以資料列決定，參數化待第二批）、**D-3 維持既有分層**。詳 §5.1 |
| 觸發 | `CR-052 §4.2`：BEAM PMO 裁定 **C-1 由 (i) 修正為 (ii)「卡片有獨立主額度」**（客戶要求），並要求架構**彈性／參數極大化** |
| 需求依據 | RFP `FR.md §2.4(1)`「歸戶、持卡人、**卡片**調額／查詢」；`CR-043 §10.5`（卡片／附卡／**企業子額度**）；`CR-045`（參數極大化三位一體） |
| 影響模組 | `limit-service` 資料模型（**本 CR 為資料模型設計／裁定；凍結前不動表結構、不動程式**） |
| 關聯 | `CR-052`（語意凍結）／`CR-014`（專用額度資料模型）／`CR-045 §6`（額度多維度規格建議） |

---

## 1. 緣起

`CR-052` 原建議 C-1 採 (i)（額度主體＝帳戶／歸戶），但**開 RFP 之客戶要求「卡片有獨立主額度」**，
BEAM PMO 2026-10-17 裁定**採 (ii)**，並要求以**參數化維度**保留彈性（可支援歸戶共享／卡片獨立等不同客戶口徑），
若窒礙難行則直接採「卡片有獨立主額度」。

依 `CR-052 §3` 原有聲明：「C-1 若採 (ii) → **另立資料模型 CR**」——**本 CR 即該資料模型 CR**。

## 2. 現況與約束（實查，非臆造）

| # | 事實 | 來源 |
|---|---|---|
| F-1 | `account_limits`／`special_limits` 為**帳戶層**——「額度本就以帳戶／歸戶為單位，**非以卡為單位**」，故 V10 **不動**此二表 | `V10__instrument_key.sql` 範圍說明 |
| F-2 | `limit_holds.instrument_id` 已新增（為 BR-16「每卡上限」鋪路），索引 `(instrument_id, status)` 已建 | `V10` |
| F-3 | **既有佔用無 `instrument_id`**，V10 明示「既有佔用**無從回填、不得臆造**」→ 歷史 per-card 明細**不可用** | `V10` |
| F-4 | 專用額度池已具：`special_limits.scope_ref`（用途範圍／MCC 白名單）、`limit_holds.special_limit_id`（佔用之池歸屬）、`hold_type` CHECK 含 `'SPECIAL'` | `V7__special_limit_pool.sql` |
| F-5 | 卡片／附卡／**企業子額度**皆為待決維度 | `CR-043 §10.5` |
| F-6 | **授權佔用／可用額度判斷須走權威即時**；投影僅供查詢（雙軌邊界，BEAM PMO 已確認） | `CR-052 §4.1` |

**→ 核心衝突**：F-1（現行模型：額度非以卡為單位）vs 客戶要求（卡片有獨立主額度）。
**→ 本 CR 任務**：在**相容既有**與**參數化彈性**下，設計可承載多維度（含卡片）之額度模型。

## 3. 建議設計方向（參數化維度）

> 不做「為本次交付硬編卡片維度」，而做「**維度可配置**」——同一套模型滿足本客戶（卡片獨立）
> 與他客戶（歸戶共享），符合 `CR-045` 參數極大化。

```
額度主體維度（可配置）＝ HOUSEHOLD｜ACCOUNT｜PARTY｜CARD｜CORP_SUB
        ↓ 由參數決定該「額度方案」作用於哪個維度（商品參數／系統參數，CR-045）
佔用（limit_holds）攜 instrument_id（V10）＋ special_limit_id（V7 池歸屬）
授權：讀權威即時（§4.1）→ 依參數取「該卡主額度」或「歸戶共享池」
查詢：投影（C-2(b)）帶維度＋ as_of（新鮮度揭露）
```

## 4. 待凍結清單（D-1～D-5）

| # | 待凍結項 | 建議立場 | 依據／影響 |
|---|---|---|---|
| **D-1** | **維度承載方式** | **(a) 於既有 `account_limits` 增 `subject_type`（HOUSEHOLD／ACCOUNT／PARTY／CARD／CORP_SUB）＋ `subject_id`**，既有列補為 `ACCOUNT`（**明確、非臆造**）；可用維度由參數表管理 | 相容 F-1（既有表不動語意、只加欄）／彈性最高。替代 (b) 新建 `card_limits` 分表：維度增加需加表，彈性差 |
| **D-2** | **參數化範圍** | 維度、是否共享、分攤順序**皆由參數承載**（商品參數 × 系統參數，`CR-045`），程式讀參數**不硬編** | 滿足 BEAM PMO「彈性／參數極大化」；參數缺值時 **fail-closed**（不臆造） |
| **D-3** | **與專用額度池（V7）之關係／優先序** | **分層**：主額度（subject 維度）為基底；專用／附加額度（`scope_ref` 用途）疊加或限定用途；佔用時依規則決定動用哪個池 | F-4；優先序未定前 **fail-closed** |
| **D-4** | **回溯／遷移** | 既有帳戶級額度補 `subject_type=ACCOUNT`；**既有卡片之主額度初始值須由客戶提供**（**不得由系統臆造複製**）；歷史 per-card 明細**不可用**並於文件／API 揭露 | F-3（V10 不得臆造回填） |
| **D-5** | **授權與查詢之路徑** | 授權＝**權威即時**（依參數取該卡主額度或歸戶池）；查詢＝**投影**並帶維度＋`as_of`。投影須可事件重放重建＋落後告警 | F-6／`CR-052 §4.1`（已確認）／`CR-031 C-5` 先例 |

**企業子額度（CORP_SUB）**：納入同一參數化維度；其隸屬與分攤語意**待客戶確認**（F-5）。

## 5. 守界（鐵律）

* 本 CR 為**資料模型設計／裁定**；**凍結前不改 `limit-service` 表結構、不動程式**。
* 凍結後路徑：D-1～D-5 裁定 → `SCS-002` 增補 → Flyway 遷移（**新增版本，不改已套用檔**）→ 實作 → 真機驗證
  （以「改權威值 → 真機行為改變」證明閉環）。
* 任何**未知／未定**一律 **fail-closed**，不得臆造維度歸屬或回填歷史。

## 5.1 裁定與執行結果（2026-10-17，`#A-285`）

> **授權基礎**：BEAM PMO 2026-10-17「按照您的建議自主推進」→ 本 CR 之 D-1～D-5 依**建議立場**
> 執行（架構決策層面），涉及客戶業務口徑者仍**fail-closed 待補**（見下表「未達」欄）。

| 項 | 處置 | 落地 | 未達／待補（誠實揭露） |
|---|---|---|---|
| **D-1** 維度承載 | **採 (a)**：`account_limits` 增 `subject_type`／`subject_id`；既有列回填 `ACCOUNT` | `V11__limit_subject_dimension.sql`（含 `BEFORE INSERT` trigger 自動補值、唯一鍵改 `(subject_type, subject_id, currency)`） | `HOUSEHOLD`／`PARTY`／`CORP_SUB` 僅值域預留，**無寫入路徑** |
| **D-2** 參數化範圍 | **部分落地** | 維度以**資料列存在**決定；查無即拒絕（fail-closed） | ⚠️ **「由商品參數決定該商品採 ACCOUNT 或 CARD 維度」尚未實作**——屬**授權路徑**（第二批），需先凍結參數鍵（`limit.model`／`shared_scope` 之語意，`SCS-002 §7.14 A1`）。**本批不臆造參數鍵** |
| **D-3** 與專用額度池之關係 | **維持既有分層**（`V7` 專用池＋`CR-035` 適用性） | 未改動專用額度行為 | 主額度與專用池之**優先序規則**仍未參數化（原建議「優先序未定前 fail-closed」→ 現行沿用既有行為，未新增臆造規則） |
| **D-4** 回溯／遷移 | **採建議**：既有列補 `ACCOUNT`；**不複製**卡片額度 | `V11` 之 `UPDATE ... SET subject_id = account_id`；**無任何 CARD 列自動產生** | 卡片主額度**初始值須客戶提供**（未提供即查無、回 `CC-LIM-1001`）；歷史 per-card 明細仍不可用（`V10`） |
| **D-5** 授權與查詢路徑 | 查詢**走權威即時**（DB 直讀，非投影） | `GET /instruments/{instrumentId}/limits` | 授權路徑之「依維度取值」未改（仍為帳戶維度，待 D-2 參數化）；**投影（C-2(b)）未實作** |

**★ 實作期發現並修正之真缺陷（重要）**：維度化後，`account_limits` 同帳戶會有多列
（`ACCOUNT` ＋ `CARD`）。既有 `restoreUsedAmount`／`reoccupyUsedAmount`／`applyAdjustedAmount`
等 7 處寫入原以 `WHERE account_id = ?` 定位，且「未帶 currency 時僅在恰 1 列才更新」之保守規則
會把「帳戶列＋卡片列」誤判為**多幣別歧義** → **繳款恢復額度永久失效**、且 UPDATE 會**污染卡片列**。
已全部限定 `subject_type='ACCOUNT'`，並以整合測試（`restoreUsedAmountOnlyTouchesAccountDimension`
／`applyAdjustedAmountOnlyTouchesAccountDimension`）鎖住。

**★ 另一實作期教訓**：`subject_id` 若直接設 `NOT NULL`，既有 51 處只帶 `account_id` 的寫入
（事件處理與測試）會全數失敗（實測 51 個測試轉紅）→ 改以 trigger 自動補值 ＋ `CHECK` 保證非空。

**驗證**：`limit-service` **186 測 0 失敗**（新增 11 例真 Oracle 整合測試）；契約 **111 端點／0 錯誤**、
`verify_contract_dto` **不符 0**；`validate_sql` **違規 0**。

## 6. 修訂紀錄

| 版本 | 日期 | 內容 |
|---|---|---|
| **1.1** | 2026-10-17 | **第一批落地（`#A-285`）**：新增 §5.1 裁定與執行結果——**D-1 採 (a)**（`V11` 維度化＋trigger 補值＋唯一鍵改主體界定）、**D-4** 既有列回填 `ACCOUNT` 且**不複製**卡片額度、**D-5** 查詢走權威即時；**D-2 部分**（維度以資料列存在決定；商品參數驅動待第二批）、**D-3 維持既有分層**。★ 揭露並修正兩項實作期缺陷：① 7 處帳戶層寫入未限定 `subject_type` → 會污染卡片列且使「恰 1 列」規則永久失效；② `subject_id` 直接 NOT NULL 會使既有 51 處寫入失敗 → 改 trigger。契約 `GET /instruments/{instrumentId}/limits`；`limit-service` 186 測 0 失敗 |
| 1.0 | 2026-10-17 | 開立：承載 `CR-052 §4.2` 之 C-1=(ii)「卡片有獨立主額度」所需之**參數化額度維度資料模型**；列現況約束 F-1～F-6（V10／V7／CR-043／CR-052 §4.1 實查）與待凍結 D-1～D-5；凍結前不動表結構與程式 |
