# CR-052　卡片級額度調額與查詢——額度多維度與共享池分攤語意凍結清單

| 項目 | 內容 |
|---|---|
| 文件編號 | CR-052 |
| 版本 | **1.5** |
| 狀態 | **C-1～C-6 已凍結**；**C-1(ii)／C-3／查詢已落地**（`#A-285`／`#A-286`，見 §5.1）；**C-2 投影已盤點、現階段不具備開工條件**（見 §5.2／`CR-054`）；C-5／C-6／C-4 預借現金**未做** |
| 觸發 | BEAM PMO 2026-10-17 核准：「ISS-2.4 卡片級——開 CR」＋核准更正 `GOV-006 2.4.4` 定性（`CR-050 §4`） |
| 需求依據 | RFP `FR.md §2.4 信用卡額度管理`（**第 1 點原文**：「歸戶、持卡人、**卡片**調額／**查詢**」）／`GOV-006 2.4.4`（定性已更正：**RFP 已列（FR §2.4(1)）、語意待凍結**） |
| 影響模組 | **本 CR 不動程式、不恢復 stale 端點**——語意凍結後由 SCS（`SCS-002`）／契約（`gen_openapi.py`）承載 |
| 關聯 | `CR-050`（揭露＋裁定）／`CR-043 §10.5`（stale 端點禁令）／`CR-014`（專用額度資料模型）／`CR-045 §6`（額度多維度規格建議） |

---

## 1. 問題陳述與定性更正

RFP `FR.md §2.4`（**信用卡額度管理**）八項子需求，第 1 點明列：

> 1. 歸戶、持卡人、**卡片調額／查詢**
> 2. 單筆限額、日限額、日限次、票證自動加值日限次
> 3. 彈性額度(SHADOW LIMIT)
> 4. 專用額度(如繳稅、保費等)
> 5. 臨時額度
> 6. 預借現金額度(含不可預借現金設定)
> 7. 國旅卡不良戶額度
> 8. 已授權未請款的交易筆數可支援5位數

**定性更正（BEAM PMO 2026-10-17 核准）**：此前 `CR-045`／`GOV-006 2.4.4` 將卡片級查詢記為
「預期需求（**非 RFP 明列**）」——經 `CR-050 §4` 以 RFP 原文揭露，該記載**有誤**；
更正為「**RFP 已列（FR §2.4(1)）、語意待凍結**」。本 CR 即承載該語意凍結。

**現況（2026-10-17 實查）**：

* **已交付（帳戶級）**：`GET /api/v1/accounts/{accountId}/limits`、`/special-limits`、
  `/special-limit-policies`——契約＋`limit-service` 實作＋測試**三重證據齊備**。
* **未交付（卡片級）**：無任何卡片級路徑。`GET /api/v1/cards/{id}/limits` 為 `CR-043`
  已清除之 **stale 端點**（`§10.5` 判例：**禁止以 stale 端點充數**，未來端點須由
  新 CR 與生成器規格建立）——本 CR 即該「新 CR」。
* 專用額度已有資料模型裁定（`CR-014`；`CC_LIM.SPECIAL_LIMITS` 等表已存在於
  `V1__baseline.sql`——「有表、有裁定」≠「卡片級查詢語意已凍結」）。

## 2. 待凍結清單（逐條裁定；凍結前不動程式）

