# API 规范

本文档定义新 SaaS 项目的 REST API 设计规范。

---

## 1. 基本原则

- **RESTful** 设计
- **JSON** 数据格式
- **HTTP 状态码** 语义化
- **版本化** API（未来）
- **文档化** (Swagger/ReDoc)

---

## 2. URL 设计

### 2.1 资源命名

**使用复数名词**：
```
✅ /api/projects
✅ /api/asset-libraries
✅ /api/assets
✅ /api/ingest-jobs

❌ /api/project
❌ /api/assetLibrary
❌ /api/get_assets
```

**使用 kebab-case**：
```
✅ /api/asset-libraries
✅ /api/ingest-jobs

❌ /api/assetLibraries
❌ /api/ingest_jobs
```

### 2.2 路径层级

**浅层级**（推荐）：
```
✅ GET /api/projects?workspace_id=ws-1
✅ GET /api/assets?library_id=lib-1

❌ GET /api/workspaces/ws-1/projects
❌ GET /api/projects/proj-1/libraries/lib-1/assets
```

**原因**：
- 避免深层嵌套
- 查询参数更灵活
- URL 更简洁

---

## 3. HTTP 方法

| 方法 | 用途 | 幂等性 | 安全性 |
|------|------|--------|--------|
| GET | 查询资源 | ✅ | ✅ |
| POST | 创建资源 | ❌ | ❌ |
| PUT | 完整更新 | ✅ | ❌ |
| PATCH | 部分更新 | ❌ | ❌ |
| DELETE | 删除资源 | ✅ | ❌ |

### 3.1 示例

```http
# 查询项目列表
GET /api/projects?workspace_id=ws-1

# 创建项目
POST /api/projects
Content-Type: application/json
{
  "workspace_id": "ws-1",
  "name": "新项目",
  "description": "描述"
}

# 更新项目
PUT /api/projects/{project_id}
Content-Type: application/json
{
  "name": "更新后的名称",
  "description": "更新后的描述"
}

# 删除项目
DELETE /api/projects/{project_id}
```

---

## 4. HTTP 状态码

### 4.1 成功响应

| 状态码 | 含义 | 使用场景 |
|--------|------|----------|
| 200 OK | 成功 | GET、PUT、PATCH |
| 201 Created | 创建成功 | POST |
| 204 No Content | 成功无内容 | DELETE |

### 4.2 客户端错误

| 状态码 | 含义 | 使用场景 |
|--------|------|----------|
| 400 Bad Request | 请求参数错误 | 参数验证失败 |
| 401 Unauthorized | 未认证 | 缺少 token |
| 403 Forbidden | 无权限 | 权限不足 |
| 404 Not Found | 资源不存在 | 资源未找到 |
| 409 Conflict | 冲突 | 资源已存在 |
| 422 Unprocessable Entity | 业务逻辑错误 | 业务规则违反 |

### 4.3 服务器错误

| 状态码 | 含义 | 使用场景 |
|--------|------|----------|
| 500 Internal Server Error | 服务器错误 | 未预期的异常 |
| 503 Service Unavailable | 服务不可用 | 维护中 |

---

## 5. 请求格式

### 5.1 查询参数（GET）

```http
GET /api/projects?workspace_id=ws-1&page=1&page_size=20
```

**命名**：snake_case

**分页参数**：
- `page` - 页码（从 1 开始）
- `page_size` - 每页数量（默认 20，最大 100）

**过滤参数**：
- `workspace_id` - 按工作空间过滤
- `kind` - 按类型过滤
- `status` - 按状态过滤

**排序参数**：
- `sort_by` - 排序字段（如 `created_at`）
- `sort_order` - 排序方向（`asc` / `desc`）

### 5.2 请求体（POST/PUT/PATCH）

```json
{
  "workspace_id": "ws-1",
  "name": "项目名称",
  "description": "项目描述"
}
```

**命名**：snake_case

---

## 6. 响应格式

### 6.1 单个资源

```json
{
  "id": "proj-123",
  "workspace_id": "ws-1",
  "name": "项目名称",
  "description": "项目描述",
  "created_at": "2026-06-15T08:00:00Z"
}
```

### 6.2 资源列表

```json
{
  "items": [
    {
      "id": "proj-123",
      "workspace_id": "ws-1",
      "name": "项目 1"
    },
    {
      "id": "proj-456",
      "workspace_id": "ws-1",
      "name": "项目 2"
    }
  ],
  "total": 42,
  "page": 1,
  "page_size": 20
}
```

### 6.3 错误响应

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "项目名称不能为空",
    "details": {
      "field": "name",
      "value": ""
    }
  }
}
```

**错误码**：
- `VALIDATION_ERROR` - 参数验证失败
- `NOT_FOUND` - 资源不存在
- `CONFLICT` - 资源冲突
- `PERMISSION_DENIED` - 权限不足
- `INTERNAL_ERROR` - 服务器错误

---

## 7. 认证与授权

### 7.1 认证（Phase 2）

```http
GET /api/projects
Authorization: Bearer {token}
```

### 7.2 授权（Phase 3）

```http
GET /api/projects/{project_id}
Authorization: Bearer {token}
X-Workspace-ID: ws-1
```

---

## 8. 版本化（Phase 3）

```http
GET /api/v1/projects
GET /api/v2/projects
```

---

## 9. 接口示例

### 9.1 项目管理

**创建项目**：
```http
POST /api/projects
Content-Type: application/json

{
  "workspace_id": "ws-1",
  "name": "新项目",
  "description": "描述"
}

Response 201:
{
  "id": "proj-123",
  "workspace_id": "ws-1",
  "name": "新项目",
  "description": "描述",
  "created_at": "2026-06-15T08:00:00Z"
}
```

**查询项目列表**：
```http
GET /api/projects?workspace_id=ws-1&page=1&page_size=20

Response 200:
{
  "items": [...],
  "total": 42,
  "page": 1,
  "page_size": 20
}
```

### 9.2 素材上传

**上传素材**：
```http
POST /api/upload
Content-Type: application/json

{
  "workspace_id": "ws-1",
  "project_id": "proj-1",
  "library_id": "lib-1",
  "filename": "video.mp4"
}

Response 201:
{
  "storage_key": "uploads/abc123/video.mp4",
  "ingest_job_id": "job-456"
}
```

### 9.3 任务查询

**查询入库任务**：
```http
GET /api/ingest-jobs/{job_id}

Response 200:
{
  "id": "job-456",
  "workspace_id": "ws-1",
  "project_id": "proj-1",
  "library_id": "lib-1",
  "storage_key": "uploads/abc123/video.mp4",
  "status": "completed",
  "result_asset_id": "asset-789",
  "created_at": "2026-06-15T08:00:00Z",
  "updated_at": "2026-06-15T08:01:00Z"
}
```

---

## 10. 性能优化

### 10.1 分页

**强制分页**（避免返回大量数据）：
```http
GET /api/assets?library_id=lib-1&page=1&page_size=20
```

### 10.2 字段过滤（Phase 2）

```http
GET /api/projects?fields=id,name
```

### 10.3 批量操作（Phase 2）

```http
POST /api/assets/batch
Content-Type: application/json

{
  "operations": [
    {"action": "delete", "id": "asset-1"},
    {"action": "delete", "id": "asset-2"}
  ]
}
```

---

## 11. 文档化

使用 **FastAPI** 自动生成文档：
- Swagger UI: `http://localhost:8000/docs`
- ReDoc: `http://localhost:8000/redoc`

---

**最后更新**: 2026-06-15  
**版本**: v1.0
