fix(cvp): O1 residue - e2 rebate_policy_pct 置 null(口径单一源 = bep_caliber)
ci/woodpecker/push/main Pipeline failed

问题:/bep-card 端点对 e2(博海)回落模块内硬编码常量 BEP_REBATE_POLICY_PCT=84.61,
而 bep_caliber.ENTITY_CALIBERS[2]["policy_pct"] 为 None(博海无渠补科目)⇒ 下游 API
消费者会把 payload 里的 rebate_policy_pct=84.61 误读为「博海有 84.61% 政策渠补率」。

改动(严格限定 dashboard.py 一个模块 + 1 条守护用例):
- 删除模块级常量 BEP_REBATE_POLICY_PCT;四处回落分支改为直接取口径值
  (未注册口径分支置 None;其余取 cal.get("policy_pct") / 已算出的 policy_pct)。
- 口径单一事实源维持 app/utils/bep_caliber.py,端点不做任何回落。
- 新增 tests/test_bep_rebate_actual_caliber.py::test_o1_policy_pct_single_source_no_hardcoded_fallback
  (改前必红 / 改后必绿,e1=84.61 作同端点负对照)。

改前/改后(端点函数直调,生产库只读,e1/e2 同批):
  改前 e2 inputs.rebate_policy_pct = 84.61 → 改后 null;e1 恒为 84.61(负对照不变)。
This commit is contained in:
Hermes CI Fix
2026-10-04 22:37:20 +08:00
parent 587d5b3983
commit 3ed9fa0611
2 changed files with 32 additions and 9 deletions
@@ -345,3 +345,22 @@ def test_acceptance_probe_2026_08(db):
for name, got, want, tol in checks:
assert got is not None, f"{name}: got None, want {want}±{tol}"
assert abs(float(got) - want) <= tol, f"{name}: got {got}, want {want}±{tol}"
# ── 五、O1 收敛(2026-10-04):政策渠补率口径单一源,端点不得回落硬编码常量 ────────
def test_o1_policy_pct_single_source_no_hardcoded_fallback():
"""O1:dashboard 模块不得再定义硬编码政策常量;policy_pct 唯一来源 = bep_caliber。
改前(HEAD 587d5b3):`dashboard.BEP_REBATE_POLICY_PCT == 84.61` 且端点对 e2 回落该常量
⇒ 本用例第一条断言必红(改前/改后判据,非事后追认)。
改后:无该属性;e1 = 84.61(同端点负对照)、e2 = None(无渠补科目)。
"""
from app.api import dashboard as DASH
from app.utils import bep_caliber as CAL
assert not hasattr(DASH, "BEP_REBATE_POLICY_PCT"), (
"dashboard 仍在定义硬编码政策渠补率常量 ⇒ 口径非单一源")
assert CAL.caliber_for(1)["policy_pct"] == 84.61 # e1 保留(负对照)
assert CAL.caliber_for(2)["policy_pct"] is None # e2 置 None(无渠补科目)