Course navigationPhase 09
Volume 03 · Phase 09

Prisma 7.9.1 Architecture, Configuration & Migrations

Integrate Prisma 7.9.1 as a repeatable persistence layer with schema, generated client, adapter/configuration, migrations, and NestJS lifecycle.

14lessons + labs
6klesson words
8source references
What you will ship

Phase outcome and project increment

Learning outcome

Integrate Prisma 7.9.1 as a repeatable persistence layer with schema, generated client, adapter/configuration, migrations, and NestJS lifecycle.

Concrete deliverable

Prisma schema + migration history + generated client + NestJS PrismaService connected to TaskFlow PostgreSQL.

Figure 9.1 — Where this phase lives in TaskFlow
schema.prisma
migration files
database schema
generated Prisma Client
PrismaService
feature service
Trace the flow left-to-right for implementation and right-to-left for debugging. At every arrow, ask what data crosses the boundary and what proves it is trustworthy.
Instructor mental model

Principles to keep while coding

01

Use Prisma migrations as the authoritative history of application schema changes.

02

Keep generated Prisma Client code derived from the schema instead of hand-editing it.

03

Use a shared Prisma service in NestJS so connection lifecycle and access patterns remain controlled.

04

Pin Prisma versions deliberately when the course architecture depends on a specific configuration model.

Code-along path

Guided phase lab

Do these in order. Each step should end with evidence before the next one starts.

  1. 01

    Pin Prisma packages to the course version contract and verify all Prisma package versions match.

  2. 02

    Initialize Prisma with the intended generated-client output and PostgreSQL configuration.

  3. 03

    Model one entity, create the first migration, and inspect the SQL before applying it.

  4. 04

    Generate the client and wire a PrismaService into NestJS with controlled lifecycle.

  5. 05

    Perform a smoke query through the service, then inspect the created database object independently.

  6. 06

    Cause a safe migration/configuration failure and practice reading Prisma error codes instead of reinstalling randomly.

TerminalVerification commands
pnpm exec prisma version
pnpm exec prisma validate
pnpm exec prisma migrate dev --name <name>
pnpm exec prisma generate

Predict what each command proves before running it. A command is useful only when its output answers a question.

Debugging studio

Failures you should know how to diagnose

Failure drill 1

CLI/client version mismatch

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 2

Editing generated client code

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 3

Using db push as a substitute for migration history in team environments

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 4

Creating a new PrismaClient per request

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Watch-order style

Lessons

The source chapters come first. Every phase now ends with a guided build, a debugging workshop, and an independent challenge so reading turns into transferable skill.

01

Prisma Mental Model and Architecture

PHASE 09 / BOOK 01 Prisma Mental Model & Architecture Understand every Prisma layer before installing it NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQL Figure

2 min
02

Install and Lock Prisma 7 9 1

PHASE 09 / BOOK 02 Install & Lock Prisma 7.9.1 Exact dependencies, local CLI and reproducible tooling NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQL Figure -

2 min
03

Prisma Init and File Anatomy

PHASE 09 / BOOK 03 prisma init & File Anatomy Understand the files before editing them NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQL Figure - The database ac

2 min
04

Schema Generator and First Model

PHASE 09 / BOOK 04 Schema, Generator & First Model Prisma Schema Language without hiding the relational model NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQL F

2 min
05

Prisma Config Supabase URLs and Shadow Database

PHASE 09 / BOOK 05 Prisma Config, Supabase URLs & Shadow Database Separate runtime traffic from migration tooling NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreS

2 min
06

Prisma Client Adapter and NestJS PrismaService

PHASE 09 / BOOK 06 Prisma Client, PrismaPg & NestJS PrismaService Turn generated types into reusable backend infrastructure NestJS PrismaService Prisma Client PrismaPg driver adapter Supabas

2 min
07

Migration Lifecycle and First Migration

PHASE 09 / BOOK 07 Migration Lifecycle & First Migration Create schema history you can inspect, commit and deploy NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreS

2 min
08

Prisma CLI Workflow Development and Production

PHASE 09 / BOOK 08 Prisma CLI Workflow: Development & Production Use the smallest correct command for each stage NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQ

2 min
09

Debugging Prisma and Common Failures

PHASE 09 / BOOK 09 Debugging Prisma & Common Failures Diagnose the failing layer instead of replacing the project NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreS

2 min
10

Hands On Lab and Phase Exit

PHASE 09 / BOOK 10 Hands-On Lab & Phase Exit Install, configure, integrate, migrate and explain the system NestJS PrismaService Prisma Client PrismaPg driver adapter Supabase PostgreSQL Figu

3 min
LAB

Guided Build Lab

Purpose Integrate Prisma 7.9.1 as a repeatable persistence layer with schema, generated client, adapter/configuration, migrations, and NestJS lifecycle.

