fix(alerts): enforce caliber ruling R5
- alert_entity_scope: add is_attributable_period / guard_alert_period (R5) and entity_alert_guard (R1, any write path) - alert_rules.run_all_alert_checks: skip non-YYYY-MM period alert rows (R5) - bot_bridge / bot_bridge_v2: R1 demo-entity guard + R5 period guard on write paths - tests: new R5 suite (10 cases) Not pushed / not deployed (release gate held by 任总).
This commit is contained in:
@@ -24,6 +24,8 @@ from app.models import (
|
||||
ActionPlan, Entity,
|
||||
)
|
||||
from app.risk_levels import risk_level
|
||||
# 裁定 R1/R5(2026-09-19 财务口径):demo 账套任何写通道不产生业务预警;期间非规整月不入库(单一事实源)
|
||||
from app.utils.alert_entity_scope import entity_alert_guard, guard_alert_period
|
||||
|
||||
logger = logging.getLogger("cma.bot_bridge_v2")
|
||||
|
||||
@@ -307,6 +309,12 @@ def receive_mpm_result(
|
||||
if not entity:
|
||||
raise HTTPException(404, f"实体entity_id={entity_id}不存在")
|
||||
|
||||
# R1/R5(裁定 2026-09-19):「R1 与入口无关」——Bot 通道按显式 entity 写入同样不得产出业务预警;
|
||||
# 期间非规整月(含 2026-H1/H2 伪期间)的 kpi_alerts 行一律不入库(跳过 + 记日志)。
|
||||
alerts_allowed = entity_alert_guard(db, entity_id, source="bot_bridge_v2.receive_mpm_result")
|
||||
period_attributable = guard_alert_period(period, source="bot_bridge_v2.receive_mpm_result",
|
||||
detail="entity_id=%s" % entity_id)
|
||||
|
||||
# ── 1. 写入MPM结果 ──
|
||||
record = MpmResult(
|
||||
entity_id=entity_id,
|
||||
@@ -367,6 +375,13 @@ def receive_mpm_result(
|
||||
|
||||
if (operator == ">" and field_value > threshold) or \
|
||||
(operator == ">=" and field_value >= threshold):
|
||||
# R1/R5 生成侧守卫(裁定 2026-09-19):demo 账套 / 不可归期期间 → 该行不入库
|
||||
if not alerts_allowed:
|
||||
logger.info("R1 账套守卫:跳过不入库(demo 演示账套)entity_id=%s", entity_id)
|
||||
continue
|
||||
if not period_attributable:
|
||||
logger.info("R5 期间守卫:跳过不入库(不可归期,非规整月 YYYY-MM)period=%r", period)
|
||||
continue
|
||||
# 查找关联KPI
|
||||
kpi_id = None
|
||||
if kpi_code:
|
||||
@@ -394,7 +409,7 @@ def receive_mpm_result(
|
||||
db.commit()
|
||||
db.refresh(record)
|
||||
|
||||
return {
|
||||
resp = {
|
||||
"success": True,
|
||||
"kpi_updated": len(kpi_updates),
|
||||
"alerts_triggered": len(alerts),
|
||||
@@ -403,7 +418,12 @@ def receive_mpm_result(
|
||||
"kpi_codes": kpi_updates,
|
||||
"alerts": alerts,
|
||||
},
|
||||
"skipped_non_month_period": (not period_attributable),
|
||||
}
|
||||
if not alerts_allowed:
|
||||
# R1(裁定 2026-09-19):demo 账套在 Bot 通道同样不产生业务预警
|
||||
resp.update({"skipped": True, "reason": "R1_demo_entity_excluded"})
|
||||
return resp
|
||||
|
||||
|
||||
@router.post("/kpi-result")
|
||||
|
||||
Reference in New Issue
Block a user