mcpField
C
convex-actions-general

convex-actions-general

github.com/sstobo开发24203 次安装40 周前更新
代码仓库

关于 convex-actions-general

为 Convex 开发者提供动作、HTTP 端点和数据库等功能的开发指南。内容还包括验证器、文件存储、定时任务及 TypeScript 类型实践。

主要功能

  1. 01动作和 HTTP 端点开发
  2. 02参数与 Schema 验证
  3. 03数据库 Schema 和索引设计
  4. 04环境变量与定时任务
  5. 05文件存储操作
  6. 06TypeScript 类型实践

适用场景

  1. 01实现外部 API 调用或长任务
  2. 02创建 Webhook 或公共 API 端点
  3. 03设计数据库表与索引
  4. 04配置定时任务及文件上传

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sstobo/convex-skills --skill convex-actions-general

安装后在 Claude Code 中输入/convex-actions-general确认已加载。

附带文件references/actions-and-general.md

详细介绍

Convex Actions 与通用指南技能

本技能为 Convex actions、HTTP 端点、校验器、schema 设计、文件存储、环境变量、调度以及 TypeScript 最佳实践提供全面指导。

何时使用本技能

在以下情况下使用本技能:

  • 为外部 API 调用和长时间运行的任务实现 action 函数
  • 为 webhook 或公共 API 创建 HTTP 端点
  • 为函数参数和数据库 schema 定义校验器
  • 设计包含表、索引和搜索功能的数据库 schema
  • 为密钥和配置设置环境变量
  • 实现 cron 作业和定时任务
  • 处理用于上传和下载的文件存储
  • 使用 Convex 特有的 TypeScript 模式和类型
  • 了解 Convex 的限制和性能约束

技能资源

本技能在 references/actions-and-general.md 中包含全面的参考文档,涵盖以下内容:

Actions 与 HTTP
  • Actions:使用 "use node" 为 Node.js 模块定义 actions
    • V8 与 Node 运行时的差异
    • Action 限制(10 分钟超时,无法访问数据库)
    • 调用外部 API 和服务
  • HTTP 端点:使用 httpRouter 设置 convex/http.ts
    • 路径注册与精确匹配
    • 请求/响应处理
    • 方法定义(POST、GET 等)
校验器与类型
  • 所有 Convex 类型的完整校验器参考
  • 常用校验器:v.object()、v.array()、v.string()、v.number()、v.id()、v.boolean()、v.null()
  • 使用 v.union() 和 v.literal() 的可辨识联合类型
  • 对象字段名必须为 ASCII 的要求
  • 大小和元素数量限制
函数开发
  • 所有函数类型的新函数语法
  • 函数注册模式(query、mutation、action、internalQuery、internalMutation、internalAction)
  • 跨运行时的函数调用模式
  • 通过 api 和 internal 对象的函数引用
  • 基于文件的路由约定
API 设计
  • 组织公共和私有函数
  • convex/ 目录内合理的文件结构
  • 公共与内部函数的可见性
  • API 表面一致性
数据库与 Schema
  • Schema 定义:convex/schema.ts 结构
    • 系统字段(_id、_creationTime)
    • 带有校验器的表定义
  • 索引:创建高效索引
    • 内置索引(by_id、by_creation_time)
    • 自定义索引命名和字段排序
    • 用于复杂查询的多字段索引
  • 全文搜索:搜索索引定义
    • 搜索字段和过滤字段
    • 使用点表示法的嵌套字段路径
环境与配置
  • 环境变量:使用 process.env
    • 存储密钥(API 密钥、凭据)
    • 按部署配置
    • 从任何函数类型访问
  • 调度:
    • Crons:使用 crons.interval() 和 crons.cron()
    • Scheduler:从 mutations/actions 使用 ctx.scheduler.runAfter()
    • 认证状态传播(不会传播到定时作业)
    • 时序约束和最佳实践
文件存储
  • 使用 ctx.storage.generateUploadUrl() 生成上传 URL
  • 使用 ctx.storage.getUrl() 获取签名 URL
  • 来自 _storage 系统表的文件元数据
  • 用于存储操作的 Blob 转换
  • 完整示例:聊天应用中的图片上传
限制与性能
  • 函数参数和返回值:最大 8 MiB
  • 数据库操作:每次 mutation 最多写入 8192 个文档,每次 query 最多读取 16384 个
  • 执行超时:queries/mutations 为 1 秒,actions 为 10 分钟
  • 数组元素限制:最大 8192
  • 对象/Record 字段限制:最大 1024
  • 嵌套深度:最大 16
  • Record 大小:最大 1 MiB
  • HTTP 流式传输:最大输出 20 MiB
TypeScript
  • Id<'tableName'> 类型用于严格文档 ID
  • Doc<'tableName'> 类型用于文档类型安全
  • Record<KeyType, ValueType> 配合正确的类型标注
  • as const 用于可辨识联合
  • 为同文件函数调用添加类型注解
  • @types/node 用于 Node.js 模块

如何使用本技能

  1. 阅读参考文档 references/actions-and-general.md 了解全面的模式
  2. 遵循语法 定义操作并正确处理 Node.js 模块
  3. 正确使用验证器 为所有函数参数和 schema 字段
  4. 设计 schema 为你的访问模式配置合适的索引
  5. 设置环境变量 用于密钥和配置
  6. 实现调度 使用 cron 或调度器处理后台任务
  7. 处理文件存储 正确生成 URL 和查询元数据
  8. 了解限制 并设计应用时遵守这些限制
  9. 严格使用 TypeScript 配合 Id 类型和正确的泛型

关键通用准则

  • 所有函数(查询、变更、操作)务必使用参数验证器
  • 不要在数据库中存储文件 URL;应存储文件 ID
  • 在将非 ASCII 字符(emoji)存入对象之前,先将其重映射为 ASCII 码
  • 认证状态不会传播到定时任务;请使用内部函数
  • 定时函数的运行频率不应超过每 10 秒一次
  • 除非跨运行时(V8 到 Node),否则不要从其他操作中调用操作
  • Convex 中的对象字段名必须仅包含 ASCII 字符
  • 严格对待 TypeScript 类型,尤其是文档 ID

示例:带 HTTP 端点的完整操作

// convex/ai.ts
"use node";
import { action } from "./_generated/server";
import { v } from "convex/values";
import { internal } from "./_generated/api";
import OpenAI from "openai";

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

export const generateResponse = action({
  args: {
    channelId: v.id("channels"),
  },
  handler: async (ctx, args) => {
    // Actions can't access ctx.db, but can call mutations
    const context = await ctx.runQuery(internal.functions.loadContext, {
      channelId: args.channelId,
    });

    const response = await openai.chat.completions.create({
      model: "gpt-4o-mini",
      messages: context,
    });

    const content = response.choices[0].message.content;
    if (!content) throw new Error("No content in response");

    await ctx.runMutation(internal.functions.writeAgentResponse, {
      channelId: args.channelId,
      content,
    });

    return null;
  },
});

示例:HTTP 端点

// convex/http.ts
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";

const http = httpRouter();

http.route({
  path: "/webhook",
  method: "POST",
  handler: httpAction(async (ctx, req) => {
    const body = await req.json();
    // Process webhook payload
    return new Response(JSON.stringify({ success: true }), { status: 200 });
  }),
});

export default http;

如需更详细的信息和更多模式,请参阅完整的参考文档。

评论

支持 Markdown