16 KiB
数据对象约定
本文件是核心表、字段、外键关系和状态字段的唯一事实源。Django model、serializer、接口返回和测试用例中的字段应与本文件一致。
1. 通用字段
多数业务表使用:
| 字段 | 说明 |
|---|---|
id |
主键,建议 bigint 或 uuid |
created_at |
创建时间 |
updated_at |
更新时间 |
created_by |
创建人,可为空时必须说明来源 |
updated_by |
最后修改人 |
deleted_at |
软删除时间,可选 |
remark |
备注,可选 |
第一版建议使用软删除,避免误删过程记录。
2. users
平台登录、角色判断和数据范围控制。Django 项目初始化时建议使用自定义用户模型。
| 字段 | 说明 |
|---|---|
id |
用户 ID |
username |
登录名或内部唯一标识 |
name |
显示姓名 |
role |
boss、manager、employee、admin |
phone |
手机号,可选,普通日志需脱敏 |
email |
邮箱,可选,普通日志需脱敏 |
feishu_open_id |
飞书 open_id,可选 |
feishu_user_id |
飞书 user_id,可选 |
feishu_union_id |
飞书 union_id,可选 |
auth_provider |
local、feishu |
last_login_channel |
platform、feishu_scan、feishu_in_app |
status |
active、disabled |
last_login_at |
最后登录时间 |
3. person_mappings
把老板输入中的姓名、称呼、部门或角色映射到平台用户和飞书身份。
| 字段 | 说明 |
|---|---|
id |
映射 ID |
user_id |
关联平台用户,可选 |
display_name |
标准姓名 |
aliases |
JSON 数组,例如 ["东东", "CJN"] |
department |
部门 |
business_role |
业务角色,例如行政、程经理、下单员 |
manager_user_id |
第一批试用管理范围归属,可选 |
phone |
手机号,可选 |
email |
邮箱,可选 |
feishu_open_id |
飞书 open_id |
feishu_user_id |
飞书 user_id,可选 |
feishu_union_id |
飞书 union_id,可选 |
mapping_status |
pending、resolved、failed |
is_trial_user |
是否第一批试用人员 |
note |
备注 |
口径:
users是登录、角色和权限判断的权威对象。person_mappings是自然语言称呼、手机号 / 邮箱、飞书身份和第一批试用人员映射的权威对象。- 同一个真实人员如果可以登录平台,应在
person_mappings.user_id绑定对应users.id。 - 程经理第一批试用管理范围先用
manager_user_id或等价白名单表达,不引入完整组织树。
4. feishu_auth_sessions
记录飞书登录过程和平台用户绑定结果。
| 字段 | 说明 |
|---|---|
id |
会话 ID |
state |
OAuth state 或登录状态标识 |
feishu_open_id |
飞书 open_id |
feishu_user_id |
飞书 user_id |
feishu_union_id |
飞书 union_id,可选 |
matched_user_id |
匹配到的平台用户 |
login_channel |
feishu_scan、feishu_in_app |
status |
pending、success、failed |
failure_reason |
失败原因 |
completed_at |
完成时间 |
5. secretary_conversations
老板 AI 秘书会话。第一阶段只有一个老板秘书入口,可先固定 conversation_id=boss_secretary_default,但表结构要能支持后续多会话。
| 字段 | 说明 |
|---|---|
id |
会话 ID |
conversation_id |
业务会话唯一标识 |
boss_id |
关联老板用户 |
source |
feishu、web、debug |
status |
active、closed |
last_message_at |
最近消息时间 |
6. secretary_messages
老板输入、AI 回复、AI 追问、普通记录和上下文回顾的统一消息记录。该表只追加,不修改,用于对话回放、上下文回顾和问题复盘。
| 字段 | 说明 |
|---|---|
id |
消息 ID |
conversation_id |
关联 secretary_conversations.conversation_id |
boss_id |
关联老板用户 |
source |
feishu、web、debug |
message_id |
外部消息 ID 或内部生成 ID,和 source 组成幂等键 |
role |
boss、assistant、system |
text |
原始输入或 AI 回复 |
answer |
AI 给老板的回复,可为空 |
intent_type |
task、reminder、qa、realtime_qa、note、need_more_info、unknown、unsupported、context_summary |
draft_id |
关联 AI 草稿,可为空 |
raw_payload |
原始请求摘要,避免保存密钥 |
bot_context_snapshot |
JSONB,消息发生时的上下文快照 |
created_at |
消息时间 |
7. bot_contexts
记录老板机器人私聊中的补充/重说上下文。
| 字段 | 说明 |
|---|---|
id |
上下文 ID |
conversation_id |
当前老板秘书会话 ID |
boss_id |
PostgreSQL 中的老板用户 ID |
status |
empty、awaiting_more_info、awaiting_confirm、awaiting_follow_up、expired、cleared |
pending_draft_id |
当前待补充或待确认的草稿 ID |
pending_draft_type |
task、reminder、none |
last_intent |
上一条有效意图 |
expires_at |
上下文有效期,进入待补充或待确认时重置为 30 分钟后 |
follow_up_count |
当前草稿累计追问轮次 |
last_message_id |
最近一次参与上下文判断的消息 ID |
extracted_facts |
JSONB,从多轮对话提取的候选事实,只用于草稿修订 |
updated_at |
上下文最近更新时间 |
awaiting_follow_up 专用于老板点击飞书确认卡片上的“补充/重说”后,等待下一条消息修订上一版草稿;该状态必须带 pending_draft_id 和 expires_at。
8. prompt_contexts
维护 AI 秘书调用模型时加载的上下文版本。
| 字段 | 说明 |
|---|---|
id |
上下文 ID |
context_type |
company_background_summary、boss_communication_style、ai_secretary_rules、role_and_alias_rules |
version |
版本号 |
title |
标题 |
content |
实际使用的摘要或规则文本 |
status |
draft、active、archived |
activated_at |
启用时间 |
created_by |
创建人 |
模型调用日志只保存本次使用的摘要、版本号和必要规则,避免反复保存完整背景库全文。
9. ai_drafts
保存 AI 从一句话整理出的可确认草稿。
| 字段 | 说明 |
|---|---|
id |
草稿 ID |
source |
platform、feishu_bot |
source_message_id |
飞书或外部入口消息 ID,可选 |
created_by |
发起人 |
parent_draft_id |
补充/重说生成新草稿时,关联上一版草稿 |
raw_input |
原始输入 |
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 |
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 |
取消原因 |
草稿生命周期口径:
- 每个草稿同一时间只能有一张有效确认卡片,对应
active_card_notification_id。 - 老板点击“补充/重说”后,原草稿进入
awaiting_follow_up,原确认卡片应失效。 - 30 分钟内收到补充消息后,系统生成新草稿,
parent_draft_id指向原草稿;原草稿进入superseded,superseded_by_draft_id指向新草稿。 - 超过 30 分钟仍未收到补充消息时,
bot_contexts标记为expired,原草稿进入expired;老板下一条消息按新输入处理。 note/unknown不进入事项、提醒或通知闭环;如需留痕,只能保存回复、消息、模型调用日志或最小草稿记录。
10. model_call_logs
记录模型输入输出、模型名、耗时和结果。
| 字段 | 说明 |
|---|---|
id |
日志 ID |
provider |
bailian |
model_name |
模型名 |
prompt_version |
提示词版本 |
background_context_version |
公司背景摘要版本 |
boss_style_version |
老板沟通风格版本 |
ai_secretary_rules_version |
AI 秘书业务规则版本 |
context_snapshot |
本次使用的上下文版本和摘要 |
input_text |
用户原始输入 |
request_payload |
请求摘要,避免保存密钥 |
response_payload |
模型原始响应结构 |
parsed_result |
后端解析后的 AiSecretaryResponse JSON |
status |
success、failed |
error_message |
失败原因 |
latency_ms |
耗时 |
created_by |
调用发起人 |
11. tasks
需要接收人处理并反馈的事情。
| 字段 | 说明 |
|---|---|
id |
事项 ID |
source_type |
ai_draft、manual |
source_draft_id |
来源草稿,可选 |
title |
标题 |
content |
事项内容 |
initiator_id |
发起人 |
receiver_id |
接收人;复杂事项在程经理确认前可为空 |
manager_id |
复杂事项确认人,可选 |
status |
见状态流转约定 |
visible_feedback_status |
received、in_progress、completed、problem |
requires_feedback |
是否需要反馈 |
due_at |
截止或期望反馈时间,可选 |
confirmed_at |
确认时间 |
notified_at |
通知时间 |
completed_at |
完成时间 |
problem_reason |
有问题原因,可选 |
复杂事项必须在老板确认后创建 status=pending_manager_confirm 的事项壳,不得一直停留在草稿中等待程经理补齐。
12. reminders
未来某个时间触发的提醒。
| 字段 | 说明 |
|---|---|
id |
提醒 ID |
source_type |
ai_draft、manual |
source_draft_id |
来源草稿,可选 |
related_task_id |
关联事项,可选 |
title |
标题 |
content |
提醒内容 |
initiator_id |
发起人 |
receiver_id |
接收人 |
status |
见状态流转约定 |
scheduled_at |
首次提醒时间 |
next_trigger_at |
下一次触发时间 |
recurrence_type |
none、daily、weekly、monthly |
requires_feedback |
是否需要反馈 |
last_triggered_at |
最近触发时间 |
cancelled_at |
取消时间 |
13. notifications
飞书或平台内通知发送记录。
| 字段 | 说明 |
|---|---|
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_personal、feishu_group、platform |
message_type |
text、card |
title |
通知标题 |
summary |
通知摘要 |
link_url |
平台详情链接 |
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 |
最近重试时间 |
提醒触发类通知的幂等键格式建议:
reminder:{reminder_id}:{trigger_time}:{receiver_id}:{channel}
任务通知、草稿确认卡片和程经理待确认提醒也必须生成各自的幂等键,避免重复点击、重复补发或回调重放造成多条有效通知。
14. feedbacks
接收人的反馈状态和问题原因。
| 字段 | 说明 |
|---|---|
id |
反馈 ID |
target_type |
task、reminder |
target_id |
关联对象 ID |
feedback_by |
反馈人 |
status |
received、in_progress、completed、problem |
problem_reason |
有问题原因,problem 时必填 |
source |
feishu_card、platform |
notification_id |
关联通知 |
created_at |
反馈时间 |
15. failure_records
AI、通知、回调、调度等失败原因。
| 字段 | 说明 |
|---|---|
id |
失败记录 ID |
failure_type |
见状态流转约定中的失败类型 |
target_type |
关联对象类型 |
target_id |
关联对象 ID |
status |
pending、processing、resolved、cancelled |
reason |
失败原因 |
raw_error |
原始错误摘要,不含密钥 |
need_manager_sync |
是否需要同步程经理 |
handled_by |
处理人 |
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
人工确认、修改、取消、补发等过程留痕。
| 字段 | 说明 |
|---|---|
id |
日志 ID |
actor_id |
操作人 |
action |
动作 |
target_type |
对象类型 |
target_id |
对象 ID |
channel |
platform、feishu_bot、feishu_card、scheduler、admin |
result |
success、failed |
summary |
操作摘要 |
metadata |
JSON,避免敏感明文 |
created_at |
操作时间 |
17. feishu_events
飞书回调原始事件和处理结果。
| 字段 | 说明 |
|---|---|
id |
事件 ID |
event_id |
飞书事件 ID |
event_type |
事件类型 |
operator_open_id |
操作人 open_id |
action_value |
按钮值 |
idempotency_key |
事件处理幂等键,可选 |
target_type |
ai_draft、task、reminder、auth、bot |
target_id |
关联业务对象 |
notification_id |
关联通知 |
raw_payload |
原始事件 |
process_status |
pending、processed、failed、ignored |
process_result |
处理结果 |
created_at |
接收时间 |
event_id 应尽量设置唯一约束;如果飞书某类回调没有稳定 event_id,则用 operator_open_id + action_value + notification_id + target_id 生成 idempotency_key 并唯一约束。重复事件只返回已处理结果,不重复创建草稿、事项、提醒、反馈或通知。
18. 敏感字段规则
phone、email可入库,但普通日志和普通列表接口默认脱敏。- API Key、App Secret、飞书 token、飞书回调验签密钥、OAuth code/state、一次性操作 token 明文不得入库到业务表或普通日志。
raw_error、metadata、request_payload、response_payload必须避免密钥和完整个人联系方式。- 飞书通知内容只保存和发送摘要,不展开敏感全文。
model_call_logs原始请求/响应和feishu_events.raw_payload仅供管理员 / AI 团队排查,普通员工不可见,老板和程经理只在必要业务范围内查看摘要。- 平台反馈页一次性操作 token 只能保存 hash,不能保存明文。