fix(cash): select cash-balance sync targets by explicit kpi_code whitelist

The voucher-import linkage branch picked write targets by kpi_name LIKE '%cash%' and wrote the monetary-fund ledger balance (yuan) into derived KPIs (F_OP_CFLOW / F_FCF / F_BEP_REVENUE_CASH / F_BEP_COVER_CASH). Replace with an explicit kpi_code whitelist plus a unit/caliber gate that refuses writes on mismatch and reports them via kpi_sync_skipped.

Read-only equivalence probe (real function + intercepted writes + rollback) before/after: before wrote 4 derived KPIs, after writes only F_CASH_SAFETY. tests: +9 new cases; pytest failure set identical to baseline (15/15 same ids).
This commit is contained in:
Hermes CI Fix
2026-09-14 20:37:12 +08:00
parent 8693c8e342
commit 1f7be6b5ae
3 changed files with 292 additions and 18 deletions
@@ -122,6 +122,7 @@ curl -s -H "Authorization: Bearer $TOKEN" "http://127.0.0.1:8010/api/cma/cash/da
"carry_forward_count": 2,
"cash_balance": 88.88,
"kpi_updates": [{"kpi_code": "EXT_069", "kpi_name": "库存现金", "period": "2026-08", "value": ...}, ...],
"kpi_sync_skipped": [{"kpi_code": "...", "kpi_name": "...", "unit": "万元", "reason": "unit_mismatch: ..."}],
"batch": "2026年08月网银流水_20260828153000",
"entity_id": 1
}
@@ -132,8 +133,10 @@ curl -s -H "Authorization: Bearer $TOKEN" "http://127.0.0.1:8010/api/cma/cash/da
## 六、现金流联动(导入成功自动触发)
1. **现金余额自动更新**:汇总 1001/1002 开头科目(排除结转行)`Σ借 - Σ贷` 得货币资金期末余额(元)→ `set_current_cash_balance`(万元)→ `GET /api/cma/cash/balance` 的 `current_cash` 实时反映
2. **EXT_现金类KPI**:名称含"现金"/"货币资金"的 active KPI(排除 F_CASH_SAFETY)写入/更新 `kpi_values`(source_type="ledger"、data_status="verified"、remark 记录批次与明细口径)——库存现金类→1001余额,银行类→1002余额,其余→货币资金总额
3. **F_CASH_SAFETY 现金安全垫KPI**(万元):不存在则自动创建(formula=货币资金余额-短期借款);短期借款取 EXT_139 最新实际值(单位元÷10000),无数据时安全垫=货币资金余额
2. **现金余额类KPI(显式白名单)**:只写 `app/api/cash.py` 中 `CASH_SYNC_KPI_WHITELIST` **显式登记的 kpi_code**(当前:`EXT_069` 库存现金→1001 科目净额、`EXT_089` 银行存款→1002 科目净额;登记形态为 `(科目选择器, 期望单位)`,选择器 `None` = 货币资金合计),且该 KPI 需 `status=active`;写入 `kpi_values`(`source_type="ledger"`、`data_status="verified"`、remark 记录批次/明细口径与选择器)。
- **禁止名称模糊匹配**:原按 `kpi_name LIKE '%现金%'/'%货币资金%'` 选取写入目标,会命中 `F_OP_CFLOW`/`F_FCF`/`F_BEP_REVENUE_CASH`/`F_BEP_COVER_CASH` 等派生指标并写入元值(2026-09-14 修复)。新增联动目标必须先把用途登记进白名单。
- **单位口径闸门**:目标 KPI 的 `unit` 与写入口径(元)不符 → **拒绝写入** + WARNING 日志 + 记入返回体 `kpi_sync_skipped`(防万元/百分比误写元值),不触碰主值面。
3. **F_CASH_SAFETY 现金安全垫KPI**(万元):按 `kpi_code` 精确匹配(不再用名称兜底),不存在则自动创建(formula=货币资金余额-短期借款);`unit != 万元` 时拒写并告警;短期借款取 EXT_139 最新实际值(单位元÷10000),无数据时安全垫=货币资金余额
---