feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# 核心业务规则总览
|
||||
|
||||
> **鐗堟湰锛?* v1.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-10-10
|
||||
> **閫傜敤鑼冨洿锛?* 鏁翠釜绯荤粺
|
||||
> **版本:** v1.0
|
||||
> **创建日期:** 2025-10-10
|
||||
> **适用范围:** 整个系统
|
||||
|
||||
---
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
1. [用户管理规则](#用户管理规则)
|
||||
2. [项目管理规则](#项目管理规则)
|
||||
3. [鏅鸿兘浣撶<EFBFBD>鐞嗚<EFBFBD>鍒橾(#鏅鸿兘浣撶<EFBFBD>鐞嗚<EFBFBD>鍒?
|
||||
3. [智能体管理规则](#智能体管理规则)
|
||||
4. [对话管理规则](#对话管理规则)
|
||||
5. [鐭ヨ瘑搴撶<EFBFBD>鐞嗚<EFBFBD>鍒橾(#鐭ヨ瘑搴撶<EFBFBD>鐞嗚<EFBFBD>鍒?
|
||||
5. [知识库管理规则](#知识库管理规则)
|
||||
6. [权限控制规则](#权限控制规则)
|
||||
7. [配额限制规则](#配额限制规则)
|
||||
|
||||
@@ -22,43 +22,43 @@
|
||||
|
||||
### 注册规则
|
||||
|
||||
**BR-U001: 閭<EFBFBD><EFBFBD>鍞<EFBFBD>竴鎬?*
|
||||
- 瑙勫垯锛氭瘡涓<EFBFBD>偖绠卞彧鑳芥敞鍐屼竴涓<EFBFBD>处鍙?
|
||||
**BR-U001: 邮箱唯一性**
|
||||
- 规则:每个邮箱只能注册一个账号
|
||||
- 验证时机:注册时
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?璇ラ偖绠卞凡琚<E587A1>敞鍐?
|
||||
- 错误提示:"该邮箱已被注册"
|
||||
|
||||
**BR-U002: 邮箱格式验证**
|
||||
- 瑙勫垯锛氬繀椤绘槸鏈夋晥鐨勯偖绠辨牸寮?
|
||||
- 规则:必须是有效的邮箱格式
|
||||
- 正则:`^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$`
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?閭<><E996AD>鏍煎紡涓嶆<E6B693>纭?
|
||||
- 错误提示:"邮箱格式不正确"
|
||||
|
||||
**BR-U003: 密码强度**
|
||||
- 瑙勫垯锛氬瘑鐮佽嚦灏?浣嶏紝鍖呭惈瀛楁瘝鍜屾暟瀛?
|
||||
- 规则:密码至少8位,包含字母和数字
|
||||
- 正则:`^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$`
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?瀵嗙爜鑷冲皯8浣嶏紝闇€鍖呭惈瀛楁瘝鍜屾暟瀛?
|
||||
- 错误提示:"密码至少8位,需包含字母和数字"
|
||||
|
||||
**BR-U004: 榛樿<EFBFBD>璇曠敤鏈?*
|
||||
**BR-U004: 默认试用期**
|
||||
- 规则:新用户默认获得30天试用期
|
||||
- 实现:`trial_ends_at = now() + 30天`
|
||||
|
||||
### 登录规则
|
||||
|
||||
**BR-U005: 璐︽埛鐘舵€佹<EFBFBD>鏌?*
|
||||
- 瑙勫垯锛氬彧鏈塻tatus=active鐨勭敤鎴峰彲浠ョ櫥褰?
|
||||
**BR-U005: 账户状态检查**
|
||||
- 规则:只有status=active的用户可以登录
|
||||
- 状态:
|
||||
- `active` - 鍙<EFBFBD>櫥褰?
|
||||
- `active` - 可登录
|
||||
- `inactive` - 未激活,不可登录
|
||||
- `suspended` - 已暂停,不可登录
|
||||
|
||||
**BR-U006: 密码错误次数限制**
|
||||
- 瑙勫垯锛?鍒嗛挓鍐呮渶澶?娆¢敊璇<E6958A>皾璇?
|
||||
- 瓒呰繃娆℃暟锛氫复鏃堕攣瀹氳处鎴?5鍒嗛挓
|
||||
- 规则:5分钟内最多5次错误尝试
|
||||
- 超过次数:临时锁定账户15分钟
|
||||
- 实现:使用Redis记录失败次数
|
||||
|
||||
**BR-U007: JWT Token鏈夋晥鏈?*
|
||||
- Access Token锛?澶?
|
||||
- Refresh Token锛?0澶?
|
||||
- 杩囨湡鍚庨渶瑕侀噸鏂扮櫥褰?
|
||||
**BR-U007: JWT Token有效期**
|
||||
- Access Token:7天
|
||||
- Refresh Token:30天
|
||||
- 过期后需要重新登录
|
||||
|
||||
---
|
||||
|
||||
@@ -66,92 +66,92 @@
|
||||
|
||||
### 创建规则
|
||||
|
||||
**BR-P001: 椤圭洰鏁伴噺鏃犻檺鍒?*
|
||||
**BR-P001: 项目数量无限制**
|
||||
- 规则:用户可以创建任意数量的项目
|
||||
- 鐞嗙敱锛氶」鐩<EFBFBD>槸鏍稿績鍔熻兘锛屼笉搴旈檺鍒?
|
||||
- 理由:项目是核心功能,不应限制
|
||||
|
||||
**BR-P002: 项目名称必填**
|
||||
- 瑙勫垯锛氶」鐩<EFBFBD>悕绉颁笉鑳戒负绌?
|
||||
- 闀垮害锛?-200瀛楃<EFBFBD>
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?椤圭洰鍚嶇О涓嶈兘涓虹┖"
|
||||
- 规则:项目名称不能为空
|
||||
- 长度:1-200字符
|
||||
- 错误提示:"项目名称不能为空"
|
||||
|
||||
**BR-P003: 项目描述必填**
|
||||
- 规则:项目描述不能为空(用于上下文注入)
|
||||
- 最小长度:10字符
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?璇疯緭鍏ラ」鐩<E3808D>儗鏅<E58497>俊鎭<E4BF8A>紝鑷冲皯10涓<30>瓧绗?
|
||||
- 错误提示:"请输入项目背景信息,至少10个字符"
|
||||
|
||||
### 更新规则
|
||||
|
||||
**BR-P004: 椤圭洰鑳屾櫙鍔ㄦ€佹洿鏂?*
|
||||
- 瑙勫垯锛氱敤鎴峰彲浠ラ殢鏃剁紪杈戦」鐩<EFBFBD>弿杩?
|
||||
- 瑙勫垯锛氬彲浠?鍥哄畾"AI鍥炲<E98DA5>鍒伴」鐩<E3808D>弿杩颁腑
|
||||
**BR-P004: 项目背景动态更新**
|
||||
- 规则:用户可以随时编辑项目描述
|
||||
- 规则:可以"固定"AI回复到项目描述中
|
||||
- 实现:追加到description字段末尾
|
||||
|
||||
**BR-P005: 项目所有权验证**
|
||||
- 瑙勫垯锛氬彧鑳戒慨鏀?鍒犻櫎鑷<E6AB8E>繁鐨勯」鐩?
|
||||
- 规则:只能修改/删除自己的项目
|
||||
- 验证:`project.userId === currentUser.id`
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?鏃犳潈闄愭搷浣滆<E6B5A3>椤圭洰"
|
||||
- 错误提示:"无权限操作该项目"
|
||||
|
||||
### 删除规则
|
||||
|
||||
**BR-P006: 级联删除**
|
||||
- 规则:删除项目时,级联删除其所有对话和消息
|
||||
- 实现:数据库ON DELETE CASCADE
|
||||
- 纭<EFBFBD><EFBFBD>锛氬墠绔<EFBFBD>渶瑕佷簩娆$‘璁?
|
||||
- 确认:前端需要二次确认
|
||||
|
||||
**BR-P007: 软删除(可选)**
|
||||
- 瑙勫垯锛氶噸瑕侀」鐩<EFBFBD>彲浠ュ厛杞<EFBFBD>垹闄わ紝淇濈暀30澶?
|
||||
- 规则:重要项目可以先软删除,保留30天
|
||||
- 实现:添加deleted_at字段
|
||||
- 澶囨敞锛氬綋鍓嶇増鏈<EFBFBD>殏涓嶅疄鐜?
|
||||
- 备注:当前版本暂不实现
|
||||
|
||||
---
|
||||
|
||||
## 鏅鸿兘浣撶<EFBFBD>鐞嗚<EFBFBD>鍒?
|
||||
## 智能体管理规则
|
||||
|
||||
### 鏅鸿兘浣撻厤缃?
|
||||
### 智能体配置
|
||||
|
||||
**BR-A001: 智能体配置化管理**
|
||||
- 规则:智能体配置存储在`config/agents.yaml`
|
||||
- 瑙勫垯锛氫笉閫氳繃鏁版嵁搴撶<EFBFBD>鐞?
|
||||
- 瑙勫垯锛氫慨鏀归厤缃<EFBFBD>悗闇€瑕侀噸鍚<EFBFBD>湇鍔?
|
||||
- 规则:不通过数据库管理
|
||||
- 规则:修改配置后需要重启服务
|
||||
|
||||
**BR-A002: 鏅鸿兘浣撶姸鎬?*
|
||||
**BR-A002: 智能体状态**
|
||||
- `active` - 可用,用户可以选择
|
||||
- `inactive` - 不可用,隐藏
|
||||
- `testing` - 测试中,仅管理员可见
|
||||
|
||||
**BR-A003: 鏅鸿兘浣撳垎绫?*
|
||||
- 閫夐<EFBFBD>闃舵<EFBFBD>锛氶€夐<EFBFBD>璇勪环銆佺<EFBFBD>瀛﹂棶棰樻⒊鐞?
|
||||
- 鐮旂┒璁捐<EFBFBD>锛歅ICOS鏋勫缓銆佽<EFBFBD>瀵熸寚鏍囪<EFBFBD>璁°€丆RF鍒跺畾銆佹牱鏈<EFBFBD>噺璁$畻銆佷复搴婄爺绌舵柟妗堟挵鍐?
|
||||
- 璁烘枃闃舵<EFBFBD>锛氳<EFBFBD>鏂囨鼎鑹层€佽<EFBFBD>鏂囩炕璇戙€佹柟娉曞<EFBFBD>璇勫<EFBFBD>銆佹湡鍒婃柟娉曞<EFBFBD>璇勫<EFBFBD>銆佹湡鍒婄ǹ绾﹁瘎瀹?
|
||||
**BR-A003: 智能体分类**
|
||||
- 选题阶段:选题评价、科学问题梳理
|
||||
- 研究设计:PICOS构建、观察指标设计、CRF制定、样本量计算、临床研究方案撰写
|
||||
- 论文阶段:论文润色、论文翻译、方法学评审、期刊方法学评审、期刊稿约评审
|
||||
|
||||
### Prompt管理
|
||||
|
||||
**BR-A004: Prompt文件管理**
|
||||
- 规则:Prompt存储在`backend/prompts/`目录
|
||||
- 鍛藉悕锛歚{agent_id}_system.txt` 鍜?`{agent_id}_user.txt`
|
||||
- 命名:`{agent_id}_system.txt` 和 `{agent_id}_user.txt`
|
||||
- 版本:通过Git管理版本
|
||||
|
||||
**BR-A005: Prompt变量注入**
|
||||
- 瑙勫垯锛歅rompt涓<EFBFBD>彲浠ヤ娇鐢ㄥ彉閲?
|
||||
- 规则:Prompt中可以使用变量
|
||||
- 格式:`{variable_name}`
|
||||
- 示例:`{project_description}`, `{user_question}`
|
||||
|
||||
### 模型配置
|
||||
|
||||
**BR-A006: 模型参数配置**
|
||||
- 瑙勫垯锛氭瘡涓<EFBFBD>櫤鑳戒綋鍙<EFBFBD>互閰嶇疆涓嶅悓妯″瀷鐨勫弬鏁?
|
||||
- 鍙傛暟锛?
|
||||
- 规则:每个智能体可以配置不同模型的参数
|
||||
- 参数:
|
||||
- `temperature`: 0.0-1.0
|
||||
- `max_tokens`: 鏈€澶ц緭鍑簍oken鏁?
|
||||
- `max_tokens`: 最大输出token数
|
||||
- `top_p`: 0.0-1.0
|
||||
|
||||
**BR-A007: 模型切换**
|
||||
- 瑙勫垯锛氱敤鎴峰彲浠ュ湪瀵硅瘽涓<EFBFBD>垏鎹㈡ā鍨?
|
||||
- 规则:用户可以在对话中切换模型
|
||||
- 可选模型:
|
||||
- `deepseek-v3` (默认)
|
||||
- `qwen3-72b`
|
||||
- `gemini-2.0-flash` (鍙<EFBFBD>€?
|
||||
- `gemini-2.0-flash` (可选)
|
||||
|
||||
---
|
||||
|
||||
@@ -160,40 +160,40 @@
|
||||
### 创建对话
|
||||
|
||||
**BR-C001: 对话归属**
|
||||
- 瑙勫垯锛氬<EFBFBD>璇濆彲浠ュ睘浜庨」鐩<EFBFBD>紝涔熷彲浠ユ槸鍏ㄥ眬蹇<EFBFBD>€熼棶绛?
|
||||
- 规则:对话可以属于项目,也可以是全局快速问答
|
||||
- 项目对话:`projectId` 不为null
|
||||
- 全局快速问答:`projectId` 为null
|
||||
|
||||
**BR-C002: 对话标题自动生成**
|
||||
- 瑙勫垯锛氶<EFBFBD>娆″垱寤哄<EFBFBD>璇濇椂锛屾爣棰樹负"涓巤鏅鸿兘浣撳悕绉皚鐨勫<E990A8>璇?
|
||||
- 瑙勫垯锛氬彲浠ユ墜鍔ㄤ慨鏀规爣棰?
|
||||
- 规则:首次创建对话时,标题为"与{智能体名称}的对话"
|
||||
- 规则:可以手动修改标题
|
||||
|
||||
### 涓婁笅鏂囩<EFBFBD>鐞?
|
||||
### 上下文管理
|
||||
|
||||
**BR-C003: 项目背景自动注入**
|
||||
- 瑙勫垯锛氬<EFBFBD>鏋滃<EFBFBD>璇濆睘浜庨」鐩<EFBFBD>紝鑷<EFBFBD>姩灏嗛」鐩甦escription娉ㄥ叆涓婁笅鏂?
|
||||
- 规则:如果对话属于项目,自动将项目description注入上下文
|
||||
- 注入位置:System prompt之后
|
||||
- 格式:`# 项目背景\n{project.description}`
|
||||
|
||||
**BR-C004: 历史对话管理**
|
||||
- 瑙勫垯锛氫繚鐣欐渶杩?0杞<30><E69D9E>璇濅綔涓轰笂涓嬫枃
|
||||
- 瑙勫垯锛氳秴杩?0杞<30>殑瀵硅瘽锛岃繘琛屾憳瑕佸帇缂?
|
||||
- 规则:保留最近10轮对话作为上下文
|
||||
- 规则:超过10轮的对话,进行摘要压缩
|
||||
- Token限制:上下文总token数不超过6000
|
||||
|
||||
**BR-C005: 鐭ヨ瘑搴撳紩鐢?*
|
||||
- 瑙勫垯锛氱敤鎴峰彲浠ラ€氳繃`@鐭ヨ瘑搴撳悕绉癭寮曠敤鐭ヨ瘑搴?
|
||||
- 瑙勫垯锛氭渶澶氬悓鏃跺紩鐢?涓<>煡璇嗗簱
|
||||
**BR-C005: 知识库引用**
|
||||
- 规则:用户可以通过`@知识库名称`引用知识库
|
||||
- 规则:最多同时引用3个知识库
|
||||
- 检索数量:每个知识库检索Top 5结果
|
||||
|
||||
### 消息固定
|
||||
|
||||
**BR-C006: 鍥哄畾娑堟伅鍒伴」鐩<EFBFBD>儗鏅?*
|
||||
- 瑙勫垯锛氬彧鏈堿I鍥炲<EFBFBD>鍙<EFBFBD>互琚<EFBFBD>浐瀹?
|
||||
- 瑙勫垯锛氬彧鏈夐」鐩<EFBFBD>唴瀵硅瘽鍙<EFBFBD>互鍥哄畾锛堝叏灞€瀵硅瘽涓嶅彲锛?
|
||||
**BR-C006: 固定消息到项目背景**
|
||||
- 规则:只有AI回复可以被固定
|
||||
- 规则:只有项目内对话可以固定(全局对话不可)
|
||||
- 实现:追加到project.description末尾
|
||||
- 鏍煎紡锛?
|
||||
- 格式:
|
||||
```
|
||||
--- 鏉ヨ嚜瀵硅瘽鐨勮ˉ鍏?---
|
||||
--- 来自对话的补充 ---
|
||||
{message.content}
|
||||
```
|
||||
|
||||
@@ -205,83 +205,83 @@
|
||||
|
||||
**BR-C008: Server-Sent Events**
|
||||
- 规则:使用SSE实现流式输出
|
||||
- 浜嬩欢绫诲瀷锛?
|
||||
- `start`: 寮€濮嬬敓鎴?
|
||||
- 事件类型:
|
||||
- `start`: 开始生成
|
||||
- `token`: 每个token
|
||||
- `done`: 完成
|
||||
- `error`: 错误
|
||||
|
||||
**BR-C009: 流式输出超时**
|
||||
- 瑙勫垯锛氬崟涓<EFBFBD><EFBFBD>姹傛渶闀?0绉?
|
||||
- 规则:单个请求最长60秒
|
||||
- 超时后:返回已生成的内容
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?鐢熸垚瓒呮椂锛岃<E9949B>閲嶈瘯"
|
||||
- 错误提示:"生成超时,请重试"
|
||||
|
||||
---
|
||||
|
||||
## 鐭ヨ瘑搴撶<EFBFBD>鐞嗚<EFBFBD>鍒?
|
||||
## 知识库管理规则
|
||||
|
||||
### 数量限制
|
||||
|
||||
**BR-K001: 鐭ヨ瘑搴撴暟閲忛檺鍒?*
|
||||
- 瑙勫垯锛氭瘡涓<EFBFBD>敤鎴锋渶澶氬垱寤?涓<>煡璇嗗簱
|
||||
- 楠岃瘉鏃舵満锛氬垱寤虹煡璇嗗簱鏃?
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?宸茶揪鍒扮煡璇嗗簱鏁伴噺涓婇檺锛?涓<>級"
|
||||
**BR-K001: 知识库数量限制**
|
||||
- 规则:每个用户最多创建3个知识库
|
||||
- 验证时机:创建知识库时
|
||||
- 错误提示:"已达到知识库数量上限(3个)"
|
||||
|
||||
**BR-K002: 文档数量限制**
|
||||
- 瑙勫垯锛氭瘡涓<EFBFBD>煡璇嗗簱鏈€澶氫笂浼?0涓<30>枃妗?
|
||||
- 规则:每个知识库最多上传50个文档
|
||||
- 验证时机:上传文档时
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?璇ョ煡璇嗗簱鏂囨。鏁伴噺宸茶揪涓婇檺锛?0涓<30>級"
|
||||
- 错误提示:"该知识库文档数量已达上限(50个)"
|
||||
|
||||
### 文档上传
|
||||
|
||||
**BR-K003: 文件格式限制**
|
||||
- 规则:只支持PDF和DOCX格式
|
||||
- MIME绫诲瀷锛?
|
||||
- MIME类型:
|
||||
- `application/pdf`
|
||||
- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?浠呮敮鎸丳DF鍜孌OCX鏍煎紡"
|
||||
- 错误提示:"仅支持PDF和DOCX格式"
|
||||
|
||||
**BR-K004: 文件大小限制**
|
||||
- 瑙勫垯锛氬崟涓<EFBFBD>枃浠舵渶澶?0MB
|
||||
- 规则:单个文件最大50MB
|
||||
- 验证时机:上传前(前端)和上传后(后端)
|
||||
- 閿欒<EFBFBD>鎻愮ず锛?鏂囦欢澶у皬瓒呰繃闄愬埗锛堟渶澶?0MB锛?
|
||||
- 错误提示:"文件大小超过限制(最大50MB)"
|
||||
|
||||
**BR-K005: 鏂囦欢鍚嶅敮涓€鎬?*
|
||||
**BR-K005: 文件名唯一性**
|
||||
- 规则:同一知识库内,文件名不能重复
|
||||
- 验证:检查是否已存在同名文件
|
||||
- 澶勭悊锛氳嚜鍔ㄩ噸鍛藉悕锛堟坊鍔犳椂闂存埑锛?
|
||||
- 处理:自动重命名(添加时间戳)
|
||||
|
||||
### 文档处理
|
||||
|
||||
**BR-K006: 鏂囨。澶勭悊鐘舵€?*
|
||||
**BR-K006: 文档处理状态**
|
||||
- 状态流转:
|
||||
1. `uploading` - 涓婁紶涓?
|
||||
2. `processing` - Dify澶勭悊涓?
|
||||
1. `uploading` - 上传中
|
||||
2. `processing` - Dify处理中
|
||||
3. `completed` - 处理完成
|
||||
4. `failed` - 处理失败
|
||||
|
||||
**BR-K007: 处理失败重试**
|
||||
- 瑙勫垯锛氬<EFBFBD>鐞嗗け璐ョ殑鏂囨。涓嶈嚜鍔ㄩ噸璇?
|
||||
- 规则:处理失败的文档不自动重试
|
||||
- 规则:用户可以删除后重新上传
|
||||
- 错误信息:记录在error_message字段
|
||||
|
||||
**BR-K008: 异步处理**
|
||||
- 规则:文档上传后立即返回
|
||||
- 规则:后台异步提交到Dify处理
|
||||
- 瑙勫垯锛氬墠绔<EFBFBD>疆璇㈣幏鍙栧<EFBFBD>鐞嗙姸鎬?
|
||||
- 规则:前端轮询获取处理状态
|
||||
|
||||
### 鐭ヨ瘑搴撴<EFBFBD>绱?
|
||||
### 知识库检索
|
||||
|
||||
**BR-K009: 娣峰悎妫€绱?*
|
||||
- 瑙勫垯锛氫娇鐢ㄥ叧閿<EFBFBD>瘝妫€绱?+ 璇<>箟妫€绱?
|
||||
- 瑙勫垯锛氬惎鐢≧eranking閲嶆帓搴?
|
||||
- Top K锛?涓<>粨鏋?
|
||||
**BR-K009: 混合检索**
|
||||
- 规则:使用关键词检索 + 语义检索
|
||||
- 规则:启用Reranking重排序
|
||||
- Top K:5个结果
|
||||
- 相似度阈值:0.5
|
||||
|
||||
**BR-K010: 妫€绱㈢粨鏋滃紩鐢?*
|
||||
**BR-K010: 检索结果引用**
|
||||
- 规则:AI回答必须注明引用来源
|
||||
- 格式:`[文档名] 内容...`
|
||||
- 瑙勫垯锛氬墠绔<E5A2A0>樉绀哄彲鐐瑰嚮鐨勫紩鐢ㄦ爣璁?
|
||||
- 规则:前端显示可点击的引用标记
|
||||
|
||||
---
|
||||
|
||||
@@ -290,27 +290,27 @@
|
||||
### 用户权限
|
||||
|
||||
**BR-P001: 角色定义**
|
||||
- `user` - 鏅<EFBFBD>€氱敤鎴?
|
||||
- 鍙<>互浣跨敤鎵€鏈夊姛鑳?
|
||||
- 鍙楅厤棰濋檺鍒?
|
||||
- `admin` - 绠$悊鍛?
|
||||
- `user` - 普通用户
|
||||
- 可以使用所有功能
|
||||
- 受配额限制
|
||||
- `admin` - 管理员
|
||||
- 所有user权限
|
||||
- 可以访问运营后台
|
||||
- 鍙<>互鏌ョ湅鎵€鏈夌敤鎴锋暟鎹?
|
||||
- 可以查看所有用户数据
|
||||
|
||||
### 数据隔离
|
||||
|
||||
**BR-P002: 用户数据隔离**
|
||||
- 规则:用户只能访问自己创建的数据
|
||||
- 验证:所有查询必须包含userId过滤
|
||||
- 瀹炵幇锛?
|
||||
- 实现:
|
||||
```sql
|
||||
WHERE user_id = currentUser.id
|
||||
```
|
||||
|
||||
**BR-P003: 项目权限验证**
|
||||
- 瑙勫垯锛氫慨鏀?鍒犻櫎椤圭洰鍓嶏紝楠岃瘉鎵€鏈夋潈
|
||||
- 瀹炵幇锛?
|
||||
- 规则:修改/删除项目前,验证所有权
|
||||
- 实现:
|
||||
```typescript
|
||||
const project = await prisma.project.findFirst({
|
||||
where: { id: projectId, userId: currentUser.id }
|
||||
@@ -318,33 +318,33 @@
|
||||
if (!project) throw new UnauthorizedError()
|
||||
```
|
||||
|
||||
### 绠$悊鍛樻潈闄?
|
||||
### 管理员权限
|
||||
|
||||
**BR-P004: 用户管理权限**
|
||||
- 规则:只有admin可以查看用户列表
|
||||
- 瑙勫垯锛氬彧鏈塧dmin鍙<EFBFBD>互淇<EFBFBD>敼鐢ㄦ埛鐘舵€?
|
||||
- 规则:只有admin可以修改用户状态
|
||||
- 规则:admin不能删除用户(只能暂停)
|
||||
|
||||
**BR-P005: 对话查看权限**
|
||||
- 规则:只有admin可以查看用户对话
|
||||
- 瑙勫垯锛氬繀椤昏<EFBFBD>褰曞<EFBFBD>璁℃棩蹇?
|
||||
- 瑙勫垯锛氭晱鎰熶俊鎭<EFBFBD>渶瑕佽劚鏁忥紙濡傞偖绠便€佹墜鏈哄彿锛?
|
||||
- 规则:必须记录审计日志
|
||||
- 规则:敏感信息需要脱敏(如邮箱、手机号)
|
||||
|
||||
---
|
||||
|
||||
## 配额限制规则
|
||||
|
||||
### 鐭ヨ瘑搴撻厤棰?
|
||||
### 知识库配额
|
||||
|
||||
**BR-Q001: 鐭ヨ瘑搴撴暟閲忛厤棰?*
|
||||
- 榛樿<EFBFBD>閰嶉<EFBFBD>锛?涓<>煡璇嗗簱
|
||||
**BR-Q001: 知识库数量配额**
|
||||
- 默认配额:3个知识库
|
||||
- 记录字段:`users.kb_quota`, `users.kb_used`
|
||||
- 鏇存柊鏃舵満锛氬垱寤?鍒犻櫎鐭ヨ瘑搴撴椂
|
||||
- 更新时机:创建/删除知识库时
|
||||
|
||||
**BR-Q002: 文档数量配额**
|
||||
- 榛樿<E6A69B>閰嶉<E996B0>锛?0涓<30>枃妗?鐭ヨ瘑搴?
|
||||
- 妫€鏌ユ椂鏈猴細涓婁紶鏂囨。鍓?
|
||||
- 瀹炵幇锛?
|
||||
- 默认配额:50个文档/知识库
|
||||
- 检查时机:上传文档前
|
||||
- 实现:
|
||||
```sql
|
||||
SELECT COUNT(*) FROM documents
|
||||
WHERE kb_id = ? AND status != 'failed'
|
||||
@@ -353,72 +353,72 @@
|
||||
### 存储配额(预留)
|
||||
|
||||
**BR-Q003: 存储空间配额**
|
||||
- 榛樿<EFBFBD>閰嶉<EFBFBD>锛?GB/鐢ㄦ埛
|
||||
- 默认配额:1GB/用户
|
||||
- 当前版本:不强制限制
|
||||
- 鏈<EFBFBD>潵锛氬彲浠ユ牴鎹<EFBFBD>疄闄呴渶姹傚惎鐢?
|
||||
- 未来:可以根据实际需求启用
|
||||
|
||||
### API限流
|
||||
|
||||
**BR-Q004: API请求频率限制**
|
||||
- 鏅<EFBFBD>€氱敤鎴凤細100娆?鍒嗛挓
|
||||
- 绠$悊鍛橈細500娆?鍒嗛挓
|
||||
- 普通用户:100次/分钟
|
||||
- 管理员:500次/分钟
|
||||
- 实现:使用Redis + 滑动窗口算法
|
||||
|
||||
**BR-Q005: 登录接口限流**
|
||||
- 瑙勫垯锛?娆?鍒嗛挓
|
||||
- 瑙勫垯锛欼P鍜岃处鎴峰弻閲嶉檺鍒?
|
||||
- 规则:5次/分钟
|
||||
- 规则:IP和账户双重限制
|
||||
- 超过后:临时封禁15分钟
|
||||
|
||||
---
|
||||
|
||||
## 业务流程
|
||||
|
||||
### 瀹屾暣鐨勫<EFBFBD>璇濇祦绋?
|
||||
### 完整的对话流程
|
||||
|
||||
```
|
||||
1. 鐢ㄦ埛閫夋嫨鏅鸿兘浣?
|
||||
鈫?
|
||||
1. 用户选择智能体
|
||||
↓
|
||||
2. 创建对话(可选关联项目)
|
||||
鈫?
|
||||
3. 鐢ㄦ埛鍙戦€佹秷鎭<EFBFBD>紙鍙<EFBFBD>€夊紩鐢ㄧ煡璇嗗簱锛?
|
||||
鈫?
|
||||
↓
|
||||
3. 用户发送消息(可选引用知识库)
|
||||
↓
|
||||
4. 后端组装上下文:
|
||||
- 项目背景(如有)
|
||||
- 智能体System Prompt
|
||||
- 鍘嗗彶瀵硅瘽锛堟渶杩?0杞<30>級
|
||||
- 鐭ヨ瘑搴撴<EFBFBD>绱㈢粨鏋滐紙濡傛湁锛?
|
||||
- 历史对话(最近10轮)
|
||||
- 知识库检索结果(如有)
|
||||
- 当前用户问题
|
||||
鈫?
|
||||
↓
|
||||
5. 调用LLM(流式输出)
|
||||
鈫?
|
||||
↓
|
||||
6. 保存消息到数据库
|
||||
鈫?
|
||||
7. 鐢ㄦ埛鍙<EFBFBD>€夛細鍥哄畾娑堟伅鍒伴」鐩<EFBFBD>儗鏅?
|
||||
↓
|
||||
7. 用户可选:固定消息到项目背景
|
||||
```
|
||||
|
||||
### 鐭ヨ瘑搴撴枃妗e<EFBFBD>鐞嗘祦绋?
|
||||
### 知识库文档处理流程
|
||||
|
||||
```
|
||||
1. 用户上传文档
|
||||
鈫?
|
||||
2. 楠岃瘉锛?
|
||||
↓
|
||||
2. 验证:
|
||||
- 文件格式
|
||||
- 文件大小
|
||||
- 数量限制
|
||||
鈫?
|
||||
3. 涓婁紶鍒板<EFBFBD>璞″瓨鍌<EFBFBD>紙OSS锛?
|
||||
鈫?
|
||||
4. 鍒涘缓document璁板綍锛坰tatus: uploading锛?
|
||||
鈫?
|
||||
5. 寮傛<EFBFBD>鎻愪氦鍒癉ify锛?
|
||||
↓
|
||||
3. 上传到对象存储(OSS)
|
||||
↓
|
||||
4. 创建document记录(status: uploading)
|
||||
↓
|
||||
5. 异步提交到Dify:
|
||||
- 调用Dify上传API
|
||||
- 获取dify_document_id
|
||||
鈫?
|
||||
6. 杞<EFBFBD><EFBFBD>澶勭悊鐘舵€侊紙姣?绉掞級锛?
|
||||
- processing 鈫?鏇存柊progress
|
||||
- completed 鈫?鏇存柊status, segments_count, tokens_count
|
||||
- failed 鈫?鏇存柊status, error_message
|
||||
鈫?
|
||||
↓
|
||||
6. 轮询处理状态(每2秒):
|
||||
- processing → 更新progress
|
||||
- completed → 更新status, segments_count, tokens_count
|
||||
- failed → 更新status, error_message
|
||||
↓
|
||||
7. 更新知识库统计:
|
||||
- file_count
|
||||
- total_size_bytes
|
||||
@@ -426,29 +426,29 @@
|
||||
|
||||
---
|
||||
|
||||
## 鏁版嵁涓€鑷存€ц<EFBFBD>鍒?
|
||||
## 数据一致性规则
|
||||
|
||||
### 统计字段更新
|
||||
|
||||
**BR-D001: 椤圭洰瀵硅瘽鏁扮粺璁?*
|
||||
**BR-D001: 项目对话数统计**
|
||||
- 字段:`projects.conversation_count`
|
||||
- 鏇存柊鏃舵満锛氬垱寤?鍒犻櫎瀵硅瘽鏃?
|
||||
- 瀹炵幇锛氫娇鐢ㄤ簨鍔′繚璇佷竴鑷存€?
|
||||
- 更新时机:创建/删除对话时
|
||||
- 实现:使用事务保证一致性
|
||||
|
||||
**BR-D002: 知识库文档数统计**
|
||||
- 字段:`knowledge_bases.file_count`
|
||||
- 更新时机:文档状态变为completed或删除时
|
||||
- 璁$畻锛氬彧缁熻<E7BC81>status='completed'鐨勬枃妗?
|
||||
- 计算:只统计status='completed'的文档
|
||||
|
||||
**BR-D003: 用户知识库数统计**
|
||||
- 字段:`users.kb_used`
|
||||
- 鏇存柊鏃舵満锛氬垱寤?鍒犻櫎鐭ヨ瘑搴撴椂
|
||||
- 更新时机:创建/删除知识库时
|
||||
- 验证:创建前检查是否超过quota
|
||||
|
||||
### 级联删除
|
||||
|
||||
**BR-D004: 用户删除级联**
|
||||
- 瑙勫垯锛氬垹闄ょ敤鎴锋椂锛岀骇鑱斿垹闄ゆ墍鏈夊叧鑱旀暟鎹?
|
||||
- 规则:删除用户时,级联删除所有关联数据
|
||||
- 包括:projects, conversations, messages, knowledge_bases, documents
|
||||
- 实现:数据库ON DELETE CASCADE
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
- 规则:删除项目时,级联删除所有对话和消息
|
||||
- 实现:数据库ON DELETE CASCADE
|
||||
|
||||
**BR-D006: 鐭ヨ瘑搴撳垹闄ょ骇鑱?*
|
||||
**BR-D006: 知识库删除级联**
|
||||
- 规则:删除知识库时:
|
||||
1. 级联删除数据库中的documents
|
||||
2. 调用Dify API删除dataset
|
||||
@@ -487,7 +487,7 @@
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "QUOTA_EXCEEDED",
|
||||
"message": "鐭ヨ瘑搴撴暟閲忓凡杈句笂闄?,
|
||||
"message": "知识库数量已达上限",
|
||||
"details": {
|
||||
"resource": "knowledge_base",
|
||||
"quota": 3,
|
||||
@@ -506,11 +506,11 @@
|
||||
|
||||
**BR-S001: 密码加密**
|
||||
- 算法:bcrypt
|
||||
- 鎴愭湰鍥犲瓙锛?2
|
||||
- 瑙勫垯锛氭案涓嶅瓨鍌ㄦ槑鏂囧瘑鐮?
|
||||
- 成本因子:12
|
||||
- 规则:永不存储明文密码
|
||||
|
||||
**BR-S002: Token安全**
|
||||
- 瑙勫垯锛歍oken鍖呭惈鐢ㄦ埛ID鍜岃<E98D9C>鑹?
|
||||
- 规则:Token包含用户ID和角色
|
||||
- 规则:Token签名使用JWT_SECRET
|
||||
- 规则:过期Token自动失效
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
### XSS防护
|
||||
|
||||
**BR-S004: 输入转义**
|
||||
- 瑙勫垯锛氭墍鏈夌敤鎴疯緭鍏ュ湪鏄剧ず鍓嶈浆涔?
|
||||
- 规则:所有用户输入在显示前转义
|
||||
- 规则:使用React默认转义
|
||||
- 规则:禁止使用dangerouslySetInnerHTML(除非必要)
|
||||
|
||||
@@ -534,22 +534,22 @@
|
||||
|
||||
### 缓存规则
|
||||
|
||||
**BR-O001: 鏅鸿兘浣撳垪琛ㄧ紦瀛?*
|
||||
**BR-O001: 智能体列表缓存**
|
||||
- 规则:智能体列表缓存1小时
|
||||
- 实现:Redis缓存
|
||||
- 失效:修改agents.yaml后需清除缓存
|
||||
|
||||
**BR-O002: 用户信息缓存**
|
||||
- 瑙勫垯锛氱敤鎴蜂俊鎭<E4BF8A>紦瀛?鍒嗛挓
|
||||
- 规则:用户信息缓存5分钟
|
||||
- Key:`user:{userId}`
|
||||
- 失效:用户信息更新时
|
||||
|
||||
### 查询优化
|
||||
|
||||
**BR-O003: 分页查询**
|
||||
- 瑙勫垯锛氬垪琛ㄦ煡璇㈠繀椤诲垎椤?
|
||||
- 榛樿<EFBFBD>锛?0鏉?椤?
|
||||
- 鏈€澶э細100鏉?椤?
|
||||
- 规则:列表查询必须分页
|
||||
- 默认:20条/页
|
||||
- 最大:100条/页
|
||||
|
||||
**BR-O004: 索引使用**
|
||||
- 规则:频繁查询的字段必须建立索引
|
||||
@@ -563,30 +563,30 @@
|
||||
### 数据归档
|
||||
|
||||
**BR-R001: 对话归档(未来)**
|
||||
- 瑙勫垯锛氳秴杩?涓<>湀鐨勫<E990A8>璇濊嚜鍔ㄥ綊妗?
|
||||
- 规则:超过6个月的对话自动归档
|
||||
- 归档表:conversations_archive
|
||||
- 查询:默认不查询归档数据
|
||||
|
||||
**BR-R002: 日志清理**
|
||||
- 规则:admin_logs保留3个月
|
||||
- 鎵ц<EFBFBD>锛氬畾鏃朵换鍔℃瘡鏈堟竻鐞?
|
||||
- 执行:定时任务每月清理
|
||||
|
||||
---
|
||||
|
||||
## 业务规则变更流程
|
||||
|
||||
1. **鎻愬嚭鍙樻洿**锛氬~鍐欏彉鏇寸敵璇?
|
||||
2. **褰卞搷璇勪及**锛氳瘎浼板<E6B5BC>绯荤粺鐨勫奖鍝?
|
||||
1. **提出变更**:填写变更申请
|
||||
2. **影响评估**:评估对系统的影响
|
||||
3. **Review**:技术团队Review
|
||||
4. **更新文档**:同步更新本文档
|
||||
5. **瀹炴柦鍙樻洿**锛氫慨鏀逛唬鐮?
|
||||
5. **实施变更**:修改代码
|
||||
6. **测试验证**:测试新规则
|
||||
7. **上线发布**:发布到生产
|
||||
|
||||
---
|
||||
|
||||
**鏂囨。缁存姢锛?* 涓氬姟瑙勫垯鍙樻洿闇€鍚屾<E98D9A>鏇存柊
|
||||
**Review棰戠巼锛?* 姣忎釜閲岀▼纰慠eview涓€娆?
|
||||
**文档维护:** 业务规则变更需同步更新
|
||||
**Review频率:** 每个里程碑Review一次
|
||||
**最后更新:** 2025-10-10
|
||||
**维护者:** 产品经理 + 技术负责人
|
||||
|
||||
|
||||
Reference in New Issue
Block a user