video-flow-b/docs/video-edit-api-specification.md
2025-10-27 15:48:42 +08:00

15 KiB
Raw Blame History

🎬 Video Edit API 完整规范文档

📋 概述

本文档为video-flow-b视频编辑功能的后端API提供完整的实现规范包括RESTful API设计、数据结构定义、认证机制、数据库设计等为后端开发团队提供详细的实现指南。

🏗️ 系统架构

技术栈建议

  • 后端框架: FastAPI (Python) / Express.js (Node.js) / Spring Boot (Java)
  • 数据库: PostgreSQL (主数据库) + Redis (缓存)
  • 认证: JWT Token
  • 文件存储: AWS S3 / 阿里云OSS
  • 消息队列: Redis / RabbitMQ (用于异步处理)

服务架构

Frontend (React) 
    ↓ HTTP/HTTPS
API Gateway 
    ↓
Video Edit Service
    ↓
Database (PostgreSQL) + Cache (Redis)

🗄️ 数据库设计

1. 编辑点表 (edit_points)

CREATE TABLE edit_points (
    id VARCHAR(50) PRIMARY KEY,
    video_id VARCHAR(100) NOT NULL,
    project_id VARCHAR(100) NOT NULL,
    user_id INTEGER NOT NULL,
    position_x FLOAT NOT NULL CHECK (position_x >= 0 AND position_x <= 100),
    position_y FLOAT NOT NULL CHECK (position_y >= 0 AND position_y <= 100),
    timestamp FLOAT NOT NULL CHECK (timestamp >= 0),
    description TEXT DEFAULT '',
    status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'edited', 'processing', 'completed', 'failed')),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    -- 索引
    INDEX idx_edit_points_video_project (video_id, project_id),
    INDEX idx_edit_points_user (user_id),
    INDEX idx_edit_points_status (status),
    INDEX idx_edit_points_created (created_at DESC),
    
    -- 外键约束
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);

2. 编辑历史表 (edit_point_history)

