Skip to main content
ClaudeWave
Skill28.4k repo starsupdated today

api-development

This skill establishes standardized practices for developing Next.js API routes in FastGPT, emphasizing the use of Zod schemas to define and validate request and response parameters, declaring API route information in file headers, and generating corresponding OpenAPI documentation. Use this when creating new API routes, modifying existing API parameters, defining API types, or reviewing API-related code to ensure consistency, type safety, and complete documentation across the FastGPT project.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/labring/FastGPT /tmp/api-development && cp -r /tmp/api-development/.agents/skills/system/api-development ~/.claude/skills/api-development
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# FastGPT API 开发规范

> FastGPT 项目 API 路由开发的标准化指南,确保 API 的一致性、类型安全和文档完整性。

## 何时使用此技能

- 开发新的 Next.js API 路由
- 修改现有 API 的入参或出参
- 需要 API 类型定义和文档
- 审查 API 相关代码

## 核心原则

### 🔴 必须遵守的规则

1. **所有 API 必须使用 zod schema 定义入参和出参**
2. **必须导出 schema 的 TypeScript 类型**
3. **必须在 schema 文件头部声明 API 信息(路由、方法、描述、标签)**
4. **入参必须使用 schema.parse() 验证**
5. **函数返回值必须使用 schema.parse() 验证**
6. **必须编写完整的 OpenAPI 文档**

## 开发流程

### 步骤 1: 定义 Zod Schema 并声明 API

**文件位置**: `packages/global/openapi/[module]/[api].ts`

**文件头部必须声明 API 信息**:

```typescript
import { z } from 'zod';

/* ============================================================================
 * API: 获取应用对话日志列表
 * Route: POST /api/core/app/logs/list
 * Method: POST
 * Description: 获取指定应用的对话日志列表,支持分页和多种筛选条件
 * Tags: ['App', 'Log', 'Read']
 * ============================================================================ */

// 入参 Schema
export const GetAppChatLogsBodySchema = PaginationSchema.extend({
  appId: z.string().meta({
    example: '68ad85a7463006c963799a05',
    description: '应用 ID'
  }),
  dateStart: z.union([z.string(), z.date()]).meta({
    example: '2024-01-01T00:00:00.000Z',
    description: '开始时间'
  }),
  dateEnd: z.union([z.string(), z.date()]).meta({
    example: '2024-12-31T23:59:59.999Z',
    description: '结束时间'
  }),
  sources: z.array(z.nativeEnum(ChatSourceEnum)).optional().meta({
    example: [ChatSourceEnum.api, ChatSourceEnum.online],
    description: '对话来源筛选'
  })
});

// 导出入参类型
export type getAppChatLogsBody = z.infer<typeof GetAppChatLogsBodySchema>;

// 出参 Schema
export const GetAppChatLogsResponseSchema = z.object({
  total: z.number().meta({ example: 100, description: '总记录数' }),
  list: z.array(ChatLogItemSchema)
});

// 导出出参类型
export type getAppChatLogsResponseType = z.infer<typeof GetAppChatLogsResponseSchema>;
```

**API 声明规范**:

```typescript
/**
 * 每个 API 文件必须在文件头部声明以下信息:
 *
 * 1. API 名称 (API): 简短的功能描述
 * 2. 路由 (Route): 完整的 API 路径
 * 3. 方法 (Method): HTTP 方法 (GET/POST/PUT/DELETE)
 * 4. 描述 (Description): API 的详细功能说明
 * 5. 标签 (Tags): API 的分类标签数组
 *
 * 标签示例:
 * - 'App': 应用相关 API
 * - 'User': 用户相关 API
 * - 'Log': 日志相关 API
 * - 'Read': 只读操作
 * - 'Write': 写入操作
 * - 'Delete': 删除操作
 */
```

**OpenAPI Tag 归属规则**:

- 如果接口能力属于通用模块 A,但会被业务模块 B 使用,则该接口必须同时声明 A 模块 tag 和 B 模块 tag。
- 如果同一个通用接口也被业务模块 C 使用,则继续追加 C 模块 tag。
- 通用模块 tag 表示接口能力和实现抽象归属;业务模块 tag 表示该接口应出现在对应业务文档视角里。
- 如果接口只是业务模块自己的状态查询或状态操作,不属于通用模块能力,则只声明业务模块 tag,不要为了实现位置或相邻目录误加通用模块 tag。
- 示例:`协作者管理` 是通用权限能力,应用协作者接口需要同时声明 `协作者管理` 和应用侧 `权限管理`;`获取应用权限`、`恢复应用继承权限` 是应用自身权限状态接口,只声明应用侧 `权限管理`。

**Schema 定义规范**:

#### ✅ 字段定义规范

```typescript
// ✅ 好的实践: 完整的 meta 信息
export const GetUserSchema = z.object({
  userId: z.string().meta({
    example: '68ad85a7463006c963799a05',
    description: '用户 ID'
  }),
  email: z.string().email().meta({
    example: 'user@example.com',
    description: '用户邮箱'
  }),
  age: z.number().int().positive().meta({
    example: 25,
    description: '用户年龄'
  }),
  status: z.enum(['active', 'inactive']).meta({
    example: 'active',
    description: '用户状态'
  })
});

// ❌ 不好的实践: 缺少 meta 信息
export const GetUserSchemaBad = z.object({
  userId: z.string(),
  email: z.string(),
  age: z.number(),
  status: z.string()
});
```

