Project

General

Profile

CR #237 » CR-036_8-6繳款截止日之精確化.md

內容更新:內部稱謂去識別化(2026-10-18) - Redmine Admin, 10/18/2026 05:32 AM

 

CR-036 8-6 之「繳款截止日」精確化——改以帳單出帳事件校正

項目 內容
文件編號 CR-036
版本 1.0
狀態 ✅ 已裁定並執行完畢
提出日 2026-10-02
提出者 WorkBuddy AI(開發團隊)
緣起 BEAM PMO:「「精確的繳款截止日」<- 是的,麻煩您直接執行!」
前案 CR-035 §2.4(8-6/8-7)——該處之迄日為推算值(DERIVED),本 CR 收斂之
關聯 BRD-001 §5.4 BR-04-02、BRD-004 POC-8 8-6、SAD-002 §3.2、SAD-004 §5.2/§5.3、SCS-002 §7.12、SCS-011
嚴重度 🟡 中——影響「調高至繳款截止日 + 7 日」之正確性(推算值可能與實際截止日相差近一個帳單週期)

1. 問題:推算值為何不精確

CR-035 §2.4 之 8-6 於請款入帳時觸發,迄日以「入帳日 + 帳單週期(25) + 7 日」推算。

誤差來源:真正的繳款截止日 =「該筆稅款所屬帳單之帳單日 + 25 天」。
而稅款落在哪一期帳單,取決於「入帳日是否已過該歸戶之帳單日」——
推算式一律以「入帳日」當作帳單日 → 最長可高估近一個帳單週期(若入帳日恰在帳單日之後)。

為何不能直接算:ACCOUNTS.STATEMENT_DAY(帳單日)在 CC_PARTY,
而 limit-service 之 schema 為 CC_LIM —— 跨 schema 讀取為架構級禁止(SAD-003/SQL-07)。


2. ★★ 關鍵洞察:精確值在原理上只有帳單出帳後才存在

在帳單出帳之前,「該筆稅款屬於哪一期帳單」尚未確定——故任何在請款當下算出的值都是猜測。

→ 正解不是「算得更準」,而是「在精確值出現時校正」。


3. 裁定:兩階段(調高 → 校正)

階段 觸發 動作 due_date_source
① 調高 posting.transaction.posted.v1(帶 authorizationId) temporary_amount += 金額;raise_until 以推算值先給 DERIVED
② 校正 statement.statement.issued.v1 以帳單之權威 paymentDueDate 覆寫 raise_until = paymentDueDate + 7;並同步 account_limits.temp_end_date STATEMENT

3.1 ★ 校正之歸屬條件(避免套錯期別)

只有「在該筆調高之後才出帳」的帳單,才是承載該筆稅款的帳單。

故校正條件為:status='OPEN' 且 due_date_source='DERIVED' 且 raised_on ≤ 帳單出帳日。

  • 若帳單在調高之前已出帳(raised_on > 出帳日)→ 略過(該期不承載此筆;下一期才是)。
  • 校正後標記 STATEMENT → 不重複校正(冪等)。

「帳單出帳日」之來源:事件信封之 occurredAt(該事件即「出帳」之事實)——
不需由 paymentDueDate − 25 反推(那會把 25 天慣例硬編進程式)。

3.2 契約:無需變更

statement.statement.issued.v1 之 payload 早已包含所需欄位
(statementId/accountId/statementMonth/totalAmount/minimumDue/paymentDueDate/currency)
——不需為本 CR 增欄,亦不升版。

3.3 temp_end_date 之同步

校正後,account_limits.temp_end_date = 該歸戶所有 OPEN 串動紀錄之 raise_until 最大值
(取最晚者:不得因校正某一筆而縮短另一筆之窗口)。


4. 架構變更:新增一組事件訂閱

文件 變更
SAD-004 §5.2 statement.statement.issued.v1 之消費者 notification → notification + limit
SAD-002 §3.2 limit-service 之「事件(訂閱)」補 statement.statement.issued.v1

理由:8-6 之迄日語意即「帳單之繳款截止日 + 7 日」——
帳單為 statement-service 之權威,limit-service 作為消費者維護其所需之最小事實
(僅取 accountId/paymentDueDate/occurredAt),符合 SAD-003 CQRS 讀側原則,
不新增任何同步呼叫、不開放任何 ACL。


5. 實作範圍

  1. SpecialLimitTempAdjustmentRepository:新增 findOpenDerivedRaisedOnOrBefore(accountId, date)
    與 applyDueDateCorrection(id, until)(只改 raise_until/due_date_source,
    不動 raised_amount/recovered_amount)。
  2. LimitRepository:新增 updateTemporaryEnd(accountId, currency, until)。
  3. SpecialLimitTempAdjustmentService#correctDueDate(accountId, statementIssuedOn, paymentDueDate)。
  4. StatementIssuedListener(新 Kafka 消費者,主題 cc.statement.statement.issued)。
  5. 規格:SCS-002 §7.13;SAD-004 §5.2;SAD-002 §3.2。
  6. 測試與真機驗證。

不做:limit-service 不快取「最近一期帳單」之狀態——本校正為事件驅動之單次覆寫,
不需維護讀模型(無新表)。


6. 已知限制(誠實揭露)

  1. 若該歸戶長期不出帳(如停用),raise_until 將停留在推算值(DERIVED)——
    可由 due_date_source 辨識並人工處理。
  2. 8-7 之回收不動日期:回收只調降 temporary_amount;temp_end_date 於全部回收後
    可能殘留(不影響金額,僅影響窗口語意)——已列 SCS-002 §10。
  3. 多幣別:校正以串動紀錄自身之 currency 為準(同 8-7 之作法);
    繳款/帳單事件之 currency 若為 null 亦不影響(不臆測)。
  4. 僅「首次出帳」校正:若同一筆因故跨兩期帳單,本設計取第一期(raised_on 之後的
    第一份帳單)——與「稅款落在第一期帳單」之會計慣例一致。

7. 修訂記錄

版本 日期 修訂內容
1.0 2026-10-02 初版:診斷推算值之誤差來源與「跨 schema 不可讀」之限制;★ 關鍵洞察:精確值在原理上只有帳單出帳後才存在 → 裁定採兩階段(調高 → 校正);訂定校正歸屬條件(raised_on ≤ 出帳日);確認契約無需變更;載明架構變更(SAD-004 §5.2 新增 limit 為 statement.issued.v1 之消費者);實作範圍與四項已知限制
    (1-1/1)