fix(budget): 偏差检查同 KPI 多计划去重(deviation-check 补 db.flush)

autoflush=False 下,check_budget_deviation 循环内 existing_alert 去重查询
查不到本次刚 add 未 flush 的行 → 同期间同 KPI 多 active 预算计划会重复告警。
add 后补 db.flush() 使其对下一次循环可见。附回归测试。

Ref: yanxue-20260914-budget-p13p14-activation 遗留②试跑发现的缺陷
This commit is contained in:
Hermes CI Fix
2026-09-14 17:56:26 +08:00
parent 40d522cd34
commit ec58efa20b
2 changed files with 31 additions and 0 deletions
+28
View File
@@ -461,6 +461,34 @@ class TestBudgetDeviationCheck:
json={"period": "2026-06", "threshold": 20})
assert resp.json()["alerts_generated"] == 0
def test_deviation_check_dedups_same_kpi_multiple_plans(self, client: TestClient, db: Session):
"""回归:同期间同 KPI 有多条 active 预算计划时,只应生成 1 条 open 告警
根因:database.py sessionmaker(autoflush=False),端点内循环的 existing_alert
去重查询查不到本次刚 add 未 flush 的行 → 第二个计划重复 INSERT。
"""
create_test_user(db)
token = get_token_for_user(client)
kpi = create_test_kpi(db, kpi_code="BUDGET_ALERT_DUP")
for _ in range(2): # 两条同 KPI 计划(模拟数据面重复计划)
db.add(BudgetPlan(kpi_id=kpi.id, period="2026-06", budget_value=100.0,
budget_year=2026, budget_month=6, status="active"))
from app.models import KPIValue
db.add(KPIValue(kpi_id=kpi.id, period="2026-06", actual_value=150.0)) # +50%
db.commit()
resp = client.post(f"{self.BASE}/deviation-check", headers=auth_header(token),
json={"period": "2026-06", "threshold": 20})
assert resp.status_code == 200
assert resp.json()["alerts_generated"] == 1
from app.models import BudgetDeviationAlert
n = db.query(BudgetDeviationAlert).filter(
BudgetDeviationAlert.kpi_id == kpi.id,
BudgetDeviationAlert.period == "2026-06",
BudgetDeviationAlert.status == "open",
).count()
assert n == 1, f"同 KPI 重复告警未去重,落库 {n} 条"
class TestBudgetDeviationAlerts:
"""偏差预警记录查询/更新"""