smithery/coderguai

new-db-schema

Create new database tables with Drizzle ORM schemas and Valibot validation. 使用 Drizzle ORM 创建新的数据库表模式和 Valibot 验证。 Use when: - Adding new database tables - Creating entity schemas - User mentions "new table", "database schema", "add entity", "新增表", "数据库模式"

Installation

$ npx skills add smithery/coderguai --skill new-db-schema

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,145 B
  • docs SUMMARY.md 332 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

New Database Schema Skill / 新增数据库模式技能

设计思路 / Design Notes:
1. 数据库模式是基础设施,需要特别注意类型安全
2. 包含 Valibot 验证模式生成,与 API 层集成
3. 提供常用字段模式(UUID、时间戳、外键等)
4. 强调 snake_case 命名规范

Overview / 概述

Create Drizzle ORM schemas with type-safe Valibot validation schemas. 创建带有类型安全 Valibot 验证模式的 Drizzle ORM 模式。

Step-by-Step Instructions / 分步指令

Step 1: Create Schema File / 创建模式文件

File: packages/db/src/schemas/<entity>.ts

// [IN]: drizzle-orm/pg-core, drizzle-valibot, valibot, ./auth / 依赖 Drizzle、验证器及认证模式
// [OUT]: <entity> table, Create<Entity>Schema / 导出 <entity> 表及创建验证模式
// [POS]: Database layer - <Entity> schema / 数据库层 - <实体>模式
// Protocol: When updating me, sync this header + parent folder's .folder.md
// 协议:更新本文件时,同步更新此头注释及所属文件夹的 .folder.md

import { pgTable } from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-valibot';
import * as v from 'valibot';
import { user } from './auth';

// ============ Table Definition / 表定义 ============

export const <entity> = pgTable('<entity>', (t) => ({
  // Primary key - UUID
  id: t.uuid().primaryKey().defaultRandom(),

  // Required fields / 必需字段
  title: t.varchar({ length: 256 }).notNull(),
  content: t.text().notNull(),

  // Optional fields / 可选字段
  description: t.text(),

  // Timestamps / 时间戳
  createdAt: t
    .timestamp({ mode: 'string', withTimezone: true })
    .notNull()
    .defaultNow(),
  updatedAt: t
    .timestamp({ mode: 'string', withTimezone: true })
    .notNull()
    .defaultNow(),

  // Foreign key to user / 用户外键
  createdBy: t
    .text()
    .references(() => user.id)
    .notNull(),
}));

// ============ Validation Schemas / 验证模式 ============

// For creating new records (excludes auto-generated fields)
// 用于创建新记录(排除自动生成的字段)
export const Create<Entity>Schema = v.omit(
  createInsertSchema(<entity>, {
    // Custom validation rules / 自定义验证规则
    title: v.pipe(v.string(), v.minLength(3), v.maxLength(256)),
    content: v.pipe(v.string(), v.minLength(5), v.maxLength(5000)),
  }),
  ['id', 'createdAt', 'updatedAt', 'createdBy'],
);

// For updating records / 用于更新记录
export const Update<Entity>Schema = v.partial(Create<Entity>Schema);

// TypeScript types / TypeScript 类型
export type <Entity> = typeof <entity>.$inferSelect;
export type New<Entity> = typeof <entity>.$inferInsert;

Step 2: Export from Schema Index / 从模式索引导出

File: packages/db/src/schema.ts

// Add export / 添加导出
export * from './schemas/<entity>';

Step 3: Update Folder Documentation / 更新文件夹文档

File: packages/db/src/schemas/.folder.md

Add the new file to the file list / 将新文件添加到文件列表:

## Files
- `auth.ts`: Local - Authentication tables / 认证表
- `posts.ts`: Local - Post table / 文章表
- `<entity>.ts`: Local - <Entity> table / <实体>表  👈 New

Step 4: Push to Database / 推送到数据库

pnpm db:push

Common Field Patterns / 常用字段模式

UUID Primary Key / UUID 主键

id: t.uuid().primaryKey().defaultRandom(),

Timestamps / 时间戳

createdAt: t.timestamp({ mode: 'string', withTimezone: true }).notNull().defaultNow(),
updatedAt: t.timestamp({ mode: 'string', withTimezone: true }).notNull().defaultNow(),

Foreign Key / 外键

userId: t.text().references(() => user.id).notNull(),
// With cascade delete / 带级联删除
userId: t.text().references(() => user.id, { onDelete: 'cascade' }).notNull(),

Enum / 枚举

status: t.text({ enum: ['draft', 'published', 'archived'] }).notNull().default('draft'),

JSON / JSON 字段

metadata: t.jsonb().$type<{ key: string; value: unknown }[]>(),

Validation Patterns / 验证模式

String with length / 带长度的字符串

v.pipe(v.string(), v.minLength(1), v.maxLength(100))

Email / 邮箱

v.pipe(v.string(), v.email())

URL

v.pipe(v.string(), v.url())

Optional with default / 可选带默认值

v.optional(v.string(), 'default value')

Reference / 参考