这些审计记录原本堆积在 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>
97 lines
5.9 KiB
Markdown
97 lines
5.9 KiB
Markdown
# 变更审计记录:数据库字段走查批量修复
|
||
|
||
| 字段 | 值 |
|
||
|------|-----|
|
||
| 日期 | 2026-03-22 21:13:30 |
|
||
| Prompt-ID | P20260322-210700 |
|
||
| Session-ID | 62a2cb83 |
|
||
| Session 路径 | docs/audit/session_logs/2026-03/22/71_2b366442_205346 |
|
||
|
||
## 操作摘要
|
||
|
||
用户要求"走查遍历所有数据库字段,是否都有数据写入/维护的函数",发现 10 个问题后要求"全部修复"。本次修改共涉及 8 个后端文件,修复 7 个字段写入/维护缺失问题。3 个问题因合理原因不修改(#2 wx_avatar_url 前端未开发、#6 stg_*.synced_at ETL 未开发、#7 public.approvals 废弃表)。
|
||
|
||
## 风险评估
|
||
|
||
| 问题编号 | 风险等级 | 说明 |
|
||
|----------|----------|------|
|
||
| #1 `reviewed_by` → `reviewer_id` | 🔴 高 | 真实 BUG,SQL 列名不匹配导致审核操作报错 |
|
||
| #3 `ai_conversations.title` 未写入 | 🟡 中 | 功能缺失,不影响现有流程 |
|
||
| #4/#10 `ai_trigger_jobs` 无 UPDATE | 🟢 低 | dispatcher 当前为内存模式,DB 更新通过 try/except 容错 |
|
||
| #5 `notes.score` 未写入 | 🟡 中 | 新增 API 契约字段,前端需配合传参 |
|
||
| #8 `wx_union_id` 仅首次写入 | 🟢 低 | 幂等保护(WHERE wx_union_id IS NULL OR wx_union_id <> %s) |
|
||
| #9 `set_generating()` 缺少 triggered_by | 🟢 低 | 参数补齐,默认值 None 向后兼容 |
|
||
|
||
## 不修改的问题
|
||
|
||
- **#2 `wx_avatar_url`**:code2session 不返回头像,属于前端功能未开发
|
||
- **#6 `stg_*.synced_at`**:ETL 消费功能未开发,NULL 是正确状态
|
||
- **#7 `public.approvals`**:废弃表,全仓零引用,后续清理时 DROP
|
||
|
||
## 本次对话文件变更
|
||
|
||
### 新增文件
|
||
- `docs/audit/prompt_logs/prompt_log_20260322_210700.md`
|
||
- `docs/audit/session_logs/2026-03/22/71_2b366442_205346/main_01_62a2cb83.md`
|
||
- `docs/audit/session_logs/2026-03/22/71_2b366442_205346/sub_01_62a2cb83.md`
|
||
- `docs/audit/session_logs/2026-03/22/71_2b366442_205346/sub_02_62a2cb83.md`
|
||
|
||
## 合规检查
|
||
|
||
- ⚠️ 接口代码已变更但 OpenAPI spec 未同步(`compliance.openapi_spec_stale: true`)
|
||
- 自动导出失败:`ModuleNotFoundError: No module named 'dashscope'`(后端依赖未安装)
|
||
- 待手动导出:先 `uv sync`(在 apps/backend/ 下),再运行 `python scripts/ops/_export_openapi.py`
|
||
- 导出成功后需重连 OpenAPI Power 的 MCP server 以加载新 spec
|
||
- ✅ 无新增迁移 SQL(`new_migration_sql` 为空)
|
||
- ⚠️ DDL 基线未更新(`has_ddl_baseline: false`)— 本次无 DDL 变更,待后续合并时统一更新
|
||
|
||
## 改动注解
|
||
|
||
### `apps/backend/app/routers/tenant_users.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#1 BUG — approve/reject 端点的 SQL UPDATE 使用了错误的列名 `reviewed_by`,实际数据库列名为 `reviewer_id`,导致审核操作执行时 SQL 报错
|
||
- 思路分析:直接将 SQL 语句中的 `reviewed_by` 替换为 `reviewer_id`,涉及 approve 和 reject 两处 UPDATE 语句。这是最小化修复,不改变业务逻辑
|
||
- 修改结果:审核通过/拒绝操作的 SQL 列名与数据库 schema 一致,修复了运行时报错。影响范围限于租户管理后台的用户审核流程
|
||
|
||
### `apps/backend/app/ai/conversation_service.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#3 — `ai_conversations` 表的 `title` 字段在 INSERT 时未写入,SELECT 时也未读取
|
||
- 思路分析:在 INSERT 语句中增加 title 参数,新增 `update_title()` 方法支持后续更新标题,SELECT 查询中补充 title 列
|
||
- 修改结果:AI 对话的标题字段完整支持读写,为前端展示对话列表标题提供数据基础
|
||
|
||
### `apps/backend/app/ai/dispatcher.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#4/#10 — `ai_trigger_jobs` 表缺少 UPDATE 逻辑,started_at/finished_at/status/error_message 字段始终为初始值
|
||
- 思路分析:新增 `_update_trigger_job_status()` 辅助函数,在 `_execute_chain` 的开始和结束阶段调用,更新任务状态。使用 try/except 容错,确保 DB 更新失败不影响主流程
|
||
- 修改结果:AI 触发任务的生命周期状态可追踪,便于后续监控和调试
|
||
|
||
### `apps/backend/app/services/note_service.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#5 — `notes` 表的 `score` 字段在 `create_note()` 中未写入
|
||
- 思路分析:在 `create_note()` 函数签名中增加 `score` 参数(默认 None),INSERT 语句增加 score 列,RETURNING 子句增加 score
|
||
- 修改结果:笔记评分字段支持写入和返回,前端传参后即可生效
|
||
|
||
### `apps/backend/app/schemas/xcx_notes.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#5 配套 — NoteCreateRequest 和 NoteOut schema 缺少 score 字段定义
|
||
- 思路分析:在 Pydantic schema 中增加 `score: Optional[float] = None`,保持向后兼容
|
||
- 修改结果:API 契约层支持 score 字段的传入和返回
|
||
|
||
### `apps/backend/app/routers/xcx_notes.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#5 配套 — 路由层未将 score 参数传递给 service 层
|
||
- 思路分析:在路由处理函数中从 request body 提取 score 并传递给 `create_note()`
|
||
- 修改结果:完成 score 字段从 API 入口到数据库写入的完整链路
|
||
|
||
### `apps/backend/app/routers/xcx_auth.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#8 — `wx_union_id` 仅在首次登录(新用户注册)时写入,已有用户后续登录即使获取到新的 unionid 也不会更新
|
||
- 思路分析:在已有用户分支增加 UPDATE 语句,当 unionid 非空且与现有值不同时更新。使用幂等保护条件 `WHERE wx_union_id IS NULL OR wx_union_id <> %s`
|
||
- 修改结果:已有用户的 wx_union_id 可在后续登录时自动补全或更新,支持微信开放平台绑定场景
|
||
|
||
### `apps/backend/app/ai/cache_service.py`
|
||
- 变更类型:修改
|
||
- 原始原因:#9 — `set_generating()` 方法的 INSERT 语句缺少 `triggered_by` 字段
|
||
- 思路分析:在方法签名中增加 `triggered_by` 参数(默认 None),INSERT 语句中写入该字段
|
||
- 修改结果:AI 缓存生成记录可追溯触发来源
|