src/orchestrator/plugins/convex/SKILL.md
Convex reactive database patterns, schema design, real-time queries, mutations, actions, authentication, migrations, performance optimization, and component creation. Use when designing Convex schemas, writing queries/mutations, managing the Convex backend, setting up auth, migrating data, optimizing performance, or building Convex components.
npx skillsauth add monkilabs/opencastle convex-databaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
For project-specific schema, functions, and deployment details, see database-config.md.
Read the matching reference file before writing code for any of these topics:
| Topic | Reference |
|-------|-----------|
| Project setup & scaffolding | references/quickstart.md |
| Schema & data migrations | references/migrations.md |
| Performance optimization | references/performance-audit.md |
| Authentication & access control | references/auth-setup.md |
| Component creation & isolation | references/components.md |
Function Registration
query/mutation/action; Private: internalQuery/internalMutation/internalAction (import from ./_generated/server)returns validator; use returns: v.null() when the function returns nothing (JS implicitly returns null)Function References
api.filename.functionName for public and internal.filename.functionName for internal functions (from ./_generated/api)ctx.runQuery/ctx.runMutation/ctx.runAction — always use function referencesQueries
.filter() — define an index in the schema and use .withIndex() instead.filter() is equivalent to JS filtering — neither pushes the filter to storage; only .withIndex() actually reduces documents scanned.unique() for single document queries.delete() on queries — collect results, then call ctx.db.delete(row._id) on eachMutations
references/migrations.mdctx.db.patch() — no-op writes still trigger invalidation and replicationActions
"use node"; at the top of files containing actions that use Node.js built-in modulesctx.db inside actions — actions don't have database access; use ctx.runQuery/ctx.runMutation insteadSchema
["field1", "field2"] → "by_field1_and_field2"_id or _creationTime — they are automatic system fieldsby_team_and_user covers both by_team queries and by_team_and_user queries)Components
ctx.auth or process.envv.string(), not v.id("parentTable")query/mutation/action from the component's own ./_generated/server, not the app's generated filesGeneral
convex/schema.ts using defineSchema/defineTablev.null() not v.undefined() — undefined is not a valid Convex valueprocess.env in actions onlyimport { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
users: defineTable({
name: v.string(),
email: v.string(),
role: v.union(v.literal("admin"), v.literal("user")),
})
.index("by_email", ["email"])
.index("by_role", ["role"]),
});
import { query } from "./_generated/server";
import { v } from "convex/values";
export const list = query({
args: { role: v.optional(v.string()) },
returns: v.array(v.any()),
handler: async (ctx, args) => {
if (args.role) {
return await ctx.db.query("users")
.withIndex("by_role", q => q.eq("role", args.role!))
.collect();
}
return await ctx.db.query("users").collect();
},
});
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const create = mutation({
args: { name: v.string(), email: v.string() },
returns: v.id("users"),
handler: async (ctx, args) => {
return await ctx.db.insert("users", { ...args, role: "user" });
},
});
import { query } from "./_generated/server";
export const getMyProfile = query({
args: {},
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Not authenticated");
return await ctx.db
.query("users")
.withIndex("by_tokenIdentifier", (q) =>
q.eq("tokenIdentifier", identity.tokenIdentifier)
)
.unique();
},
});
references/migrations.md if the change is breaking (adding required fields, changing types, deleting fields)convex/schema.ts and run npx convex dev locally; confirm the dev server starts and responds. Run a small validation script or sample queries to verify schema changes.returns validators and unit test against the dev server.npx convex deploy to push the change to production.curl -fsS https://<APP_URL>/health || (echo "health check failed" && exit 1)
If an issue occurs: roll back via npx convex import of the last good export, fix locally, and re-deploy.
| Step | Checkpoint |
|------|-----------|
| Schema change | npx convex dev starts without errors |
| Migration needed | references/migrations.md checklist completed |
| Auth function | ctx.auth.getUserIdentity() returns non-null in test |
| Deploy | Smoke check passes; no convex insights regressions |
| Component | npx convex codegen succeeds; sibling functions inspected |
development
Defines 10 sequential validation gates: secret scanning, lint/test/build checks, blast radius analysis, dependency auditing, browser testing, cache management, regression checks, smoke tests. Use when running pre-deploy validation or CI checks, CI/CD pipelines, deployment pipeline validation, pre-merge checks, continuous integration, or pull request validation.
development
Generates test plans, writes unit/integration/E2E test files, identifies coverage gaps, flags common testing anti-patterns. Use when writing tests, creating test suites, planning test strategies, mocking dependencies, measuring code coverage, or test planning.
development
Provides model routing rules, validates delegation prerequisites, supplies cost tracking templates, defines dead-letter queue formats for Team Lead orchestration. Load when assigning tasks to agents, choosing model tiers, starting delegation session, running multi-agent workflow, delegating work, choosing which model to use, or assigning tasks.
testing
Saves, restores session state including task progress, file changes, delegation history. Use when saving progress, resuming interrupted work, picking up where you left off, or checkpointing current work.