CREATE TABLE edit_point_history (
    id SERIAL PRIMARY KEY,
    edit_point_id VARCHAR(50) NOT NULL,
    action VARCHAR(20) NOT NULL CHECK (action IN ('created', 'updated', 'deleted', 'submitted')),
    old_data JSONB,
    new_data JSONB,
    user_id INTEGER NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    -- 索引
    INDEX idx_history_edit_point (edit_point_id),
    INDEX idx_history_user (user_id),
    INDEX idx_history_created (created_at DESC),
    
    -- 外键约束
    FOREIGN KEY (edit_point_id) REFERENCES edit_points(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

3. 编辑任务队列表 (edit_tasks)

CREATE TABLE edit_tasks (
    id SERIAL PRIMARY KEY,
    edit_point_id VARCHAR(50) NOT NULL,
    task_type VARCHAR(20) NOT NULL DEFAULT 'edit_request',
    priority INTEGER DEFAULT 0,
    status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
    payload JSONB NOT NULL,
    result JSONB,
    error_message TEXT,
    retry_count INTEGER DEFAULT 0,
    max_retries INTEGER DEFAULT 3,
    scheduled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    started_at TIMESTAMP,
    completed_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    -- 索引
    INDEX idx_tasks_status (status),
    INDEX idx_tasks_scheduled (scheduled_at),
    INDEX idx_tasks_edit_point (edit_point_id),
    
    -- 外键约束
    FOREIGN KEY (edit_point_id) REFERENCES edit_points(id) ON DELETE CASCADE
);

🔌 API 端点规范

基础配置

  • Base URL: https://api.smartvideo.py.qikongjian.com/v1
  • Content-Type: application/json
  • 认证方式: Bearer Token (JWT)

1. 获取编辑点列表

GET /video-edit/edit-points

查询参数:

interface GetEditPointsQuery {
  video_id: string;        // 必需视频ID
  project_id: string;      // 必需项目ID
  offset?: number;         // 可选偏移量默认0
  limit?: number;          // 可选限制数量默认50最大100
  status?: EditPointStatus; // 可选:状态筛选
  sort?: 'created_at' | 'updated_at' | 'timestamp'; // 可选:排序字段
  order?: 'asc' | 'desc';  // 可选排序方向默认desc
}

响应格式:

interface GetEditPointsResponse {
  code: number;            // 状态码0表示成功
  successful: boolean;     // 是否成功
  message: string;         // 响应消息
  data: {
    edit_points: EditPoint[];
    total_count: number;
    has_more: boolean;
    pagination: {
      offset: number;
      limit: number;
      total: number;
    };
  };
}

示例请求:

curl -X GET "https://api.smartvideo.py.qikongjian.com/v1/video-edit/edit-points?video_id=video123&project_id=proj456&limit=20" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json"

2. 创建编辑点

POST /video-edit/edit-points

请求体:

interface CreateEditPointRequest {
  video_id: string;        // 必需视频ID
  project_id: string;      // 必需项目ID
  position_x: number;      // 必需X坐标百分比 (0-100)
  position_y: number;      // 必需Y坐标百分比 (0-100)
  timestamp: number;       // 必需:时间戳(秒)
  description?: string;    // 可选:编辑描述
  status?: EditPointStatus; // 可选初始状态默认pending
}

响应格式:

interface CreateEditPointResponse {
  code: number;
  successful: boolean;
  message: string;
  data: EditPoint;
}

示例请求:

curl -X POST "https://api.smartvideo.py.qikongjian.com/v1/video-edit/edit-points" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "video_id": "video123",
    "project_id": "proj456",
    "position_x": 50.5,
    "position_y": 30.2,
    "timestamp": 15.5,
    "description": "需要在这里添加特效"
  }'

3. 更新编辑点

PUT /video-edit/edit-points/{edit_point_id}

路径参数:

  • edit_point_id: 编辑点ID

请求体:

interface UpdateEditPointRequest {
  description?: string;    // 可选:编辑描述
  status?: EditPointStatus; // 可选:状态
  position_x?: number;     // 可选X坐标百分比
  position_y?: number;     // 可选Y坐标百分比
}

响应格式:

interface UpdateEditPointResponse {
  code: number;
  successful: boolean;
  message: string;
  data: EditPoint;
}

4. 删除编辑点

DELETE /video-edit/edit-points/{edit_point_id}

路径参数:

  • edit_point_id: 编辑点ID

响应格式:

interface DeleteEditPointResponse {
  code: number;
  successful: boolean;
  message: string;
  data: null;
}

5. 批量删除编辑点

POST /video-edit/edit-points/batch-delete

请求体:

interface BatchDeleteRequest {
  edit_point_ids: string[]; // 必需要删除的编辑点ID列表
}

6. 提交编辑请求

POST /video-edit/edit-points/{edit_point_id}/submit

路径参数:

  • edit_point_id: 编辑点ID

响应格式:

interface SubmitEditResponse {
  code: number;
  successful: boolean;
  message: string;
  data: {
    task_id: string;        // 任务ID用于跟踪处理状态
    estimated_duration: number; // 预估处理时间(秒)
  };
}

7. 获取编辑统计

GET /video-edit/stats

查询参数:

interface GetStatsQuery {
  project_id?: string;     // 可选项目ID筛选
  video_id?: string;       // 可选视频ID筛选
  date_from?: string;      // 可选:开始日期 (ISO 8601)
  date_to?: string;        // 可选:结束日期 (ISO 8601)
}

响应格式:

interface GetStatsResponse {
  code: number;
  successful: boolean;
  message: string;
  data: {
    total_edit_points: number;
    status_breakdown: {
      pending: number;
      edited: number;
      processing: number;
      completed: number;
      failed: number;
    };
    daily_stats: Array<{
      date: string;
      count: number;
    }>;
  };
}

🔐 认证和权限控制

JWT Token 结构

interface JWTPayload {
  user_id: number;
  username: string;
  email: string;
  role: 'admin' | 'user' | 'viewer';
  permissions: string[];
  exp: number;             // 过期时间戳
  iat: number;             // 签发时间戳
}

权限级别

  • admin: 所有操作权限
  • user: 可以创建、编辑、删除自己的编辑点
  • viewer: 只能查看编辑点

权限检查中间件

# FastAPI 示例
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer

security = HTTPBearer()

async def verify_token(token: str = Depends(security)):
    try:
        payload = jwt.decode(token.credentials, SECRET_KEY, algorithms=["HS256"])
        return payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token has expired"
        )
    except jwt.JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )

async def check_edit_permission(
    edit_point_id: str,
    current_user: dict = Depends(verify_token)
):
    # 检查用户是否有权限编辑该编辑点
    edit_point = await get_edit_point(edit_point_id)
    if not edit_point:
        raise HTTPException(status_code=404, detail="Edit point not found")
    
    if current_user["role"] != "admin" and edit_point.user_id != current_user["user_id"]:
        raise HTTPException(status_code=403, detail="Permission denied")
    
    return edit_point

📊 数据类型定义

TypeScript 接口定义

// 编辑点状态枚举
enum EditPointStatus {
  PENDING = 'pending',
  EDITED = 'edited',
  PROCESSING = 'processing',
  COMPLETED = 'completed',
  FAILED = 'failed'
}

// 编辑点位置
interface EditPointPosition {
  x: number;               // X坐标百分比 (0-100)
  y: number;               // Y坐标百分比 (0-100)
}

// 编辑点主数据结构
interface EditPoint {
  id: string;              // 编辑点唯一ID
  video_id: string;        // 视频ID
  project_id: string;      // 项目ID
  user_id: number;         // 用户ID
  position_x: number;      // X坐标百分比
  position_y: number;      // Y坐标百分比
  timestamp: number;       // 视频时间戳(秒)
  description: string;     // 编辑描述
  status: EditPointStatus; // 状态
  created_at: string;      // 创建时间 (ISO 8601)
  updated_at: string;      // 更新时间 (ISO 8601)
}