3 min
LAB

Debugging Workshop

Goal Learn to diagnose this phase's failures systematically instead of reinstalling packages, changing random configuration, or copying a fix without understanding it.

2 min
LAB

Phase Synthesis & Independent Challenge

Mission Rebuild the capability of Phase 09 without following the exact code line-by-line. The goal is transfer: can you use the ideas when the variable names, UI, or route shape changes?

2 min
LAB

Mastery Capstone Lab

Integrate Phase 09 without following a transcript.

2 min
Practice ladder

Exercises that increase independence

Guided

Pin Prisma packages to the course version contract and verify all Prisma package versions match.

Practice

Model one entity, create the first migration, and inspect the SQL before applying it.

Debug

reproduce and diagnose — CLI/client version mismatch.

Independent

deliver Prisma schema + migration history + generated client + NestJS PrismaService connected to TaskFlow PostgreSQL.

Explain-back

Can explain schema vs migration vs generated client and Can create and inspect a migration.

Mastery gate

Do not leave the phase only because you reached the bottom

Phase exit criteria

Knowledge check

Scenario and concept quiz

These questions test engineering choices rather than whether you remember a lesson title.

0/0 correct · 0/8 answered
01Which practice best matches Phase 09's engineering goal?
02Which practice best matches Phase 09's engineering goal?
03Which practice best matches Phase 09's engineering goal?
04Which practice best matches Phase 09's engineering goal?
05You are working through the Phase 09 lab. Which next action is the most disciplined step?
06You are working through the Phase 09 lab. Which next action is the most disciplined step?
07You are working through the Phase 09 lab. Which next action is the most disciplined step?
08You are working through the Phase 09 lab. Which next action is the most disciplined step?
Source snapshot

Reference files

Attempt the work first. Use snapshots to compare a checkpoint, not as a substitute for understanding.

reference/TaskFlow_Prisma_Snapshot/.env.example
# Runtime application connection (Phase 08 recommends a session-capable pooled URL for local NestJS).
DATABASE_URL=

# Prisma CLI / migration connection. Prefer a direct URL when reachable.
DIRECT_URL=

# Optional only if migrate dev cannot create an automatic shadow database.
# NEVER point this at the same database as DIRECT_URL.
SHADOW_DATABASE_URL=
reference/TaskFlow_Prisma_Snapshot/README.txt
TaskFlow Phase 09 Prisma reference snapshot

These files are reference outputs for the end of Phase 09.
Do not paste them blindly over an existing project. Compare responsibilities and adapt the existing files.

Important:
- Prisma packages are locked to 7.9.1.
- DATABASE_URL is for runtime PrismaPg.
- DIRECT_URL is for Prisma CLI/migrations.
- If SHADOW_DATABASE_URL is used, it must point to a separate disposable shadow database.
- src/generated/prisma is generated by `pnpm exec prisma generate`; it is intentionally not included here.
reference/TaskFlow_Prisma_Snapshot/install-prisma.ps1
pnpm add -D prisma@7.9.1 @types/pg
pnpm add @prisma/client@7.9.1 @prisma/adapter-pg@7.9.1 pg dotenv @nestjs/config
reference/TaskFlow_Prisma_Snapshot/prisma/schema.prisma
generator client {
  provider     = "prisma-client"
  output       = "../src/generated/prisma"
  moduleFormat = "cjs"
}

datasource db {
  provider = "postgresql"
}

model Todo {
  id        String   @id @default(cuid())
  title     String
  completed Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
reference/TaskFlow_Prisma_Snapshot/prisma.config.ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    // CLI / migrations: direct or session-capable connection.
    url: env("DIRECT_URL"),
  },
});
reference/TaskFlow_Prisma_Snapshot/src/app.module.ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { HealthModule } from "./health/health.module";
import { TodosModule } from "./todos/todos.module";
import { PrismaModule } from "./prisma/prisma.module";

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    PrismaModule,
    HealthModule,
    TodosModule,
  ],
})
export class AppModule {}
reference/TaskFlow_Prisma_Snapshot/src/prisma/prisma.module.ts
import { Global, Module } from "@nestjs/common";
import { PrismaService } from "./prisma.service";

@Global()
@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
reference/TaskFlow_Prisma_Snapshot/src/prisma/prisma.service.ts
import { Injectable, OnModuleDestroy, OnModuleInit } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client";

@Injectable()
export class PrismaService
  extends PrismaClient
  implements OnModuleInit, OnModuleDestroy
{
  constructor(config: ConfigService) {
    const connectionString = config.getOrThrow<string>("DATABASE_URL");
    const adapter = new PrismaPg({ connectionString });
    super({ adapter });
  }

  async onModuleInit() {
    await this.$connect();
  }