83 lines
3.5 KiB
Markdown
83 lines
3.5 KiB
Markdown
# ORM Decision Record
|
|
|
|
Date: 2026-05-05
|
|
|
|
Status: Adopt Prisma 7; evaluate Drizzle later only as a separate ORM migration.
|
|
|
|
## Context
|
|
|
|
The project currently uses:
|
|
|
|
- `prisma`: `7.8.0`
|
|
- `@prisma/client`: `7.8.0`
|
|
- `@prisma/adapter-pg`: `7.8.0`
|
|
- Root-level Prisma schema and migrations via `prisma/`.
|
|
- `packages/db` as the database ownership package for generated-client imports and database command entrypoints.
|
|
|
|
The monorepo, API, worker and database package boundaries are still settling. Changing ORM at the same time would mix a structural migration with a persistence-layer migration and make regressions harder to isolate.
|
|
|
|
## Decision
|
|
|
|
Keep Prisma during the current architecture split and upgrade it to Prisma 7 in-place.
|
|
|
|
This means:
|
|
|
|
- Do not migrate to Drizzle during package-boundary work.
|
|
- Use the Prisma 7 generated TypeScript client entrypoints owned by `packages/db` at `packages/db/generated/prisma/client`.
|
|
- Route generate, migrate deploy, seed, build and typecheck through the `@toolctrl/db` package boundary while preserving the existing root Prisma schema and migrations.
|
|
- Treat any future Drizzle migration as a later, isolated decision with its own migration plan and verification.
|
|
|
|
## Revisit Triggers
|
|
|
|
Reopen this decision after the following are true:
|
|
|
|
- `packages/db` owns the generated database client boundary.
|
|
- Web, API and worker server-side imports use the database package rather than root-local Prisma imports.
|
|
- Build, seed, migration and deploy commands have one documented database entrypoint.
|
|
- Current Prisma 7 deprecation warnings are captured with exact command output and affected files.
|
|
- Query-heavy workflows have at least a basic regression checklist or test coverage.
|
|
|
|
## Evaluation Criteria
|
|
|
|
Compare staying on Prisma 7 and moving to Drizzle against the same criteria:
|
|
|
|
- Migration cost: schema, migrations, seed data, generated types and query call sites.
|
|
- Runtime behavior: query count, transaction support, connection behavior and server/worker compatibility.
|
|
- Build and deploy impact: client generation, Docker behavior, CI time and production startup.
|
|
- Type safety: generated model ergonomics, relation typing and validation boundaries.
|
|
- Package ownership: how cleanly the ORM fits inside `packages/db`.
|
|
- Operational risk: rollback path, data migration requirements and expected downtime.
|
|
- Team ergonomics: local setup, debugging, migrations and query review.
|
|
|
|
## Options For The Later Phase
|
|
|
|
### Stay On Prisma 7
|
|
|
|
Choose Prisma 7 if the current setup remains cheaper to maintain than rewriting the Prisma-heavy query layer.
|
|
|
|
Required proof:
|
|
|
|
- Prisma generate, build, seed and migrations work through `pnpm --filter @toolctrl/db ...` package commands.
|
|
- Docker and CI run without new ORM-specific warnings.
|
|
- Representative API, worker and web database paths pass verification.
|
|
|
|
### Drizzle
|
|
|
|
Choose Drizzle if explicit SQL-near queries, smaller runtime surface and package-boundary clarity justify rewriting current Prisma query code and generated-type assumptions.
|
|
|
|
Required proof:
|
|
|
|
- A representative domain is migrated end to end.
|
|
- Migration and seed conventions are documented.
|
|
- Query readability and performance are measurably better or simpler for the chosen domain.
|
|
- Rollback to Prisma remains possible until the migration is complete.
|
|
|
|
- A follow-up deadline or phase is assigned.
|
|
- No new code depends on root-local Prisma ownership.
|
|
|
|
## Non-Goals
|
|
|
|
- No runtime code change in this documentation foundation.
|
|
- No package dependency change.
|
|
- No Prisma schema, migration or Docker change.
|