convex-schema-validator
Defining and validating database schemas with proper typing, index configuration, optional fields, unions, and migration strategies for schema changes
DeepseekModel
キュレーション済みスキル
品質 優秀 · 78
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=waynesutton-convexskills-skills-convex-schema-validator-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
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" >;
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |