| name | prisma-expert |
| type | reference |
| description | Provides Prisma ORM patterns for schema design, migrations, query optimization, and relation modeling. Use when working with Prisma schema files (schema.prisma) or when the user mentions Prisma, Prisma migrations, or Prisma queries. |
| paths | ["**/prisma/**","**/*.prisma","**/schema.prisma"] |
| when_to_use | When working with Prisma ORM for schema design, migrations, query optimization, or troubleshooting database operations |
| allowed-tools | Read, Glob, Grep, Write, Edit, Bash |
| user-invocable | true |
| effort | 3 |
Prisma Expert
Critical rules (non-obvious)
- Never use
migrate dev in production — use migrate deploy; migrate dev can reset data
- Singleton client in serverless — new
PrismaClient() per request exhausts connections; use global singleton
include vs select: include: { posts: true } fetches ALL post fields; use select to limit
$queryRaw returns unknown[] — you must cast with as or validate; Prisma can't infer raw query types
- Missing
@relation on both sides causes "The relation is not defined on both sides" runtime error
Schema: canonical model structure
model User {
id String @id @default(cuid())
email String @unique
role Role @default(USER)
posts Post[] @relation("UserPosts")
profile Profile? @relation("UserProfile")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
@@map("users")
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
author User @relation("UserPosts", fields: [authorId], references: [id], onDelete: Cascade)
authorId String
@@index([authorId])
@@map("posts")
}
enum Role { USER ADMIN MODERATOR }
Query optimization: N+1 fix
const users = await prisma.user.findMany();
for (const user of users) {
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
}
const users = await prisma.user.({ : { : } });
users = prisma..({
: {
: , : ,
: { : { : , : } },
},
});
result = prisma.<{ : ; : }[]>;