Files
Neo-ZQYY/docs/audit/changes/2026-03-22__db-field-walkthrough-batch-fix.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

97 lines
5.9 KiB
Markdown
Raw Permalink 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.
# 变更审计记录:数据库字段走查批量修复
| 字段 | 值 |
|------|-----|
| 日期 | 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` | 🔴 高 | 真实 BUGSQL 列名不匹配导致审核操作报错 |
| #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` 参数(默认 NoneINSERT 语句增加 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` 参数(默认 NoneINSERT 语句中写入该字段
- 修改结果AI 缓存生成记录可追溯触发来源