From harness-claude
Provides Prisma Client query patterns: findUnique/findMany, create/update/delete, upsert, select, include, nested writes, and client instantiation best practices.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:prisma-client-queriesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Query data with Prisma Client findUnique/findMany, create/update/delete, upsert, select, include
Query data with Prisma Client findUnique/findMany, create/update/delete, upsert, select, include
PrismaClient per request:// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
findUnique for lookups by @id or @unique fields. Use findFirst when filtering by non-unique fields:const user = await prisma.user.findUnique({ where: { id: userId } });
const admin = await prisma.user.findFirst({ where: { role: 'ADMIN' } });
findMany returns an array. Always paginate large result sets:const users = await prisma.user.findMany({
where: { role: 'USER' },
take: 20,
skip: 0,
orderBy: { createdAt: 'desc' },
});
const names = await prisma.user.findMany({
select: { id: true, name: true, email: true },
});
// Type: { id: string; name: string | null; email: string }[]
include:const userWithPosts = await prisma.user.findUnique({
where: { id: userId },
include: { posts: { where: { published: true }, take: 10 } },
});
const user = await prisma.user.create({
data: { email: '[email protected]', name: 'New User' },
});
where clause:const updated = await prisma.user.update({
where: { id: userId },
data: { name: 'Updated Name' },
});
const user = await prisma.user.upsert({
where: { email: '[email protected]' },
create: { email: '[email protected]', name: 'New' },
update: { name: 'Existing' },
});
delete for single records, deleteMany for bulk:await prisma.user.delete({ where: { id: userId } });
await prisma.post.deleteMany({ where: { authorId: userId } });
const user = await prisma.user.create({
data: {
email: '[email protected]',
posts: { create: [{ title: 'First Post' }, { title: 'Second Post' }] },
},
include: { posts: true },
});
Prisma Client is auto-generated from the schema and provides full TypeScript types for every query. The generated types enforce that you only pass valid field names, filter operators, and relation includes.
select vs include: These are mutually exclusive at the same level. select returns only the specified fields (plus any nested select/include). include returns all scalar fields plus the specified relations.
findUnique vs findFirst: findUnique can only filter by @id or @unique fields and benefits from Prisma's internal query deduplication (DataLoader batching). findFirst can filter by any field but does not deduplicate.
findUniqueOrThrow / findFirstOrThrow: These variants throw a PrismaClientKnownRequestError with code P2025 instead of returning null. Use them when absence is an error condition.
Nested writes are atomic: create with nested create/connect/connectOrCreate runs in a single implicit transaction. If any nested operation fails, the entire write is rolled back.
Return types narrow automatically: When you use select, the return type includes only the selected fields. This is enforced at the TypeScript level, so your code stays type-safe.
Common mistakes:
findFirst where findUnique would work — loses batching optimizationinclude — each level adds a separate database query. Three levels deep on a list page causes N+1 problemsnull from findUnique — always check or use findUniqueOrThrowupdateMany/deleteMany do not return the affected records — only a counthttps://prisma.io/docs/orm/prisma-client/queries
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeOptimizes Prisma queries using select, findUnique batching, N+1 prevention, bulk operations, indexing, query logging, connection pooling, and cursor pagination.
Production patterns and non-obvious traps for Prisma ORM in TypeScript backends — schema design, query optimization, transactions, pagination, bulk operations, migrations, and serverless deployment gotchas.
Provides fast reference for Prisma 5+ ORM: schema design, migrations, type-safe CRUD, relations, transactions, error handling, testing, and integrations with Supabase, PlanetScale, Neon for TypeScript/JavaScript database access.