Files
AIclinicalresearch/docs/01-设计文档/API设计规范.md
2025-10-12 10:08:27 +08:00

1132 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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": "XXIII",
"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": "XXIII",
"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": "XXIII",
"description": "..."
}
Response: 200 OK
{
"success": true,
"data": {
"id": "proj-123",
"name": "XXIII",
"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可选新对话时不传
**响应说明:**
- 使用SSEServer-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
**维护者:** 开发团队