Files
agent-park/docs/api-reference.md
T
蔡浩涵 bef12403fb feat: 添加项目删除 API 接口和完整 API 文档
- 新增 DELETE /api/projects/:slug 接口,支持根据 slug 删除项目
- 删除操作会级联删除关联的外部链接和标签关系
- 新增 GET /api/projects/:slug 接口,支持查询项目详情
- 添加完整的 API 参考文档(docs/api-reference.md)
- 修复 ProjectDetail 组件的 iframe 嵌入逻辑,添加可嵌入域名白名单
- 删除旧的数据摄入流程文档,由新 API 文档替代
2026-01-11 13:58:52 +08:00

16 KiB
Raw Blame History

API 接口文档

AI 项目导航站对外提供的 REST API 接口文档

目录


1. 概述

1.1 Base URL

生产环境: https://your-domain.com
开发环境: http://localhost:3000

1.2 响应格式

所有接口返回 JSON 格式数据:

// 成功响应
{
  "success": true,
  "data": { ... },
  "message": "操作成功"
}

// 错误响应
{
  "success": false,
  "error": "错误类型",
  "details": ["详细错误信息1", "详细错误信息2"]
}

1.3 通用请求头

Content-Type: application/json
x-api-key: your-api-key-here  # 需要认证的接口

2. 认证方式

API Key 认证

所有 API 接口均使用 API Key 进行认证。API Key 通过请求头 x-api-key 传递。

# 设置环境变量
WEBHOOK_API_KEY=your-secret-api-key

# 请求示例
curl -X POST https://your-domain.com/api/webhook/projects \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-secret-api-key" \
  -d '...'

注意事项:

  • API Key 需要在服务端环境变量中配置 WEBHOOK_API_KEY
  • 请妥善保管 API Key,不要在客户端代码中暴露
  • 建议定期轮换 API Key

3. 接口列表

3.1 创建/更新项目 (Webhook)

批量创建或更新项目数据。支持多级去重策略自动识别已存在的项目。

3.1.1 接口信息

POST /api/webhook/projects

3.1.2 请求参数

Headers:

参数 类型 必填 说明
x-api-key string API 密钥
Content-Type string 必须为 application/json

Body:

{
  apiKey: string;           // API 密钥(与 header x-api-key 二选一)
  projects: ProjectInput[]; // 项目数组(1-100个)
}

ProjectInput 类型:

{
  // 基础信息(必填)
  name: string;              // 中文名称
  nameEn?: string;           // 英文名称(可选)
  description: string;       // 中文描述
  descriptionEn?: string;    // 英文描述(可选)

  // 内容(可选)
  content?: string;          // 中文内容(Markdown 格式)
  contentEn?: string;        // 英文内容(Markdown 格式)

  // 状态(可选)
  status?: "ACTIVE" | "ARCHIVED";  // 默认: "ACTIVE"
  source?: string;           // 数据来源标识

  // 关联(必填)
  tags: Array<{              // 标签数组(1-10个)
    name: string;            // 标签名
    nameEn?: string;         // 英文标签名(可选)
  }>;
  links: Array<{             // 外部链接数组(1-10个)
    type: "WEBSITE" | "GITHUB" | "HUGGINGFACE" | "PAPER";
    url: string;             // 链接 URL
    title?: string;          // 链接标题(可选)
  }>;
}

3.1.3 多级去重策略

Webhook 会按以下优先级识别已存在的项目:

  1. GitHub URL 精确匹配(最准确)
  2. Website URL 精确匹配
  3. slug 匹配(兜底)

如果找到已存在的项目,将执行更新操作:

  • 更新所有项目字段
  • 替换所有标签(删除旧的,创建新的)
  • 替换所有链接(删除旧的,创建新的)

3.1.4 请求示例

