# API设计规范 > **版本:** v1.0 > **创建日期:** 2025-10-10 > **API风格:** RESTful API > **基础URL:** `http://localhost:3001/api/v1` --- ## 📋 目录 1. [设计原则](#设计原则) 2. [通用规范](#通用规范) 3. [认证与授权](#认证与授权) 4. [API端点设计](#api端点设计) 5. [错误处理](#错误处理) 6. [数据格式](#数据格式) --- ## 设计原则 ### API First原则 - ✅ 先设计API,再实现功能 - ✅ API是前后端的契约 - ✅ API变更需要版本控制 ### RESTful设计 - ✅ 使用HTTP动词表示操作(GET、POST、PUT、DELETE) - ✅ URL表示资源,不表示动作 - ✅ 使用复数名词表示资源集合 - ✅ 嵌套资源不超过2层 ### 命名规范 - ✅ URL使用小写字母和连字符(kebab-case) - ✅ 查询参数使用驼峰命名(camelCase) - ✅ JSON字段使用驼峰命名(camelCase) --- ## 通用规范 ### HTTP方法 | 方法 | 用途 | 是否幂等 | |------|------|---------| | GET | 获取资源 | ✅ | | POST | 创建资源 | ❌ | | PUT | 完整更新资源 | ✅ | | PATCH | 部分更新资源 | ❌ | | DELETE | 删除资源 | ✅ | ### 状态码规范 | 状态码 | 含义 | 使用场景 | |--------|------|---------| | 200 | OK | 成功返回数据 | | 201 | Created | 成功创建资源 | | 204 | No Content | 成功但无返回数据(如删除) | | 400 | Bad Request | 请求参数错误 | | 401 | Unauthorized | 未认证 | | 403 | Forbidden | 无权限 | | 404 | Not Found | 资源不存在 | | 409 | Conflict | 资源冲突(如重复创建) | | 422 | Unprocessable Entity | 语义错误(如验证失败) | | 429 | Too Many Requests | 请求过于频繁 | | 500 | Internal Server Error | 服务器错误 | ### 响应格式 **成功响应:** ```json { "success": true, "data": { // 实际数据 }, "message": "操作成功", "timestamp": "2025-10-10T10:00:00.000Z" } ``` **错误响应:** ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "参数验证失败", "details": [ { "field": "email", "message": "邮箱格式不正确" } ] }, "timestamp": "2025-10-10T10:00:00.000Z" } ``` ### 分页规范 **请求参数:** ``` GET /api/v1/projects?page=1&pageSize=20&sortBy=createdAt&sortOrder=desc ``` **响应格式:** ```json { "success": true, "data": { "items": [...], "pagination": { "page": 1, "pageSize": 20, "total": 100, "totalPages": 5, "hasNext": true, "hasPrev": false } } } ``` --- ## 认证与授权 ### JWT认证 **登录获取Token:** ```http POST /api/v1/auth/login Content-Type: application/json { "email": "user@example.com", "password": "password123" } Response: { "success": true, "data": { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expiresIn": 604800, "user": { "id": "user-123", "email": "user@example.com", "name": "张三", "role": "user" } } } ``` **使用Token:** ```http GET /api/v1/projects Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### 权限控制 | 端点 | 需要认证 | 角色要求 | |------|---------|---------| | `/auth/login` | ❌ | 无 | | `/auth/register` | ❌ | 无 | | `/users/me` | ✅ | user | | `/projects/*` | ✅ | user | | `/admin/*` | ✅ | admin | --- ## API端点设计 ### 1. 认证模块 #### 1.1 用户注册 ```http POST /api/v1/auth/register Content-Type: application/json Request: { "email": "user@example.com", "password": "password123", "name": "张三" } Response: 201 Created { "success": true, "data": { "userId": "user-123", "email": "user@example.com", "message": "注册成功,请登录" } } ``` #### 1.2 用户登录 ```http POST /api/v1/auth/login Content-Type: application/json Request: { "email": "user@example.com", "password": "password123" } Response: 200 OK { "success": true, "data": { "accessToken": "eyJhbG...", "refreshToken": "eyJhbG...", "expiresIn": 604800, "user": { "id": "user-123", "email": "user@example.com", "name": "张三", "role": "user" } } } ``` #### 1.3 刷新Token ```http POST /api/v1/auth/refresh Content-Type: application/json Request: { "refreshToken": "eyJhbG..." } Response: 200 OK { "success": true, "data": { "accessToken": "new_token...", "expiresIn": 604800 } } ``` #### 1.4 退出登录 ```http POST /api/v1/auth/logout Authorization: Bearer {token} Response: 204 No Content ``` --- ### 2. 用户模块 #### 2.1 获取当前用户信息 ```http GET /api/v1/users/me Authorization: Bearer {token} Response: 200 OK { "success": true, "data": { "id": "user-123", "email": "user@example.com", "name": "张三", "role": "user", "kbQuota": 3, "kbUsed": 1, "isTrial": true, "trialEndsAt": "2025-11-10T00:00:00.000Z", "createdAt": "2025-10-01T00:00:00.000Z" } } ``` #### 2.2 更新用户信息 ```http PATCH /api/v1/users/me Authorization: Bearer {token} Content-Type: application/json Request: { "name": "李四", "avatarUrl": "https://..." } Response: 200 OK { "success": true, "data": { "id": "user-123", "name": "李四", "avatarUrl": "https://..." } } ``` #### 2.3 修改密码 ```http POST /api/v1/users/me/change-password Authorization: Bearer {token} Content-Type: application/json Request: { "oldPassword": "old123", "newPassword": "new456" } Response: 200 OK { "success": true, "message": "密码修改成功" } ``` --- ### 3. 项目管理模块 #### 3.1 获取项目列表 ```http GET /api/v1/projects?page=1&pageSize=20 Authorization: Bearer {token} Response: 200 OK { "success": true, "data": { "items": [ { "id": "proj-123", "name": "XX药物III期临床试验", "description": "项目背景描述...", "conversationCount": 5, "createdAt": "2025-10-01T00:00:00.000Z", "updatedAt": "2025-10-10T00:00:00.000Z" } ], "pagination": { "page": 1, "pageSize": 20, "total": 2, "totalPages": 1, "hasNext": false, "hasPrev": false } } } ``` #### 3.2 创建项目 ```http POST /api/v1/projects Authorization: Bearer {token} Content-Type: application/json Request: { "name": "骨质疏松研究", "description": "探索肠道菌群与骨质疏松的关系..." } Response: 201 Created { "success": true, "data": { "id": "proj-456", "name": "骨质疏松研究", "description": "探索肠道菌群与骨质疏松的关系...", "conversationCount": 0, "createdAt": "2025-10-10T10:00:00.000Z" } } ``` #### 3.3 获取项目详情 ```http GET /api/v1/projects/:id Authorization: Bearer {token} Response: 200 OK { "success": true, "data": { "id": "proj-123", "name": "XX药物III期临床试验", "description": "项目背景描述...", "conversationCount": 5, "createdAt": "2025-10-01T00:00:00.000Z", "updatedAt": "2025-10-10T00:00:00.000Z" } } ``` #### 3.4 更新项目 ```http PUT /api/v1/projects/:id Authorization: Bearer {token} Content-Type: application/json Request: { "name": "XX药物III期临床试验(更新)", "description": "更新后的项目背景..." } Response: 200 OK { "success": true, "data": { "id": "proj-123", "name": "XX药物III期临床试验(更新)", "description": "更新后的项目背景...", "updatedAt": "2025-10-10T11:00:00.000Z" } } ``` #### 3.5 删除项目 ```http DELETE /api/v1/projects/:id Authorization: Bearer {token} Response: 204 No Content ``` --- ### 4. 对话管理模块 #### 4.1 获取对话列表 ```http GET /api/v1/conversations?projectId=proj-123&page=1&pageSize=20 Authorization: Bearer {token} Query Parameters: - projectId (可选): 筛选特定项目的对话,不传则返回所有对话 - agentId (可选): 筛选特定智能体的对话 - page: 页码 - pageSize: 每页数量 Response: 200 OK { "success": true, "data": { "items": [ { "id": "conv-123", "title": "PICOS构建", "agentId": "agent-picos", "agentName": "PICOS构建智能体", "projectId": "proj-123", "projectName": "XX药物研究", "modelName": "deepseek-v3", "messageCount": 10, "totalTokens": 5000, "createdAt": "2025-10-10T09:00:00.000Z", "updatedAt": "2025-10-10T10:00:00.000Z" } ], "pagination": {...} } } ``` #### 4.2 创建对话 ```http POST /api/v1/conversations Authorization: Bearer {token} Content-Type: application/json Request: { "projectId": "proj-123", // 可选,全局快速问答时不传 "agentId": "agent-picos", "title": "PICOS构建", "modelName": "deepseek-v3" // 可选,默认deepseek-v3 } Response: 201 Created { "success": true, "data": { "id": "conv-456", "title": "PICOS构建", "agentId": "agent-picos", "projectId": "proj-123", "modelName": "deepseek-v3", "messageCount": 0, "createdAt": "2025-10-10T10:00:00.000Z" } } ``` #### 4.3 获取对话详情(含消息) ```http GET /api/v1/conversations/:id Authorization: Bearer {token} Response: 200 OK { "success": true, "data": { "id": "conv-123", "title": "PICOS构建", "agentId": "agent-picos", "projectId": "proj-123", "modelName": "deepseek-v3", "messageCount": 2, "messages": [ { "id": "msg-1", "role": "user", "content": "请帮我构建PICOS框架", "createdAt": "2025-10-10T09:00:00.000Z" }, { "id": "msg-2", "role": "assistant", "content": "好的,我们开始构建PICOS...", "isPinned": false, "tokens": 500, "createdAt": "2025-10-10T09:00:05.000Z" } ], "createdAt": "2025-10-10T09:00:00.000Z", "updatedAt": "2025-10-10T09:00:05.000Z" } } ``` #### 4.4 发送消息(流式) ```http POST /api/v1/conversations/:id/messages/stream Authorization: Bearer {token} Content-Type: application/json Request: { "content": "请帮我构建PICOS框架", "kbReferences": ["kb-123"] // 可选,引用的知识库 } Response: 200 OK (Server-Sent Events) Content-Type: text/event-stream data: {"type":"start","conversationId":"conv-123"} data: {"type":"token","content":"好"} data: {"type":"token","content":"的"} data: {"type":"token","content":","} data: {"type":"done","messageId":"msg-456","tokens":500} ``` #### 4.5 固定消息到项目背景 ```http POST /api/v1/messages/:id/pin Authorization: Bearer {token} Response: 200 OK { "success": true, "message": "已固定到项目背景" } ``` #### 4.6 删除对话 ```http DELETE /api/v1/conversations/:id Authorization: Bearer {token} Response: 204 No Content ``` --- ### 5. 智能体模块 #### 5.1 获取智能体列表 ```http GET /api/v1/agents Authorization: Bearer {token} Response: 200 OK { "success": true, "data": [ { "id": "agent-picos", "name": "PICOS构建", "description": "结构化地定义临床研究的核心要素", "category": "研究设计", "icon": "construction", "ragEnabled": true, "fileUploadEnabled": false, "status": "active" }, { "id": "agent-topic-evaluation", "name": "选题评价", "description": "从创新性、临床价值等维度评价研究选题", "category": "选题阶段", "icon": "lightbulb", "ragEnabled": true, "fileUploadEnabled": false, "status": "active" } ] } ``` #### 5.2 获取智能体详情 ```http GET /api/v1/agents/:id Authorization: Bearer {token} Response: 200 OK { "success": true, "data": { "id": "agent-picos", "name": "PICOS构建", "description": "结构化地定义临床研究的核心要素", "category": "研究设计", "icon": "construction", "ragEnabled": true, "fileUploadEnabled": false, "outputFormat": "structured", "models": { "deepseek-v3": { "temperature": 0.3, "maxTokens": 2500 }, "qwen3-72b": { "temperature": 0.4, "maxTokens": 2500 } }, "status": "active" } } ``` --- ### 6. 知识库模块 #### 6.1 获取知识库列表 ```http GET /api/v1/knowledge-bases Authorization: Bearer {token} Response: 200 OK { "success": true, "data": [ { "id": "kb-123", "name": "骨质疏松专题", "description": "关于骨质疏松的文献资料", "fileCount": 15, "totalSizeMB": 45.6, "quota": { "used": 15, "limit": 50 }, "createdAt": "2025-10-01T00:00:00.000Z", "updatedAt": "2025-10-10T00:00:00.000Z" } ], "quota": { "used": 1, "limit": 3 } } ``` #### 6.2 创建知识库 ```http POST /api/v1/knowledge-bases Authorization: Bearer {token} Content-Type: application/json Request: { "name": "肺癌研究资料", "description": "肺癌相关的临床研究文献" } Response: 201 Created { "success": true, "data": { "id": "kb-456", "name": "肺癌研究资料", "description": "肺癌相关的临床研究文献", "fileCount": 0, "difyDatasetId": "dify-dataset-xxx", "createdAt": "2025-10-10T10:00:00.000Z" } } ``` #### 6.3 上传文档 ```http POST /api/v1/knowledge-bases/:id/documents Authorization: Bearer {token} Content-Type: multipart/form-data Request: - file: (binary) - filename: "文献综述.pdf" Response: 201 Created { "success": true, "data": { "id": "doc-123", "filename": "文献综述.pdf", "fileType": "pdf", "fileSizeBytes": 2048000, "status": "processing", "progress": 0, "uploadedAt": "2025-10-10T10:00:00.000Z" } } ``` #### 6.4 获取文档列表 ```http GET /api/v1/knowledge-bases/:id/documents Authorization: Bearer {token} Response: 200 OK { "success": true, "data": [ { "id": "doc-123", "filename": "文献综述.pdf", "fileType": "pdf", "fileSizeMB": 2.0, "status": "completed", "progress": 100, "segmentsCount": 50, "tokensCount": 10000, "uploadedAt": "2025-10-10T10:00:00.000Z", "processedAt": "2025-10-10T10:02:00.000Z" } ] } ``` #### 6.5 删除文档 ```http DELETE /api/v1/knowledge-bases/:kbId/documents/:docId Authorization: Bearer {token} Response: 204 No Content ``` #### 6.6 删除知识库 ```http DELETE /api/v1/knowledge-bases/:id Authorization: Bearer {token} Response: 204 No Content ``` --- ### 7. 历史记录模块 #### 7.1 获取历史记录(跨项目) ```http GET /api/v1/history?page=1&pageSize=20&agentId=agent-picos&startDate=2025-10-01&endDate=2025-10-10 Authorization: Bearer {token} Query Parameters: - projectId (可选): 筛选特定项目 - agentId (可选): 筛选特定智能体 - startDate (可选): 开始日期 - endDate (可选): 结束日期 - keyword (可选): 关键词搜索 Response: 200 OK { "success": true, "data": { "items": [ { "conversationId": "conv-123", "title": "PICOS构建", "agentId": "agent-picos", "agentName": "PICOS构建智能体", "projectId": "proj-123", "projectName": "XX药物研究", "source": "project", // project 或 global "messageCount": 10, "createdAt": "2025-10-10T09:00:00.000Z", "lastMessageAt": "2025-10-10T10:00:00.000Z" } ], "pagination": {...} } } ``` --- ### 8. 管理后台模块(简化版) #### 8.1 获取用户列表(管理员) ```http GET /api/v1/admin/users?page=1&pageSize=20&status=active&keyword=zhang Authorization: Bearer {admin_token} Response: 200 OK { "success": true, "data": { "items": [ { "id": "user-123", "email": "user@example.com", "name": "张三", "role": "user", "status": "active", "kbUsed": 1, "conversationCount": 25, "lastLoginAt": "2025-10-10T09:00:00.000Z", "createdAt": "2025-10-01T00:00:00.000Z" } ], "pagination": {...} } } ``` #### 8.2 更新用户状态(管理员) ```http PATCH /api/v1/admin/users/:id Authorization: Bearer {admin_token} Content-Type: application/json Request: { "status": "suspended" // active, inactive, suspended } Response: 200 OK { "success": true, "message": "用户状态已更新" } ``` #### 8.3 获取数据统计(管理员) ```http GET /api/v1/admin/statistics Authorization: Bearer {admin_token} Response: 200 OK { "success": true, "data": { "users": { "total": 1000, "active": 850, "newToday": 15, "new7Days": 120 }, "conversations": { "total": 5000, "today": 200, "avgPerUser": 5 }, "agents": { "mostUsed": [ { "agentId": "agent-picos", "name": "PICOS构建", "count": 800 } ] }, "knowledgeBases": { "total": 300, "totalDocuments": 4500, "totalSizeGB": 12.5 } } } ``` --- ### 9. 通用对话模块(智能问答) **功能**: 提供无项目、无智能体概念的纯AI对话功能,支持可选的@知识库引用 #### 9.1 发送消息(流式输出) ```http POST /api/v1/chat/stream Content-Type: application/json Request: { "content": "你好,介绍一下自己", "modelType": "deepseek-v3", "knowledgeBaseIds": ["kb-uuid-1", "kb-uuid-2"], // 可选 "conversationId": "conv-uuid" // 可选,续接已有对话 } Response: 200 OK (Server-Sent Events) Content-Type: text/event-stream data: {"content":"你","usage":null} data: {"content":"好","usage":null} data: {"content":"!","usage":null} data: {"content":"我","usage":null} ... data: [DONE] ``` **参数说明:** - `content` - 用户消息内容(必填) - `modelType` - 使用的模型(必填):deepseek-v3 | qwen3-72b | gemini-pro - `knowledgeBaseIds` - 知识库ID数组(可选) - `conversationId` - 对话ID(可选,新对话时不传) **响应说明:** - 使用SSE(Server-Sent Events)流式返回 - 每个chunk包含:`content`(增量内容)、`usage`(token统计) - 最后发送 `data: [DONE]` 表示完成 --- #### 9.2 获取对话列表 ```http GET /api/v1/chat/conversations Authorization: Bearer {token} Response: 200 OK { "success": true, "data": [ { "id": "conv-uuid", "userId": "user-uuid", "title": "关于骨质疏松的讨论", "modelName": "deepseek-v3", "createdAt": "2025-10-11T10:00:00.000Z", "updatedAt": "2025-10-11T10:30:00.000Z" } ] } ``` **响应说明:** - 按 `updatedAt` 降序排序 - 最多返回50条 - 不包括已删除的对话(deleted_at != null) --- #### 9.3 删除对话 ```http DELETE /api/v1/chat/conversations/:id Authorization: Bearer {token} Response: 200 OK { "success": true, "message": "删除成功" } ``` **说明:** - 软删除,设置 `deleted_at` 字段 - 级联删除所有消息 - 不可恢复 --- ### 通用对话 vs 项目对话 | 特性 | 通用对话(/chat) | 项目对话(/conversations) | |------|------------------|---------------------------| | **概念** | 无项目/智能体 | 基于项目和智能体 | | **使用场景** | 快速提问、知识库问答 | 结构化研究流程 | | **上下文** | 纯对话历史 | 项目背景 + 智能体角色 + 对话历史 | | **知识库** | 可选@引用 | 可选@引用 | | **System Prompt** | 通用AI助手 | 专业智能体角色 | | **数据表** | general_conversations | conversations | --- ## 错误处理 ### 错误代码规范 | 错误代码 | 说明 | HTTP状态码 | |---------|------|-----------| | VALIDATION_ERROR | 参数验证失败 | 422 | | UNAUTHORIZED | 未认证 | 401 | | FORBIDDEN | 无权限 | 403 | | NOT_FOUND | 资源不存在 | 404 | | CONFLICT | 资源冲突 | 409 | | RATE_LIMIT | 请求过于频繁 | 429 | | QUOTA_EXCEEDED | 配额超限 | 403 | | INTERNAL_ERROR | 服务器错误 | 500 | ### 错误响应示例 ```json { "success": false, "error": { "code": "QUOTA_EXCEEDED", "message": "知识库数量已达上限", "details": { "resource": "knowledge_base", "quota": 3, "used": 3 } }, "timestamp": "2025-10-10T10:00:00.000Z" } ``` --- ## 数据格式 ### 时间格式 - 使用ISO 8601格式:`2025-10-10T10:00:00.000Z` - 统一使用UTC时区 ### 文件大小 - 使用字节(bytes)存储 - 前端显示时转换为MB/GB ### ID格式 - 使用UUID v4 - 格式:`user-123abc...` 或 `proj-456def...` --- ## 版本控制 ### API版本 - 当前版本:`v1` - URL格式:`/api/v1/...` - 向后兼容:同一主版本内保持兼容 ### 废弃策略 - 提前3个月通知 - 响应头标注:`X-API-Deprecated: true` - 提供迁移指南 --- ## 性能优化 ### 缓存策略 - 静态数据(智能体列表):缓存1小时 - 用户数据:不缓存或缓存5分钟 - 使用ETag实现条件请求 ### 限流策略 - 普通用户:100次/分钟 - 管理员:500次/分钟 - 登录接口:5次/分钟 --- ## 安全性 ### HTTPS - 生产环境强制HTTPS - 开发环境可使用HTTP ### CORS - 允许的域名列表(白名单) - 不允许通配符 `*` ### SQL注入防护 - 使用Prisma ORM - 永不拼接SQL ### XSS防护 - 所有用户输入转义 - Content-Type正确设置 --- ## 文档维护 - **更新频率:** API变更时必须同步更新 - **Review:** 每个里程碑Review一次 - **版本记录:** 记录重大变更 --- **最后更新:** 2025-10-10 **维护者:** 开发团队