CR #202 » CR-001_帳戶信用額度主檔.md
CR-001 補建「帳戶信用額度主檔」
| 項目 | 內容 |
|---|---|
| 文件編號 | CR-001 |
| 版本 | 1.0 |
| 狀態 | 待 SA 核定 |
| 提出日期 | 2026-09-19 |
| 提出者 | 開發團隊(授權服務實作時發現) |
| 影響文件 | SDD-001(ER 設計)、SDD-006(契約)、SAD-003(資料架構) |
| 影響服務 |
limit-service(主檔擁有者)、authorization-service(主要消費者) |
| 優先級 | 高(P1)——授權核心功能之阻斷性缺口 |
1. 摘要
SDD-001 之 ER 設計未包含「帳戶信用額度主檔」,導致授權服務在執行「可用額度檢核」時
無資料來源可判斷。目前僅能以本地讀模型權宜承接,屬臨時方案,須正式補建主檔。
2. 現況(含實測證據)
以下皆為 2026-09-19 於本地 Oracle 26ai(FREEPDB1)實測之結果,非推測。
2.1 帳戶主檔無額度欄位
CC_PARTY.ACCOUNTS 之全部欄位:
ID, ACCOUNT_NO, CIF_NO, ACCOUNT_TYPE, BLOCK_CODE,
STATEMENT_CYCLE, STATEMENT_DAY, STATUS, CREATED_AT, UPDATED_AT, VERSION
→ 完全沒有任何額度相關欄位。
2.2 全庫搜尋亦無額度欄位
select owner, table_name, column_name from all_tab_columns
where owner like 'CC\_%' escape '\'
and regexp_like(column_name,'LIMIT|CREDIT|AVAILABLE');
結果僅命中兩項與信用額度無關之欄位:
-
CC_PAYMENT.PAYMENTS.LIMIT_RESTORED(繳款已回復額度) -
CC_STMT.STATEMENTS.PAYMENTS_CREDITS(帳單貸項)
2.3 CC_LIM 僅有兩張表,且皆非信用額度主檔
| 表 | 用途 |
|---|---|
LIMIT_HOLDS |
額度佔用紀錄(授權時凍結) |
SPECIAL_LIMITS |
特定用途額度(非一般信用額度) |
2.4 實測:SPECIAL_LIMITS 無法充當信用額度
SPECIAL_LIMITS.PURPOSE 之 CHECK 約束實測為:
purpose IN ('TAX','INSURANCE','TUITION','MEDICAL','OTHER')
以 PURPOSE='CREDIT' 插入將觸發 ORA-02290(已實測)。
⚠️ 此點特別重要:先前曾考慮以
SPECIAL_LIMITS權宜充當信用額度,
實測證明不可行。任何文件若留有此建議應予更正。
3. 缺口說明
「可用額度」之定義為:
可用額度 = 信用額度 − 已用額度 − 未到期之佔用
其中**「信用額度」與「已用額度」無處存放**,使授權之 LIMIT 檢核無從實作。
4. 影響分析
| 面向 | 影響 |
|---|---|
| 功能 | 授權之「可用額度檢核」無法依權威資料執行 |
| 架構 | 違反 SAD-002 bounded context——額度應由 limit-service 擁有並供應 |
| 資料 | 違反 SAD-003——權威資料應有明確歸屬,消費者透過讀模型或 API 取得 |
| 稽核 | 無信用額度歷程,無法還原「決策當時之額度」,爭議時難以舉證 |
| 風險 | 若僅依赖各服務自建讀模型,將產生多套不一致之額度真相 |
5. 建議方案
5.1 於 CC_LIM 新增 ACCOUNT_LIMITS(由 limit-service 擁有)
存放一般信用額度,與 SPECIAL_LIMITS(特定用途額度)明確區分。
5.2 供應方式
| 對象 | 方式 | 依據 |
|---|---|---|
| 授權等強一致性需求 |
limit-service 提供 API(OpenFeign) |
SAD-002 |
| 查詢/報表 | 事件(limit.limit.changed.v1)同步至讀模型 |
SAD-003 CQRS |
5.3 欄位設計(建議)
欄位以契約 LimitView 為準,採三層額度設計:
CREATE TABLE CC_LIM.account_limits (
id RAW(16) DEFAULT SYS_GUID() NOT NULL PRIMARY KEY,
account_id RAW(16) NOT NULL,
currency CHAR(3 CHAR) NOT NULL,
permanent_amount NUMBER(19,0) DEFAULT 0 NOT NULL, -- 永久額度(分)
temporary_amount NUMBER(19,0) DEFAULT 0 NOT NULL, -- 臨時額度(分)
temp_start_date DATE, -- 臨時額度起日
temp_end_date DATE, -- 臨時額度迄日(到期自動失效)
shadow_amount NUMBER(19,0) DEFAULT 0 NOT NULL, -- 彈性額度(分)
used_amount NUMBER(19,0) DEFAULT 0 NOT NULL, -- 已用額度(分)
status VARCHAR2(64 CHAR) DEFAULT 'ACTIVE' NOT NULL,
created_at TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
updated_at TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL,
version NUMBER(10) DEFAULT 0 NOT NULL,
CONSTRAINT uk_account_limits_key UNIQUE (account_id, currency)
);
可用額度 = 永久 + 臨時(有效期內) + 彈性 − 已用 − 未釋放之佔用
表名複數、含
id/created_at/version,符合CSP-001 §5SQL-04/SQL-05。
金額一律以「分」之整數儲存,不用浮點(SAD-003 DP-03)。
臨時額度到期失效對齊SDD-005 §8額度調整狀態機。
實作狀態:已於 limit-service 之 V2__account_limits.sql 建立(Oracle 實測)。
6. 影響範圍與回改清單
核定後須同步調整:
| # | 項目 | 說明 |
|---|---|---|
| 1 |
SDD-001 ER 設計 |
新增 ACCOUNT_LIMITS 實體與關係 |
| 2 |
limit-service 契約 |
新增額度查詢/調整之 API 與事件 |
| 3 | authorization-service |
讀模型 account_limit_caches 改由事件或 API 供料,移除種子資料 |
| 4 | ops/local/init/oracle/02-dev-setup.sql |
測試資料改由 ACCOUNT_LIMITS 種入 |
| 5 |
V2__read_model.sql 註解 |
移除「權宜承接」之說明 |
7. 目前權宜做法(待本 CR 核定後替換)
為使授權流程可驗證,authorization-service 暫以自己的 CQRS 讀模型
(card_status_caches/account_limit_caches/limit_holds)承接所需資料,
由 V2__read_model.sql 建立、本地以種子資料填充。
此做法符合 SAD-003 CQRS 精神(消費者維護讀模型),
但未解決「權威主檔不存在」之根本問題,故仍須核定本 CR。
8. 建議
- 優先級 P1:此為授權核心功能之阻斷性缺口,建議於 Sprint 4 內核定
- 若時程受限,至少先確認
ACCOUNT_LIMITS之欄位與擁有者歸屬,
使讀模型之供料來源有明確對口
9. 修訂記錄
| 版本 | 說明 |
|---|---|
| 1.0 | 初版:授權服務實作時發現缺口,提出補建建議 |