fix(portal-bff): downgrade Prisma to 6.x for nestjs-prisma compatibility #3

Merged
julien merged 1 commits from fix/portal-bff/prisma-client-generator into main 2026-05-04 10:46:13 +02:00
Owner

Summary

  • Pin prisma and @prisma/client to ^6 (resolved 6.19.3) instead of the previous ^7.
  • Switch the generator in apps/portal-bff/prisma/schema.prisma from prisma-client to prisma-client-js (Prisma 6's default).
  • Add the explicit url = env("DATABASE_URL") in the datasource db block (required by Prisma 6; was implicit in Prisma 7 via prisma.config.ts).
  • Remove apps/portal-bff/prisma.config.ts (Prisma 7-only feature).
  • Drop the now-irrelevant /generated/prisma entry from apps/portal-bff/.gitignore.

Motivation

Two distinct Prisma 7 breaking changes surfaced as runtime errors in pnpm nx serve portal-bff:

  1. Generator output path: Prisma 7's default prisma-client generator writes to a custom output dir declared in the schema. @prisma/client/default.js's runtime stub still resolves .prisma/client/default in a sibling node_modules/.prisma/client/, which only the legacy prisma-client-js generator populates. Result: ESM loader error: Cannot find module '.prisma/client/default'.

  2. PrismaClientOptions API: In Prisma 7, PrismaClientOptions no longer exposes datasourceUrl nor datasources. The connection must come through a driver adapter (e.g. @prisma/adapter-pg). nestjs-prisma@0.27.0 calls super(undefined) when no prismaServiceOptions is passed, which Prisma 7 rejects with PrismaClientInitializationError: PrismaClient needs to be constructed with a non-empty, valid PrismaClientOptions.

Both issues are downstream of Prisma 7's "adapter-first" architecture being incompatible with nestjs-prisma's still-Prisma-6-shaped wrapper. Working around each issue separately would lead into bespoke wiring (custom PrismaService, manual @prisma/adapter-pg install, hand-rolled DI). That's bricolage on a foundational layer.

Per CLAUDE.md ("default to stable, recognized, battle-tested choices; cutting-edge alternatives only when the trade-off is captured in an ADR"), the cheapest, cleanest fix is to use Prisma 6 — still actively maintained, fully aligned with nestjs-prisma's design, supported by every tutorial and example in the wider ecosystem.

Implementation notes

  • ADR-0006 ("Persistence — PostgreSQL with Prisma") specifies "Prisma" without pinning a version. The version choice is a tactical detail. No ADR amendment.
  • apps/portal-bff/.env.example is unchanged — the DATABASE_URL variable name is the same in Prisma 6 and 7.
  • prisma.config.ts removed: it was a Prisma 7 file that Prisma 6 ignores; keeping it would only confuse a future contributor.
  • The Prisma 7 prisma-client generator left a residual output dir at apps/portal-bff/generated/ from the previous setup; removed locally and excluded from gitignore (no longer needed).
  • Re-evaluate when nestjs-prisma releases an update aligned with Prisma 7's adapter model. The path back is symmetric: pin Prisma to ^7, restore the schema's prisma-client generator, install @prisma/adapter-pg, and update app.module.ts to instantiate the adapter.

Verification

  • pnpm exec prisma generate populates node_modules/.../@prisma+client@6.19.3/.prisma/client/default.js (no more 7.x in the active resolution).
  • pnpm nx build portal-bff green.
  • pnpm nx serve portal-bff boots cleanly (no PrismaClientInitializationError) — to be confirmed locally before merge. Connection to a real Postgres is out of scope of this PR; if Postgres is not running, an ECONNREFUSED is expected and unrelated.
  • pnpm ci:check — runs in CI on PR open.

Related

## Summary - Pin `prisma` and `@prisma/client` to `^6` (resolved 6.19.3) instead of the previous `^7`. - Switch the generator in `apps/portal-bff/prisma/schema.prisma` from `prisma-client` to `prisma-client-js` (Prisma 6's default). - Add the explicit `url = env("DATABASE_URL")` in the `datasource db` block (required by Prisma 6; was implicit in Prisma 7 via `prisma.config.ts`). - Remove `apps/portal-bff/prisma.config.ts` (Prisma 7-only feature). - Drop the now-irrelevant `/generated/prisma` entry from `apps/portal-bff/.gitignore`. ## Motivation Two distinct Prisma 7 breaking changes surfaced as runtime errors in `pnpm nx serve portal-bff`: 1. **Generator output path:** Prisma 7's default `prisma-client` generator writes to a custom output dir declared in the schema. `@prisma/client/default.js`'s runtime stub still resolves `.prisma/client/default` in a sibling `node_modules/.prisma/client/`, which only the legacy `prisma-client-js` generator populates. Result: `ESM loader error: Cannot find module '.prisma/client/default'`. 2. **PrismaClientOptions API:** In Prisma 7, `PrismaClientOptions` no longer exposes `datasourceUrl` nor `datasources`. The connection must come through a driver adapter (e.g. `@prisma/adapter-pg`). `nestjs-prisma@0.27.0` calls `super(undefined)` when no `prismaServiceOptions` is passed, which Prisma 7 rejects with `PrismaClientInitializationError: PrismaClient needs to be constructed with a non-empty, valid PrismaClientOptions`. Both issues are downstream of Prisma 7's "adapter-first" architecture being incompatible with `nestjs-prisma`'s still-Prisma-6-shaped wrapper. Working around each issue separately would lead into bespoke wiring (custom PrismaService, manual `@prisma/adapter-pg` install, hand-rolled DI). That's bricolage on a foundational layer. Per CLAUDE.md ("default to stable, recognized, battle-tested choices; cutting-edge alternatives only when the trade-off is captured in an ADR"), the cheapest, cleanest fix is to use Prisma 6 — still actively maintained, fully aligned with `nestjs-prisma`'s design, supported by every tutorial and example in the wider ecosystem. ## Implementation notes - ADR-0006 ("Persistence — PostgreSQL with Prisma") specifies "Prisma" without pinning a version. The version choice is a tactical detail. No ADR amendment. - `apps/portal-bff/.env.example` is unchanged — the `DATABASE_URL` variable name is the same in Prisma 6 and 7. - `prisma.config.ts` removed: it was a Prisma 7 file that Prisma 6 ignores; keeping it would only confuse a future contributor. - The Prisma 7 `prisma-client` generator left a residual output dir at `apps/portal-bff/generated/` from the previous setup; removed locally and excluded from gitignore (no longer needed). - Re-evaluate when `nestjs-prisma` releases an update aligned with Prisma 7's adapter model. The path back is symmetric: pin Prisma to `^7`, restore the schema's `prisma-client` generator, install `@prisma/adapter-pg`, and update `app.module.ts` to instantiate the adapter. ## Verification - [x] `pnpm exec prisma generate` populates `node_modules/.../@prisma+client@6.19.3/.prisma/client/default.js` (no more 7.x in the active resolution). - [x] `pnpm nx build portal-bff` green. - [X] `pnpm nx serve portal-bff` boots cleanly (no `PrismaClientInitializationError`) — to be confirmed locally before merge. Connection to a real Postgres is out of scope of this PR; if Postgres is not running, an `ECONNREFUSED` is expected and unrelated. - [ ] `pnpm ci:check` — runs in CI on PR open. ## Related - [ADR-0006 — Persistence: PostgreSQL with Prisma](docs/decisions/0006-persistence-postgresql-prisma.md). Generator and version are tactical; no amendment. - Future: revisit Prisma version when `nestjs-prisma` ships an update with first-class driver-adapter support.
julien added 1 commit 2026-05-04 10:33:09 +02:00
fix(portal-bff): downgrade Prisma to 6.x for nestjs-prisma compatibility
CI / commits (pull_request) Failing after 5s
CI / scan (pull_request) Failing after 9s
CI / a11y (pull_request) Failing after 3s
CI / perf (pull_request) Failing after 4s
CI / check (pull_request) Failing after 3s
d82c455973
Prisma 7 introduced two breaking changes that conflict with
nestjs-prisma 0.27.0:

1. The `prisma-client` provider (new default in Prisma 7) outputs
   the typed client to a custom path declared in schema.prisma.
   nestjs-prisma's PrismaService extends @prisma/client's runtime,
   which boots through @prisma/client/default.js — that stub requires
   `.prisma/client/default` in a sibling node_modules tree. Only the
   legacy `prisma-client-js` generator populates that path.

2. PrismaClientOptions in Prisma 7 no longer exposes `datasourceUrl`
   nor `datasources`. Connection now requires a driver adapter
   (e.g. `@prisma/adapter-pg` for Postgres). nestjs-prisma 0.27.0
   does not pass an adapter, and `new PrismaClient(undefined)` is
   rejected with `PrismaClientInitializationError: PrismaClient needs
   to be constructed with a non-empty, valid PrismaClientOptions`.

Both quirks are Prisma 7's adapter-first architecture surfacing
through a still-Prisma-6-shaped wrapper. nestjs-prisma's peer-deps
say `^7.0.0` but its design assumes the older API. Working around
each issue separately leads further into bespoke wiring (custom
PrismaService, manual @prisma/adapter-pg setup) — bricolage on a
foundational layer.

Per CLAUDE.md ("default to stable, recognized, battle-tested
choices"), downgrade to Prisma 6.19 (still actively maintained):

- package.json: prisma + @prisma/client pinned to ^6 (resolved 6.19.3)
- apps/portal-bff/prisma/schema.prisma:
  - generator client: `prisma-client-js` (Prisma 6 default)
  - datasource db: explicit `url = env("DATABASE_URL")` (required by
    Prisma 6, was implicit in Prisma 7 via prisma.config.ts)
- apps/portal-bff/prisma.config.ts: removed (Prisma 7-only feature)
- apps/portal-bff/.gitignore: drop the now-irrelevant
  `/generated/prisma` entry (no custom output dir with prisma-client-js)

ADR-0006 ("Persistence — PostgreSQL with Prisma") is unchanged: it
specifies Prisma without pinning a version. The version choice is a
tactical detail.

Re-evaluate when nestjs-prisma releases an update aligned with
Prisma 7's adapter model.

Verified: pnpm exec prisma generate populates Prisma 6's
.prisma/client/default.{js,d.ts}; pnpm nx build portal-bff green.
Runtime serve to be re-verified locally before merge.
julien merged commit a0f6e594ba into main 2026-05-04 10:46:13 +02:00
julien deleted branch fix/portal-bff/prisma-client-generator 2026-05-04 10:46:13 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#3