Files
Neo-ZQYY/docs/audit/changes/2026-03-29__fix-recall-completion-event-chain.md
Neo 14a12342b5 chore(audit): 补追 96 份未入仓审计孤本 — 覆盖 2026-02-26 ~ 2026-04-08
这些审计记录原本堆积在 docs/audit/changes/changes/ 嵌套误产物目录下(由开发机迁移
79d3c2e 前后的不明批量操作产生)。由于同期 .gitignore 屏蔽了 docs/audit/ 全目录,
它们从未入过 git 任何分支 history。删除即永久丢失。

按 docs/specs/audit-gap-recovery/tasks.md 阶段 1 执行,将全部 96 份 D 类孤本
(主目录无同名、git history 亦无记录)复制到 docs/audit/changes/ 主目录入仓。

涵盖主题: P1-P18 全栈集成 / 多模块累积变更 / ETL bug 修复 / 业务日切 /
   召回与任务引擎改造 / 租户管理与审批 / 董事会财务 / 客户与助教详情 /
   DDL 基线合并 / Kiro 到 Claude Code 迁移

阶段 2(B 类内容漂移 1 份)和阶段 4(嵌套目录删除)独立推进。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 06:35:42 +08:00

101 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 变更审计记录:修复 recall_completion_check 事件链断裂
| 字段 | 值 |
|------|-----|
| 日期 | 2026-03-29 05:33:11 |
| Prompt-ID | P20260329-052721 |
| Session-ID | 9e51396e |
| Session 路径 | docs/audit/session_logs/2026-03/29/10_4d217477_050959 |
## 操作摘要
修复 recall_completion_check 事件链断裂让回访任务follow_up_visit能正常生成。ETL DWD 加载完成后,通过 HTTP 调用后端新增的 `/api/internal/fire-event` 端点,触发 `etl_data_updated` 事件,驱动 `recall_completion_check``recall_detector.run()` → 标记召回完成 → 生成回访任务。
## 风险评估
- 后端新增端点:**低**独立路由Internal-Token 认证,不影响现有功能)
- ETL 触发调用:**低**(失败仅记录日志,不中断 DWD 加载)
- 认证解耦:**低**(复用同一个 INTERNAL_API_TOKEN 环境变量)
## 数据库变更
无。利用现有的 `biz.trigger_jobs` 表和 `fire_event()` 机制。
## 本次对话文件变更
### 新增文件
- `apps/backend/app/auth/internal_token.py`
- `apps/backend/app/routers/internal_events.py`
- `apps/etl/connectors/feiqiu/utils/biz_trigger.py`
### 删除文件
- `docs/audit/session_logs/2026-03/29/10_4d217477_050959/main_01_55fd330d.md`Session 日志重建)
## 改动注解
### `apps/backend/app/auth/internal_token.py`
- 变更类型:新增
- 原始原因:将 Internal-Token 认证逻辑从 AIConfig 解耦,使 `/api/internal/*` 端点可独立使用 token 校验,不依赖 AI 模块配置
- 思路分析:从 `Authorization` header 解析 `Internal-Token {token}` 格式,与环境变量 `INTERNAL_API_TOKEN` 比对。三层防御:格式校验 → 空值校验 → 匹配校验。未配置时返回 500 而非静默放行
- 修改结果:提供 `verify_internal_token` FastAPI 依赖函数,供 `internal_events` 路由使用。与 `internal_ai` 路由的认证方式一致
### `apps/backend/app/routers/internal_events.py`
- 变更类型:新增
- 原始原因ETL 完成 DWD 加载后需要一个 HTTP 入口来触发后端的事件驱动任务(如 recall_completion_check此前事件链在 ETL→后端 这一环断裂
- 思路分析:设计为通用事件触发端点 `POST /api/internal/fire-event`,接收 `event_name` + 可选 `payload`,调用 `trigger_scheduler.fire_event()` 查找并执行 `biz.trigger_jobs` 中匹配的 event 类型任务。使用 Internal-Token 认证防止外部调用
- 修改结果ETL 可通过 HTTP 触发任意已注册的 event 类型 job响应返回实际执行的 job 数量。当前主要消费者是 `etl_data_updated` 事件
### `apps/etl/connectors/feiqiu/utils/biz_trigger.py`
- 变更类型:新增
- 原始原因DWD 加载任务需要在完成后通知后端触发器系统,但 ETL 侧缺少调用后端 API 的工具函数
- 思路分析:封装 `trigger_biz_event()` 函数,通过 `BACKEND_API_URL` + `INTERNAL_API_TOKEN` 环境变量构造 HTTP 请求。设计为"尽力而为"模式:环境变量缺失时 warning 并返回 False请求失败时 warning 并返回 False绝不抛异常中断 ETL 流程。超时设置 (5s, 10s) 防止后端无响应时阻塞
- 修改结果ETL 任务可安全调用 `trigger_biz_event("etl_data_updated")` 通知后端,失败不影响数据加载
### `apps/backend/app/main.py`
- 变更类型:修改
- 原始原因:需要注册新增的 `internal_events` 路由到 FastAPI 应用
- 思路分析:在 import 列表和 `include_router` 调用中添加 `internal_events`。同时包含了其他近期新增路由的注册tenant_*, admin_*, trigger_jobs 等,属于累积变更)
- 修改结果:`/api/internal/fire-event` 端点可用。CHANGE 注释记录了路由注册历史
### `apps/etl/connectors/feiqiu/tasks/dwd/dwd_load_task.py`
- 变更类型:修改
- 原始原因DWD 加载完成后需要触发 `etl_data_updated` 事件,驱动召回完成检测
- 思路分析:在 `load()` 方法末尾、return 之前插入事件触发逻辑。触发条件精确限定为"本批处理了 `dwd_assistant_service_log``dwd_assistant_service_log_ex`"(召回检测依赖助教服务记录数据)。用 try/except 包裹,异常仅 warning 不中断。同时包含了 2026-03-26 的字段映射扩展other_pay_money_sum、last_consume_time 等新字段从 payload 提取)
- 修改结果DWD 加载助教服务记录后自动触发事件链:`etl_data_updated``recall_completion_check``recall_detector.run()` → 标记召回完成 → 生成回访任务
### `apps/backend/app/routers/xcx_board.py`
- 变更类型:修改(非本次核心变更)
- 简要说明:看板路由的近期调整,与事件链修复无直接关联
### `apps/backend/app/schemas/xcx_board.py`
- 变更类型:修改(非本次核心变更)
- 简要说明:看板 Schema 的近期调整
### `apps/backend/app/services/board_service.py`
- 变更类型:修改(非本次核心变更)
- 简要说明:看板服务层的近期调整
### `apps/backend/app/services/customer_service.py`
- 变更类型:修改(非本次核心变更)
- 简要说明:客户服务层的近期调整
### `apps/miniprogram/miniprogram/pages/board-coach/board-coach.ts`
- 变更类型:修改(非本次核心变更)
- 简要说明:助教看板页面的近期调整
### `apps/miniprogram/miniprogram/services/api.ts`
- 变更类型:修改(非本次核心变更)
- 简要说明:小程序 API 服务层的近期调整
## 回滚策略
1. 删除 3 个新增文件
2.`main.py` 移除 `internal_events` 路由注册
3.`dwd_load_task.py` 移除事件触发代码块(`load()` 末尾的 `_service_log_tables` 相关逻辑)
## 合规检查
- ⚠️ 接口代码已变更但 OpenAPI spec 未同步(`compliance.openapi_spec_stale: true`
- ⚠️ DDL 基线待确认(`compliance.has_ddl_baseline: false`,但本次无数据库变更)
- 无新增迁移 SQL