curl -X POST https://your-domain.com/api/webhook/projects \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "apiKey": "your-api-key",
    "projects": [
      {
        "name": "LangChain",
        "nameEn": "LangChain",
        "description": "开发由语言模型驱动的应用程序框架",
        "descriptionEn": "Developing applications powered by language models",
        "content": "# LangChain\n\nLangChain 是一个...",
        "contentEn": "# LangChain\n\nLangChain is a...",
        "status": "ACTIVE",
        "source": "GITHUB",
        "tags": [
          { "name": "LLM", "nameEn": "Large Language Model" },
          { "name": "Python", "nameEn": "Python" },
          { "name": "开发框架", "nameEn": "Development Framework" }
        ],
        "links": [
          {
            "type": "GITHUB",
            "url": "https://github.com/langchain-ai/langchain",
            "title": "GitHub 仓库"
          },
          {
            "type": "WEBSITE",
            "url": "https://langchain.com",
            "title": "官方网站"
          }
        ]
      }
    ]
  }'

3.1.5 响应示例

成功响应 (200 OK):

{
  "success": true,
  "processed": 1,
  "created": 0,
  "updated": 1,
  "failed": 0,
  "errors": []
}

错误响应 (400 Bad Request):

{
  "success": false,
  "error": "Validation error",
  "details": [
    "tags: Field must contain at least 1 element",
    "links: Field must contain at most 10 elements"
  ]
}

认证失败 (401 Unauthorized):

{
  "success": false,
  "error": "Unauthorized",
  "details": ["Invalid or missing API Key"]
}

3.2 获取项目详情

根据项目的 slug 获取项目详细信息。

3.2.1 接口信息

GET /api/projects/:slug

3.2.2 路径参数

参数 类型 必填 说明
slug string 项目的唯一标识符

3.2.3 请求示例

curl -X GET https://your-domain.com/api/projects/langchain \
  -H "Content-Type: application/json"

3.2.4 响应示例

成功响应 (200 OK):

{
  "success": true,
  "data": {
    "id": "clx1234567890",
    "name": "LangChain",
    "nameEn": "LangChain",
    "slug": "langchain",
    "description": "开发由语言模型驱动的应用程序框架",
    "descriptionEn": "Developing applications powered by language models",
    "content": "# LangChain\n\nLangChain 是一个...",
    "contentEn": "# LangChain\n\nLangChain is a...",
    "status": "ACTIVE",
    "source": "GITHUB",
    "createdAt": "2024-01-01T00:00:00.000Z",
    "updatedAt": "2024-01-15T00:00:00.000Z",
    "links": [
      {
        "id": "link123",
        "type": "GITHUB",
        "url": "https://github.com/langchain-ai/langchain",
        "title": "GitHub 仓库"
      }
    ],
    "tags": [
      {
        "id": "tag123",
        "name": "LLM",
        "nameEn": "Large Language Model",
        "slug": "large-language-model"
      }
    ]
  }
}

项目不存在 (404 Not Found):

{
  "success": false,
  "error": "Not Found",
  "details": ["Project with slug \"nonexistent\" not found"]
}

3.3 删除项目

根据项目的 slug 删除项目及其所有关联数据。

3.3.1 接口信息

DELETE /api/projects/:slug

3.3.2 路径参数

参数 类型 必填 说明
slug string 项目的唯一标识符

3.3.3 请求头

参数 类型 必填 说明
x-api-key string API 密钥
Content-Type string 必须为 application/json

3.3.4 级联删除说明

