# 变更审计记录:数据库字段走查批量修复 | 字段 | 值 | |------|-----| | 日期 | 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 缓存生成记录可追溯触发来源