TraceStudio-dev/docs/web1.1_filemanager/BACKEND_API_REQUIREMENTS.md

476 lines
11 KiB
Markdown
Raw Normal View History

# 后端 API 需求文档
## 📋 概述
本文档描述了前端新增功能所需的后端 API 接口。这些接口用于支持多用户管理、节点数据持久化等功能。
---
## 🔌 新增 API 接口
### 1. 获取用户列表
#### 接口信息
- **路径**: `GET /api/users/list`
- **用途**: 获取系统中所有用户的列表,用于用户切换下拉框显示
- **优先级**: ⭐⭐⭐ 高
#### 请求参数
#### 响应格式
```json
{
"users": ["guest", "admin", "dev", "test", "user1", "user2"],
"count": 6
}
```
#### 响应字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| users | string[] | 用户名列表 |
| count | integer | 用户总数 |
#### 实现建议
1. 扫描 `cloud/users/` 目录,返回所有子目录名称
2. 按字母顺序排序
3. 可以添加缓存机制TTL 60秒
4. 排除系统目录(如 `.git`, `__pycache__` 等)
#### 示例代码
```python
from fastapi import APIRouter
from pathlib import Path
from typing import List
router = APIRouter()
@router.get("/api/users/list")
async def list_users():
"""获取所有用户列表"""
users_dir = Path("cloud/users")
if not users_dir.exists():
users_dir.mkdir(parents=True, exist_ok=True)
return {"users": [], "count": 0}
users = []
for item in users_dir.iterdir():
if item.is_dir() and not item.name.startswith('.'):
users.append(item.name)
users.sort()
return {"users": users, "count": len(users)}
```
#### 错误处理
- 如果 `cloud/users/` 不存在,自动创建并返回空列表
- 权限问题返回 `403 Forbidden`
---
### 2. 保存节点数据
#### 接口信息
- **路径**: `POST /api/nodes/save`
- **用途**: 保存单个节点的配置数据到服务器持久化存储
- **优先级**: ⭐⭐ 中
#### 请求参数
**Content-Type**: `application/json`
```json
{
"nodeId": "n_1704614400000_1234",
"nodeData": {
"label": "我的CSV加载器",
"file_path": "users/guest/data/sales.csv",
"delimiter": ",",
"meta": { ... },
"preview": { ... }
}
}
```
#### 请求字段说明
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| nodeId | string | 是 | 节点唯一标识符 |
| nodeData | object | 是 | 节点完整数据对象 |
| nodeData.label | string | 否 | 节点自定义标题 |
| nodeData.* | any | 否 | 其他节点参数 |
#### 响应格式
**成功响应** (200):
```json
{
"success": true,
"nodeId": "n_1704614400000_1234",
"savedAt": "2026-01-07T12:34:56.789Z"
}
```
**失败响应** (400):
```json
{
"success": false,
"error": "Invalid nodeId format"
}
```
#### 实现建议
##### 存储方案 A文件系统
```python
# 存储路径: cloud/nodes/{nodeId}.json
import json
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from pathlib import Path
from datetime import datetime
class NodeSaveRequest(BaseModel):
nodeId: str
nodeData: dict
@router.post("/api/nodes/save")
async def save_node(request: NodeSaveRequest):
"""保存节点数据到文件系统"""
nodes_dir = Path("cloud/nodes")
nodes_dir.mkdir(parents=True, exist_ok=True)
# 验证 nodeId 格式
if not request.nodeId.startswith('n_'):
raise HTTPException(status_code=400, detail="Invalid nodeId format")
# 添加元数据
save_data = {
"nodeId": request.nodeId,
"nodeData": request.nodeData,
"savedAt": datetime.utcnow().isoformat() + "Z"
}
# 保存到文件
file_path = nodes_dir / f"{request.nodeId}.json"
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(save_data, f, indent=2, ensure_ascii=False)
return {
"success": True,
"nodeId": request.nodeId,
"savedAt": save_data["savedAt"]
}
```
##### 存储方案 BSQLite 数据库
```python
# 使用 SQLite 存储节点数据
import sqlite3
import json
def init_db():
conn = sqlite3.connect('cloud/tracestudio.db')
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS nodes (
node_id TEXT PRIMARY KEY,
node_data TEXT NOT NULL,
saved_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
@router.post("/api/nodes/save")
async def save_node(request: NodeSaveRequest):
"""保存节点数据到数据库"""
conn = sqlite3.connect('cloud/tracestudio.db')
c = conn.cursor()
c.execute('''
INSERT OR REPLACE INTO nodes (node_id, node_data, saved_at)
VALUES (?, ?, CURRENT_TIMESTAMP)
''', (request.nodeId, json.dumps(request.nodeData)))
conn.commit()
# 获取保存时间
c.execute('SELECT saved_at FROM nodes WHERE node_id = ?', (request.nodeId,))
saved_at = c.fetchone()[0]
conn.close()
return {
"success": True,
"nodeId": request.nodeId,
"savedAt": saved_at
}
```
#### 使用场景
1. 用户在 Inspector 面板编辑节点参数
2. 点击 "💾 保存" 按钮
3. 前端调用此 API 保存节点状态
4. 可用于恢复节点配置、协作编辑等场景
#### 扩展功能(可选)
- 添加用户权限验证(只能保存自己的节点)
- 节点版本控制(保存历史记录)
- 批量保存接口 `POST /api/nodes/batch-save`
---
## 🔄 现有 API 增强建议
### 文件上传 API 增强
**当前**: `POST /api/files/upload?path=xxx&username=xxx`
**建议增强**:
1. 支持批量上传(拖拽多个文件)
2. 返回上传文件的详细信息(路径、大小、类型)
3. 添加上传进度支持WebSocket 或 Server-Sent Events
```python
@router.post("/api/files/upload")
async def upload_files(
files: List[UploadFile], # 支持多文件
path: str = "",
username: str = "guest"
):
"""批量上传文件"""
results = []
for file in files:
# ... 上传逻辑 ...
results.append({
"filename": file.filename,
"path": f"{path}/{file.filename}",
"size": file.size,
"status": "success"
})
return {
"uploaded": len(results),
"files": results
}
```
---
## 📊 优先级排序
| 优先级 | 接口 | 原因 |
|--------|------|------|
| ⭐⭐⭐ 高 | GET /api/users/list | 用户切换下拉框依赖此接口无此接口会显示写死的4个用户 |
| ⭐⭐ 中 | POST /api/nodes/save | 节点持久化功能,不实现不影响基本使用 |
| ⭐ 低 | 文件上传增强 | 已有基础功能,增强为优化体验 |
---
## 🧪 测试用例
### 测试用户列表 API
```bash
# 测试 1: 获取用户列表
curl http://localhost:8000/api/users/list
# 预期响应:
{
"users": ["admin", "dev", "guest", "test"],
"count": 4
}
# 测试 2: 空用户目录
rm -rf cloud/users/*
curl http://localhost:8000/api/users/list
# 预期响应:
{
"users": [],
"count": 0
}
```
### 测试节点保存 API
```bash
# 测试 1: 保存节点
curl -X POST http://localhost:8000/api/nodes/save \
-H "Content-Type: application/json" \
-d '{
"nodeId": "n_1704614400000_1234",
"nodeData": {
"label": "测试节点",
"file_path": "users/guest/data/test.csv"
}
}'
# 预期响应:
{
"success": true,
"nodeId": "n_1704614400000_1234",
"savedAt": "2026-01-07T12:34:56.789Z"
}
# 测试 2: 无效节点ID
curl -X POST http://localhost:8000/api/nodes/save \
-H "Content-Type: application/json" \
-d '{
"nodeId": "invalid_id",
"nodeData": {}
}'
# 预期响应: 400 Bad Request
{
"success": false,
"error": "Invalid nodeId format"
}
```
---
## 🔐 安全注意事项
### 1. 路径遍历防护
```python
def validate_path(path: str) -> bool:
"""防止 ../ 路径遍历攻击"""
safe_path = Path(path).resolve()
base_path = Path("cloud/").resolve()
return str(safe_path).startswith(str(base_path))
```
### 2. 文件大小限制
```python
MAX_FILE_SIZE = 100 * 1024 * 1024 # 100MB
MAX_NODE_DATA_SIZE = 10 * 1024 * 1024 # 10MB
# 在上传和保存时检查大小
if len(json.dumps(request.nodeData)) > MAX_NODE_DATA_SIZE:
raise HTTPException(413, "Node data too large")
```
### 3. 用户权限验证
```python
def check_user_permission(username: str, resource_path: str) -> bool:
"""验证用户只能访问自己的资源"""
if not resource_path.startswith(f"users/{username}/"):
raise HTTPException(403, "Permission denied")
```
---
## 📦 数据库 Schema可选
如果使用数据库存储节点数据,建议的表结构:
```sql
-- 节点数据表
CREATE TABLE nodes (
node_id TEXT PRIMARY KEY,
node_type TEXT NOT NULL,
node_data TEXT NOT NULL, -- JSON 格式
created_by TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
version INTEGER DEFAULT 1
);
-- 创建索引
CREATE INDEX idx_nodes_created_by ON nodes(created_by);
CREATE INDEX idx_nodes_created_at ON nodes(created_at);
-- 节点历史表(可选,用于版本控制)
CREATE TABLE node_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
node_id TEXT NOT NULL,
node_data TEXT NOT NULL,
version INTEGER NOT NULL,
saved_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (node_id) REFERENCES nodes(node_id)
);
```
---
## 🚀 实施步骤
### 阶段 1: 基础功能(立即实施)
1. ✅ 实现 `GET /api/users/list` 接口
2. ✅ 测试用户列表显示
### 阶段 2: 节点持久化(后续实施)
1. ⏳ 实现 `POST /api/nodes/save` 接口
2. ⏳ 添加节点加载接口 `GET /api/nodes/{nodeId}`
3. ⏳ 添加节点列表接口 `GET /api/nodes/list`
### 阶段 3: 增强功能(可选)
1. ⏸️ 节点版本控制
2. ⏸️ 多用户协作编辑
3. ⏸️ 节点模板管理
---
## 📝 前端调用示例
### 获取用户列表
```typescript
// web/src/components/HeaderBar.tsx
React.useEffect(() => {
const fetchUsers = async () => {
try {
const response = await fetch('/api/users/list')
if (response.ok) {
const data = await response.json()
setUserList(data.users)
}
} catch (error) {
console.warn('获取用户列表失败,使用默认列表')
}
}
fetchUsers()
}, [])
```
### 保存节点数据
```typescript
// web/src/components/Inspector.tsx
const handleSaveNode = async () => {
try {
const response = await fetch('/api/nodes/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
nodeId: node.id,
nodeData: node.data
})
})
if (response.ok) {
const result = await response.json()
alert(`✅ 节点已保存: ${result.savedAt}`)
} else {
const error = await response.text()
alert(`❌ 保存失败: ${error}`)
}
} catch (error) {
alert(`❌ 网络错误: ${error}`)
}
}
```
---
## 🔄 版本历史
| 版本 | 日期 | 更新内容 |
|------|------|---------|
| v1.0 | 2026-01-07 | 初始版本定义用户列表和节点保存API |
---
## 📧 联系方式
如有疑问或建议,请通过以下方式联系:
- GitHub Issues: [TraceStudio Issues]
- 文档维护者: 前端开发团队