Skills Plugins MCP Prompt Model 博客 我的中心
Development #data #database

convex-schema-validator

Defining and validating database schemas with proper typing, index configuration, optional fields, unions, and migration strategies for schema changes

DeepseekModel Curated skill Quality Excellent · 78 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=waynesutton-convexskills-skills-convex-schema-validator-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name convex-schema-validator displayName Convex Schema Validator description Defining and validating database schemas with proper typing, index configuration, optional fields, unions, and migration strategies for schema changes version 1.0.0 author Convex tags ["convex","schema","validation","typescript","indexes","migrations"] Convex Schema Validator Define and validate database schemas in Convex with proper typing, index configuration, optional fields, unions, and strategies for schema migrations. Documentation Sources Before implementing, do not assume; fetch the latest documentation: Primary: https://docs.convex.dev/database/schemas Indexes: https://docs.convex.dev/database/indexes Data Types: https://docs.convex.dev/database/types For broader context: https://docs.convex.dev/llms.txt Instructions Basic Schema Definition // convex/schema.ts import { defineSchema, defineTable } from "convex/server" ; import { v } from "convex/values" ; export default defineSchema ({ users : defineTable ({ name : v. string (), email : v. string (), avatarUrl : v. optional (v. string ()), createdAt : v. number (), }), tasks : defineTable ({ title : v. string (), description : v. optional (v. string ()), completed : v. boolean (), userId : v. id ( "users" ), priority : v. union ( v. literal ( "low" ), v. literal ( "medium" ), v. literal ( "high" ) ), }), }); Validator Types Validator TypeScript Type Example v.string() string "hello" v.number() number 42 , 3.14 v.boolean() boolean true , false v.null() null null v.int64() bigint 9007199254740993n v.bytes() ArrayBuffer Binary data v.id("table") Id<"table"> Document reference v.array(v) T[] [1, 2, 3] v.object({}) { ... } { name: "..." } v.optional(v) T | undefined Optional field v.union(...) T1 | T2 Multiple types v.literal(x) "x" Exact value v.any() any Any value v.record(k, v) Record<K, V> Dynamic keys Index Configuration export default defineSchema ({ messages : defineTable ({ channelId : v. id ( "channels" ), authorId : v. id ( "users" ), content : v. string (), sentAt : v. number (), }) // Single field index . index ( "by_channel" , [ "channelId" ]) // Compound index . index ( "by_channel_and_author" , [ "channelId" , "authorId" ]) // Index for sorting . index ( "by_channel_and_time" , [ "channelId" , "sentAt" ]), // Full-text search index articles : defineTable ({ title : v. string (), body : v. string (), category : v. string (), }) . searchIndex ( "search_content" , { searchField : "body" , filterFields : [ "category" ], }), }); Complex Types export default defineSchema ({ // Nested objects profiles : defineTable ({ userId : v. id ( "users" ), settings : v. object ({ theme : v. union (v. literal ( "light" ), v. literal ( "dark" )), notifications : v. object ({ email : v. boolean (), push : v. boolean (), }), }), }), // Arrays of objects orders : defineTable ({ customerId : v. id ( "users" ), items : v. array (v. object ({ productId : v. id ( "products" ), quantity : v. number (), price : v. number (), })), status : v. union ( v. literal ( "pending" ), v. literal ( "processing" ), v. literal ( "shipped" ), v. literal ( "delivered" ) ), }), // Record type for dynamic keys analytics : defineTable ({ date : v. string (), metrics : v. record (v. string (), v. number ()), }), }); Discriminated Unions export default defineSchema ({ events : defineTable ( v. union ( v. object ({ type : v. literal ( "user_signup" ), userId : v. id ( "users" ), email : v. string (), }), v. object ({ type : v. literal ( "purchase" ), userId : v. id ( "users" ), orderId : v. id ( "orders" ), amount : v. number (), }), v. object ({ type : v. literal ( "page_view" ), sessionId : v. string (), path : v. string (), }) ) ). index ( "by_type" , [ "type" ]), }); Optional vs Nullable Fields export default defineSchema ({ items : defineTable ({ // Optional: field may not exist description : v. optional (v. string ()), // Nullable: field exists but can be null deletedAt : v. union (v. number (), v. null ()), // Optional and nullable notes : v. optional (v. union (v. string (), v. null ())), }), }); Index Naming Convention Always include all indexed fields in the index name: export default defineSchema ({ posts : defineTable ({ authorId : v. id ( "users" ), categoryId : v. id ( "categories" ), publishedAt : v. number (), status : v. string (), }) // Good: descriptive names . index ( "by_author" , [ "authorId" ]) . index ( "by_author_and_category" , [ "authorId" , "categoryId" ]) . index ( "by_category_and_status" , [ "categoryId" , "status" ]) . index ( "by_status_and_published" , [ "status" , "publishedAt" ]), }); Schema Migration Strategies Adding New Fields // Before users : defineTable ({ name : v. string (), email : v. string (), }) // After - add as optional first users : defineTable ({ name : v. string (), email : v. string (), avatarUrl : v. optional (v. string ()), // New optional field }) Backfilling Data // convex/migrations.ts import { internalMutation } from "./_generated/server" ; import { v } from "convex/values" ; export const backfillAvatars = internalMutation ({ args : {}, returns : v. number (), handler : async (ctx) => { const users = await ctx. db . query ( "users" ) . filter ( ( q ) => q. eq (q. field ( "avatarUrl" ), undefined )) . take ( 100 ); for ( const user of users) { await ctx. db . patch (user. _id , { avatarUrl : `https://api.dicebear.com/7.x/initials/svg?seed= ${user.name} ` , }); } return users. length ; }, }); Making Optional Fields Required // Step 1: Backfill all null values // Step 2: Update schema to required users : defineTable ({ name : v. string (), email : v. string (), avatarUrl : v. string (), // Now required after backfill }) Examples Complete E-commerce Schema // convex/schema.ts import { defineSchema, defineTable } from "convex/server" ; import { v } from "convex/values" ; export default defineSchema ({ users : defineTable ({ email : v. string (), name : v. string (), role : v. union (v. literal ( "customer" ), v. literal ( "admin" )), createdAt : v. number (), }) . index ( "by_email" , [ "email" ]) . index ( "by_role" , [ "role" ]), products : defineTable ({ name : v. string (), description : v. string (), price : v. number (), category : v. string (), inventory : v. number (), isActive : v. boolean (), }) . index ( "by_category" , [ "category" ]) . index ( "by_active_and_category" , [ "isActive" , "category" ]) . searchIndex ( "search_products" , { searchField : "name" , filterFields : [ "category" , "isActive" ], }), orders : defineTable ({ userId : v. id ( "users" ), items : v. array (v. object ({ productId : v. id ( "products" ), quantity : v. number (), priceAtPurchase : v. number (), })), total : v. number (), status : v. union ( v. literal ( "pending" ), v. literal ( "paid" ), v. literal ( "shipped" ), v. literal ( "delivered" ), v. literal ( "cancelled" ) ), shippingAddress : v. object ({ street : v. string (), city : v. string (), state : v. string (), zip : v. string (), country : v. string (), }), createdAt : v. number (), updatedAt : v. number (), }) . index ( "by_user" , [ "userId" ]) . index ( "by_user_and_status" , [ "userId" , "status" ]) . index ( "by_status" , [ "status" ]), reviews : defineTable ({ productId : v. id ( "products" ), userId : v. id ( "users" ), rating : v. number (), comment : v. optional (v. string ()), createdAt : v. number (), }) . index ( "by_product" , [ "productId" ]) . index ( "by_user" , [ "userId" ]), }); Using Schema Types in Functions // convex/products.ts import { query, mutation } from "./_generated/server" ; import { v } from "convex/values" ; import { Doc , Id } from "./_generated/dataModel" ; // Use Doc type for full documents type Product = Doc < "products" >;
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。