Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:20:34 +08:00
commit 10052112c1
29 changed files with 8734 additions and 0 deletions

View File

@@ -0,0 +1,582 @@
---
description: Generate Prisma schema from natural language descriptions
shortcut: psg
category: database
difficulty: beginner
estimated_time: 3-5 minutes
---
# Prisma Schema Generator
Generates complete Prisma schema files from natural language descriptions, including models, relationships, indexes, and validation.
## What This Command Does
**Generated Schema:**
- Prisma models with fields
- Relationships (one-to-one, one-to-many, many-to-many)
- Indexes and unique constraints
- Default values and validators
- Database-specific configuration
- Example queries
**Output:** Complete `schema.prisma` file ready for migration
**Time:** 3-5 minutes
---
## Usage
```bash
# Generate schema from description
/prisma-schema-gen "Blog with users, posts, and comments"
# Shortcut
/psg "E-commerce with products, orders, and customers"
# Specify database
/psg "Task management app" --database postgresql
# With specific relationships
/psg "Social network with users, posts, likes, and follows"
```
---
## Example Output
**Input:**
```
/psg "Blog platform with users, posts, comments, and tags"
```
**Generated schema.prisma:**
```prisma
// This is your Prisma schema file
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
name String
password String
bio String?
avatar String?
posts Post[]
comments Comment[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
@@map("users")
}
model Post {
id String @id @default(uuid())
title String
slug String @unique
content String @db.Text
excerpt String?
published Boolean @default(false)
publishedAt DateTime?
viewCount Int @default(0)
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
comments Comment[]
tags PostTag[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
@@index([slug])
@@index([published, publishedAt])
@@map("posts")
}
model Comment {
id String @id @default(uuid())
content String @db.Text
postId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([postId])
@@index([authorId])
@@map("comments")
}
model Tag {
id String @id @default(uuid())
name String @unique
slug String @unique
posts PostTag[]
@@index([slug])
@@map("tags")
}
// Junction table for many-to-many
model PostTag {
id String @id @default(uuid())
postId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
tagId String
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@unique([postId, tagId])
@@index([postId])
@@index([tagId])
@@map("post_tags")
}
```
---
## Generated Files
### **Migrations**
```bash
# After generating schema, run:
npx prisma migrate dev --name init
# This creates:
# - migrations/
# └── 20250110000000_init/
# └── migration.sql
```
### **Example Queries (TypeScript)**
```typescript
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// Create user
async function createUser() {
const user = await prisma.user.create({
data: {
email: '[email protected]',
name: 'John Doe',
password: 'hashed_password_here'
}
})
return user
}
// Create post with tags
async function createPost() {
const post = await prisma.post.create({
data: {
title: 'Getting Started with Prisma',
slug: 'getting-started-with-prisma',
content: 'Full blog post content...',
published: true,
publishedAt: new Date(),
authorId: 'user-uuid-here',
tags: {
create: [
{
tag: {
connectOrCreate: {
where: { slug: 'prisma' },
create: { name: 'Prisma', slug: 'prisma' }
}
}
}
]
}
},
include: {
author: true,
tags: {
include: {
tag: true
}
}
}
})
return post
}
// Get posts with related data
async function getPosts() {
const posts = await prisma.post.findMany({
where: {
published: true
},
include: {
author: {
select: {
id: true,
name: true,
avatar: true
}
},
tags: {
include: {
tag: true
}
},
_count: {
select: {
comments: true
}
}
},
orderBy: {
publishedAt: 'desc'
},
take: 10
})
return posts
}
// Create comment
async function createComment() {
const comment = await prisma.comment.create({
data: {
content: 'Great article!',
postId: 'post-uuid-here',
authorId: 'user-uuid-here'
},
include: {
author: {
select: {
name: true,
avatar: true
}
}
}
})
return comment
}
// Search posts
async function searchPosts(query: string) {
const posts = await prisma.post.findMany({
where: {
OR: [
{ title: { contains: query, mode: 'insensitive' } },
{ content: { contains: query, mode: 'insensitive' } }
],
published: true
},
include: {
author: true
}
})
return posts
}
// Get post with comments
async function getPostWithComments(slug: string) {
const post = await prisma.post.findUnique({
where: { slug },
include: {
author: true,
comments: {
include: {
author: {
select: {
name: true,
avatar: true
}
}
},
orderBy: {
createdAt: 'desc'
}
},
tags: {
include: {
tag: true
}
}
}
})
if (!post) {
throw new Error('Post not found')
}
// Increment view count
await prisma.post.update({
where: { id: post.id },
data: { viewCount: { increment: 1 } }
})
return post
}
// Get posts by tag
async function getPostsByTag(tagSlug: string) {
const posts = await prisma.post.findMany({
where: {
published: true,
tags: {
some: {
tag: {
slug: tagSlug
}
}
}
},
include: {
author: true,
tags: {
include: {
tag: true
}
}
},
orderBy: {
publishedAt: 'desc'
}
})
return posts
}
```
---
## Common Patterns
### **1. E-commerce Schema**
```prisma
model Customer {
id String @id @default(uuid())
email String @unique
name String
phone String?
orders Order[]
cart Cart?
}
model Product {
id String @id @default(uuid())
name String
description String?
price Decimal @db.Decimal(10, 2)
stock Int @default(0)
orderItems OrderItem[]
cartItems CartItem[]
}
model Order {
id String @id @default(uuid())
customerId String
customer Customer @relation(fields: [customerId], references: [id])
items OrderItem[]
total Decimal @db.Decimal(10, 2)
status String // 'pending', 'paid', 'shipped', 'delivered'
createdAt DateTime @default(now())
}
model OrderItem {
id String @id @default(uuid())
orderId String
order Order @relation(fields: [orderId], references: [id])
productId String
product Product @relation(fields: [productId], references: [id])
quantity Int
price Decimal @db.Decimal(10, 2)
}
```
### **2. Social Network Schema**
```prisma
model User {
id String @id @default(uuid())
username String @unique
email String @unique
posts Post[]
likes Like[]
following Follow[] @relation("Following")
followers Follow[] @relation("Followers")
}
model Post {
id String @id @default(uuid())
content String
authorId String
author User @relation(fields: [authorId], references: [id])
likes Like[]
createdAt DateTime @default(now())
}
model Like {
id String @id @default(uuid())
userId String
user User @relation(fields: [userId], references: [id])
postId String
post Post @relation(fields: [postId], references: [id])
@@unique([userId, postId])
}
model Follow {
id String @id @default(uuid())
followerId String
followingId String
follower User @relation("Following", fields: [followerId], references: [id])
following User @relation("Followers", fields: [followingId], references: [id])
@@unique([followerId, followingId])
}
```
### **3. Multi-tenant SaaS Schema**
```prisma
model Organization {
id String @id @default(uuid())
name String
slug String @unique
members Member[]
projects Project[]
}
model User {
id String @id @default(uuid())
email String @unique
memberships Member[]
}
model Member {
id String @id @default(uuid())
userId String
user User @relation(fields: [userId], references: [id])
orgId String
org Organization @relation(fields: [orgId], references: [id])
role String // 'owner', 'admin', 'member'
@@unique([userId, orgId])
}
model Project {
id String @id @default(uuid())
name String
orgId String
org Organization @relation(fields: [orgId], references: [id])
tasks Task[]
}
model Task {
id String @id @default(uuid())
title String
completed Boolean @default(false)
projectId String
project Project @relation(fields: [projectId], references: [id])
}
```
---
## Database Support
**PostgreSQL:**
```prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// PostgreSQL-specific types
model Example {
jsonData Json
textData String @db.Text
amount Decimal @db.Decimal(10, 2)
}
```
**MySQL:**
```prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
```
**SQLite (Development):**
```prisma
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
```
**MongoDB:**
```prisma
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
email String @unique
}
```
---
## Getting Started
**1. Install Prisma:**
```bash
npm install @prisma/client
npm install -D prisma
```
**2. Initialize Prisma:**
```bash
npx prisma init
```
**3. Use generated schema:**
- Replace `prisma/schema.prisma` with generated content
- Set `DATABASE_URL` in `.env`
**4. Create migration:**
```bash
npx prisma migrate dev --name init
```
**5. Generate Prisma Client:**
```bash
npx prisma generate
```
**6. Use in code:**
```typescript
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
```
---
## Related Commands
- `/sql-query-builder` - Generate SQL queries
- Database Designer (agent) - Schema design review
---
**Generate schemas fast. Migrate safely. Query confidently.**