93ba41ed79
- 新增 backend/app/api/approval.py 审批API - 前端H5支持发起审批、审批操作 - 添加审批卡片弹窗组件 - 路由注册审批模块
16 KiB
16 KiB
数据库 ER 图 + 环境变量清点
日期: 2026-06-15 审计人: Claude(满载跑批) 关联: 技术架构 / 风险跟踪表 / 前端审计报告
📌 1. ER 图(ASCII + Mermaid)
1.1 实体清单(16 张表)
| # | 表名 | 中文 | 模型文件 | 用途 |
|---|---|---|---|---|
| 1 | conversations |
会话 | conversation.py |
核心:员工-坐席咨询会话 |
| 2 | messages |
消息 | message.py |
会话内的所有消息 |
| 3 | agents |
坐席 | agent.py |
IT 服务人员 |
| 4 | employees |
员工 | employee.py |
通过 OAuth2 认证的员工 |
| 5 | agent_notes |
坐席备注 | agent_note.py |
坐席对会话的备注 |
| 6 | system_configs |
系统配置 | system_config.py |
动态配置(关键词/阈值) |
| 7 | config_change_logs |
配置变更日志 | config_change_log.py |
配置项的审计 |
| 8 | quick_reply_templates |
快速回复模板 | quick_reply_template.py |
坐席常用回复 |
| 9 | funny_phrases |
趣味话术 | funny_phrase.py |
等候中的趣味话 |
| 10 | approval_links |
审批流程链接 | approval_link.py |
各类审批入口 |
| 11 | software_downloads |
软件下载 | software_download.py |
常用软件清单 |
| 12 | troubleshooting_templates |
排障模板 | troubleshooting_template.py |
标准化排障路径 |
| 13 | todo_items |
待办事项 | todo_item.py |
工单/审批/设备 |
| 14 | roles |
角色 | role.py |
RBAC 角色定义 |
| 15 | user_roles |
用户-角色关联 | user_role.py |
多对多关联 |
| 16 | role_mapping_rules |
角色映射规则 | role_mapping_rule.py |
自动分配规则 |
1.2 ER 图(Mermaid)
erDiagram
EMPLOYEES ||--o{ CONVERSATIONS : "创建(通过 corp_id+employee_id)"
EMPLOYEES ||--o{ USER_ROLES : "拥有角色"
CONVERSATIONS ||--o{ MESSAGES : "包含"
CONVERSATIONS ||--o{ AGENT_NOTES : "有备注"
CONVERSATIONS }o--|| AGENTS : "被分配给"
AGENTS ||--o{ AGENT_NOTES : "写"
AGENTS ||--o{ QUICK_REPLY_TEMPLATES : "提交"
AGENTS ||--o{ CONFIG_CHANGE_LOGS : "改配置"
ROLES ||--o{ USER_ROLES : "分配给"
ROLES ||--o{ ROLE_MAPPING_RULES : "按规则映射"
CONVERSATIONS ||--o| TODO_ITEMS : "关联待办"
SYSTEM_CONFIGS ||--o{ CONFIG_CHANGE_LOGS : "被改"
EMPLOYEES {
string id PK "UUID"
string corp_id "企业ID"
string employee_id "企微UserID"
string name "姓名"
string department "部门(IDs)"
string position "岗位"
string mobile
string email
string avatar
int status "1激活 2禁用 4未激活"
string it_level "技能等级"
string it_level_source
json notes "坐席备注"
datetime last_login_at
datetime created_at
datetime updated_at
}
AGENTS {
string id PK
string user_id UK "企微UserID"
string name
string status "online/offline/busy"
int current_load
int max_load
string role "admin/agent"
json skill_tags
string otp_secret "TOTP密钥"
boolean otp_enabled
string password_hash "bcrypt"
datetime created_at
datetime updated_at
}
CONVERSATIONS {
string id PK
string corp_id
string employee_id
string employee_name
string department
string position
string level
string status "ai/queued/serving/resolved"
boolean is_vip
boolean is_pinned
boolean is_todo
int urgency_score "1-5"
json tags
string assigned_agent_id FK
json collaborating_agent_ids
json participants
int ai_substantive_reply_count
int impact_scope
boolean is_blocking
string emotion_state
string dify_conversation_id
datetime last_message_at
string last_message_summary
datetime created_at
datetime updated_at
}
MESSAGES {
string id PK
string conversation_id FK
string sender_type "employee/agent/ai/system"
string sender_id
string sender_name
text content
string msg_type "text/image/file/voice/system"
string reply_to_id "引用"
string media_id
string media_url
string file_name
int file_size
json extra_data
boolean ai_suggestion
string status "sending/sent/delivered/read"
datetime recallable_until
boolean is_read
string suggestion_action "accepted/edited/ignored"
datetime created_at
}
AGENT_NOTES {
string id PK
string conversation_id FK
string agent_id
text content
datetime created_at
datetime updated_at
}
SYSTEM_CONFIGS {
string id PK
string config_key UK
text config_value
string description
datetime updated_at
}
CONFIG_CHANGE_LOGS {
string id PK
string config_key
text old_value
text new_value
string changed_by
datetime changed_at
}
QUICK_REPLY_TEMPLATES {
string id PK
string category
string title
text content
json variables
int sort_order
string status "draft/pending/approved/rejected"
int version
string submitted_by
datetime created_at
datetime updated_at
}
FUNNY_PHRASES {
string id PK
string scene "shake/keyword/waiting/connected/timeout/vip"
text content
string tone
int sort_order
boolean is_active
datetime created_at
datetime updated_at
}
APPROVAL_LINKS {
string id PK
string category "IT/HR/行政/财务"
string title
text url
int sort_order
datetime created_at
datetime updated_at
}
SOFTWARE_DOWNLOADS {
string id PK
string category "办公/开发/安全/工具"
string name
string version
string platform
text download_url
int sort_order
datetime created_at
datetime updated_at
}
TROUBLESHOOTING_TEMPLATES {
string id PK
string name
string category "vpn/email/system/account"
json path_steps
json flowchart
boolean is_active
datetime created_at
datetime updated_at
}
TODO_ITEMS {
string id PK
string type "ticket/approval/device"
string title
string priority "urgent/high/normal"
json description
string status "pending/processing/resolved"
string assigned_agent_id
string corp_id
datetime created_at
datetime updated_at
}
ROLES {
string id PK
string name UK "user/agent/admin"
string display_name
text description
json permissions
boolean is_default
datetime created_at
datetime updated_at
}
USER_ROLES {
string id PK
string employee_id
string role_id FK
string source "auto/tag/ehr/manual"
string assigned_by
datetime assigned_at
datetime expires_at
}
ROLE_MAPPING_RULES {
string id PK
string role_id FK
string source_type "wecom_tag/ehr_position"
string source_value
int priority
boolean is_active
datetime created_at
}
1.3 ER 关系总结
┌────────────┐
│ EMPLOYEES │
│ (员工) │
└─────┬──────┘
│ corp_id + employee_id
┌─────────────┼─────────────┐
│ │ │
v v v
┌────────┐ ┌──────────────┐ ┌──────────────┐
│CONVER- │ │ USER_ROLES │ │TODO_ITEMS │
│SATIONS │ │ ↕ │ │(企业内待办) │
└──┬─────┘ │ ROLES │ └──────────────┘
│ │↕ │
│ │ROLE_MAPPING │
│ │_RULES │
│ └──────────────┘
│ 1:N
v
┌────────┐ 1:N ┌────────┐
│MESSAGES│◄─────│AGENT_ │
└────────┘ │NOTES │
└────┬───┘
│ 写
v
┌────────┐
┌──────────┐ │AGENTS │
│CONFIGS │ └───┬────┘
│ ↕ │ │ 改
│CHANGE │◄───────┘
│LOGS │
└──────────┘
关系数: 13 个外键关联 + 3 个 JSON 数组(协作/参与者/技能) 外键关系:
conversations.employee_id→ 企微 ID(无 DB FK,跨企业灵活)conversations.assigned_agent_id→agents.id(可空)messages.conversation_id→conversations.id(CASCADE)agent_notes.conversation_id→conversations.id(CASCADE)agent_notes.agent_id→agents.id(无 CASCADE)user_roles.role_id→roles.id(CASCADE)role_mapping_rules.role_id→roles.id(CASCADE)config_change_logs.changed_by→agents.id(无 FK)quick_reply_templates.submitted_by→agents.id(可空)
📌 2. 字段-模块映射
| 业务模块 | 主要表 | 关键字段 |
|---|---|---|
| 鉴权登录 | agents, employees, roles, user_roles |
user_id, password_hash, otp_secret, role |
| 会话管理 | conversations |
status, urgency_score, assigned_agent_id, is_vip |
| 消息 | messages |
sender_type, content, msg_type, reply_to_id |
| AI 助手 | conversations, system_configs |
dify_conversation_id, ai_substantive_reply_count |
| 排障 | troubleshooting_templates |
path_steps, flowchart |
| 快速回复 | quick_reply_templates |
category, content, variables |
| 待办 | todo_items |
type, status, priority |
| 工具面板 | approval_links, software_downloads, funny_phrases |
category, scene |
| 动态配置 | system_configs, config_change_logs |
config_key, config_value |
| 审计 | config_change_logs |
changed_by, changed_at, old_value, new_value |
📌 3. 数据规模评估(生产估算)
| 表 | 日增(估) | 总量/年 | 备注 |
|---|---|---|---|
conversations |
100-500 | 50K-100K | 视企业规模 |
messages |
1K-10K | 1M-3M | 高频 |
employees |
10-30 | 5K-20K | 增长慢 |
agents |
0-1 | 20-50 | 增长极慢 |
agent_notes |
50-200 | 30K-70K | 每会话 1-2 条 |
quick_reply_templates |
1-3 | 50-200 | 缓慢增长 |
system_configs |
0-1 | 50-100 | 极慢 |
config_change_logs |
5-20 | 5K-10K | 审计 |
todo_items |
50-200 | 30K-70K | 流转快 |
troubleshooting_templates |
0-1 | 30-50 | 缓慢 |
funny_phrases |
0 | 30-50 | 几乎不变 |
approval_links |
0-1 | 20-50 | 缓慢 |
software_downloads |
0-1 | 30-80 | 缓慢 |
roles |
0 | 3-10 | 几乎不变 |
user_roles |
5-15 | 5K-20K | 跟员工同步 |
role_mapping_rules |
0 | 5-15 | 几乎不变 |
总数据量估算: 第 1 年 ~5-10 MB(纯数据), 含索引 ~20-50 MB 建议: PostgreSQL 起步 10 GB 足够,3-5 年无需扩容
📌 4. 环境变量清点(15 个 + 4 个文档化待补)
4.1 后端核心(backend/app/config.py)
| # | 变量 | 类型 | 默认 | 必填 | 敏感 | 用途 |
|---|---|---|---|---|---|---|
| 1 | WECOM_CORP_ID |
str | ww1234... | ✅ | ❌ | 企微企业 ID |
| 2 | WECOM_AGENT_ID |
str | 1000002 | ✅ | ❌ | 企微应用 ID |
| 3 | WECOM_SECRET |
str | your-agent-secret | ✅ | 🔴 高 | 企微应用 Secret |
| 4 | WECOM_TOKEN |
str | your-callback-token | ✅ | 🟠 中 | 回调 Token |
| 5 | WECOM_ENCODING_AES_KEY |
str | your-aes-key-43-... | ✅ | 🟠 中 | 回调 AES Key |
| 6 | DATABASE_URL |
str | postgresql://wecom:... | ✅ | 🔴 高(密码部分) | DB 连接 |
| 7 | REDIS_URL |
str | redis://localhost:6379/0 | ✅ | 🟠 中(密码) | Redis 连接 |
| 8 | BACKEND_HOST |
str | 0.0.0.0 | ❌ | ❌ | 监听地址 |
| 9 | BACKEND_PORT |
int | 8000 | ❌ | ❌ | 监听端口 |
| 10 | CORS_ORIGINS |
str(逗号分隔) | localhost:5173,5174 | 🟡 生产必填 | ❌ | CORS 白名单 |
| 11 | DIFY_API_URL |
str | "" | 🟡 启用 AI 必填 | ❌ | Dify Chat 端点 |
| 12 | DIFY_API_KEY |
str | "" | 🟡 启用 AI 必填 | 🔴 高 | Dify API Key |
| 13 | DIFY_TIMEOUT |
int | 30 | ❌ | ❌ | Dify 超时 |
| 14 | DIFY_WINGMAN_API_URL |
str | "" | ❌ | ❌ | Wingman 端点 |
| 15 | DIFY_WINGMAN_API_KEY |
str | "" | ❌ | 🔴 高 | Wingman Key |
| 16 | DIFY_WINGMAN_TIMEOUT |
int | 30 | ❌ | ❌ | Wingman 超时 |
| 17 | MOCK_LOGIN_ENABLED |
bool | false | ❌ | ❌ | Mock 登录开关 |
合计 17 个(Settings 字段),5 个敏感(3 个 P0-高,2 个 P0-中)
4.2 部署相关(deploy-server/.env / deploy-nas/.env.nas)
| # | 变量 | 用途 |
|---|---|---|
| 18 | POSTGRES_USER |
DB 用户名 |
| 19 | POSTGRES_PASSWORD |
DB 密码(🔴) |
| 20 | POSTGRES_DB |
DB 名 |
| 21 | REDIS_PASSWORD |
Redis 密码(🔴) |
4.3 前端(Vue 4 个端)
| 前端 | 变量 | 用途 |
|---|---|---|
| admin | VITE_API_BASE_URL |
后端地址 |
| agent | VITE_API_BASE_URL, VITE_WS_URL |
后端 + WebSocket |
| h5 | VITE_API_BASE_URL, VITE_WS_URL |
同上 |
| portal | VITE_API_BASE_URL, VITE_PORTAL_REDIRECT |
入口跳转 |
4.4 漏配/待补
| # | 变量 | 状态 | 影响 |
|---|---|---|---|
| A | LOG_LEVEL |
❌ 缺失 | 日志粒度无法控制 |
| B | JWT_SECRET / SESSION_SECRET |
❌ 缺失 | token 加密用,但还没用 JWT |
| C | WS_TOKEN_SECRET |
❌ 缺失 | WS token 签名用 |
| D | DIFY_PROXY_URL |
❌ 文档化但未用 | 公司有内部 Dify,本项目直连 |
📌 5. 敏感凭据安全审计
5.1 现状
| # | 凭据 | 存储位置 | 风险 |
|---|---|---|---|
| 1 | WECOM_SECRET | .env.production(git?) |
🟠 中(看是否加 .gitignore) |
| 2 | POSTGRES_PASSWORD | .env.production |
🟠 中 |
| 3 | REDIS_PASSWORD | .env.production |
🟠 中 |
| 4 | DIFY_API_KEY | .env.production |
🟠 中 |
| 5 | 内部 Gitea tokens | wincred(✅) | 🟢 已修 |
5.2 待办(风险跟踪表 M-11)
.env.production是否在 .gitignore?(需确认).env.nas是否入仓?(文档明确说不入)- 公司有内部 Vault?目前直连 Dify
- WECOM_TOKEN / AES_KEY 走 vault(下一轮)
5.3 短期方案(本周)
# 1. 验证 .gitignore 覆盖
git check-ignore -v .env.production .env.nas backend/.env
# 2. 验证仓里无 secret
git log --all -p --source -- .env.production 2>/dev/null | head -20
# 3. 跑 gitleaks 扫描
bash scripts/security-audit.sh --secrets
5.4 长期方案(下季度)
- NAS Vault:用 Synology 的「密码保险箱」存关键 secret
- Server Keyring:用 systemd-creds / HashiCorp Vault
- 环境变量注入:容器启动时从 vault 拉,不入镜像
📌 6. 关联文档
- 技术架构 §3 数据层
- 风险跟踪表 M-11(凭据管理)/ D-3(DB 密码)
- 外部系统集成 §1-4(火绒/联软/aTrust/eHR 凭据)
- SOP-001-Gitea部署 - token 走 wincred
- Gitea部署指南 - Gitea app.ini 凭据
本清点是 2026-06-15 Claude 满载跑批产出,待评审