飞书通知与问答接入数据库设计
文档信息
| 项目 |
内容 |
| 需求分析文档 |
docs/1.需求分析/4.飞书通知与问答接入.md |
| 功能设计文档 |
docs/2.功能设计/4.飞书通知与问答接入.md |
| 数据库类型 |
SQLite / Django ORM |
| 表名前缀 |
ra_ |
| 设计日期 |
2026-06-07 |
| 设计版本 |
V1.0 |
一、设计原则
| 原则 |
说明 |
| 统一通知抽象 |
三个工作流共用统一通知服务和通用通知记录,减少重复实现 |
| 兼容现有表 |
现有法规通知、填表通知可保留;新增通用表作为后续统一入口 |
| 可判重 |
通知记录必须支持同一批次、同一流程、同一状态只发送一次 |
| 摘要入库 |
只保存发送摘要、状态、错误,不保存完整富文本 payload |
| 映射可维护 |
系统用户与飞书用户映射独立建表,通过 Django Admin 维护 |
| 问答可扩展 |
预留问答日志表,首期可不接事件回调 |
| SQLite 兼容 |
使用 Django ORM 常规字段,避免数据库特有能力 |
二、ER 图
三、表结构设计
3.1 ra_feishu_user_mapping
系统用户与飞书用户标识映射表。首期通知发送给环境变量中配置的指定个人账号,本表通过 Django Admin 手工维护,用于后续按发起人私聊通知和飞书私聊问答身份识别。
| 字段名 |
Django 类型 |
SQLite 类型 |
必填 |
说明 |
| id |
BigAutoField |
integer |
是 |
主键 |
| system_user_id |
ForeignKey |
bigint |
是 |
关联 Django 用户 |
| feishu_display_name |
CharField(120) |
varchar(120) |
否 |
飞书展示名,便于后台识别 |
| feishu_open_id |
CharField(120) |
varchar(120) |
否 |
飞书 open_id,优先用于 @ |
| feishu_user_id |
CharField(120) |
varchar(120) |
否 |
飞书 user_id,第二优先级 |
| feishu_mobile |
CharField(40) |
varchar(40) |
否 |
飞书手机号,兜底 |
| is_active |
BooleanField |
bool |
是 |
是否启用 |
| remark |
CharField(255) |
varchar(255) |
否 |
备注 |
| created_at |
DateTimeField |
datetime |
是 |
创建时间 |
| updated_at |
DateTimeField |
datetime |
是 |
更新时间 |
约束:
| 约束名 |
字段 |
说明 |
| uq_ra_feishu_mapping_user |
system_user_id |
一个系统用户首期只维护一条启用映射 |
索引:
| 索引名 |
字段 |
说明 |
| idx_ra_feishu_mapping_active |
is_active |
后台筛选启用映射 |
| idx_ra_feishu_mapping_open |
feishu_open_id |
后续私聊事件反查用户 |
| idx_ra_feishu_mapping_userid |
feishu_user_id |
后续私聊事件反查用户 |
| idx_ra_feishu_mapping_mobile |
feishu_mobile |
手机号兜底查询 |
校验规则:
| 规则 |
说明 |
| 至少一个飞书标识 |
feishu_open_id、feishu_user_id、feishu_mobile 至少填写一个 |
| @ 优先级 |
feishu_open_id -> feishu_user_id -> feishu_mobile |
3.2 ra_workflow_notification_record
通用工作流通知记录表。用于记录自动汇总、法规核查、自动填表的飞书通知发送结果。现有专项通知表可继续保留,后续逐步收敛到本表。
| 字段名 |
Django 类型 |
SQLite 类型 |
必填 |
说明 |
| id |
BigAutoField |
integer |
是 |
主键 |
| workflow_type |
CharField(40) |
varchar(40) |
是 |
file_summary、regulatory_review、application_form_fill |
| workflow_batch_id |
PositiveBigIntegerField |
bigint |
是 |
对应工作流批次 ID |
| workflow_batch_no |
CharField(80) |
varchar(80) |
是 |
批次编号冗余,便于展示 |
| workflow_status |
CharField(40) |
varchar(40) |
是 |
success、partial_success、failed 等 |
| dedupe_key |
CharField(160) |
varchar(160) |
是 |
判重键 |
| trigger_user_id |
ForeignKey |
bigint |
是 |
发起人或上传人 |
| feishu_mapping_id |
ForeignKey |
bigint |
否 |
命中的飞书用户映射 |
| channel |
CharField(40) |
varchar(40) |
是 |
mock、feishu_api、disabled |
| target |
CharField(160) |
varchar(160) |
否 |
指定个人账号名称、open_id、user_id 或目标标识 |
| at_display_name |
CharField(120) |
varchar(120) |
否 |
被 @ 人展示名 |
| at_identifier_type |
CharField(30) |
varchar(30) |
否 |
open_id、user_id、mobile、missing |
| at_identifier_masked |
CharField(120) |
varchar(120) |
否 |
脱敏后的 @ 标识 |
| send_status |
CharField(30) |
varchar(30) |
是 |
pending、success、failed、skipped_duplicate、disabled |
| message_title |
CharField(200) |
varchar(200) |
是 |
通知标题 |
| message_summary |
TextField |
text |
否 |
发送摘要,不保存完整 payload |
| result_url |
CharField(500) |
varchar(500) |
否 |
系统结果入口 |
| external_message_id |
CharField(120) |
varchar(120) |
否 |
Webhook 一般为空,API 发送时保存 |
| error_code |
CharField(80) |
varchar(80) |
否 |
飞书或客户端错误码 |
| error_message |
TextField |
text |
否 |
失败原因 |
| request_duration_ms |
PositiveIntegerField |
integer |
否 |
HTTP 请求耗时 |
| sent_at |
DateTimeField |
datetime |
否 |
成功发送时间 |
| created_at |
DateTimeField |
datetime |
是 |
创建时间 |
| updated_at |
DateTimeField |
datetime |
是 |
更新时间 |
唯一约束:
| 约束名 |
字段 |
说明 |
| uq_ra_notify_dedupe_key |
dedupe_key |
同一批次、流程、状态只保留一个成功发送意图 |
索引:
| 索引名 |
字段 |
说明 |
| idx_ra_notify_workflow |
workflow_type, workflow_batch_id |
批次详情页查询通知 |
| idx_ra_notify_user_created |
trigger_user_id, created_at |
用户通知历史 |
| idx_ra_notify_status |
send_status, created_at |
排查失败通知 |
| idx_ra_notify_batch_no |
workflow_batch_no |
按批次编号检索 |
dedupe_key 生成规则:
3.3 ra_feishu_question_log
飞书问答日志预留表。首期可创建表但不接入事件回调;后续私聊问答 MVP 使用该表记录问题、意图、查询对象、回答摘要和错误信息。
| 字段名 |
Django 类型 |
SQLite 类型 |
必填 |
说明 |
| id |
BigAutoField |
integer |
是 |
主键 |
| system_user_id |
ForeignKey |
bigint |
否 |
识别出的系统用户 |
| feishu_mapping_id |
ForeignKey |
bigint |
否 |
命中的飞书映射 |
| feishu_open_id |
CharField(120) |
varchar(120) |
否 |
事件中的 open_id |
| feishu_user_id |
CharField(120) |
varchar(120) |
否 |
事件中的 user_id |
| source_type |
CharField(30) |
varchar(30) |
是 |
private_chat、group_mention |
| message_id |
CharField(120) |
varchar(120) |
否 |
飞书消息 ID |
| question_text |
TextField |
text |
是 |
用户原始问题 |
| intent |
CharField(60) |
varchar(60) |
否 |
batch_status、risk_summary、export_summary 等 |
| query_object |
JSONField |
text/json |
是 |
批次号、工作流类型、最近批次等查询对象 |
| answer_summary |
TextField |
text |
否 |
回答摘要,不保存完整回答正文 |
| permission_result |
CharField(40) |
varchar(40) |
否 |
allowed、denied、unbound |
| status |
CharField(30) |
varchar(30) |
是 |
success、failed、ignored |
| error_message |
TextField |
text |
否 |
异常说明 |
| processed_at |
DateTimeField |
datetime |
否 |
处理完成时间 |
| created_at |
DateTimeField |
datetime |
是 |
创建时间 |
索引:
| 索引名 |
字段 |
说明 |
| idx_ra_feishu_q_user_created |
system_user_id, created_at |
用户问答历史 |
| idx_ra_feishu_q_intent |
intent, created_at |
按意图分析 |
| idx_ra_feishu_q_status |
status, created_at |
排查失败问答 |
| idx_ra_feishu_q_message |
message_id |
消息幂等 |
四、状态枚举
4.1 WorkflowNotificationRecord.channel
| 值 |
说明 |
| mock |
模拟通知 |
| disabled |
真实通知未启用 |
| feishu_api |
飞书官方智能体/企业自建应用消息 API |
| feishu_webhook |
备选自定义机器人 Webhook,非首期主方案 |
4.2 WorkflowNotificationRecord.send_status
| 值 |
说明 |
| pending |
待发送 |
| success |
发送成功 |
| failed |
发送失败 |
| skipped_duplicate |
重复通知跳过 |
| disabled |
未启用真实发送 |
4.3 FeishuQuestionLog.intent
| 值 |
说明 |
| batch_status |
查询批次状态 |
| risk_summary |
查询风险摘要 |
| missing_summary |
查询缺失摘要 |
| export_summary |
查询导出摘要 |
| unknown |
未识别 |
五、与现有表的兼容关系
| 现有表 |
处理建议 |
ra_regulatory_notification_record |
保留现有数据;法规核查真实飞书通知可新增写入通用表,后续再决定是否迁移 |
ra_application_form_fill_notification_record |
保留现有数据;自动填表通知状态展示可优先读通用表,兼容旧表 |
ra_exported_summary_file |
通知摘要中的导出文件数量来自该表 |
ra_workflow_event |
可记录通知节点事件,但不替代通知记录表 |
auth_user |
飞书映射通过外键关联系统用户 |
六、数据脱敏与安全
| 数据 |
入库策略 |
| App ID |
不入库,只在环境变量中维护 |
| App Secret |
不入库,只在环境变量中维护 |
| tenant_access_token |
不持久化入库,仅允许进程内短期缓存 |
| 富文本完整 payload |
不入库 |
| 手机号 |
映射表保存原值;通知记录只保存脱敏值 |
| open_id/user_id |
映射表保存原值;通知记录保存脱敏值 |
| 用户问题 |
问答日志保存原始问题,用于审计;不保存完整回答正文 |
七、迁移计划
| 步骤 |
说明 |
| 1 |
新增 FeishuUserMapping 模型和迁移 |
| 2 |
新增 WorkflowNotificationRecord 模型和迁移 |
| 3 |
新增 FeishuQuestionLog 预留模型和迁移 |
| 4 |
注册 Django Admin 管理入口 |
| 5 |
批次详情页查询通用通知记录展示 |
| 6 |
保留现有专项通知表,不做破坏性迁移 |
八、验收 SQL 示例
查询某个批次通知状态:
查询未配置飞书映射的失败或降级通知:
查询飞书用户映射: