# 状态流转约定 本文件是状态枚举、允许流转、触发人和日志要求的唯一事实源。代码枚举、接口返回和测试用例应与本文件一致。 ## 1. 通用原则 1. 状态统一使用英文枚举。 2. 状态变化必须通过 service 层完成。 3. 关键状态变化必须写 `operation_logs`。 4. 非法状态跳转必须返回 `state_conflict`。 5. 通知、回调、调度相关状态变化必须幂等。 ## 2. AI 草稿状态 | 状态 | 含义 | | --- | --- | | `PENDING_CONFIRM` | 草稿已整理完成,等待老板确认、修改、取消或转经理 | | `NEED_MANAGER_CONFIRM` | 老板已确认,但复杂任务需要程经理确认 | | `CONFIRMED` | 已人工确认,等待转换任务或提醒 | | `CONVERTED` | 已转换为事项或提醒 | | `CANCELLED` | 已取消 | | `FAILED` | AI 解析或草稿处理失败,仅用于调试追踪 | 允许流转: ```text PENDING_CONFIRM -> CONFIRMED PENDING_CONFIRM -> NEED_MANAGER_CONFIRM PENDING_CONFIRM -> CANCELLED PENDING_CONFIRM -> FAILED NEED_MANAGER_CONFIRM -> CONFIRMED CONFIRMED -> CONVERTED CONFIRMED -> FAILED ``` 约束: 1. `FAILED`、`CANCELLED`、`CONVERTED` 为终态。 2. 未进入 `CONFIRMED` 的草稿不得转换。 3. `need_more_info`、`answered`、`context_summary` 是非草稿处理结果,不落 `ai_drafts.status`。 4. 多次补充/重说优先合并到同一个 `pending_draft`,直到老板确认、取消、过期或明确新建,不要求每次补充都新建草稿。 ## 3. 事项状态 | 状态 | 含义 | | --- | --- | | `pending_manager_confirm` | 等待程经理确认 | | `pending_notify` | 待通知 | | `notified` | 已通知 | | `notify_failed` | 通知失败 | | `feedback_received` | 已收到反馈 | | `completed` | 已完成 | | `problem` | 有问题 | | `cancelled` | 已取消 | 允许流转: ```text 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 ``` 约束: 1. `cancelled` 为终态。 2. 未通知事项不得接收飞书反馈。 3. `problem` 必须有问题原因。 4. 通知失败不得标记为 `notified`。 ## 4. 事项用户可见反馈状态 | 状态 | 含义 | | --- | --- | | `received` | 已收到 | | `in_progress` | 处理中 | | `completed` | 已完成 | | `problem` | 有问题 | 约束: 1. `problem` 必须填写 `problem_reason`。 2. 反馈人必须是事项接收人。 3. `received` 和 `in_progress` 反馈写入 `feedbacks.status`,并将 `tasks.status` 置为 `feedback_received`、`tasks.visible_feedback_status` 置为对应值。 4. `completed` 反馈将 `tasks.status` 和 `tasks.visible_feedback_status` 都置为 `completed`。 5. `problem` 反馈将 `tasks.status` 和 `tasks.visible_feedback_status` 都置为 `problem`,并写入 `problem_reason`。 ## 5. 提醒状态 | 状态 | 含义 | | --- | --- | | `active` | 生效中 | | `paused` | 已暂停 | | `triggered` | 一次性提醒已触发 | | `trigger_failed` | 触发失败 | | `cancelled` | 已取消 | | `expired` | 已过期 | 允许流转: ```text active -> paused paused -> active active -> triggered active -> trigger_failed trigger_failed -> active active -> cancelled paused -> cancelled trigger_failed -> cancelled triggered -> expired ``` 约束: 1. 只有 `active` 可以被 scheduler 触发。 2. `cancelled` 为终态。 3. `paused` 不触发通知。 4. `trigger_failed` 必须写失败记录。 5. 一次性提醒成功触发后,状态从 `active` 变为 `triggered`,并可在后续清理或展示时变为 `expired`。 6. `daily`、`weekly`、`monthly` 周期提醒成功触发后状态保持 `active`,只更新 `last_triggered_at` 和下一次 `next_trigger_at`。 7. 提醒反馈不改变提醒调度状态;反馈结果保存在 `feedbacks`,提醒是否继续触发只由 `status`、`repeat_rule` 和 `next_trigger_at` 决定。 ## 6. 重复规则 | 值 | 含义 | | --- | --- | | `none` | 一次性 | | `daily` | 每天 | | `weekly` | 每周 | | `monthly` | 每月 | 第一版不支持 cron 表达式和自定义复杂周期。 ## 7. 通知状态 | 状态 | 含义 | | --- | --- | | `pending` | 待发送 | | `sent` | 已发送 | | `failed` | 发送失败 | | `retrying` | 补发中 | | `cancelled` | 已取消 | 允许流转: ```text pending -> sent pending -> failed failed -> retrying retrying -> sent retrying -> failed pending -> cancelled failed -> cancelled ``` 约束: 1. `sent` 不得重复发送同一通知。 2. 补发必须保留原失败记录和新发送结果。 3. 飞书通知必须使用幂等键。 通知幂等键建议: ```text target_type + target_id + receiver_id + channel + trigger_time ``` 提醒触发幂等键建议: ```text reminder_id + trigger_time + receiver_id + notification_channel ``` ## 8. 反馈状态 | 状态 | 含义 | | --- | --- | | `received` | 已收到 | | `in_progress` | 处理中 | | `completed` | 已完成 | | `problem` | 有问题 | 约束: 1. 反馈目标只能是 `task` 或 `reminder`。 2. 反馈人必须是接收人。 3. `problem` 必须填写一句原因。 4. 重复点击卡片不得重复创建相同反馈。 ## 9. 失败记录状态 | 状态 | 含义 | | --- | --- | | `pending` | 待处理 | | `processing` | 处理中 | | `resolved` | 已处理 | | `cancelled` | 已取消 | 允许流转: ```text pending -> processing pending -> resolved pending -> cancelled processing -> resolved processing -> cancelled ``` 约束: 1. `resolved` 必须填写处理结果。 2. 状态变化必须写操作日志。 ## 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` | 已忽略 | 约束: 1. 同一 `event_id` 只处理一次。 2. 验签失败不得执行业务动作。 3. 处理失败必须写失败记录。 ## 12. 用户和配置状态 用户状态: | 状态 | 含义 | | --- | --- | | `active` | 启用 | | `disabled` | 停用 | 人员映射状态: | 状态 | 含义 | | --- | --- | | `pending` | 待解析 | | `resolved` | 已解析 | | `failed` | 解析失败 | Prompt 上下文状态: | 状态 | 含义 | | --- | --- | | `draft` | 草稿 | | `active` | 启用 | | `archived` | 已归档 | 飞书登录会话状态: | 状态 | 含义 | | --- | --- | | `pending` | 登录处理中 | | `success` | 登录成功 | | `failed` | 登录失败 | 机器人上下文状态: | 状态 | 含义 | | --- | --- | | `empty` | 当前没有可补充或可确认的草稿 | | `awaiting_more_info` | AI 已追问,等待老板补充 | | `awaiting_confirm` | 草稿已整理完成,等待老板确认、修改、取消或转经理 | | `expired` | 已过期 | | `cleared` | 草稿已确认、取消或转换完成,上下文已清空 |