refactor(db): migrate ORM from Drizzle to Prisma#108
Open
jee7s wants to merge 1 commit into
Open
Conversation
Replaces Drizzle ORM with Prisma 7 across @arbor/db while preserving the public store contract (PostgresUrlStore/ConfigStore/AuditStore + SQLite equivalents, createStores factory, and the UrlEntry/AuditRecord types) so no consuming package changes. Dual-database support is kept via two Prisma schemas that generate separate clients (prisma/postgres + prisma/sqlite) into packages/db/generated, selected at runtime by createStores() as before. Prisma 7 has no embedded query engine, so connections go through driver adapters: @prisma/adapter-pg for Postgres and @prisma/adapter-better-sqlite3 for SQLite. The SQLite path keeps its zero-migration, schema-on-first-connect behaviour (including :memory:) by bootstrapping the DDL over the adapter's single connection; timestampFormat "iso8601" preserves the ISO-string timestamp contract. Tooling: - db:generate -> prisma generate (both schemas); postinstall regenerates clients on every install so CI's non-build jobs and Docker have them. - db:migrate -> prisma migrate deploy; Postgres migrations live in prisma/postgres/migrations (baseline 20260608000000_init mirrors the prior Drizzle schema). Existing DBs must baseline once via `prisma migrate resolve` (see docs/deployment.md). - Dockerfile migrate stage now runs prisma migrate deploy; builder copies the schemas before install and runtime copies the generated clients. Generated clients are gitignored. Docs updated to reference Prisma. Verified: full build, 255 unit tests, 27 SQLite dev/integration tests, and the Lambda bundle (Prisma WASM query compiler inlined, handler loads, pg query path initialises). Live Postgres roundtrip is exercised by CI's Postgres job. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces Drizzle ORM with Prisma 7 across
@arbor/db, preserving the public store contract so no consuming package changes:PostgresUrlStore/PostgresConfigStore/PostgresAuditStore(and SQLite equivalents), thecreateStores()factory, and theUrlEntry/AuditRecordtypes are all unchanged. The agent, lambda, logger, and mcp-url-fetcher packages are untouched.Dual-database design (preserved)
The existing "Postgres in prod, SQLite for dev/tests" split is kept. Prisma binds a client to one provider at generate time, so this uses two schemas generating two clients:
prisma/postgres/schema.prismagenerated/postgres@prisma/adapter-pgprisma/sqlite/schema.prismagenerated/sqlite@prisma/adapter-better-sqlite3createStores()selects the client by connection string exactly as before. Prisma 7 has no embedded query engine (it uses a WASM query compiler + driver adapters).SQLite specifics
The zero-migration, schema-on-first-connect behaviour is retained — including
:memory:. The better-sqlite3 adapter keeps a single connection, so the bootstrap DDL (run via$executeRawUnsafe) applies to the same connection the client queries.timestampFormat: "iso8601"preserves the ISO-stringadded_at/created_atcontract.Tooling changes
db:generate→prisma generatefor both schemas. Apostinstallhook regenerates the clients on everynpm install/npm ci, so CI's non-build jobs (unit, dev) and Docker always have them. Generated clients are gitignored (packages/db/generated/).db:migrate→prisma migrate deploy. Postgres migrations now live inprisma/postgres/migrations/; the baseline20260608000000_initmirrors the previous Drizzle schema.prisma migrate deploy; the builder copies schemas before install (for the postinstall generate) and the runtime stage copies the generated clients.drizzle-orm,drizzle-kit,postgres. Added:@prisma/client,prisma,@prisma/adapter-pg,@prisma/adapter-better-sqlite3.Existing prod/dev databases already have these tables. Before the first
migrate deploy, mark the baseline as applied so Prisma doesn't try to recreate them:Fresh databases need no baselining. Documented in
docs/deployment.md.Verification
npm run build)npm run test)npm run test:dev) —:memory:, file-backed persistence, Boolean/DateTime/ISO roundtrip, autoincrement ids, ordering, null model.wasm), bundled handler loads, Postgres query path initialises (connection-only failure against a dead DB, i.e. the compiler works)migrate deployagainst a real DBNotes for reviewers
@map), so the DB schema is unchanged.deleteusesdeleteManyto keep the no-throw-on-missing semantics Drizzle had.drizzle-kit migrate→prisma migrate deploy).🤖 Generated with Claude Code