prisma

Installation
SKILL.md

Prisma

Commands

Task Command
Create and apply a migration pnpm exec prisma migrate dev --name <migration-name>
Apply pending migrations (CI/prod) pnpm exec prisma migrate deploy
Check migration status pnpm exec prisma migrate status
Regenerate Prisma client pnpm exec prisma generate
Seed the database pnpm exec prisma db seed
Reset the database (dev only) pnpm exec prisma migrate reset
Open Prisma Studio pnpm exec prisma studio
Format the schema file pnpm exec prisma format

Default action: When asked to "apply a schema change", the correct sequence is: update prisma/schema.prisma → run prisma format → run migrate dev → run generate.

⚠️ migrate reset drops and recreates the entire database. Only use it in local development against a database you are comfortable losing. Never run it against a production or shared staging environment.

Before changing the schema — explore the project first

Before modifying prisma/schema.prisma, read the existing schema and migration history to understand:

  • The datasource block — confirm the provider (mysql with the MariaDB adapter) and that the environment variables used in the prisma config file to create a database connection URL are set in the .env file.
  • The existing models — understand the relationships (one-to-many, many-to-many join tables) and naming conventions before adding new models or fields
  • The existing migrations in prisma/migrations/ — skim recent migrations to understand what has already been applied and what naming convention is used (<timestamp>_<snake_case_description>)
  • The seed script at prisma/seed.ts — understand what data is currently seeded and whether the new model needs corresponding seed entries

Also check .env.template to confirm which environment variables the datasource requires, and ensure .env is fully populated before running any Prisma commands.

Schema conventions

Follow these conventions when adding or modifying models

  • Use PascalCase for model names and camelCase for field names
  • Always include id, createdAt, and updatedAt on new top-level models
  • Use @unique on fields that serve as natural business identifiers (e.g. email, slug, clientId)
  • Prefer @default(nanoid()) for integer primary keys
  • Use explicit @relation attributes when the inferred relation is ambiguous — do not rely on Prisma's name inference for complex multi-relation models
  • Always map field names for the tables so that they are lower_snake_case in the actual database tables.

Migration workflow

Follow this sequence for every schema change:

  1. Edit prisma/schema.prisma — make the schema change
  2. Run prisma format — auto-format the schema file for consistency
  3. Run prisma migrate dev --name <description> — generates a SQL migration file under prisma/migrations/ and applies it to the local database
  4. Run prisma generate — regenerates the Prisma client with updated TypeScript types
  5. Verify — run the application or test suite to confirm the change works end-to-end

Migration names should be short, lowercase, and descriptive in snake_case (e.g. add_user_email_verified, remove_legacy_token_field, add_role_permission_join_table).

Destructive migrations

Treat the following operations as destructive — they risk data loss in any environment with existing data:

  • Dropping a column or table
  • Renaming a column (Prisma generates a DROP + ADD, not an ALTER RENAME)
  • Changing a field from optional to required without providing a default value

Before applying a destructive migration to any environment other than a fresh local database:

  • Create a database back-up by exporting all the data from the database schemas affected, which can be used to restore the database after something went wrong.
    • This should include how to create the database and the actual data.
  • Review the generated SQL in prisma/migrations/<timestamp>_<name>/migration.sql before applying
  • Confirm the migration is intentional and that a data backfill strategy exists if rows will be affected
  • Never use migrate reset outside of local development

Seeding

The seed script is invoked via pnpm exec prisma db seed, using the entry point defined in package.json under prisma.seed. When a new model requires initial data:

  1. Add seed entries to prisma/seed.ts using prisma.<model>.upsert — not create — so the seed script is idempotent and safe to re-run without creating duplicate records
  2. Test the seed locally with pnpm exec prisma db seed
  3. Confirm the seed produces clean results when run multiple times on the same database

Prisma client usage in NestJS

  • Use the generated Prisma client types for return values — avoid any or manually defined database object types
  • Use findUnique for lookups by a unique identifier; use findFirst only when filtering by non-unique fields
  • Wrap multi-step write operations in prisma.$transaction to guarantee atomicity

Workflow notes

  • Run prisma generate any time schema.prisma changes — the Prisma client in prisma/client becomes stale immediately after a schema edit, causing TypeScript errors
  • Always commit both the updated schema.prisma and the generated prisma/migrations/ folder — never commit a schema change without its corresponding migration file
  • Do not manually edit migration SQL files after they have been applied to any environment — create a new migration to correct the state instead
    • When a model is added at the same time as a constraint (foreign key, unique, etc.), modify the migration before committing them to include the creation of the constraint with the creation of the table.
  • Run pnpm test after any schema change to catch type errors introduced by the regenerated Prisma client
Related skills
Installs
10
First Seen
Apr 11, 2026