Files
2026-03-15 10:15:02 +08:00

95 lines
7.0 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.
# 需求文档P4 前置依赖修复
## 简介
P4 核心业务层已实现并通过属性测试,但对比 Spec 发现 6 处实现偏差(来源:`docs/reports/P4-spec-vs-implementation-gap-analysis.md`)。这些偏差会影响 P6前端任务模块的正常开发必须前置修复。本需求覆盖 GAP-3、GAP-6、GAP-7、GAP-9 的代码修复以及两项新增修正回访完成条件、cron 时间)。
修复范围6 个定点修复,无新表、无新接口,仅修改现有服务层逻辑和一条迁移脚本。
## 术语表
- **Task_Manager**: 任务管理服务(`task_manager.py`),负责任务列表查询和状态操作
- **Recall_Detector**: 召回完成检测器(`recall_detector.py`ETL 数据更新后匹配服务记录完成召回任务
- **Note_Reclassifier**: 备注回溯重分类器(`note_reclassifier.py`),召回完成后回溯普通备注为回访备注并创建回访任务
- **Note_Service**: 备注服务(`note_service.py`),负责备注 CRUD 和回访任务自动完成
- **Trigger_Scheduler**: 触发器调度框架(`trigger_scheduler.py`),统一管理 cron/interval/event 三种触发方式
- **coach_tasks**: 助教任务表(`biz.coach_tasks`
- **trigger_jobs**: 触发器配置表(`biz.trigger_jobs`
- **active**: 任务有效状态
- **abandoned**: 任务已放弃状态
- **inactive**: 任务无效状态(被顶替)
- **completed**: 任务已完成状态
- **high_priority_recall**: 高优先召回任务类型
- **priority_recall**: 优先召回任务类型
- **follow_up_visit**: 客户回访任务类型
- **relationship_building**: 关系构建任务类型
- **abandon_reason**: 放弃原因字段
- **last_run_at**: 触发器上次运行时间戳
- **ai_analyze_note()**: AI 备注分析占位函数P5 实现,当前返回 None
## 需求
### 需求 1任务列表返回已放弃任务
**用户故事:** 作为助教,我希望在任务列表中看到已放弃的任务及其放弃原因,以便执行「取消放弃」操作恢复任务。
#### 验收标准
1. WHEN 助教请求任务列表, THE Task_Manager SHALL 返回 active 和 abandoned 两种状态的任务
2. THE Task_Manager SHALL 按以下顺序排列任务abandoned 排在所有 active 任务之后active 任务内部按 is_pinned DESC、priority_score DESC NULLS LAST、created_at ASC 排序
3. THE Task_Manager SHALL 在返回结构中始终包含 abandon_reason 字段active 状态任务的 abandon_reason 为 nullabandoned 状态任务的 abandon_reason 为非空字符串
4. WHEN 不存在 abandoned 任务时, THE Task_Manager SHALL 仅返回 active 任务返回结构不变abandon_reason 为 null
### 需求 2召回完成检测器过滤任务类型
**用户故事:** 作为系统运维人员,我希望召回完成检测器仅完成召回类任务,避免错误地将回访和关系构建任务标记为已完成。
#### 验收标准
1. WHEN ETL 检测到新增服务记录, THE Recall_Detector SHALL 仅匹配 task_type 为 high_priority_recall 或 priority_recall 的 active 任务进行完成标记
2. WHILE 存在 active 的 follow_up_visit 任务, THE Recall_Detector SHALL 跳过该任务,不执行完成标记
3. WHILE 存在 active 的 relationship_building 任务, THE Recall_Detector SHALL 跳过该任务,不执行完成标记
### 需求 3备注回溯重分类器冲突处理
**用户故事:** 作为系统运维人员,我希望备注回溯重分类器在创建回访任务时正确处理冲突,避免唯一约束违反和重复任务。
#### 验收标准
1. WHEN Note_Reclassifier 准备创建 follow_up_visit 任务且同 (site_id, assistant_id, member_id) 已存在 completed 的 follow_up_visit 任务, THEN THE Note_Reclassifier SHALL 跳过创建(回访完成语义已满足)
2. WHEN Note_Reclassifier 准备创建 follow_up_visit 任务且同 (site_id, assistant_id, member_id) 已存在 active 的 follow_up_visit 任务, THEN THE Note_Reclassifier SHALL 将旧任务标记为 inactive 并记录变更历史,然后创建新的 follow_up_visit 任务(顶替方案)
3. WHEN Note_Reclassifier 准备创建 follow_up_visit 任务且同 (site_id, assistant_id, member_id) 不存在任何 follow_up_visit 任务, THE Note_Reclassifier SHALL 正常创建新任务
4. IF Note_Reclassifier 重复触发相同 payload, THEN THE Note_Reclassifier SHALL 不产生唯一约束冲突错误
### 需求 4回访任务完成条件改为「有备注即完成」
**用户故事:** 作为助教,我希望为客户提交备注后对应的回访任务自动完成,无需等待 AI 评分。
#### 验收标准
1. WHEN 助教通过 Note_Service 为某客户创建备注, THE Note_Service SHALL 查询该客户是否存在 active 的 follow_up_visit 任务(通过 user_assistant_binding 获取 assistant_id再匹配 site_id、assistant_id、member_id
2. WHEN 存在 active 的 follow_up_visit 任务且助教提交了备注, THE Note_Service SHALL 将该任务标记为 completed 并记录变更历史,完成判定不依赖 ai_analyze_note() 的返回值
3. THE Note_Service SHALL 保留 ai_analyze_note() 占位调用P5 接入时调用链不变),但 ai_analyze_note() 的返回值不作为回访任务完成的判定条件
4. WHEN Note_Reclassifier 回溯发现已有备注, THE Note_Reclassifier SHALL 直接创建 status='completed' 的回访任务(回溯完成),不依赖 AI 评分
5. WHEN Note_Reclassifier 回溯未发现备注, THE Note_Reclassifier SHALL 创建 status='active' 的回访任务(等待助教提交备注)
### 需求 5trigger_scheduler last_run_at 事务安全
**用户故事:** 作为系统运维人员,我希望触发器的 last_run_at 更新与 handler 执行在同一事务中,避免 handler 成功但 last_run_at 更新失败导致重复处理。
#### 验收标准
1. WHEN Trigger_Scheduler 执行 event 类型触发器fire_event, THE Trigger_Scheduler SHALL 将 last_run_at 更新纳入 handler 执行的同一事务范围handler 成功与 last_run_at 更新要么一起提交要么一起回滚
2. WHEN Trigger_Scheduler 执行 cron/interval 类型触发器check_scheduled_jobs, THE Trigger_Scheduler SHALL 将 last_run_at 和 next_run_at 更新纳入 handler 执行的同一事务范围
3. IF handler 执行成功但事务提交失败, THEN THE Trigger_Scheduler SHALL 回滚整个事务(包括 handler 的数据变更和 last_run_at 更新),下次重跑时 handler 的幂等性保证不会产生副作用
### 需求 6任务生成器 cron 时间改为 07:00
**用户故事:** 作为运营人员,我希望任务生成器在每天早上 7 点运行,与门店营业节奏匹配。
#### 验收标准
1. THE 迁移脚本 SHALL 将 trigger_jobs 表中 task_generator 的 cron_expression 从 `0 4 * * *` 更新为 `0 7 * * *`
2. THE Trigger_Scheduler SHALL 在 _calculate_next_run() 中使用 `0 7 * * *` 作为 cron 默认值
3. WHEN task_generator 触发器下次运行时间被计算, THE Trigger_Scheduler SHALL 基于 `0 7 * * *` 计算正确的 next_run_at