Files
Neo-ZQYY/docs/audit/changes/2026-03-25__baseline-relationship-building-tasks.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

91 lines
3.8 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.
# 变更审计记录:保底 relationship_building 任务生成
| 字段 | 值 |
|------|-----|
| 日期 | 2026-03-25 |
| Prompt | 扩大 relationship_building 任务生成范围(保底任务) |
## 操作摘要
扩大 relationship_building 任务生成范围:对每个助教,所有确切发生过服务关系(`session_count > 0`)的客户都生成一条 relationship_building 保底任务。只有满足 RS 指数范围(`1 < RS < 6`,来自 `cfg_task_generator_params`)的才展示在前端任务列表中,范围外的任务通过服务详情列表入口访问详情页。
## 风险标签
`dir:backend``dir:db``db-schema-change`
## 文件变更
### 新增文件
- `db/zqyy_app/migrations/2026-03-25__relationship_building_baseline.sql` — partial unique index
### 修改文件
- `apps/backend/app/services/fdw_queries.py` — 新增 `get_all_service_pairs()`
- `apps/backend/app/services/task_generator.py` — 新增 Step 3b + `_generate_baseline_relationship_tasks()`
- `apps/backend/app/services/task_manager.py``get_task_list_v2()` SQL 层面排除 RS 范围外的保底任务
## 改动注解
### 1. 迁移脚本(新建)
- 新增 partial unique index `idx_coach_tasks_rb_unique_active` on `biz.coach_tasks (site_id, assistant_id, member_id) WHERE task_type = 'relationship_building' AND status = 'active'`
- 保证每个 (site_id, assistant_id, member_id) 最多 1 条 active 的 relationship_building 任务
- 支持 upsert 的 ON CONFLICT 子句
### 2. fdw_queries.py — get_all_service_pairs()
- 查询 `app.v_dws_member_assistant_relation_index WHERE session_count > 0`
- 不限 os_label只要确切发生过服务关系
- 返回 `[{"assistant_id", "member_id", "rs"}]`
### 3. task_generator.py — _generate_baseline_relationship_tasks()
-`_run_for_site()` 的 Step 3 和 Step 4 之间插入 Step 3b
- 查询全量服务关系对 → 排除已有任何类型 active 任务的对 → 批量 upsert
- 每条失败独立 rollback + 重新 BEGIN不影响其他记录
- 写入 coach_task_historyaction="created", detail={"reason": "baseline_relationship_building"}
### 4. task_manager.py — get_task_list_v2() 分页修复
- 原方案:内存过滤(循环中 continue 跳过 + total - filtered_count跨页 total 不准确
- 新方案Step 0 预查 ETL RS 排除列表 → SQL COUNT/分页查询加 NOT (task_type='relationship_building' AND member_id=ANY(exclude)) 条件
- RS 范围参数从 cfg_task_generator_params 读取(复用任务生成器配置)
## 风险评估
- 低风险:纯函数未修改,属性测试 23 passed, 3 skipped
- 中风险_generate_baseline_relationship_tasks 循环内事务处理(部分失败时其他记录仍可提交)
- 低风险get_task_list_v2 新增一次 ETL 查询(单助教级别,数据量小)
## 回滚策略
```sql
-- 1. 删除索引
DROP INDEX IF EXISTS biz.idx_coach_tasks_rb_unique_active;
-- 2. 清理保底任务(按时间范围)
DELETE FROM biz.coach_tasks
WHERE task_type = 'relationship_building'
AND created_at >= '2026-03-25'::date
AND id IN (
SELECT h.task_id FROM biz.coach_task_history h
WHERE h.detail->>'reason' = 'baseline_relationship_building'
);
```
代码回滚revert 三个 Python 文件的改动。
## 验证 SQL
```sql
-- 1. 确认索引存在
SELECT indexname, indexdef FROM pg_indexes WHERE indexname = 'idx_coach_tasks_rb_unique_active';
-- 2. 确认无重复(每对最多 1 条 active relationship_building
SELECT site_id, assistant_id, member_id, COUNT(*)
FROM biz.coach_tasks
WHERE task_type = 'relationship_building' AND status = 'active'
GROUP BY site_id, assistant_id, member_id
HAVING COUNT(*) > 1;
-- 应返回 0 行
-- 3. 确认保底任务已生成
SELECT COUNT(*) FROM biz.coach_tasks
WHERE task_type = 'relationship_building' AND status = 'active';
```