| # | 待凍結項 | 依據／現況 | 候選立場（供裁定） |
|---|---|---|---|
| C-1 | **額度維度模型**：帳戶／歸戶／持卡人／卡片（含**附卡**）／企業子額度之從屬與繼承 | RFP §2.4(1)「歸戶、持卡人、卡片」＋BRD 額度章節；現行 `limit-service` 以**帳戶**為額度主體 | 維度鏈（歸戶→帳戶→卡片）與各層可調整性——待客戶口徑 |
| C-2 | **共享池分攤語意**：卡片級「可用額度」如何由帳戶／歸戶池分攤（**即時計算 vs 事件投影**） | 授權即時性要求（RFP §2.4(8) 已授權未請款 5 位數；`SYS-2.1` 授權額度更新）與投影延遲之取捨 | (a) 查詢時即時彙算（權威在 limit，延遲低但查詢重）；(b) 事件投影（快但須管一致性）——須客戶對「即時性」口徑 |
| C-3 | **API 範圍**：本 CR 先「**查詢**」或含「**調額**」寫入？ | RFP §2.4(1) 兩者並列；帳戶級調整（`JdbcLimitAdjustmentRepository`／special-limit temp adjustment）已存在 | 建議**查詢先行**（風險低、依賴少），調額待 C-1/C-2 凍結後第二批 |
| C-4 | **輸出範圍**：SHADOW LIMIT／臨時額度／預借現金額度是否納入卡片級查詢輸出 | RFP §2.4(3)(5)(6)；`SPECIAL_LIMITS` 表已備部分欄位 | 待客戶逐項確認「卡片級」是否需要逐額度類型可見 |
| C-5 | **資料來源與 ACL**：卡片清單／卡片狀態對 `limit-service` 之取得路徑 | 實查 `cardcore-service-acl.yml`（2026-10-17）：`card-service` 允許清單**僅** `cc-authorization-service`——**limit 無法直呼 card**；且 `limit-service` 自身允許清單（authorization／installment／payment）**不含 card 亦不含 party**——同步直呼路徑**不存在**；既有先例＝事件投影（`party` 卡片狀態投影 `CR-031 C-5`） | (a) 事件投影（與 `CR-031 C-5` 先例一致；卡片狀態/卡片清單由 card 發事件、limit 投影）；(b) 放寬 ACL（影響面大，須安全評估＋`gen_service_acl.py` 同步） |
| C-6 | **批次與 POC 關聯**：POC #8「專用額度」（UT-LIM-020）、#14「授權額度更新」（UT-LIM-040）與本 CR 之驗收關係 | `BRD-004`；`gen_traceability.POC` | 本 CR 凍結後，上述 POC 之驗收劇本是否需補卡片級案例——待凍結後定 |

## 3. 建議立場（架構裁定；開發團隊 2026-10-17 擬，**待 BEAM PMO 核准**）

> 僅就**架構可判定**之 C-1／C-2／C-3／C-5 擬立場；C-4、C-6 仍有待客戶／POC 口徑，維持待裁定。
> 每項皆附**實查證據**（V7／V10 遷移、ACL、既有程式），並揭露**回溯資料缺口**——**不臆造**。

| 項 | 建議立場 | 依據（實查／原文／先例） | 待補（客戶口徑） |
|---|---|---|---|
| **C-1** 維度模型 | **額度主體維持帳戶／歸戶**（`account_limits`／`special_limits` **不動**）；卡片維度以 `limit_holds.instrument_id` 承載（V10 既有）。「卡片級可用」＝**共享池剩餘**；「該卡已用」由 `instrument_id` 彙總 → 提供 **per-card 使用明細**（**非** per-card 上限）。若客戶要求卡片有**獨立子額度**（附卡限額／企業子額度）→ 屬 C-1 擴充，**另立資料模型 CR** | **V10 範圍說明明示**：「`account_limits`／`special_limits` 為**帳戶層**（額度本就以帳戶／歸戶為單位，**非以卡為單位**），故不動」；V10 新增 `limit_holds.instrument_id` 正是為 BR-16「每卡上限」鋪路。**V7** 已有專用額度池（`special_limits.scope_ref` 用途範圍、`limit_holds.special_limit_id` 池歸屬） | 客戶要的是 **(i) 共享池下查該卡可用** 還是 **(ii) 卡片有獨立子額度** |
| **C-2** 共享池分攤 | **(a) 查詢時即時彙算**（不走投影）。★ **揭露回溯缺口**：既有佔用**無** `instrument_id`（V10「先可空＋建索引；既有佔用**無從回填、不得臆造**」）→ per-card 明細**僅對 V10 後之新佔用有效**，**歷史不得回填** | V10 已建 **`idx_holds_instrument (instrument_id, status)`** 索引，支援即時彙總；RFP §2.4(8)「已授權未請款筆數支援 5 位數」＝即時性要求；**額度正確性為風控底線——寧可查得慢，不可查錯**；投影有延遲風險 | 客戶對即時性之容忍（若要求極低延遲且量極大，再議投影） |
| **C-3** API 範圍 | **查詢先行**：先交付卡片級可用額度查詢（`GET`，唯讀）；調額（寫入）待 C-1／C-2 凍結後第二批 | 帳戶級調整既有（`JdbcLimitAdjustmentRepository`／`LimitAdjustmentService`）；查詢為唯讀、風險低、可獨立驗收，符合「**先低複雜度**」排序原則（`GOV-006` 1.69 WBS B1 排序） | 無（架構可定） |
| **C-5** ACL／資料來源 | **(a) 事件投影**，但**限縮範圍**為「**instrument ↔ 帳戶／歸戶對映**」之輕量投影；**不做**全卡片狀態投影（避免過度設計） | ACL 實查：`card-service` 允許清單**僅** `cc-authorization-service`；`limit-service` 自身允許清單（authorization／installment／payment）**不含 card 亦不含 party** → **同步直呼路徑不存在**；先例 `CR-031 C-5`（party 卡片狀態投影）。又因 C-2 採即時彙算，「可用額度」本身只需 `instrument_id` 彙總，投影僅供「**帳戶有哪些卡**」對映 | 無（架構可定） |

