fix(cma): scope ai-suggestion action_plan and preview KPI to session entity

_apply_action_plan: constrain the target KPIDefinition lookup to sug.entity_id so a
suggestion whose target_id/suggestion_data.kpi_id points at a foreign-entity KPI now
returns 404 instead of creating an ActionPlan row with a cross-entity kpi_id.

preview_suggestion: same constraint; a foreign-entity KPI now degrades to the existing
placeholder (KPI#<id>, current_target=None) instead of echoing the foreign KPI name and
current_target. Degradation (not 404) keeps the read-side preview usable when the stored
kpi_id is inconsistent.

Regression: backend/tests/test_ai_suggestion_kpi_attribution_residual_20260918.py
(RED 2 failed before, GREEN 5 passed after; full suite 1228+2F -> 1230 passed / 1 xfailed).
This commit is contained in:
Hermes CI Fix
2026-09-18 21:04:30 +08:00
parent 9cb960da25
commit 557771a803
2 changed files with 300 additions and 2 deletions
+9 -2
View File
@@ -236,7 +236,10 @@ def _apply_action_plan(db: Session, sug: AISuggestion, params: dict, current_use
kpi_id = params.get("kpi_id") or sug.target_id
if not kpi_id:
raise HTTPException(400, "缺少 kpi_id")
kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first()
kpi = db.query(KPIDefinition).filter(
KPIDefinition.id == kpi_id,
KPIDefinition.entity_id == sug.entity_id, # 2026-09-18 派生单 2030b: 目标KPI须归属建议账套
).first()
if not kpi:
raise HTTPException(404, f"KPI {kpi_id} 不存在")
@@ -311,7 +314,11 @@ def preview_suggestion(suggestion_id: int, db: Session = Depends(get_db),
kpi = None
kpi_id = sd.get("kpi_id") or sug.target_id
if kpi_id:
kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first()
# 2026-09-18 派生单 2030b: 目标KPI须归属建议账套;对端KPI降级为 KPI#<id>(不回显名/目标值)
kpi = db.query(KPIDefinition).filter(
KPIDefinition.id == kpi_id,
KPIDefinition.entity_id == sug.entity_id,
).first()
if sug.suggestion_type == "kpi_target":
return {"data": {