由于数据库配置了 onDelete: Cascade,删除项目时会自动删除:

  • 该项目的所有外部链接(ExternalLink
  • 该项目的所有标签关联(ProjectTag
  • Tag 本身不会被删除(只删除项目与标签的关联关系)

3.3.5 请求示例

curl -X DELETE https://your-domain.com/api/projects/langchain \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key"

3.3.6 响应示例

成功响应 (200 OK):

{
  "success": true,
  "message": "Project deleted successfully",
  "data": {
    "project": {
      "id": "clx1234567890",
      "name": "LangChain",
      "nameEn": "LangChain",
      "slug": "langchain"
    },
    "deleted": {
      "linksCount": 2,
      "tagsCount": 3
    }
  }
}

项目不存在 (404 Not Found):

{
  "success": false,
  "error": "Not Found",
  "details": ["Project with slug \"nonexistent\" not found"]
}

认证失败 (401 Unauthorized):

{
  "success": false,
  "error": "Unauthorized",
  "details": ["Invalid or missing API Key"]
}

4. 数据模型

4.1 Project 状态枚举

enum ProjectStatus {
  ACTIVE = "ACTIVE",     // 活跃项目
  ARCHIVED = "ARCHIVED"  // 已归档项目
}

4.2 链接类型枚举

enum LinkType {
  WEBSITE = "WEBSITE",         // 官方网站
  GITHUB = "GITHUB",           // GitHub 仓库
  HUGGINGFACE = "HUGGINGFACE", // Hugging Face 模型/数据集
  PAPER = "PAPER"              // 论文链接
}

4.3 完整项目模型

interface Project {
  id: string;                  // 项目唯一 IDcuid 格式)
  name: string;                // 中文名称
  nameEn: string | null;       // 英文名称
  slug: string;                // URL 友好标识符(唯一)
  description: string;         // 中文描述
  descriptionEn: string | null;// 英文描述
  content: string | null;      // 中文内容(Markdown
  contentEn: string | null;    // 英文内容(Markdown
  status: ProjectStatus;       // 项目状态
  source: string | null;       // 数据来源
  createdAt: Date;             // 创建时间
  updatedAt: Date;             // 更新时间

  // 关联数据
  tags: Tag[];                 // 标签数组
  links: ExternalLink[];       // 外部链接数组
}

4.4 Tag 模型

interface Tag {
  id: string;          // 标签唯一 ID
  name: string;        // 中文名称(唯一)
  nameEn: string | null; // 英文名称
  slug: string;        // URL 友好标识符(唯一)
  createdAt: Date;     // 创建时间
}
interface ExternalLink {
  id: string;          // 链接唯一 ID
  type: LinkType;      // 链接类型
  url: string;         // 链接 URL
  title: string | null; // 链接标题
  projectId: string;   // 所属项目 ID
}

5. 错误码

5.1 HTTP 状态码

状态码 说明 示例场景
200 OK 请求成功 成功获取/创建/更新/删除数据
400 Bad Request 请求参数错误 必填字段缺失、字段格式错误
401 Unauthorized 认证失败 API Key 无效或缺失
404 Not Found 资源不存在 请求的项目 slug 不存在
500 Internal Server Error 服务器内部错误 数据库连接失败、程序异常

5.2 业务错误类型

错误类型 说明 处理建议
Validation error 数据验证失败 检查请求体字段是否符合要求
Unauthorized API Key 无效 检查 API Key 是否正确
Not Found 资源不存在 确认 slug 是否正确
Internal server error 服务器错误 联系技术支持或稍后重试

5.3 验证规则

项目数据验证

// 必填字段
- name: 非空字符串,长度 1-200
- description: 非空字符串,长度 1-5000
- tags: 数组,长度 1-10,每个 tag.name 非空
- links: 数组,长度 1-10,每个 link.url  link.type 非空

// 可选字段
- nameEn: 字符串,长度 1-200
- descriptionEn: 字符串,长度 1-5000
- content/contentEn: 文本类型,支持 Markdown
- status: 枚举值 "ACTIVE"  "ARCHIVED",默认 "ACTIVE"
- source: 字符串,标识数据来源

// URL 格式
- links[*].url: 必须是有效的 HTTP/HTTPS URL
- links[*].type: 必须是 LinkType 枚举值之一

Webhook 批量操作限制

// 批量操作
- projects: 数组,长度 1-100
- apiKey: 必须与环境变量 WEBHOOK_API_KEY 匹配

6. 使用示例

6.1 完整的工作流示例

// 1. 创建/更新项目
const createResponse = await fetch('https://your-domain.com/api/webhook/projects', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'your-api-key'
  },
  body: JSON.stringify({
    apiKey: 'your-api-key',
    projects: [{
      name: 'My AI Project',
      nameEn: 'My AI Project',
      description: '一个创新的 AI 项目',
      descriptionEn: 'An innovative AI project',
      status: 'ACTIVE',
      source: 'MANUAL',
      tags: [
        { name: 'AI', nameEn: 'Artificial Intelligence' },
        { name: '机器学习', nameEn: 'Machine Learning' }
      ],
      links: [
        { type: 'GITHUB', url: 'https://github.com/user/project', title: 'GitHub' },
        { type: 'WEBSITE', url: 'https://project.com', title: 'Website' }
      ]
    }]
  })
});

