9.6 KiB
9.6 KiB
状态流转约定
本文件是状态枚举、允许流转、触发人和日志要求的唯一事实源。代码枚举、接口返回和测试用例应与本文件一致。
1. 通用原则
- 状态统一使用英文枚举。
- 状态变化必须通过 service 层完成。
- 关键状态变化必须写
operation_logs。 - 非法状态跳转必须返回
state_conflict。 - 通知、回调、调度相关状态变化必须幂等。
2. AI 草稿状态
| 状态 | 含义 |
|---|---|
pending_confirmation |
草稿已整理完成,等待老板确认、修改、取消或补充/重说 |
awaiting_follow_up |
老板已点击补充/重说,等待 30 分钟内下一条补充消息 |
confirmed |
已人工确认,等待转换为事项或提醒 |
converted |
已转换为事项或提醒;复杂事项已创建 pending_manager_confirm 事项壳也视为已转换 |
cancelled |
已取消 |
answered |
已直接回复或留痕,不进入事项、提醒或通知闭环 |
superseded |
已被补充/重说生成的新草稿替代 |
expired |
补充/重说等待超时,旧确认卡片不可继续使用 |
parse_failed |
AI 解析或草稿处理失败,仅用于调试追踪 |
允许流转:
pending_confirmation -> confirmed
pending_confirmation -> awaiting_follow_up
pending_confirmation -> cancelled
pending_confirmation -> parse_failed
awaiting_follow_up -> superseded
awaiting_follow_up -> expired
awaiting_follow_up -> cancelled
confirmed -> converted
confirmed -> parse_failed
约束:
parse_failed、cancelled、converted、answered、superseded、expired为终态。- 未进入
confirmed的草稿不得转换。 note、unknown、qa、realtime_qa、need_more_info、unsupported不进入事项、提醒或通知闭环;如需留痕,只能使用answered或parse_failed。- 老板点击补充/重说后,原草稿进入
awaiting_follow_up,并使原确认卡片失效。 - 30 分钟内收到补充消息后,新草稿
parent_draft_id指向原草稿,原草稿进入superseded。 - 超过 30 分钟后,原草稿进入
expired,老板下一条消息按新输入处理。 - 飞书回调确认、取消、补充/重说前,必须校验回调来自
active_card_notification_id对应的当前有效卡片。 - 复杂事项不使用草稿状态等待程经理确认;老板确认后应创建
tasks.status=pending_manager_confirm的事项壳。 answered和parse_failed可以作为最小留痕草稿的初始终态,不参与确认和转换。
3. 事项状态
| 状态 | 含义 |
|---|---|
pending_manager_confirm |
等待程经理确认 |
pending_notify |
待通知 |
notified |
已通知 |
notify_failed |
通知失败 |
feedback_received |
已收到反馈 |
completed |
已完成 |
problem |
有问题 |
cancelled |
已取消 |
允许流转:
pending_manager_confirm -> pending_notify
pending_manager_confirm -> cancelled
pending_notify -> notified
pending_notify -> notify_failed
notify_failed -> pending_notify
notified -> feedback_received
notified -> completed
notified -> problem
feedback_received -> completed
feedback_received -> problem
problem -> pending_notify
约束:
cancelled为终态。- 未通知事项不得接收飞书反馈。
problem必须有问题原因。- 通知失败不得标记为
notified。
4. 事项用户可见反馈状态
| 状态 | 含义 |
|---|---|
received |
已收到 |
in_progress |
处理中 |
completed |
已完成 |
problem |
有问题 |
约束:
problem必须填写problem_reason。- 反馈人必须是事项接收人。
received和in_progress反馈写入feedbacks.status,并将tasks.status置为feedback_received、tasks.visible_feedback_status置为对应值。completed反馈将tasks.status和tasks.visible_feedback_status都置为completed。problem反馈将tasks.status和tasks.visible_feedback_status都置为problem,并写入problem_reason。
5. 提醒状态
| 状态 | 含义 |
|---|---|
active |
生效中 |
paused |
已暂停 |
triggered |
一次性提醒已触发 |
trigger_failed |
触发失败 |
cancelled |
已取消 |
expired |
已过期 |
允许流转:
active -> paused
paused -> active
active -> triggered
active -> trigger_failed
trigger_failed -> active
active -> cancelled
paused -> cancelled
trigger_failed -> cancelled
triggered -> expired
约束:
- 只有
active可以被 scheduler 触发。 cancelled为终态。paused不触发通知。trigger_failed必须写失败记录。- 一次性提醒成功触发后,状态从
active变为triggered,并可在后续清理或展示时变为expired。 daily、weekly、monthly周期提醒成功触发后状态保持active,只更新last_triggered_at和下一次next_trigger_at。- 提醒反馈不改变提醒调度状态;反馈结果保存在
feedbacks,提醒是否继续触发只由status、repeat_rule和next_trigger_at决定。
6. 重复规则
| 值 | 含义 |
|---|---|
none |
一次性 |
daily |
每天 |
weekly |
每周 |
monthly |
每月 |
第一版不支持 cron 表达式和自定义复杂周期。
7. 通知状态
| 状态 | 含义 |
|---|---|
pending |
待发送 |
sending |
发送中 |
sent |
已发送 |
failed |
发送失败 |
retrying |
补发中 |
cancelled |
已取消 |
expired |
卡片或通知操作已过期 |
允许流转:
pending -> sending
pending -> sent
pending -> failed
sending -> sent
sending -> failed
failed -> retrying
retrying -> sent
retrying -> failed
pending -> cancelled
failed -> cancelled
pending -> expired
sent -> expired
约束:
sent不得重复发送同一通知。- 补发必须保留原失败记录和新发送结果。
- 飞书通知必须使用幂等键。
expired、cancelled通知不得继续处理卡片确认、反馈或补充/重说。- 被新卡片替代或业务取消时,必须写
invalidated_at。
通知幂等键建议:
target_type + target_id + receiver_id + channel + trigger_time
提醒触发幂等键建议:
reminder_id + trigger_time + receiver_id + notification_channel
8. 反馈状态
| 状态 | 含义 |
|---|---|
received |
已收到 |
in_progress |
处理中 |
completed |
已完成 |
problem |
有问题 |
约束:
- 反馈目标只能是
task或reminder。 - 反馈人必须是接收人。
problem必须填写一句原因。- 重复点击卡片不得重复创建相同反馈。
9. 失败记录状态
| 状态 | 含义 |
|---|---|
pending |
待处理 |
processing |
处理中 |
resolved |
已处理 |
cancelled |
已取消 |
允许流转:
pending -> processing
pending -> resolved
pending -> cancelled
processing -> resolved
processing -> cancelled
约束:
resolved必须填写处理结果。- 状态变化必须写操作日志。
10. 失败类型
| 类型 | 含义 |
|---|---|
ai_parse_failed |
AI 输出解析失败 |
ai_model_failed |
百炼或模型网关超时、网络失败、服务异常,重试后仍失败 |
bot_message_failed |
入口消息结构缺失、无法解析文本或 sender 信息 |
missing_person_mapping |
缺少人员映射 |
memory_store_failed |
PostgreSQL AI 记忆表、上下文或快照保存/读取失败 |
draft_convert_failed |
老板或程经理确认后,转换任务/提醒失败 |
feishu_auth_failed |
飞书登录失败 |
feishu_send_failed |
飞书通知失败 |
feishu_callback_failed |
飞书回调处理失败 |
feishu_signature_invalid |
飞书验签失败 |
reminder_trigger_failed |
定时提醒触发失败 |
bot_unauthorized |
非老板使用机器人入口 |
follow_up_expired |
补充/重说上下文过期 |
user_feedback_problem |
用户反馈有问题 |
permission_error |
权限拒绝 |
system_error |
未归类系统异常 |
11. 飞书事件处理状态
| 状态 | 含义 |
|---|---|
pending |
已接收待处理 |
processed |
已处理 |
failed |
处理失败 |
ignored |
已忽略 |
约束:
- 同一
event_id只处理一次。 - 如果飞书某类回调没有稳定
event_id,必须使用idempotency_key做事件幂等。 - 验签失败不得执行业务动作。
- 旧卡片、失效卡片、已替代草稿和已过期通知的回调只记录事件并标记
ignored,不得写业务对象。 - 处理失败必须写失败记录。
12. 用户和配置状态
用户状态:
| 状态 | 含义 |
|---|---|
active |
启用 |
disabled |
停用 |
人员映射状态:
| 状态 | 含义 |
|---|---|
pending |
待解析 |
resolved |
已解析 |
failed |
解析失败 |
Prompt 上下文状态:
| 状态 | 含义 |
|---|---|
draft |
草稿 |
active |
启用 |
archived |
已归档 |
飞书登录会话状态:
| 状态 | 含义 |
|---|---|
pending |
登录处理中 |
success |
登录成功 |
failed |
登录失败 |
机器人上下文状态:
| 状态 | 含义 |
|---|---|
empty |
当前没有可补充或可确认的草稿 |
awaiting_more_info |
AI 已追问,等待老板补充 |
awaiting_confirm |
草稿已整理完成,等待老板确认、修改、取消或转经理 |
awaiting_follow_up |
老板点击补充/重说后,等待下一条消息修订上一版草稿 |
expired |
已过期 |
cleared |
草稿已确认、取消或转换完成,上下文已清空 |