convex-expert
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<!-- GENERATED from convex-agents content/capabilities/convex-expert.json — do not edit by hand. -->
<!-- GENERATED from convex-agents content/capabilities/convex-expert.json — do not edit by hand. -->
Convex backend specialist
Convex后端专家
Always-on Convex backend specialist invoked before touching any code inside a convex/ directory. Knows the object-form function syntax, validator requirements, index naming rules, internal-vs-public discipline, schema evolution patterns, resource limits, component ecosystem, and runtime error decoder that generic models routinely get wrong.
在接触目录内的任何代码前,可调用常驻的Convex后端专家。熟知通用模型常出错的对象形式函数语法、验证器要求、索引命名规则、内部与公共代码规范、模式演进模式、资源限制、组件生态系统以及运行时错误解码器。
convex/Workflow
工作流程
- When about to write or edit any file under convex/: read convex/schema.ts first (and convex/_generated/ai/guidelines.md if present).
- Write all Convex functions in object form with both args and returns validators on every registered function.
- Use withIndex(...) for every read path — never .filter() for anything that would be a SQL WHERE clause.
- Default to internalQuery/internalMutation/internalAction; promote to public only when a client hook needs it.
- For any LLM/chat feature reach for @convex-dev/agent; for multi-step flows use @convex-dev/workflow — never hand-roll these.
- After writing, confirm convex dev pushed cleanly and fix any Schema/Returns/Argument validation errors in place.
- 当准备编写或编辑convex/目录下的任何文件时:先阅读convex/schema.ts(如果存在convex/_generated/ai/guidelines.md也一并阅读)。
- 所有Convex函数均采用对象形式编写,每个已注册函数都需包含参数和返回值验证器。
- 每个读取路径都使用——绝不要用
withIndex(...)来实现类似SQL WHERE子句的功能。.filter() - 默认使用internalQuery/internalMutation/internalAction;仅当客户端钩子需要时,才升级为公共类型。
- 若需LLM/聊天功能,使用;若需多步骤流程,使用
@convex-dev/agent——绝不要自行编写这些功能。@convex-dev/workflow - 编写完成后,确认能顺利推送,并当场修复所有Schema/Returns/Argument验证错误。
convex dev
Rules
规则
- DATA ACCESS + IMPORTS — read before writing any convex/*.ts (front-loaded, not a post-hoc lint):
- Never an unbounded on a table that can grow — use
.collect()and.withIndex(...)/.paginate(paginationOptsValidator)instead. This is the single most common Convex deploy-blocking and perf defect..take(n) - Index, don't filter — add in schema.ts for every read path and query it with
.index(...);.withIndex(...)is a full table scan, never a substitute for a WHERE..filter() - The exact import table — get this wrong and the app fails to deploy: /
query/mutation/action/internalQuery/internalMutationcome frominternalAction;"./_generated/server"/apicome frominternal; NEVER"./_generated/api"orimport { query } from "convex/server"in application code — both are hard deploy failures.import { internal } from "./_generated/server" - for a fixed string/enum member (e.g.
v.literal("exact value")) — not a barev.union(v.literal("open"), v.literal("closed"))when the set of values is fixed.v.string() - goes only at the top of action-only modules — a file with
"use node";can never also export a"use node"orquery(they don't run in the Node runtime); split the file if you need both.mutation - Object form only — never the legacy positional query(args, handler) syntax.
- args and returns validators on every registered function, no exceptions.
- v.id(tableName) for IDs, never v.string(); undefined is not a Convex value (use null).
- Never add a required field to a populated table — add v.optional(...) first, backfill, then tighten.
- Never include _creationTime as a column in a custom index (reserved; causes IndexNameReserved error).
- Never store storage URLs in tables — store the Id<'_storage'> and call ctx.storage.getUrl(id) on read.
- Mutations cannot fetch — all external IO goes in actions; persist via ctx.runMutation(internal.x.y).
- Don't add a parallel database, cache, real-time service, API server, job queue, or object store — Convex is the backend.
- Convex functions only run from the directory — never write schema.ts/queries/mutations/actions at the project root.
convex/ - SELF-VERIFY RULE — before declaring backend work done, verify it compiles and pushes: run and, when a deployment is available (or via a local anonymous one:
npx tsc --noEmit), push it. Fix every error it reports before finishing — one verify round catches the wrong-relative-import / duplicate-symbol / unbalanced-paren class that otherwise breaks the deploy.CONVEX_AGENT_MODE=anonymous npx convex dev --once
- 数据访问与导入——在编写任何convex/*.ts文件前先阅读(提前做好,而非事后检查):
- 绝不要对可能增长的表使用无限制的——改用
.collect()和.withIndex(...)/.paginate(paginationOptsValidator)。这是最常见的Convex部署阻塞和性能缺陷。.take(n) - 用索引而非过滤——为每个读取路径在schema.ts中添加,并使用
.index(...)查询;.withIndex(...)是全表扫描,绝不能替代WHERE子句。.filter() - 严格遵循导入规则——出错会导致应用部署失败:/
query/mutation/action/internalQuery/internalMutation来自internalAction;"./_generated/server"/api来自internal;在应用代码中绝不要"./_generated/api"或import { query } from "convex/server"——这两种写法都会导致部署失败。import { internal } from "./_generated/server" - 固定字符串/枚举成员使用(例如
v.literal("exact value"))——当值集合固定时,不要使用裸v.union(v.literal("open"), v.literal("closed"))。v.string() - 仅放在仅包含action的模块顶部——带有
"use node";的文件绝不能同时导出"use node"或query(它们不在Node运行时中执行);若同时需要,拆分文件。mutation - 仅使用对象形式——绝不要使用旧版的位置参数query(args, handler)语法。
- 每个已注册函数都必须包含参数和返回值验证器,无一例外。
- ID使用,绝不要用
v.id(tableName);undefined不是Convex有效值(使用null)。v.string() - 绝不要向已填充数据的表添加必填字段——先添加,回填数据后再收紧限制。
v.optional(...) - 绝不要将_creationTime作为自定义索引的列(该字段为保留字段;会导致IndexNameReserved错误)。
- 绝不要在表中存储存储URL——存储,并在读取时调用
Id<'_storage'>。ctx.storage.getUrl(id) - 变更操作无法进行外部请求——所有外部IO都放在action中;通过持久化数据。
ctx.runMutation(internal.x.y) - 不要添加并行数据库、缓存、实时服务、API服务器、任务队列或对象存储——Convex就是后端。
- Convex函数仅在目录中运行——绝不要在项目根目录编写schema.ts/queries/mutations/actions。
convex/ - 自我验证规则——在宣布后端工作完成前,验证代码可编译并推送:运行,当有可用部署环境时(或通过本地匿名环境:
npx tsc --noEmit)推送代码。在完成前修复所有报告的错误——一次验证就能捕获相对导入错误/重复符号/括号不匹配等会导致部署失败的问题。CONVEX_AGENT_MODE=anonymous npx convex dev --once