// API 通用响应格式
interface ApiResponse<T = any> {
  code: number;            // 状态码0表示成功
  successful: boolean;     // 是否成功
  message: string;         // 响应消息
  data: T;                 // 响应数据
  timestamp?: string;      // 响应时间戳
  request_id?: string;     // 请求ID用于追踪
}

// 分页信息
interface PaginationInfo {
  offset: number;          // 偏移量
  limit: number;           // 限制数量
  total: number;           // 总数量
  has_more: boolean;       // 是否有更多数据
}

// 错误详情
interface ErrorDetail {
  field?: string;          // 错误字段
  code: string;            // 错误代码
  message: string;         // 错误消息
}

⚠️ 错误码定义

HTTP 状态码

  • 200: 成功
  • 201: 创建成功
  • 400: 请求参数错误
  • 401: 未认证
  • 403: 权限不足
  • 404: 资源不存在
  • 409: 资源冲突
  • 422: 数据验证失败
  • 429: 请求过于频繁
  • 500: 服务器内部错误
  • 503: 服务不可用

业务错误码

enum BusinessErrorCode {
  // 通用错误 (1000-1099)
  INVALID_PARAMETER = 1001,
  MISSING_PARAMETER = 1002,
  INVALID_FORMAT = 1003,
  
  // 认证错误 (1100-1199)
  TOKEN_EXPIRED = 1101,
  TOKEN_INVALID = 1102,
  PERMISSION_DENIED = 1103,
  
  // 编辑点错误 (1200-1299)
  EDIT_POINT_NOT_FOUND = 1201,
  EDIT_POINT_LIMIT_EXCEEDED = 1202,
  INVALID_POSITION = 1203,
  INVALID_TIMESTAMP = 1204,
  
  // 视频错误 (1300-1399)
  VIDEO_NOT_FOUND = 1301,
  VIDEO_NOT_ACCESSIBLE = 1302,
  
  // 项目错误 (1400-1499)
  PROJECT_NOT_FOUND = 1401,
  PROJECT_NOT_ACCESSIBLE = 1402,
  
  // 系统错误 (1500-1599)
  DATABASE_ERROR = 1501,
  EXTERNAL_SERVICE_ERROR = 1502,
  RATE_LIMIT_EXCEEDED = 1503
}

🚀 部署和运维

环境变量配置

# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/video_flow
REDIS_URL=redis://localhost:6379/0

# JWT配置
JWT_SECRET_KEY=your-super-secret-key
JWT_ALGORITHM=HS256
JWT_EXPIRE_HOURS=24

# 服务配置
API_HOST=0.0.0.0
API_PORT=8000
DEBUG=false
LOG_LEVEL=INFO

# 外部服务
S3_BUCKET=video-edit-storage
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key

# 限流配置
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60

Docker 部署

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

监控和日志

  • 健康检查: GET /health
  • 指标监控: Prometheus + Grafana
  • 日志收集: ELK Stack
  • 错误追踪: Sentry

📈 性能优化建议

数据库优化

  1. 索引策略: 为常用查询字段创建复合索引
  2. 分页优化: 使用游标分页替代偏移分页
  3. 连接池: 配置合适的数据库连接池大小
  4. 读写分离: 读操作使用只读副本

缓存策略

  1. Redis缓存: 缓存热点数据和查询结果
  2. CDN: 静态资源使用CDN加速
  3. 应用缓存: 内存中缓存频繁访问的数据

API优化

  1. 批量操作: 支持批量创建、更新、删除
  2. 字段选择: 支持指定返回字段减少数据传输
  3. 压缩: 启用gzip压缩
  4. 限流: 实现智能限流防止滥用

🧪 测试策略

单元测试

import pytest
from fastapi.testclient import TestClient

def test_create_edit_point():
    response = client.post("/video-edit/edit-points", json={
        "video_id": "test-video",
        "project_id": "test-project",
        "position_x": 50.0,
        "position_y": 30.0,
        "timestamp": 15.5,
        "description": "Test edit point"
    })
    assert response.status_code == 201
    assert response.json()["successful"] == True

集成测试

  • API端点完整性测试
  • 数据库事务测试
  • 认证授权测试
  • 错误处理测试

性能测试

  • 负载测试:模拟高并发请求
  • 压力测试:测试系统极限
  • 稳定性测试:长时间运行测试

📝 开发指南

开发环境搭建

  1. 克隆代码仓库
  2. 安装依赖:pip install -r requirements.txt
  3. 配置环境变量
  4. 初始化数据库:alembic upgrade head
  5. 启动开发服务器:uvicorn main:app --reload

代码规范

  • 使用 Black 进行代码格式化
  • 使用 flake8 进行代码检查
  • 使用 mypy 进行类型检查
  • 遵循 PEP 8 编码规范

Git 工作流

  • 使用 Git Flow 分支模型
  • 提交信息遵循 Conventional Commits
  • 代码审查必须通过才能合并
  • 自动化 CI/CD 流程

📞 技术支持

如有任何技术问题或需要进一步的实现指导,请联系开发团队。

文档版本: v1.0.0
最后更新: 2024-09-19
维护者: video-flow-b 开发团队