fix(cma): 工作台跨实体治本 · DAMA 回查收口 — 审计可归属 + 通知日志口径
DAMA 独立回查 dama-recheck-workbench-entity-isolation-20260922 的 §4b/§5 两处待办:
1. POST /api/cma/tenant/switch 审计行原来不可归属:
- user_id=None → 改为注入会话用户(user=Depends(require_auth_401))
- target_type/target_id 从 system_config/None 对齐为 entity/<entity_id>,
与 /auth/switch-entity 的 switch_entity 共用目标维度 ⇒ 按账套可过滤,零 DDL
- action 字面 switch_tenant_state 保留不合并(与会话级 switch_entity 语义不同),
口径登记 docs/audit-and-notification-caliber-20260922.md
2. /api/cma/notifications/logs 增加 policy/note 口径字段,前端发送记录表
empty-text 提示同一口径 —— 避免「B2 上线后 e1/e2 均 0 条」被当成页面故障
(现库 8 行历史记录全为 alert_id IS NULL 的 OKR 复盘提醒,无账套归属)
回归:tests/test_workbench_entity_isolation_20260922.py 22/22;全量 1370 passed;前端 vite build 通过
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# 口径登记:审计留痕(`operation_logs`)与通知发送记录(`notification_logs`)
|
||||
|
||||
- **立档**: wecom-fullstack,2026-09-22
|
||||
- **来源**: DAMA 独立回查 `dama-recheck-workbench-entity-isolation-20260922`(2026-09-22 11:07–11:20)
|
||||
§4b(审计字面与库内既有口径不一致 / 无 `entity_id` 列 / `user_id=None`)与
|
||||
§5(B2 上线后 `/notifications/logs` 在 e1/e2 均为 0 条 = 口径副作用)两处待办
|
||||
- **性质**: 口径登记 + 代码收口说明。**不含**任何数据订正(数据订正另立单 + 审批)
|
||||
|
||||
---
|
||||
|
||||
## 一、`operation_logs` 审计字面字典(换账套类)
|
||||
|
||||
| action 字面 | 写入端点 | 语义 | target_type | target_id |
|
||||
|---|---|---|---|---|
|
||||
| `switch_entity` | `post /api/cma/auth/switch-entity`(`app/api/auth.py`) | 改**用户自己的会话账套**(重签 token、旧 token 下线) | `entity` | 目标 `entity_id` |
|
||||
| `switch_tenant_state` | `post /api/cma/tenant/switch`(`app/api/tenant.py`) | 改**平台全局状态记录** `system_configs.current_tenant`(项目Bot 分发 A2A 任务用;**非数据维度**) | `entity` | 目标 `entity_id` |
|
||||
|
||||
**为什么两个字面不合并**:两者作用域不同(个人会话 vs 全局单值键),合并后审计上不可分辨
|
||||
「谁把自己切走了」与「谁改了全平台状态」。DAMA 复核提出「统一为 `switch_entity` 或登记字典」——
|
||||
本档取**后者(登记不合并)**,原因是前者会丢语义可分辨性;若后续裁定要求合并,改动面为
|
||||
`app/api/tenant.py` 一行字面 + 本表一行(可逆)。
|
||||
|
||||
**可归属与可过滤(2026-09-22 收口,随本档同一提交落地)**:
|
||||
|
||||
- `operation_logs` **无** `entity_id` 列(仅 `user_id / action / target_type / target_id / detail / created_at`)。
|
||||
故「按账套查换账套记录」不靠新列,而靠**目标维度**:
|
||||
```sql
|
||||
SELECT * FROM operation_logs WHERE target_type='entity' AND target_id=? ORDER BY id DESC;
|
||||
```
|
||||
- `/tenant/switch` 原写 `user_id=None`(端点无当前用户注入)⇒ 事后无法追操作人。
|
||||
已改为注入会话用户(`user=Depends(require_auth_401)` → `user_id=user.id`),
|
||||
并把 `target_type='entity'` / `target_id=entity_id` 与 `switch_entity` 对齐。
|
||||
- `detail` JSON 仍保留 `entity_id / entity_name / source / previous`(人读明细)。
|
||||
|
||||
**现网实况(只读核对,2026-09-22 11:15,`cma_reader` 16/16 PASS)**:
|
||||
`switch_entity` = 49 行、`switch_tenant_state` = 0 行(本单尚未部署 ⇒ 字面是新引入的,
|
||||
上线前库里无该字面属正常)。ops 止血那次 `POST /tenant/switch`(10:36:01,部署码)**没有**审计行——
|
||||
部署码该端点无审计,正是本单补齐项。
|
||||
|
||||
---
|
||||
|
||||
## 二、`/api/cma/notifications/logs` 口径(发送记录页)
|
||||
|
||||
- **归属口径**:`notification_logs` 无 `entity_id` 列 ⇒ 经**父键** join 归属:
|
||||
`notification_logs.alert_id → kpi_alerts.id → kpi_alerts.entity_id`;按会话账套过滤,
|
||||
与 batch5 对 `kpi_data_quality_log` 的处置同口径(**宁少勿错**)。
|
||||
- **`alert_id IS NULL` 的行**:无可归属父键 ⇒ **不返回给任何账套**(不跨账套暴露)。
|
||||
现库 8 行历史记录(2026-09-11/12「OKR 季度复盘提醒」)**100% 属此类**,
|
||||
写入方 = `backend/scripts/okr_review_reminder.py`(复用本表留存审计,`alert_id` 留空)。
|
||||
- **上线后现象(须预期,不是故障)**:`/notifications/logs` 在 e1/e2 均返回 `total=0`,
|
||||
前端发送记录页为空。现役预警推送写入器 `app/utils/notifier.py` **必带** `alert_id`,
|
||||
故此后由预警产生的新记录会正常显示;只有「无父键历史行」永不出现在该页。
|
||||
- **页面与接口的提示(随本档同一提交落地)**:
|
||||
- 接口返回 `policy="alert-linked-only"` + `note`(说明「仅显示与预警关联的推送」);
|
||||
- 前端 `NotificationManage.vue` 发送记录表 `empty-text` 写明同一口径。
|
||||
- **未做(留待 P2 裁定)**:为无父键通知单列只读视图(需先给 `notification_logs` 补账套维度,
|
||||
属 DDL/迁移,超出「零迁移 B2」范围)。
|
||||
|
||||
---
|
||||
|
||||
## 三、本档未覆盖(另立单,见对应任务文件)
|
||||
|
||||
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 §七 已记录未施工)。
|
||||
Reference in New Issue
Block a user