install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/prisma-type-generation" ~/.claude/skills/intense-visions-harness-engineering-prisma-type-generation && rm -rf "$T"
manifest:
agents/skills/claude-code/prisma-type-generation/SKILL.mdsource content
Prisma Type Generation
Use generated Prisma types like XxxCreateInput, XxxWhereInput, $Enums, and validator utilities
When to Use
- Typing function parameters that accept Prisma query inputs
- Building type-safe service layers that wrap Prisma operations
- Accessing generated enum types in application code
- Creating DTOs or API schemas that align with the Prisma data model
Instructions
- Regenerate types after schema changes:
npx prisma generate
This runs automatically after
migrate dev but must be run manually after editing the schema without migrating.
- Import generated types from
:@prisma/client
import { Prisma, User, Post, Role } from '@prisma/client';
,User
— model types (the shape returned by queries)Post
— enum typeRole
— namespace containing all input/output typesPrisma
- Use input types for service function parameters:
import { Prisma } from '@prisma/client'; async function createUser(data: Prisma.UserCreateInput) { return prisma.user.create({ data }); } async function findUsers(where: Prisma.UserWhereInput) { return prisma.user.findMany({ where }); }
- Access enum values from the
export or directly:$Enums
import { Role } from '@prisma/client'; // Use as a type function isAdmin(role: Role): boolean { return role === 'ADMIN'; } // Use enum values const defaultRole: Role = 'USER';
- Extract return types from queries using
:Prisma.UserGetPayload
type UserWithPosts = Prisma.UserGetPayload<{ include: { posts: true }; }>; // UserWithPosts = User & { posts: Post[] }
- Type the result of
queries:select
type UserSummary = Prisma.UserGetPayload<{ select: { id: true; name: true; email: true }; }>; // UserSummary = { id: string; name: string | null; email: string }
- Use
to create reusable, type-checked query objects:Prisma.validator
const userWithPosts = Prisma.validator<Prisma.UserDefaultArgs>()({ include: { posts: true }, }); // Use in queries const user = await prisma.user.findUnique({ where: { id }, ...userWithPosts, });
- Type service layers that return a subset of fields:
const userSelect = Prisma.validator<Prisma.UserSelect>()({ id: true, email: true, name: true, }); type PublicUser = Prisma.UserGetPayload<{ select: typeof userSelect }>; async function getPublicUser(id: string): Promise<PublicUser | null> { return prisma.user.findUnique({ where: { id }, select: userSelect }); }
- Use
for dynamic field selection:Prisma.UserScalarFieldEnum
const sortableFields = ['createdAt', 'name', 'email'] as const; function buildOrderBy(field: (typeof sortableFields)[number]): Prisma.UserOrderByWithRelationInput { return { [field]: 'desc' }; }
- Handle
types from Json fields:JsonValue
import { Prisma } from '@prisma/client'; // Prisma.JsonValue = string | number | boolean | null | Prisma.JsonObject | Prisma.JsonArray function parseMetadata(json: Prisma.JsonValue): Record<string, unknown> { if (typeof json === 'object' && json !== null && !Array.isArray(json)) { return json as Record<string, unknown>; } return {}; }
Details
Prisma generates TypeScript types in
node_modules/.prisma/client/index.d.ts based on your schema. These types power autocompletion, compile-time checking, and the entire Prisma Client API.
Type categories:
- Model types (
,User
) — plain objects representing a full database rowPost - Input types (
,UserCreateInput
,UserUpdateInput
) — types for query argumentsUserWhereInput - Output types (
) — types derived from specific select/include combinationsUserGetPayload<T> - Enum types (
,Role
) — string literal unions matching schema enumsStatus - Scalar field enums (
) — union of field name stringsUserScalarFieldEnum
vs UserCreateInput
: The UserUncheckedCreateInput
Create input uses relation fields (author: { connect: { id } }). The Unchecked variant uses raw foreign keys (authorId: string). Both produce the same SQL. Use the standard version for type safety; use the unchecked version when working with raw IDs.
Keeping types in sync: Types are generated into
node_modules and are not committed to version control. Run prisma generate in CI before type-checking. Add it to your build pipeline:
{ "scripts": { "build": "prisma generate && tsc" } }
Zod integration: Use
zod-prisma-types or prisma-zod-generator to auto-generate Zod schemas from your Prisma models. This eliminates manual synchronization between Prisma types and runtime validation:
generator zod { provider = "zod-prisma-types" }
Source
https://prisma.io/docs/orm/prisma-client/type-safety
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.