补充安全权限日志与草稿状态约定

This commit is contained in:
talesofzes
2026-06-22 17:30:59 +08:00
parent df0b3fa267
commit a41e2c28d4
19 changed files with 451 additions and 129 deletions
+75 -16
View File
@@ -50,6 +50,7 @@
| `aliases` | JSON 数组,例如 `["东东", "CJN"]` |
| `department` | 部门 |
| `business_role` | 业务角色,例如行政、程经理、下单员 |
| `manager_user_id` | 第一批试用管理范围归属,可选 |
| `phone` | 手机号,可选 |
| `email` | 邮箱,可选 |
| `feishu_open_id` | 飞书 open_id |
@@ -59,6 +60,13 @@
| `is_trial_user` | 是否第一批试用人员 |
| `note` | 备注 |
口径:
1. `users` 是登录、角色和权限判断的权威对象。
2. `person_mappings` 是自然语言称呼、手机号 / 邮箱、飞书身份和第一批试用人员映射的权威对象。
3. 同一个真实人员如果可以登录平台,应在 `person_mappings.user_id` 绑定对应 `users.id`
4. 程经理第一批试用管理范围先用 `manager_user_id` 或等价白名单表达,不引入完整组织树。
## 4. feishu_auth_sessions
记录飞书登录过程和平台用户绑定结果。
@@ -103,7 +111,7 @@
| `role` | `boss``assistant``system` |
| `text` | 原始输入或 AI 回复 |
| `answer` | AI 给老板的回复,可为空 |
| `intent_type` | `task``reminder``qa``realtime_qa``note``need_more_info``unsupported``context_summary` |
| `intent_type` | `task``reminder``qa``realtime_qa``note``need_more_info``unknown``unsupported``context_summary` |
| `draft_id` | 关联 AI 草稿,可为空 |
| `raw_payload` | 原始请求摘要,避免保存密钥 |
| `bot_context_snapshot` | JSONB,消息发生时的上下文快照 |
@@ -118,7 +126,7 @@
| `id` | 上下文 ID |
| `conversation_id` | 当前老板秘书会话 ID |
| `boss_id` | PostgreSQL 中的老板用户 ID |
| `status` | `empty``awaiting_more_info``awaiting_confirm``expired``cleared` |
| `status` | `empty``awaiting_more_info``awaiting_confirm``awaiting_follow_up``expired``cleared` |
| `pending_draft_id` | 当前待补充或待确认的草稿 ID |
| `pending_draft_type` | `task``reminder``none` |
| `last_intent` | 上一条有效意图 |
@@ -128,6 +136,8 @@
| `extracted_facts` | JSONB,从多轮对话提取的候选事实,只用于草稿修订 |
| `updated_at` | 上下文最近更新时间 |
`awaiting_follow_up` 专用于老板点击飞书确认卡片上的“补充/重说”后,等待下一条消息修订上一版草稿;该状态必须带 `pending_draft_id``expires_at`
## 8. prompt_contexts
维护 AI 秘书调用模型时加载的上下文版本。
@@ -153,26 +163,42 @@
| --- | --- |
| `id` | 草稿 ID |
| `source` | `platform``feishu_bot` |
| `source_message_id` | 飞书或外部入口消息 ID,可选 |
| `created_by` | 发起人 |
| `parent_draft_id` | 补充/重说生成新草稿时,关联上一版草稿 |
| `raw_input` | 原始输入 |
| `intent` | `task``reminder` |
| `draft_type` | `task``reminder` |
| `should_create_draft` | 固定为 true`qa/realtime_qa/note/need_more_info/unsupported` 不落 ai_drafts |
| `intent` | `task``reminder``qa``realtime_qa``note``need_more_info``unknown``unsupported` |
| `draft_type` | `task``reminder``none` |
| `should_create_draft` | `task/reminder` 为 true;其他意图必须为 false |
| `status` | 见状态流转约定 |
| `title` | 草稿标题 |
| `content` | 事项或提醒内容 |
| `receiver_candidates` | JSON,接收人候选和置信度 |
| `receiver_text` | 未映射成功时保留老板原始称呼 |
| `selected_receiver_id` | 人工确认后的接收人,可选 |
| `scheduled_at` | 提醒时间,可为空;任务可使用 `schedule_text` 表达期望时间 |
| `schedule_text` | 老板原始时间表达 |
| `recurrence_type` | `none``daily``weekly``monthly` |
| `requires_feedback` | 是否需要反馈 |
| `route_type` | `direct_after_boss_confirm``manager_confirm_required` |
| `route_type` | `none``direct_after_boss_confirm``manager_confirm_required` |
| `need_manager_confirm` | 是否需要程经理确认 |
| `missing_fields` | JSON 数组 |
| `questions` | JSON 数组,最多 3 个;确认草稿一般为空 |
| `answer` | 给老板看的回复摘要;不得写“已通知、已创建、已发送”等执行语义 |
| `active_card_notification_id` | 当前有效确认卡片通知,可选 |
| `superseded_by_draft_id` | 被补充/重说的新草稿替代时,指向新草稿 |
| `model_call_log_id` | 关联模型调用日志 |
| `confirmed_by` | 确认人 |
| `confirmed_at` | 确认时间 |
| `cancelled_reason` | 取消原因 |
草稿生命周期口径:
1. 每个草稿同一时间只能有一张有效确认卡片,对应 `active_card_notification_id`
2. 老板点击“补充/重说”后,原草稿进入 `awaiting_follow_up`,原确认卡片应失效。
3. 30 分钟内收到补充消息后,系统生成新草稿,`parent_draft_id` 指向原草稿;原草稿进入 `superseded``superseded_by_draft_id` 指向新草稿。
4. 超过 30 分钟仍未收到补充消息时,`bot_contexts` 标记为 `expired`,原草稿进入 `expired`;老板下一条消息按新输入处理。
5. `note` / `unknown` 不进入事项、提醒或通知闭环;如需留痕,只能保存回复、消息、模型调用日志或最小草稿记录。
## 10. model_call_logs
@@ -183,12 +209,17 @@
| `id` | 日志 ID |
| `provider` | `bailian` |
| `model_name` | 模型名 |
| `prompt_context_snapshot` | 本次使用的上下文版本和摘要 |
| `prompt_version` | 提示词版本 |
| `background_context_version` | 公司背景摘要版本 |
| `boss_style_version` | 老板沟通风格版本 |
| `ai_secretary_rules_version` | AI 秘书业务规则版本 |
| `context_snapshot` | 本次使用的上下文版本和摘要 |
| `input_text` | 用户原始输入 |
| `request_payload` | 请求摘要,避免保存密钥 |
| `raw_response` | 模型原始响应 |
| `parsed_json` | 解析后的 `AiSecretaryResponse` JSON |
| `response_payload` | 模型原始响应结构 |
| `parsed_result` | 后端解析后的 `AiSecretaryResponse` JSON |
| `status` | `success``failed` |
| `failure_reason` | 失败原因 |
| `error_message` | 失败原因 |
| `latency_ms` | 耗时 |
| `created_by` | 调用发起人 |
@@ -199,11 +230,12 @@
| 字段 | 说明 |
| --- | --- |
| `id` | 事项 ID |
| `source_type` | `ai_draft``manual` |
| `source_draft_id` | 来源草稿,可选 |
| `title` | 标题 |
| `content` | 事项内容 |
| `initiator_id` | 发起人 |
| `receiver_id` | 接收人 |
| `receiver_id` | 接收人;复杂事项在程经理确认前可为空 |
| `manager_id` | 复杂事项确认人,可选 |
| `status` | 见状态流转约定 |
| `visible_feedback_status` | `received``in_progress``completed``problem` |
@@ -214,6 +246,8 @@
| `completed_at` | 完成时间 |
| `problem_reason` | 有问题原因,可选 |
复杂事项必须在老板确认后创建 `status=pending_manager_confirm` 的事项壳,不得一直停留在草稿中等待程经理补齐。
## 12. reminders
未来某个时间触发的提醒。
@@ -221,6 +255,7 @@
| 字段 | 说明 |
| --- | --- |
| `id` | 提醒 ID |
| `source_type` | `ai_draft``manual` |
| `source_draft_id` | 来源草稿,可选 |
| `related_task_id` | 关联事项,可选 |
| `title` | 标题 |
@@ -244,16 +279,33 @@
| `id` | 通知 ID |
| `target_type` | `ai_draft``task``reminder``failure_record` |
| `target_id` | 关联对象 ID |
| `purpose` | `draft_confirm``manager_confirm``task_notify``reminder_trigger` |
| `receiver_id` | 接收人 |
| `channel` | `feishu``platform` |
| `channel` | `feishu_personal``feishu_group``platform` |
| `message_type` | `text``card` |
| `title` | 通知标题 |
| `summary` | 通知摘要 |
| `link_url` | 平台详情链接 |
| `status` | `pending``sent``failed``retrying``cancelled` |
| `idempotency_key` | 幂等键 |
| `card_id` | 飞书卡片 ID,可选 |
| `status` | `pending``sending``sent``failed``retrying``cancelled``expired` |
| `trigger_time` | 提醒触发时间;非提醒触发通知可为空 |
| `idempotency_key` | 幂等键,按通知目的生成并唯一约束 |
| `action_token_hash` | 平台反馈页一次性操作 token 的 hash,可选 |
| `feishu_message_id` | 飞书消息 ID |
| `sent_at` | 发送时间 |
| `expires_at` | 卡片或通知操作过期时间,可选 |
| `invalidated_at` | 被新卡片替代或业务取消时的失效时间,可选 |
| `failure_reason` | 失败原因 |
| `retry_count` | 重试次数 |
| `last_retry_at` | 最近重试时间 |
提醒触发类通知的幂等键格式建议:
```text
reminder:{reminder_id}:{trigger_time}:{receiver_id}:{channel}
```
任务通知、草稿确认卡片和程经理待确认提醒也必须生成各自的幂等键,避免重复点击、重复补发或回调重放造成多条有效通知。
## 14. feedbacks
@@ -289,6 +341,8 @@ AI、通知、回调、调度等失败原因。
| `handled_at` | 处理时间 |
| `handle_result` | 处理结果 |
`target_type` 可使用 `ai_draft``task``reminder``notification``feishu_event``model_call_log` 等实际对象类型。AI 解析失败时,如果无法创建最小 `parse_failed` 草稿,可关联 `model_call_log`
## 16. operation_logs
人工确认、修改、取消、补发等过程留痕。
@@ -317,6 +371,7 @@ AI、通知、回调、调度等失败原因。
| `event_type` | 事件类型 |
| `operator_open_id` | 操作人 open_id |
| `action_value` | 按钮值 |
| `idempotency_key` | 事件处理幂等键,可选 |
| `target_type` | `ai_draft``task``reminder``auth``bot` |
| `target_id` | 关联业务对象 |
| `notification_id` | 关联通知 |
@@ -325,9 +380,13 @@ AI、通知、回调、调度等失败原因。
| `process_result` | 处理结果 |
| `created_at` | 接收时间 |
`event_id` 应尽量设置唯一约束;如果飞书某类回调没有稳定 `event_id`,则用 `operator_open_id + action_value + notification_id + target_id` 生成 `idempotency_key` 并唯一约束。重复事件只返回已处理结果,不重复创建草稿、事项、提醒、反馈或通知。
## 18. 敏感字段规则
1. `phone``email` 可入库,但普通日志和普通列表接口默认脱敏。
2. API Key、App Secret、飞书 token 不得入库到业务表或普通日志。
3. `raw_error``metadata``request_payload` 必须避免密钥和完整个人联系方式。
2. API Key、App Secret、飞书 token、飞书回调验签密钥、OAuth code/state、一次性操作 token 明文不得入库到业务表或普通日志。
3. `raw_error``metadata``request_payload``response_payload` 必须避免密钥和完整个人联系方式。
4. 飞书通知内容只保存和发送摘要,不展开敏感全文。
5. `model_call_logs` 原始请求/响应和 `feishu_events.raw_payload` 仅供管理员 / AI 团队排查,普通员工不可见,老板和程经理只在必要业务范围内查看摘要。
6. 平台反馈页一次性操作 token 只能保存 hash,不能保存明文。