**守界**：本節為**建議**，非已定案；核准後方進入 `SCS-002` 增補 → 契約（`gen_openapi.py`）。核准前**不補端點、不動程式、不建表、不恢復 stale 路徑**；
實作後須以「改權威值 → 真機行為改變」證明閉環（不讀快取充數）。

## 4. BEAM PMO 裁定結果（2026-10-17）— C-1～C-6 全數凍結

| 項 | 裁定 | 與建議之差異 | 落地影響（待 SCS 承接） |
|---|---|---|---|
| **C-1** | **同意**（採建議：額度主體維持**帳戶／歸戶**；卡片維度由 `limit_holds.instrument_id` 承載 → **per-card 使用明細**，非 per-card 主額度） | 一致 | 不需新增卡片級額度主檔；卡片「獨立子額度」若客戶日後要求 → **另立資料模型 CR** |
| **C-2** | **(b) 事件投影**（**推翻建議 (a) 即時彙算**） | 建議 (a) → 裁定 (b) | 卡片級可用額度由**讀模型投影**提供；★ 須守下方 **§4.1 雙軌邊界**（授權不得讀投影） |
| **C-3** | **含額度寫入**（查詢＋調額寫入，不限查詢） | 建議「查詢先行」→ 裁定**含寫入** | SCS 須增補**卡片維度調額寫入**語意；★ 與 C-1 之張力見 **§4.2**（建議解讀，待確認） |
| **C-4** | **納入卡片級查詢輸出**（SHADOW LIMIT／臨時額度／預借現金額度皆納入） | 建議留待客戶 → 裁定**納入** | 查詢回應須包含上述額度類型與其可用額；須定義各類型之「可用」計算口徑 |
| **C-5** | **(a) 事件投影**（限縮為 instrument ↔ 帳戶／歸戶對映） | 一致 | 輕量投影；不做全卡片狀態投影 |
| **C-6** | **需補卡片級案例**（POC #8 專用額度、#14 授權額度更新） | 建議留待 POC → 裁定**補** | `BRD-004` 該二情境須增列卡片級驗收案例 |

### 4.1 ★ C-2＝(b) 投影之風險與**雙軌邊界**（風控底線，必須守）——**BEAM PMO 2026-10-17 確認＝是**

裁定改採投影後，必須明訂此邊界，否則有**超額風險**：

* **投影僅服務「查詢」**（客服／報表／持卡人 App 等**人讀**場景）；
* **授權佔用與可用額度判斷，仍須走權威即時路徑**（現行 `authorization → limit` 同步佔用／`account_limits`＋`special_limits`＋`limit_holds`），
  **不得以投影替代**——額度正確性是風控底線，寧可查詢慢，不可授權算錯。
* **一致性治理**：投影須帶 `as_of`（投影時間戳／事件序號）並**於 API 回應揭露**，讓消費端知悉資料新鮮度；
  須有「投影落後」監控告警（積壓／延遲）。
* **可重建**：投影採冪等 upsert＋亂序防護，可由事件重放重建（比照 `CR-031 C-5` 先例）。
* **回溯缺口仍在**（V10：既有佔用無 `instrument_id`、**不得臆造回填**）→ 歷史 per-card 明細不可用，須於文件或 API 註明。

### 4.2 ★ C-1 之最終裁定（2026-10-17 BEAM PMO）：採 **(ii) 卡片有獨立主額度**，但以**參數化維度**保留彈性

BEAM PMO 裁定：**開 RFP 之這家客戶要的是「卡片有獨立主額度」**；惟希望架構**彈性**（參數極大化），
若窒礙難行則採「卡片有獨立主額度」方案。

