skills/db-prisma/SKILL.md
Prisma 7 ORM with PostgreSQL — schema design, migrations, seeding, and Railway deployment patterns. This skill should be used when setting up Prisma in a new project, writing migrations, managing database schemas, or deploying Prisma-backed services to Railway.
npx skillsauth add aussiegingersnap/cursor-skills db-prismaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Production patterns for Prisma 7 ORM with PostgreSQL, including schema design, versioned migrations, seeding, and Railway-specific configuration.
npm install prisma @prisma/client
npx prisma init --datasource-provider postgresql
prisma/
schema.prisma # Schema definition
migrations/ # Versioned SQL migrations
seed.ts # Database seeder
# .env (development)
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/myapp?schema=public"
# Railway (production) — auto-wired from Postgres service
DATABASE_URL="postgresql://user:pass@host:port/railway?schema=public&connection_limit=5"
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
Singular model names, PascalCase. Fields use camelCase. Database columns use snake_case via @map.
model User {
id String @id @default(uuid())
email String @unique
name String
role Role @default(MEMBER)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
sessions Session[]
posts Post[]
@@map("user")
}
Every model gets createdAt and updatedAt:
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
enum Role {
ADMIN
MEMBER
GUEST
}
enum Status {
DRAFT
PUBLISHED
ARCHIVED
}
One-to-Many:
model User {
id String @id @default(uuid())
posts Post[]
@@map("user")
}
model Post {
id String @id @default(uuid())
title String
userId String @map("user_id")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@map("post")
}
Many-to-Many (explicit join table):
model Post {
id String @id @default(uuid())
tags PostTag[]
@@map("post")
}
model Tag {
id String @id @default(uuid())
name String @unique
posts PostTag[]
@@map("tag")
}
model PostTag {
postId String @map("post_id")
tagId String @map("tag_id")
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@id([postId, tagId])
@@map("post_tag")
}
model User {
id String @id @default(uuid())
email String @unique
name String
@@index([name])
@@map("user")
}
model Product {
id String @id @default(uuid())
metadata Json?
tags String[]
price Decimal @db.Decimal(10, 2)
@@map("product")
}
# Create migration from schema changes
npx prisma migrate dev --name add_user_table
# Apply without creating (schema push for prototyping)
npx prisma db push
# Reset database (drops all data)
npx prisma migrate reset
# Check migration status
npx prisma migrate status
# Deploy pending migrations (non-interactive, no data loss prompts)
npx prisma migrate deploy
migrate dev locally, migrate deploy in CI/productionmigrations/ directory — it's your migration historydb push only for prototyping — no migration historynpx prisma generate
Run after every schema change. The build command should include this.
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Create
const user = await prisma.user.create({
data: { email: '[email protected]', name: 'John' },
});
// Read one
const found = await prisma.user.findUnique({
where: { email: '[email protected]' },
});
// Read many with filter
const users = await prisma.user.findMany({
where: { role: 'MEMBER' },
orderBy: { createdAt: 'desc' },
take: 10,
});
// Update
await prisma.user.update({
where: { id: user.id },
data: { name: 'Jane' },
});
// Delete
await prisma.user.delete({ where: { id: user.id } });
// Include relations
const userWithPosts = await prisma.user.findUnique({
where: { id: userId },
include: { posts: true, sessions: true },
});
// Nested create
const user = await prisma.user.create({
data: {
email: '[email protected]',
name: 'John',
posts: {
create: [
{ title: 'First Post' },
{ title: 'Second Post' },
],
},
},
include: { posts: true },
});
// Select specific fields
const emails = await prisma.user.findMany({
select: { id: true, email: true },
});
const [user, post] = await prisma.$transaction([
prisma.user.create({ data: { email: '[email protected]', name: 'A' } }),
prisma.post.create({ data: { title: 'Hello', userId: 'known-id' } }),
]);
// Interactive transaction
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: { email: '[email protected]', name: 'A' },
});
await tx.post.create({
data: { title: 'Hello', userId: user.id },
});
});
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
await prisma.user.upsert({
where: { email: '[email protected]' },
update: {},
create: {
email: '[email protected]',
name: 'Admin',
role: 'ADMIN',
},
});
console.log('Seed complete');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(() => prisma.$disconnect());
{
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
npx prisma db seed
Seed runs automatically after prisma migrate reset.
Railway Postgres provides DATABASE_URL automatically when the backend service references the Postgres service. Append connection pooling for production:
DATABASE_URL="postgresql://user:pass@host:port/railway?schema=public&connection_limit=5"
npx prisma generate && npx prisma migrate deploy && npm run build
This sequence:
[build]
builder = "nixpacks"
buildCommand = "npx prisma generate && npx prisma migrate deploy && npm run build"
[deploy]
startCommand = "node dist/main.js"
healthcheckPath = "/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
npx prisma studio
Opens a browser-based GUI for viewing and editing data at http://localhost:5555.
{
"scripts": {
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev",
"db:migrate:deploy": "prisma migrate deploy",
"db:push": "prisma db push",
"db:reset": "prisma migrate reset",
"db:seed": "prisma db seed",
"db:studio": "prisma studio"
}
}
Check DATABASE_URL is set and Postgres is running:
echo $DATABASE_URL
docker compose ps # if using Docker locally
Check migration status and logs:
npx prisma migrate status
npx prisma migrate resolve --rolled-back <migration-name>
Run generate after schema changes:
npx prisma generate
Append &connection_limit=5 to DATABASE_URL. Railway instances have limited connections.
Regenerate client and restart TypeScript server:
npx prisma generate
# Restart TS server in IDE: Cmd+Shift+P → "TypeScript: Restart TS Server"
tools
# Versioning Skill Semantic versioning automation based on conventional commits. Automatically manages version bumps, changelogs, and git tags using `standard-version`. ## When to Use - Before releasing a new version - When preparing a deployment - To generate/update CHANGELOG.md - When the user asks about version management - Setting up versioning for a new project ## Prerequisites - Conventional commits enforced (recommended: lefthook) - Node.js project with package.json ## Setup (One-Ti
tools
Theme generation with tweakcn for shadcn/ui and Magic UI animations. Use when setting up project themes, customizing color schemes, adding dark mode, or integrating animated components.
tools
shadcn/studio component library with MCP integration, theme generation, and block patterns. This skill should be used when building UI with shadcn components, selecting dashboard layouts, or generating landing pages. Canonical source for all shadcn-based work.
development
Enforce a precise, minimal design system inspired by Linear, Notion, and Stripe. Use this skill when building dashboards, admin interfaces, or any UI that needs Jony Ive-level precision - clean, modern, minimalist with taste. Every pixel matters.