schema-builder by get-convex/agent-skills
npx skills add https://github.com/get-convex/agent-skills --skill schema-builder遵循最佳实践构建结构良好的 Convex 模式,包括关系、索引和验证器。
convex/schema.ts 文件v.* 类型的严格验证器import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
tableName: defineTable({
// 必填字段
field: v.string(),
// 可选字段
optional: v.optional(v.number()),
// 关系(使用 ID)
userId: v.id("users"),
// 枚举使用 union + literal
status: v.union(
v.literal("active"),
v.literal("pending"),
v.literal("archived")
),
// 时间戳
createdAt: v.number(),
updatedAt: v.optional(v.number()),
})
// 为该字段的查询建立索引
.index("by_user", ["userId"])
// 为常见查询模式建立复合索引
.index("by_user_and_status", ["userId", "status"])
// 为基于时间的查询建立索引
.index("by_created", ["createdAt"]),
});
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
export default defineSchema({
users: defineTable({
name: v.string(),
email: v.string(),
}).index("by_email", ["email"]),
posts: defineTable({
userId: v.id("users"),
title: v.string(),
content: v.string(),
}).index("by_user", ["userId"]),
});
export default defineSchema({
users: defineTable({
name: v.string(),
}),
projects: defineTable({
name: v.string(),
}),
projectMembers: defineTable({
userId: v.id("users"),
projectId: v.id("projects"),
role: v.union(v.literal("owner"), v.literal("member")),
})
.index("by_user", ["userId"])
.index("by_project", ["projectId"])
.index("by_project_and_user", ["projectId", "userId"]),
});
export default defineSchema({
comments: defineTable({
postId: v.id("posts"),
parentId: v.optional(v.id("comments")), // 顶级评论为 null
userId: v.id("users"),
text: v.string(),
})
.index("by_post", ["postId"])
.index("by_parent", ["parentId"]),
});
export default defineSchema({
users: defineTable({
name: v.string(),
// 小型、有限的集合是可以的
roles: v.array(
v.union(v.literal("admin"), v.literal("editor"), v.literal("viewer"))
),
tags: v.array(v.string()), // 例如,最多 10 个标签
}),
});
// 基本类型
v.string()
v.number()
v.boolean()
v.null()
v.id("tableName")
// 可选
v.optional(v.string())
// 联合类型(枚举)
v.union(v.literal("a"), v.literal("b"))
// 对象
v.object({
key: v.string(),
nested: v.number(),
})
// 数组
v.array(v.string())
// 记录(任意键)
v.record(v.string(), v.boolean())
// 任意类型(尽量避免使用)
v.any()
by_user: ["userId"]by_email: ["email"]by_user_and_status: ["userId", "status"]by_team_and_created: ["teamId", "createdAt"]by_a_and_b 通常已覆盖 by_av.union(v.literal(...)) 模式v.number()(自纪元以来的毫秒数)如果要从嵌套结构转换:
转换前:
users: defineTable({
posts: v.array(
v.object({
title: v.string(),
comments: v.array(v.object({ text: v.string() })),
})
),
});
转换后:
users: defineTable({
name: v.string(),
}),
posts: defineTable({
userId: v.id("users"),
title: v.string(),
}).index("by_user", ["userId"]),
comments: defineTable({
postId: v.id("posts"),
text: v.string(),
}).index("by_post", ["postId"]),
每周安装量
545
代码仓库
GitHub 星标数
15
首次出现
2026年2月18日
安全审计
安装于
github-copilot540
cursor539
gemini-cli539
amp539
codex539
kimi-cli539
Build well-structured Convex schemas following best practices for relationships, indexes, and validators.
convex/schema.ts filev.* typesimport { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
tableName: defineTable({
// Required fields
field: v.string(),
// Optional fields
optional: v.optional(v.number()),
// Relations (use IDs)
userId: v.id("users"),
// Enums with union + literal
status: v.union(
v.literal("active"),
v.literal("pending"),
v.literal("archived")
),
// Timestamps
createdAt: v.number(),
updatedAt: v.optional(v.number()),
})
// Index for queries by this field
.index("by_user", ["userId"])
// Compound index for common query patterns
.index("by_user_and_status", ["userId", "status"])
// Index for time-based queries
.index("by_created", ["createdAt"]),
});
export default defineSchema({
users: defineTable({
name: v.string(),
email: v.string(),
}).index("by_email", ["email"]),
posts: defineTable({
userId: v.id("users"),
title: v.string(),
content: v.string(),
}).index("by_user", ["userId"]),
});
export default defineSchema({
users: defineTable({
name: v.string(),
}),
projects: defineTable({
name: v.string(),
}),
projectMembers: defineTable({
userId: v.id("users"),
projectId: v.id("projects"),
role: v.union(v.literal("owner"), v.literal("member")),
})
.index("by_user", ["userId"])
.index("by_project", ["projectId"])
.index("by_project_and_user", ["projectId", "userId"]),
});
export default defineSchema({
comments: defineTable({
postId: v.id("posts"),
parentId: v.optional(v.id("comments")), // null for top-level
userId: v.id("users"),
text: v.string(),
})
.index("by_post", ["postId"])
.index("by_parent", ["parentId"]),
});
export default defineSchema({
users: defineTable({
name: v.string(),
// Small, bounded collections are fine
roles: v.array(v.union(
v.literal("admin"),
v.literal("editor"),
v.literal("viewer")
)),
tags: v.array(v.string()), // e.g., max 10 tags
}),
});
// Primitives
v.string()
v.number()
v.boolean()
v.null()
v.id("tableName")
// Optional
v.optional(v.string())
// Union types (enums)
v.union(v.literal("a"), v.literal("b"))
// Objects
v.object({
key: v.string(),
nested: v.number(),
})
// Arrays
v.array(v.string())
// Records (arbitrary keys)
v.record(v.string(), v.boolean())
// Any (avoid if possible)
v.any()
Single-field indexes : For simple lookups
by_user: ["userId"]by_email: ["email"]Compound indexes : For filtered queries
by_user_and_status: ["userId", "status"]by_team_and_created: ["teamId", "createdAt"]Remove redundant : by_a_and_b usually covers by_a
v.union(v.literal(...)) patternv.number() (milliseconds since epoch)If converting from nested structures:
Before:
users: defineTable({
posts: v.array(v.object({
title: v.string(),
comments: v.array(v.object({ text: v.string() })),
})),
})
After:
users: defineTable({
name: v.string(),
}),
posts: defineTable({
userId: v.id("users"),
title: v.string(),
}).index("by_user", ["userId"]),
comments: defineTable({
postId: v.id("posts"),
text: v.string(),
}).index("by_post", ["postId"]),
Weekly Installs
545
Repository
GitHub Stars
15
First Seen
Feb 18, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
github-copilot540
cursor539
gemini-cli539
amp539
codex539
kimi-cli539
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
106,200 周安装