const createResult = await createResponse.json();
console.log('创建结果:', createResult);
// { success: true, processed: 1, created: 1, updated: 0, failed: 0, errors: [] }

// 2. 获取项目详情
const slug = 'my-ai-project'; // 根据 nameEn 自动生成
const getResponse = await fetch(`https://your-domain.com/api/projects/${slug}`);
const getResult = await getResponse.json();
console.log('项目详情:', getResult.data);

// 3. 删除项目
const deleteResponse = await fetch(`https://your-domain.com/api/projects/${slug}`, {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'your-api-key'
  }
});
const deleteResult = await deleteResponse.json();
console.log('删除结果:', deleteResult);

6.2 批量创建项目示例

const projects = [
  {
    name: '项目 A',
    nameEn: 'Project A',
    description: '项目 A 的描述',
    descriptionEn: 'Description of Project A',
    tags: [{ name: '分类1' }],
    links: [{ type: 'GITHUB', url: 'https://github.com/user/a' }]
  },
  {
    name: '项目 B',
    nameEn: 'Project B',
    description: '项目 B 的描述',
    descriptionEn: 'Description of Project B',
    tags: [{ name: '分类2' }],
    links: [{ type: 'GITHUB', url: 'https://github.com/user/b' }]
  }
];

const response = await fetch('https://your-domain.com/api/webhook/projects', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'your-api-key'
  },
  body: JSON.stringify({
    apiKey: 'your-api-key',
    projects: projects
  })
});

const result = await response.json();
console.log('批量创建结果:', result);
// { success: true, processed: 2, created: 2, updated: 0, failed: 0, errors: [] }

7. 注意事项

7.1 Slug 生成规则

项目 slug 根据以下规则自动生成:

  1. 优先使用 nameEn(英文)
  2. 如果 nameEn 不存在,使用 name(中文)
  3. 转换为小写
  4. 空格替换为连字符 -
  5. 移除特殊字符

示例:

  • nameEn: "LangChain"slug: "langchain"
  • name: "大语言模型"slug: "大语言模型" (会进行拼音转换)

7.2 标签去重

  • 标签的 name 字段在数据库中是唯一的
  • 如果创建已存在的标签,会自动复用现有标签
  • 标签的 slug 也是唯一的,会根据 nameEnname 自动生成

7.3 链接去重

  • 同一个项目不能有重复的 URL
  • 通过 projectId + url 的组合保证唯一性

7.4 更新策略

  • Webhook 使用 替换策略 更新标签和链接
  • 不是增量更新,而是完全替换
  • 更新时会删除旧的标签/链接关联,创建新的

8. 附录

8.1 环境变量配置

# .env
WEBHOOK_API_KEY=your-secret-api-key-here
DATABASE_URL=postgresql://user:password@host:5432/dbname?sslmode=require

8.2 相关文档


文档版本: v1.0.0 最后更新: 2024-01-11 维护者: AI 项目导航站团队