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

工作流程

  1. When about to write or edit any file under convex/: read convex/schema.ts first (and convex/_generated/ai/guidelines.md if present).
  2. Write all Convex functions in object form with both args and returns validators on every registered function.
  3. Use withIndex(...) for every read path — never .filter() for anything that would be a SQL WHERE clause.
  4. Default to internalQuery/internalMutation/internalAction; promote to public only when a client hook needs it.
  5. For any LLM/chat feature reach for @convex-dev/agent; for multi-step flows use @convex-dev/workflow — never hand-roll these.
  6. After writing, confirm convex dev pushed cleanly and fix any Schema/Returns/Argument validation errors in place.
  1. 当准备编写或编辑convex/目录下的任何文件时:先阅读convex/schema.ts(如果存在convex/_generated/ai/guidelines.md也一并阅读)。
  2. 所有Convex函数均采用对象形式编写,每个已注册函数都需包含参数和返回值验证器。
  3. 每个读取路径都使用
    withIndex(...)
    ——绝不要用
    .filter()
    来实现类似SQL WHERE子句的功能。
  4. 默认使用internalQuery/internalMutation/internalAction;仅当客户端钩子需要时,才升级为公共类型。
  5. 若需LLM/聊天功能,使用
    @convex-dev/agent
    ;若需多步骤流程,使用
    @convex-dev/workflow
    ——绝不要自行编写这些功能。
  6. 编写完成后,确认
    convex dev
    能顺利推送,并当场修复所有Schema/Returns/Argument验证错误。

Rules

规则

  • DATA ACCESS + IMPORTS — read before writing any convex/*.ts (front-loaded, not a post-hoc lint):
  • Never an unbounded
    .collect()
    on a table that can grow — use
    .withIndex(...)
    and
    .paginate(paginationOptsValidator)
    /
    .take(n)
    instead. This is the single most common Convex deploy-blocking and perf defect.
  • Index, don't filter — add
    .index(...)
    in schema.ts for every read path and query it with
    .withIndex(...)
    ;
    .filter()
    is a full table scan, never a substitute for a WHERE.
  • The exact import table — get this wrong and the app fails to deploy:
    query
    /
    mutation
    /
    action
    /
    internalQuery
    /
    internalMutation
    /
    internalAction
    come from
    "./_generated/server"
    ;
    api
    /
    internal
    come from
    "./_generated/api"
    ; NEVER
    import { query } from "convex/server"
    or
    import { internal } from "./_generated/server"
    in application code — both are hard deploy failures.
  • v.literal("exact value")
    for a fixed string/enum member (e.g.
    v.union(v.literal("open"), v.literal("closed"))
    ) — not a bare
    v.string()
    when the set of values is fixed.
  • "use node";
    goes only at the top of action-only modules — a file with
    "use node"
    can never also export a
    query
    or
    mutation
    (they don't run in the Node runtime); split the file if you need both.
  • 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
    convex/
    directory — never write schema.ts/queries/mutations/actions at the project root.
  • SELF-VERIFY RULE — before declaring backend work done, verify it compiles and pushes: run
    npx tsc --noEmit
    and, when a deployment is available (or via a local anonymous one:
    CONVEX_AGENT_MODE=anonymous npx convex dev --once
    ), 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/*.ts文件前先阅读(提前做好,而非事后检查):
  • 绝不要对可能增长的表使用无限制的
    .collect()
    ——改用
    .withIndex(...)
    .paginate(paginationOptsValidator)
    /
    .take(n)
    。这是最常见的Convex部署阻塞和性能缺陷。
  • 用索引而非过滤——为每个读取路径在schema.ts中添加
    .index(...)
    ,并使用
    .withIndex(...)
    查询;
    .filter()
    是全表扫描,绝不能替代WHERE子句。
  • 严格遵循导入规则——出错会导致应用部署失败:
    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()
  • "use node";
    仅放在仅包含action的模块顶部——带有
    "use node"
    的文件绝不能同时导出
    query
    mutation
    (它们不在Node运行时中执行);若同时需要,拆分文件。
  • 仅使用对象形式——绝不要使用旧版的位置参数query(args, handler)语法。
  • 每个已注册函数都必须包含参数和返回值验证器,无一例外。
  • ID使用
    v.id(tableName)
    ,绝不要用
    v.string()
    ;undefined不是Convex有效值(使用null)。
  • 绝不要向已填充数据的表添加必填字段——先添加
    v.optional(...)
    ,回填数据后再收紧限制。
  • 绝不要将_creationTime作为自定义索引的列(该字段为保留字段;会导致IndexNameReserved错误)。
  • 绝不要在表中存储存储URL——存储
    Id<'_storage'>
    ,并在读取时调用
    ctx.storage.getUrl(id)
  • 变更操作无法进行外部请求——所有外部IO都放在action中;通过
    ctx.runMutation(internal.x.y)
    持久化数据。
  • 不要添加并行数据库、缓存、实时服务、API服务器、任务队列或对象存储——Convex就是后端。
  • Convex函数仅在
    convex/
    目录中运行——绝不要在项目根目录编写schema.ts/queries/mutations/actions。
  • 自我验证规则——在宣布后端工作完成前,验证代码可编译并推送:运行
    npx tsc --noEmit
    ,当有可用部署环境时(或通过本地匿名环境:
    CONVEX_AGENT_MODE=anonymous npx convex dev --once
    )推送代码。在完成前修复所有报告的错误——一次验证就能捕获相对导入错误/重复符号/括号不匹配等会导致部署失败的问题。