ASK-20260924-15/17: Bot 通道缺省账套→400 + 差异/趋势入口期间口径回落
- deps.get_entity_id: Bot 通道(带 X-BOT-KEY)无显式账套 → 400(旧为兜底 entity 1=酣客); 无 key 的存量公开/用户端点行为不变(仍 401/兜底 1) - 新增 deps.require_bot_entity_id():写端点缺省账套一处收口 → 400(406/422 同族) 接入 bot_bridge(×2) / bot_bridge_v2 / bot_suggestions / cash_vouchers_json,并同步文档口径 - deviation_engine.run_deviation_check: period=None 不再硬编码当月,逐 KPI 回落 「该 KPI 自己的最近可用期间」(裁定2b,单一实现收口到 alert_entity_scope);(当月无 kpi_values ⇒ 差异/趋势入口永久 0 新增);R2/R3 窗口判定改为逐 KPI;显式 period 语义不变 - alert_generator.resolve_latest_period 委托同一实现(消除期间口径两份) - 测试:新增 tests/test_ask15_17_engine_and_entity_required_20260925.py(12 例); 4 个既有测试文件把「旧兜底账套 1」显式化(断言未改)
This commit is contained in:
@@ -9,7 +9,7 @@ from sqlalchemy import func, desc
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from app.database import get_db
|
||||
from app.deps import get_entity_id
|
||||
from app.deps import get_entity_id, require_bot_entity_id
|
||||
from app.models import (
|
||||
User, UserEntity, StrategicMap, KPIDefinition, KPITemplate, KPIValue,
|
||||
DataSourceConfig, KPIAlert, OperationLog, NotificationChannel,
|
||||
@@ -666,7 +666,8 @@ def bot_kpi_value_with_check(data: dict, db: Session = Depends(get_db), bot: dic
|
||||
kpi_id = data.get("kpi_id")
|
||||
actual_value = data.get("actual_value")
|
||||
period = data.get("period")
|
||||
entity_id = int(data.get("entity_id") or 1)
|
||||
# ASK-20260924-17(任总 2026-09-24 放行):Bot 通道缺省账套 = 报错,不再静默落 entity 1
|
||||
entity_id = require_bot_entity_id(data, source="bot_bridge.kpi-value-with-check")
|
||||
run_check = bool(data.get("run_check", True))
|
||||
if not kpi_id or actual_value is None:
|
||||
raise HTTPException(400, "kpi_id 和 actual_value 必填")
|
||||
@@ -753,7 +754,7 @@ def bot_kpi_create_with_links(data: dict, db: Session = Depends(get_db), bot: di
|
||||
考核基准类(目标值)= 人拍板;target_value 一律显式置 0(满足治理必填,
|
||||
后续由人工设定或走 POST /api/cma/bot/ai/suggestions 建议通道待审批)。
|
||||
"""
|
||||
entity_id = int(data.get("entity_id") or 1)
|
||||
entity_id = require_bot_entity_id(data, source="bot_bridge.kpis.create-with-links")
|
||||
from app.api.kpis import _validate_kpi_data, apply_calc_type_inference
|
||||
kpi_data = {k: v for k, v in data.items() if k not in ("entity_id", "link_map_id", "link_causality")}
|
||||
|
||||
@@ -1202,6 +1203,13 @@ def bot_subjects_upsert(
|
||||
true → 更新 name/parent/level/category —— **但只更新本账套私有行**;
|
||||
同码若只以**全局标准科目**(`entity_id IS NULL`)存在,则**永不被账套 UPSERT 改写**(计入 `skipped_global`),
|
||||
同时也不再插入本账套同码副本(避免标准科目重复)。
|
||||
- **幂等语义(2026-09-24 R6 收口,判据勿误读)**:`update_existing=true` ⇒ **批内既存行全量重写**
|
||||
(逐行 UPDATE,不做值级 diff)⇒ 返回的 `updated=N` 是「**批内既存行数**」,**不是**「值发生变化的行数」,
|
||||
且**含本轮 `inserted` 的新行**:同一 payload 连跑两次,首跑 `inserted=k, updated=m`,
|
||||
复跑 `inserted=0, updated=k+m`(实测例:首跑 `inserted=5/updated=2` → 复跑 `updated=7`,
|
||||
见 `operation_logs` detail 原文 id=347/348)。此形态**属既定行为、非异常写入**:库内不产生重复行
|
||||
(唯一键 `(entity_id, subject_code)` + 只 UPDATE 不 DELETE/INSERT)。幂等判据取 `inserted=0`
|
||||
且 `before == after`(叠加 `COUNT(*)`/`MAX(id)` 不变),**不得用 `updated` 判幂等**。
|
||||
- dry_run=true → 只校验与回显,零写入
|
||||
返回: {"ok":true,"inserted":n,"updated":m,"skipped":k,"skipped_global":g,"entity_id":e,"errors":[]};未授权 401。
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user