ADR-0006 — Prisma schema split across 3 files¶
Status: Accepted Date: 2026-04-16 Author(s): Platform engineering
Context¶
The ebit-api data model contains 81 models, views, and enums across three PostgreSQL schemas (public, blackjack, speed_roulette). A single schema.prisma file would exceed 2,200 lines, mixing unrelated domains — user accounts and betting alongside blackjack table state alongside speed-roulette game rounds. Prisma 5.15+ supports the prismaSchemaFolder preview feature, which allows a directory of .prisma files to be treated as a single logical schema.
Decision¶
Split the schema into three files under libs/_prisma/src/schema/:
| File | Lines | Models/views | PostgreSQL schema |
|---|---|---|---|
api.prisma |
~1,976 | 70 | public |
blackjack.prisma |
~157 | 8 | blackjack |
speed_roulette.prisma |
~74 | 3 | speed_roulette |
The generator and datasource blocks live in api.prisma:1-14 with four preview features enabled:
generator client {
provider = "prisma-client-js"
previewFeatures = ["prismaSchemaFolder", "multiSchema", "views", "tracing"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["public", "blackjack", "speed_roulette"]
}
package.json:210-213 points Prisma at the directory (not a file):
Each model uses @@schema("blackjack") or @@schema("speed_roulette") to declare its PostgreSQL schema. Models in api.prisma default to public.
Alternatives considered¶
-
Single monolithic
schema.prisma. Rejected: 2,200+ lines with three unrelated domains interleaved. Merge conflicts are frequent when backend and game teams edit the same file. The file becomes unnavigable without IDE search. -
Separate Prisma clients per schema (3 generators, 3 clients). Rejected: cross-schema relations (e.g.,
SpeedRouletteBetreferencesUserinpublic) would require manual joins instead of Prisma's relation API. ThreePrismaClientinstances triple connection pool overhead and complicate transaction boundaries. -
One file per model (80+ files). Rejected: Prisma's
prismaSchemaFoldersupports it, but 80 files creates excessive filesystem noise. The natural split is by PostgreSQL schema — each file maps to one@@schema, which matches the database boundary and the team ownership boundary.
Consequences¶
- All
prismaCLI commands (generate,migrate,db push) must use--schema=libs/_prisma/src/schemaor rely on thepackage.jsonprisma.schemadirective. The npm scripts (db:migrate:dev,prisma:generate) already handle this — never callnpx prismadirectly. - Adding a model to the blackjack or speed-roulette domain means editing the domain-specific file, not
api.prisma. The@@schema()directive must match the file's domain. - The
prismaSchemaFolderpreview feature must remain enabled. Removing it reverts Prisma to expecting a single file, breaking the build. - Cross-schema Prisma relations work transparently at the query level but require PostgreSQL's cross-schema foreign key support — all three schemas live in the same database.
References¶
libs/_prisma/src/schema/api.prisma:1-14— generator + datasource with preview featureslibs/_prisma/src/schema/blackjack.prisma— 8 blackjack modelslibs/_prisma/src/schema/speed_roulette.prisma— 3 speed-roulette modelsebit-api/package.json:210-213—prisma.schemadirectory pointer