* **C-1 由 (i) 修正為 (ii)**：卡片（instrument／card）**有自己的主額度**——此與 V10「額度本就以帳戶／歸戶為單位、
  **非以卡為單位**」之現行模型**直接衝突**，屬**資料模型變更**。
* **→ 依本 CR §3 之原有聲明，C-1=(ii) 須「另立資料模型 CR」**：已開立 **`CR-053`**
  （卡片級獨立主額度之**參數化額度維度資料模型**），承載維度模型、參數化範圍、遷移與回溯等設計裁定。
* **彈性／參數極大化之落法**（由 `CR-053` 承載）：額度「主體維度」（歸戶／帳戶／持卡人／**卡片**／企業子額度）
  **可配置**，使同一套模型既能滿足本客戶「卡片獨立主額度」，亦能支援他客戶「歸戶共享」——
  **不以硬編維度換取本次交付**。
* **本 CR 邊界**：CR-052 凍結**語意**；**資料模型與遷移由 `CR-053` 承接**。CR-053 凍結前，
  **不動 limit-service 之表結構、不動程式**。

## 5. 凍結後之交付路徑（鐵律）

```
C-1～C-6 BEAM PMO／客戶逐條凍結 → SCS-002（額度服務規格增補）→ SDD-001 §3.4／契約（gen_openapi.py）
→ 實作（含 ACL／投影之架構裁定落地）→ 真 Oracle／真機驗證 → 追溯（GAPS 除名、BRD-002/GOV-004 重生）
```

★ **守界**：不恢復 `GET /api/v1/cards/{id}/limits` stale 路徑（`CR-043 §10.5`）；
**未凍結前不動程式、不建表、不補端點**（`GOV-006 2.4.4` 依賴列不變）；
查詢實作須以「改權威值→真機行為改變」證明閉環，不讀快取充數。

## 5.1 執行結果（2026-10-17，`#A-285`／`#A-286`）
| 項 | 落地 | 證據 | 未達（誠實揭露） |
|---|---|---|---|
| **C-1 (ii)** 卡片獨立主額度 | ✅ 資料模型 | `CR-053` D-1：`V11` 維度化（`subject_type`／`subject_id`＋trigger） | `HOUSEHOLD`／`PARTY`／`CORP_SUB` 僅值域預留 |
| **C-3 含額度寫入** | ✅ 調額維度化 | `V12`（`limit_adjustments` 加維度）＋`POST /limit-adjustments` 帶 `instrumentId` → 只改 CARD 列；無 CARD 列時核准後建立（客戶提供初始值之唯一途徑） | 卡片級**不支援** `SPECIAL`（專用池為帳戶層，已擋）；卡→帳戶歸屬**未驗證**（本服務無對映能力） |
| **查詢**（RFP §2.4(1)） | ✅ | `GET /instruments/{instrumentId}/limits`（`#A-285`） | `availableAmount` 為**保守下界**（卡片級已用無權威來源） |
| **C-2 (b)** 事件投影分攤 | ❌ 未做 | — | 需先凍結分攤規則；本批**不臆造** |
| **C-4** 查詢輸出納入 SHADOW／臨時／預借現金 | 🟡 部分 | 已輸出 permanent／temporary（有效）／shadow | **預借現金**無資料來源（未建模）→ 未輸出 |
| **C-5 (a)** 投影限縮為 instrument↔帳戶對映 | ❌ 未做 | — | 現行查詢走權威即時，**不需**投影即可運作 |
| **C-6** 補卡片級 POC 案例 | ❌ 未做 | — | 待 POC 情境清單口徑 |

**★ 實作期之關鍵守界（勿重犯）**：卡片級調額**不發射** `limit.limit.adjusted.v1`
——該事件 payload 為「**帳戶總額度**」，若以卡片額度送出，授權讀模型 `account_limit_caches`
之帳戶總額度會被覆蓋（超額放行或誤拒）。卡片額度之授權取值走即時查詢（`SCS-002 §7.16.3`）。

### 5.2 C-2 投影：**前置盤點已完成，現階段不具備開工條件**（`CR-054`）

BEAM PMO 2026-10-17「先做 C-2 投影的前置盤點」→ 已產出 **`CR-054`**（盤點與三重缺口）。要點：