#### ✅ 嵌套对象定义

```typescript
// 嵌套对象应该定义为独立的 Schema
export const AddressSchema = z.object({
  street: z.string().meta({ description: '街道地址' }),
  city: z.string().meta({ description: '城市' }),
  country: z.string().meta({ description: '国家' })
});

export const CreateUserSchema = z.object({
  name: z.string().meta({ description: '用户名' }),
  address: AddressSchema.meta({ description: '地址信息' })
});
```

#### ✅ 数组定义

```typescript
export const GetUserListResponseSchema = z.object({
  total: z.number().meta({ example: 100, description: '总数' }),
  list: z.array(
    z.object({
      id: z.string().meta({ description: '用户 ID' }),
      name: z.string().meta({ description: '用户名' })
    })
  ).meta({ description: '用户列表' })
});
```

#### ✅ 可选字段

```typescript
export const UpdateUserSchema = z.object({
  userId: z.string().meta({ description: '用户 ID' }),
  // 可选字段使用 .optional()
  name: z.string().optional().meta({ description: '用户名' }),
  // 或使用 .nullish() 允许 null 和 undefined
  email: z.string().email().nullish().meta({ description: '用户邮箱' })
});
```

#### ✅ 分页 Schema

```typescript
import { PaginationSchema } from '@fastgpt/global/openapi/api';

// 继承分页 Schema
export const GetUserListSchema = PaginationSchema.extend({
  // 添加额外的筛选字段
  keyword: z.string().optional().meta({ description: '搜索关键词' }),
  status: z.enum(['active', 'inactive']).optional().meta({ description: '状态筛选' })
});
```

#### ✅ 多个 API 的 Schema 文件

```typescript
/* ============================================================================
 * API: 获取日志键
 * Route: GET /api/core/app/logs/keys
 * Method: GET
 * Description: 获取应用的日志配置键列表
 * Tags: ['App', 'Log', 'Read']
 * ============================================================================ */

export const GetLogKeysQuerySchema = z.object({
  appId: z.string().meta({ description: '应用 ID' })
});

export const GetLogKeysResponseSchema = z.object({
  logKeys: z.array(AppLogKeysSchema).meta({ description: '日志键列表' })
});

/* ============================================================================
 * API: 更新日志键
 * Route: POST /api/core/app/logs/keys
 * Method: POST
 * Description: 更新应用的日志配置键
 * Tags: ['App', 'Log', 'Write']
 * ============================================================================ */

export const UpdateLogKeysBodySchema = z.object({
  appId: z.string().meta({ description: '应用 ID' }),
  logKeys: z.array(AppLogKeysSchema).meta({ description: '日志键列表' })
});
```

### 步骤 2: 实现 API 路由

**文件位置**: `projects/app/src/pages/api/[path]/[route].ts`

**标准实现模板**:

```typescript
import type { NextApiResponse } from 'next';
import { NextAPI } from '@/service/middleware/entry';
import type { ApiRequestProps } from '@fastgpt/service/type/next';
import {
  GetAppChatLogsBodySchema,
  GetAppChatLogsResponseSchema,
  type getAppChatLogsRespons
prompt-optimizeSkill

Expert prompt engineering skill that transforms Claude into "Alpha-Prompt" - a master prompt engineer who collaboratively crafts high-quality prompts through flexible dialogue. Activates when user asks to "optimize prompt", "improve system instruction", "enhance AI instruction", or mentions prompt engineering tasks.

deprecate-workflow-nodeSkill

当用户需要弃用一个工作流节点(保留向后兼容、隐藏出模板面板)时触发该 skill。FastGPT 工作流节点的弃用流程标准化封装,覆盖模板、Dispatcher、UI 引用等所有需要改动的位置。

doc-i18nSkill

将 FastGPT 文档从中文翻译为面向北美用户的英文。当用户提到翻译文档、i18n、国际化、translate docs、新增/修改了中文文档需要同步英文版时,使用此 skill。也适用于用户要求检查文档翻译缺失、批量翻译、或对比中英文文档差异的场景。

add-permissionSkill

为 FastGPT 新资源接入权限管理。当用户需要为新资源(如 AgentSkill、Plugin 等)添加权限支持时触发。

pr-reviewSkill

仅当用户明确手动指定使用 pr-review skill 时触发;不要因为用户传入 PR 链接、要求 review 或要求代码审查而自动触发。

test-caseSkill

当用户需要编写一个单元测试时,触发该 skill,编写单元测试。

pr-change-analysisSkill

手动触发的 FastGPT PR 或本地分支变更梳理技能。仅当用户显式调用 $pr-change-analysis 时使用;用于 reviewer 分析一个 GitHub PR 或当前本地分支相对 upstream/main 的需求变更、影响范围、代码质量与代码风格,不用于自动审查触发。