data-modeler
Design database schemas with Prisma for AI and Web3 applications. Define models, relations, indexes, and migrations. Use when designing databases, creating Prisma schemas, or when the user mentions database, schema, model, prisma, or migration.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-12
- Stars
- ★ 6
- Forks
- 1
01 前言 Front Matter
- name
- data-modeler
- description
- Design database schemas with Prisma for AI and Web3 applications. Define models, relations, indexes, and migrations. Use when designing databases, creating Prisma schemas, or when the user mentions database, schema, model, prisma, or migration.
02 资源文件 3
- 参考文档.cloud-manifest.json156 B
- 参考文档.gene-manifest.json264 B
- 参考文档phenotype.json2.2 KB
03 SKILL.md 正文
Data Modeler (数据建模师)
Goal: 设计清晰、高效、可扩展的数据库结构。
技术栈: Prisma + PostgreSQL (主要) / SQLite (开发)
1. Schema Design Principles
命名规范
// 模型: PascalCase (单数)
model User {}
model ChatMessage {}
// 字段: camelCase
model User {
id String
createdAt DateTime
firstName String
}
// 关系字段: 描述关系
model Post {
author User @relation(...)
authorId String
}
必备字段
model BaseModel {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// 所有模型都应包含这三个字段
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 业务字段...
}
软删除 (推荐)
model User {
// ...
deletedAt DateTime? // null = 未删除
@@index([deletedAt])
}
// 查询时过滤
const users = await prisma.user.findMany({
where: { deletedAt: null }
})
2. Common Patterns
用户认证
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 认证
email String @unique
emailVerified DateTime?
passwordHash String? // null if OAuth only
// 资料
name String?
image String?
// 关系
accounts Account[]
sessions Session[]
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
// OAuth tokens
accessToken String?
refreshToken String?
expiresAt Int?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
AI 对话
model Conversation {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String?
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
messages Message[]
@@index([userId])
}
model Message {
id String @id @default(cuid())
createdAt DateTime @default(now())
role String // 'user' | 'assistant' | 'system'
content String @db.Text
conversationId String
// Token 统计
promptTokens Int?
completionTokens Int?
// AI 元数据
model String?
finishReason String?
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
@@index([conversationId])
}
Web3 用户
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Web3
address String @unique // 0x...
chainId Int @default(1)
// ENS (缓存)
ensName String?
ensAvatar String?
ensUpdatedAt DateTime?
// 关系
wallets Wallet[]
@@index([address])
}
model Wallet {
id String @id @default(cuid())
createdAt DateTime @default(now())
address String
chainId Int
label String? // "Main", "Trading", etc.
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, address, chainId])
}
交易记录
model Transaction {
id String @id @default(cuid())
createdAt DateTime @default(now())
hash String @unique
chainId Int
from String
to String?
value Decimal @db.Decimal(78, 0) // BigInt as Decimal
status TransactionStatus @default(PENDING)
// Gas
gasLimit Decimal? @db.Decimal(78, 0)
gasUsed Decimal? @db.Decimal(78, 0)
gasPrice Decimal? @db.Decimal(78, 0)
// 关系
userId String
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([hash])
@@index([status])
}
enum TransactionStatus {
PENDING
CONFIRMED
FAILED
}
3. Relations
一对多
model User {
id String @id
posts Post[]
}
model Post {
id String @id
author User @relation(fields: [authorId], references: [id])
authorId String
@@index([authorId])
}
多对多 (显式)
model User {
id String @id
memberships Membership[]
}
model Team {
id String @id
memberships Membership[]
}
model Membership {
id String @id @default(cuid())
role String @default("member") // "owner" | "admin" | "member"
userId String
teamId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
@@unique([userId, teamId])
}
自引用
model Category {
id String @id
name String
parentId String?
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id])
children Category[] @relation("CategoryHierarchy")
}
4. Indexes & Performance
索引策略
model User {
id String @id
email String @unique // 自动索引
createdAt DateTime
status String
// 复合索引 (常用查询)
@@index([status, createdAt])
// 单字段索引
@@index([createdAt])
}
何时添加索引
| 场景 | 需要索引 |
|---|---|
| WHERE 条件字段 | ✅ |
| ORDER BY 字段 | ✅ |
| 外键字段 | ✅ (手动添加) |
| JOIN 条件 | ✅ |
| 唯一约束字段 | 自动 |
BigInt 处理
// 方式 1: Decimal (推荐)
model Token {
balance Decimal @db.Decimal(78, 0) // 最大 uint256
}
// 方式 2: BigInt (Prisma 4.x+)
model Token {
balance BigInt
}
5. Migrations
开发流程
# 1. 修改 schema.prisma
# 2. 创建迁移
pnpm prisma migrate dev --name add_user_avatar
# 3. 应用到开发库 (自动)
生产部署
# CI/CD 中运行
pnpm prisma migrate deploy
迁移最佳实践
# ✅ 小步迁移
add_user_table
add_user_email_index
add_user_avatar_field
# ❌ 大爆炸迁移
initial_schema_with_everything
数据迁移
// prisma/migrations/xxx/data-migration.ts
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
// 填充默认值
await prisma.user.updateMany({
where: { role: null },
data: { role: 'user' }
})
}
main()
6. Query Patterns
常用查询
// 分页
const users = await prisma.user.findMany({
skip: (page - 1) * pageSize,
take: pageSize,
orderBy: { createdAt: 'desc' },
})
// 包含关系
const user = await prisma.user.findUnique({
where: { id },
include: { posts: true },
})
// 选择字段
const user = await prisma.user.findUnique({
where: { id },
select: { id: true, name: true, email: true },
})
// 统计
const count = await prisma.user.count({
where: { status: 'active' },
})
事务
// 隐式事务
const [user, post] = await prisma.$transaction([
prisma.user.create({ data: userData }),
prisma.post.create({ data: postData }),
])
// 交互式事务
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData })
await tx.post.create({
data: { ...postData, authorId: user.id }
})
})
7. Schema Checklist
## 数据模型检查清单
### 基础
- [ ] 所有模型有 id, createdAt, updatedAt
- [ ] 使用正确的命名规范
- [ ] 外键字段有索引
### 关系
- [ ] onDelete 策略明确 (Cascade/SetNull/Restrict)
- [ ] 多对多使用显式中间表
- [ ] 自引用关系正确
### 性能
- [ ] 常用查询字段有索引
- [ ] 复合索引顺序正确
- [ ] BigInt 使用 Decimal
### 安全
- [ ] 敏感字段不直接暴露
- [ ] 软删除用于重要数据
- [ ] 审计字段 (createdBy, updatedBy)
Quick Reference
Prisma CLI
prisma generate # 生成客户端
prisma migrate dev # 创建迁移
prisma migrate deploy # 部署迁移
prisma studio # 可视化界面
04 同仓库更多 Skills
fixture-skill
A synthetic ClawHub skill for wrap --from-clawhub tests
rotifer-self-evolving-agent
Rank an Agent's Rotifer Genes against the Arena and swap in stronger ones. Invoked explicitly via /evolve — scan local capabilities, compare Genes, inspect fitness scores, and replace weak ones with user approval. Not for capabilities outside Rotifer.
rotifer-guide
Entry point for Rotifer Protocol — onboarding to Rotifer Genes, scaffolding a Gene from a description, diagnosing a Gene's F(g) or compile failure, searching the Rotifer Gene registry, and upgrading a Gene's fidelity from Wrapped to Native. Invoke explicitly when starting with Rotifer, or when unsure which Rotifer capability to use. Do NOT use for general onboarding, tutorials, troubleshooting, or search — every capability here operates on Rotifer Genes and the Rotifer CLI, and nothing else.
rotifer-gene
The Gene manual for Rotifer Protocol — write a Gene's express function and phenotype schema, run the four-layer security audit before publishing, and migrate a Gene's fidelity from Wrapped to Hybrid or Native. Invoke explicitly when building, auditing, or upgrading a Rotifer Gene. Do NOT use for general code review, dependency auditing, or framework migration — every procedure here operates on Rotifer Genes, their phenotype schemas, and the Rotifer CLI, and nothing else.
rotifer-arena
Benchmark Rotifer Genes against each other in the Arena — import from ClawHub / local / scratch, compile, match opponents, run Arena evaluation, and produce a Markdown report with F(g) fitness and V(g) security grades. Invoke explicitly to compare or benchmark Rotifer Genes. Do NOT use for general benchmarking, load testing, or comparing anything that is not a Rotifer Gene or Agent.
rotifer-agent
Build a Rotifer Agent from Genes — decompose intent into capability units, pick Genes by Arena F(g), compose a Rotifer Genome, create the Agent and test it. Use when the user is working with Rotifer specifically: "Rotifer Agent", "compose Genes", "Rotifer Genome", "Gene composition", "rotifer agent create". Do NOT use for general agent frameworks, or when the words Seq / Par / Cond / Try appear as ordinary programming terms — in Rotifer those name Genome composition strategies, and this Skill applies only when the user is composing Rotifer Genes.