关于 convex-core
面向 Convex 应用开发者的基础技能,涵盖数据建模、数据库查询、验证和函数编写,侧重类型化 Schema、索引查询与安全数据库操作。
主要功能
- 01Schema 与表建模
- 02参数和返回值验证
- 03索引查询与分页
- 04Query、Mutation 和 Action 模式
- 05TypeScript 与数据库操作指引
适用场景
- 01定义 Convex 表和验证器
- 02编写类型化查询与 mutation 函数
- 03使用索引优化读取
- 04为大型查询结果分页
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ igorwarzocha/ opencode-workflows --skill convex-core安装后在 Claude Code 中输入/convex-core确认已加载。
详细介绍
Convex 建模和函数编写的核心模式。本技能是 Convex 工作的默认基线。
- **架构**:https://docs.convex.dev/database/schemas
- **读取数据 + 索引**:https://docs.convex.dev/database/reading-data/indexes
- **验证**:https://docs.convex.dev/functions/validation
- **函数**:https://docs.convex.dev/functions
- **分页**:https://docs.convex.dev/database/pagination
- **系统表**:https://docs.convex.dev/database/advanced/system-tables
- 架构:在 `convex/schema.ts` 中使用 `defineSchema`/`defineTable`;使用 `v` 验证器。
- 选项:`schemaValidation: false` 会禁用运行时验证;`strictTableNameTypes: false` 允许在 TS 类型中使用未声明的表。
- 验证:查询、变更和操作的 `args`/`returns` 验证器;对象会拒绝额外属性;`undefined` 无效(请使用 `null`)。
- 判别联合:使用 `v.union` 和 `v.literal`,并配合 `as const` 定义类型安全的状态/种类。
- 类型:使用 `v.int64()` 表示 64 位整数(不要使用 `v.bigint()`);使用 `v.null()` 显式返回 null。
- ID:使用 `Id<"table">` 和 `v.id("table")`,而不是原始字符串。
- 记录:`v.record(keys, values)` 的键必须是 ASCII 字符、非空,且不能以 `_` 或 `$` 开头。
- 验证器组合:对象验证器支持 `Infer`、`.pick`、`.omit`、`.extend`、`.partial`。
架构规则
- 必须在
convex/schema.ts中使用defineSchema/defineTable定义所有表。 - 系统字段:
_id(v.id(tableName))和_creationTime(v.number())会自动添加。 - 每个字段都必须使用
v.*验证器;除非必要,否则应避免使用v.any()。 - 索引命名:名称中应包含所有字段,例如
"by_field1_and_field2"。 - 索引规则:
- 必须使用
.index(name, [fields...])。 - 字段顺序很重要;范围表达式必须遵循索引顺序。
- 限制:每个索引最多包含 16 个字段,每张表最多包含 32 个索引。
- 必须使用
函数规则
- 必须使用包含
args、returns和handler的新函数语法。 - 必须始终验证
args和returns(HTTP 操作除外)。 - 读取使用
query,写入使用mutation,外部调用或长时间运行的任务使用action。 action不得访问ctx.db;必须使用ctx.runQuery/ctx.runMutation。- 循环依赖:通过
ctx.run*调用同一文件中的函数时,必须为接收变量添加显式返回类型注解。
数据库操作
- 调用
ctx.db.get、ctx.db.patch、ctx.db.replace和ctx.db.delete时,必须将明确的表名作为第一个参数。 - 替换:使用
ctx.db.replace完整替换文档(文档不存在时会抛出错误)。 - 局部更新:使用
ctx.db.patch执行浅合并更新(文档不存在时会抛出错误)。 - 删除:Convex 查询不支持
.delete()。必须先使用.collect()获取结果,再遍历调用ctx.db.delete(id)。 - 唯一结果:单个文档结果使用
.unique();如果匹配到多个文档,该方法必须抛出错误。 - 生产查询中不得使用
filter;应使用索引和.withIndex。
TypeScript 最佳实践
- 判别联合中的字符串字面量必须使用
as const。 - 数组必须定义为
const array: Array<T> = [...],记录必须定义为const record: Record<K, V> = {...}。 - 所有文档标识符都应优先使用
Id<"table">,而不是string。
查询性能
- 对大型表,应优先使用
.withIndex,而不是.filter。 - 如果使用不带范围的
.withIndex,必须配合take、first、unique或paginate。 - 搜索限制:如果
collect()获取的文档超过 1024 个,就会抛出错误;处理大型数据集时应使用take(n)、paginate()或for await迭代。 - 异步迭代:对大型结果集进行流式处理时,使用
for await (const row of query),而不是.collect()。
分页
- 参数中必须使用
paginationOptsValidator。 .paginate()返回{ page, isDone, continueCursor }。- 分页是响应式的;页面大小可能会变化。
- 应避免为完整的
.paginate()结果对象使用严格的returns验证器;应验证page或使用v.any()。
客户端模式
- 必须使用来自
convex/_generated/api的api.*引用。 - React 钩子:
useQuery、useMutation、useAction、usePaginatedQuery。 - 渲染期间不得调用 mutation 或 action。
安全
- 必须为每个函数实施身份验证;使用
ctx.auth辅助方法检查身份。 - 不得在公共函数中暴露敏感逻辑;必须使用内部函数。
评论
支持 Markdown