这些审计记录原本堆积在 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>
5.9 KiB
5.9 KiB
变更审计记录:修复 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.pyapps/backend/app/routers/internal_events.pyapps/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 模块配置 - 思路分析:从
Authorizationheader 解析Internal-Token {token}格式,与环境变量INTERNAL_API_TOKEN比对。三层防御:格式校验 → 空值校验 → 匹配校验。未配置时返回 500 而非静默放行 - 修改结果:提供
verify_internal_tokenFastAPI 依赖函数,供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 服务层的近期调整
回滚策略
- 删除 3 个新增文件
- 从
main.py移除internal_events路由注册 - 从
dwd_load_task.py移除事件触发代码块(load()末尾的_service_log_tables相关逻辑)
合规检查
- ⚠️ 接口代码已变更但 OpenAPI spec 未同步(
compliance.openapi_spec_stale: true) - ⚠️ DDL 基线待确认(
compliance.has_ddl_baseline: false,但本次无数据库变更) - 无新增迁移 SQL