fix(cma): 隔离扫尾 — kpi_alert_higher_better 拆账套 + tenant/switch 审计收口
ci/woodpecker/push/main Pipeline was canceled
ci/woodpecker/push/main Pipeline was canceled
任务 dama-entity-isolation-sweep-20260923(DAMA 独立回查漏项 / 任总 2026-09-23「按照建议执行」)
① 补漏同源全局键 kpi_alert_higher_better(system_configs,零 DDL)
- deviation_engine: 新增 higher_better_key(entity_id);get_higher_better_codes(db, entity_id)
改为只读本账套键、不回退旧全局键;未配置 → DEFAULT_HIGHER_BETTER(兜底,与原行为逐字一致)
- budget.py: GET/PUT /alert-direction 挂 get_entity_id,只读写会话账套键;body entity_id 不信
- scripts/migrate_higher_better_key_entity_20260923.py: --check/--apply/--down + 库名保护 + 幂等
- 生产实况:库内该键 0 行 ⇒ 无原值可搬运(--apply 走 skip 零写入),e1 行为不变
② kpi_visibility 口径裁定:角色级天然全局 = 非账套维度,不拆(关闭本项)
- auth_middleware 注释 + docstring 登记「有意不做账套后缀」;口径字典
docs/global-config-keys-caliber-20260923.md(含 budget_mode/budget_driver_mode 评估结论)
③ tenant/switch 审计收口
- detail 显式 from_entity_id → to_entity_id + source + operator{id,username,name,role}
- 审计失败不静默:同事务回滚 + AUDIT_WRITE_FAILED ERROR + HTTP 500(不留「改了但没审计」)
- GET /current 无写路径不落审计;历史缺口不补写
证据:新增/改写用例 17 条;全量 1397 passed(去新增文件 1380 + 17);RED 态 8 failed
This commit is contained in:
@@ -32,6 +32,22 @@
|
||||
并把 `target_type='entity'` / `target_id=entity_id` 与 `switch_entity` 对齐。
|
||||
- `detail` JSON 仍保留 `entity_id / entity_name / source / previous`(人读明细)。
|
||||
|
||||
**2026-09-23 收口(`dama-entity-isolation-sweep-20260923` §二)**:
|
||||
|
||||
- `detail` 再补 **显式 from→to** 与操作者三段:`from_entity_id` / `to_entity_id`(原只有 `previous` 整包,
|
||||
要人肉解析才知道「从哪来」)、`source`、`operator{user_id,username,name,role}`。
|
||||
`entity_id` 字段保留(= `to_entity_id`,兼容既有消费方)。
|
||||
- **审计失败不静默**:状态键与审计行**同一事务**提交,审计写入异常 → `rollback()`
|
||||
(状态变更一并回滚,绝不留「改了但没审计」的窗口)+ `logger.error("AUDIT_WRITE_FAILED …")` + HTTP 500。
|
||||
运维可在 `logs` 里 grep `AUDIT_WRITE_FAILED` 订阅。
|
||||
- `GET /tenant/current` **无写路径**(纯只读、已限 it/ceo)⇒ 不落审计(不给读操作写审计表)。
|
||||
- 历史缺口(2026-09-22 10:36 止血那次 `POST /tenant/switch` 无审计行)**不补写**:审计不得事后伪造。
|
||||
该次操作的留痕以 ops 止血单 + 本档 §一「现网实况」为准。
|
||||
|
||||
**在线实测(2026-09-23,`POST /api/cma/tenant/switch` 带会话 Bearer,`from=1 → to=1`)**:
|
||||
切换一次 → `operation_logs` 出现 `switch_tenant_state` 行(`user_id` 非空、`target_type='entity'`)
|
||||
⇒ 「全平台影响动作无审计」的缺口已在生产关闭(实测证据见回报件 §二)。
|
||||
|
||||
**现网实况(只读核对,2026-09-22 11:15,`cma_reader` 16/16 PASS)**:
|
||||
`switch_entity` = 49 行、`switch_tenant_state` = 0 行(本单尚未部署 ⇒ 字面是新引入的,
|
||||
上线前库里无该字面属正常)。ops 止血那次 `POST /tenant/switch`(10:36:01,部署码)**没有**审计行——
|
||||
@@ -63,5 +79,8 @@
|
||||
1. `kpi_alerts` id 589/590 跨账套错挂(`entity_id=1` 挂 e2 的 `BH_ADM_EXPENSE`):数据订正须
|
||||
另立单 + 任总放行(生产写)。
|
||||
2. `kpi_id=1` 兜底残留清点(9 行、其中 1 行 `pending`)与归属裁定。
|
||||
3. 同源全局键继续拆账套:`kpi_alert_higher_better`、`kpi_visibility`(DAMA §7 反向挑错新增漏项)、
|
||||
`budget_mode` / `budget_driver_mode`(batch5 §七 已记录未施工)。
|
||||
3. ~~同源全局键继续拆账套:`kpi_alert_higher_better`、`kpi_visibility`(DAMA §7 反向挑错新增漏项)、
|
||||
`budget_mode` / `budget_driver_mode`(batch5 §七 已记录未施工)。~~
|
||||
→ **2026-09-23 已分流**:`kpi_alert_higher_better` 已拆账套、`kpi_visibility` 裁定「非账套维度」
|
||||
关闭(见 `global-config-keys-caliber-20260923.md` §二/§三);`budget_mode` / `budget_driver_mode`
|
||||
评估为「应拆」但**另立 P2 单**(原值落账需拍板,见同档 §四)。
|
||||
|
||||
Reference in New Issue
Block a user