1. **分攤前提已被 C-1(ii) 改變**——卡片有獨立主額度後，「分攤」僅存在於**仍走共享池**的商品，
   而「哪些商品走共享池」屬 **D-2**（未做、待客戶口徑）→ **分攤規則無所依附**。
2. **per-card 佔用資料覆蓋率＝0%**——真 Oracle 實查 **34 筆佔用全數無 `instrument_id`**
   （29 筆仍 `HELD`），且 `V10` **不得回填**。
3. **事件帶不出載體**——`limit.hold.created.v1`／`released.v1` 之 payload **無 `instrumentId`**
   （`SDD-006 §4.2` 權威定義即無）；程式之 `hold()` **有**收到 `instrumentId`、權威表也寫了，
   但**未傳入**事件工廠 → 「**權威表有、事件沒有**」。
4. 投影表（`CC_AUTH.limit_holds`）亦**無** `instrument_id`；PostgreSQL `proj` **為空**
   （既有投影皆在服務本地 Oracle，非 Postgres）。

**→ 待裁定 Q1～Q5（見 `CR-054 §5`）**，其中 **Q1（事件補 `instrumentId`）** 為後續一切之先決；
建議批次 **P1（事件補欄）→ P2（投影表加欄）→ P3（投影查詢＋告警）→ P4（分攤，待 D-2）**。

## 6. 修訂紀錄

| 版本 | 日期 | 內容 |
|---|---|---|
| **1.5** | 2026-10-17 | **C-2 投影前置盤點完成**（新增 §5.2）：產出 **`CR-054`**——揭露 **三重缺口**（① per-card 佔用資料覆蓋率 **0%**：34/34 無 `instrument_id`；② 事件 payload 無 `instrumentId`，「權威表有、事件沒有」；③ 投影表無該欄）＋ **分攤前提已被 C-1(ii) 改變、依賴 D-2**。判定**現階段不具備開工條件**；列 Q1～Q5 待裁定與 P1～P4 分批 |
| **1.4** | 2026-10-17 | **C-1／C-3／查詢已落地**（新增 §5.1）：`V11` 維度化（`#A-285`）＋`V12` 調額單維度化（`#A-286`）＋`GET /instruments/{instrumentId}/limits`；卡片級調額只改 CARD 列、**不發** `limit.limit.adjusted.v1`（避免覆蓋帳戶總額度）。★ **未達**：C-2 投影分攤、C-5 投影限縮、C-6 POC 案例、C-4 之預借現金（無資料來源） |
| **1.3** | 2026-10-17 | **二處確認結果**：① `§4.1` 雙軌邊界**確認＝是**（投影僅供查詢、授權走權威即時）；② `§4.2` **C-1 由 (i) 修正為 (ii)「卡片有獨立主額度」**（客戶要求；以參數化維度保留彈性）→ 依原聲明**另立 `CR-053`**（參數化額度維度資料模型）。CR-052 凍結語意，**資料模型／遷移由 CR-053 承接** |
| **1.2** | 2026-10-17 | **BEAM PMO 裁定 C-1～C-6 全數凍結**（§4）：C-1 同意；**C-2 改 (b) 事件投影**（推翻建議 (a)）；C-3 **含額度寫入**；C-4 **納入**卡片級查詢輸出；C-5 (a)；C-6 **補**卡片級 POC 案例。★ 新增 **§4.1 雙軌邊界**（投影僅供查詢、**授權不得讀投影**）與 **§4.2 語意張力之建議解讀（待確認）**。下一步：`SCS-002` 增補 |
| **1.1** | 2026-10-17 | **新增 §3 建議立場**（開發團隊擬，**待 BEAM PMO 核准**）：C-1 額度主體維持帳戶／歸戶、卡片維度由 `limit_holds.instrument_id` 承載（V10）；C-2 即時彙算不走投影，並**揭露回溯缺口**（既有佔用無 `instrument_id`、歷史不得回填）；C-3 查詢先行；C-5 事件投影但限縮為 instrument↔帳戶對映。C-4／C-6 仍待客戶／POC 口徑 |
| 1.0 | 2026-10-17 | 開立（BEAM PMO 核准）：承載 `ISS-2.4` 卡片級額度調額／查詢之語意凍結清單 C-1～C-6；記載 `GOV-006 2.4.4` 定性更正（RFP 已列）；C-5 揭露 ACL 架構約束（card→limit 無直呼路徑，投影為既有先例） |
