Skip to content

epic: migrate NetScript DB layer to Prisma Next (Postgres-first pilot, deferred) #313

Description

@rickylabs

Summary

Adopt Prisma Next (prisma/prisma-next, v0.14.0, Early Access) for NetScript's DB layer as an
opt-in, additive Postgres engine path running alongside the existing classic Prisma 7 +
custom Zod-generator layer. This is Option A (Postgres-first pilot), staged to widen as upstream
matures — not a cutover.

Implementation is DEFERRED. This will not land this week, likely not this month. The value
delivered now is a locked, build-ready design + a live upstream gap tracker, so that the
moment a precondition clears we execute a pre-designed slice instead of re-researching a
fast-moving Early-Access surface. Full spec:
.llm/tmp/run/epic-prisma-next-migration--supervisor/spec.md (build-ready, 12 sections).

Child of the Road-to-0.0.1-stable umbrella epic.

Why Prisma Next (the real wins)

Why NOT a full cutover (verified against source @ v0.14.0)

Two of the epic's original premises do not hold on Early Access today:

  1. Standard Schema output is NOT a core feature. Prisma Next ships no per-model validator
    codegen
    — only a not-yet-shipped consumer-library pattern (arktype reference). But the custom
    Zod generator is a hard build-dep of every scaffolded service (@database/zod CRUD barrel →
    createCrudContract). So the Zod generator cannot be deleted until a validator consumer
    exists — we build our own over the contract IR (see spec §5).
  2. Multi-DB coverage is partial. Postgres 17 (GA-track) + MongoDB supported; SQLite is Node
    node:sqlite path-only; MySQL planned (no date); Turso/libsql absent; MSSQL absent &
    unplanned
    . NetScript ships Postgres + MySQL + MSSQL + SQLite. Only Postgres can move today.

Plus: Deno is best-effort tier-2 (Node 24 primary; every DB path pulls a Node builtin/native
dep) against NetScript's Deno-native runtime → a Node control-plane split is required (spec §4.4).

Scope

  • In: an opt-in postgres × prisma-next engine path (--impl prisma-next); a defineContract
    TS-schema workspace shape; a Node control-plane for migrate/init/apply; our own
    contract.json → Zod barrel validator consumer
    emitting the exact CRUD alias names scaffolded
    services already consume (behind a delegation seam to a future upstream consumer); a ./zod compat
    alias so userland contract.ts compiles unchanged; a new POSTGRES_PRISMA_NEXT scaffold.runtime
    axis added alongside (never replacing) the classic Postgres axis.
  • Out (non-goals): no cutover; no MSSQL/MySQL/SQLite move to Prisma Next; no deletion of any
    classic generator file until its precondition is met; no production dependency on Prisma Next; no
    Turso work (nothing is wired today); no changes to service/contracts/sdk/kv/plugin-*-core
    public surfaces (all verified schema-agnostic).

Multi-DB guarantee (holds throughout)

Engine Path today Prisma Next path Precondition Fallback
postgres classic (E2E) this pilot validator consumer (gap b) stay classic (default)
mysql classic (E2E) later MySQL engine (gap c) + b stay classic indefinitely
mssql classic later MSSQL support (gap a, unplanned) stay classic — NOT dropped
sqlite classic (scaffold-only) later SQLite promotion + Deno-viable binding stay classic
turso/libsql not wired n/a libsql driver (gap d) no-op — nothing to preserve

At every phase each engine keeps at least its classic column green. The pilot only ever adds a
Postgres column. MSSQL is not dropped — "MSSQL-in-Prisma-Next" is tracked precondition (a).

Delete-list (precondition-gated — nothing removed in the pilot)

Removed only after (a) our validator consumer ships + green, (b) the pilot passes scaffold.runtime,
and — for the default to flip — (c) all five gaps closed. Wave B (repo-wide) waits until no engine
depends on the classic lane.

Grounded Wave-B delete-list
  • packages/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.ts
  • packages/cli/src/kernel/assets/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.ts.template
  • packages/cli/src/kernel/assets/database/zod-generator.config.json.template
  • packages/database/tests/zod-crud-barrel_test.ts
  • db:zod / db:fix-zod / db:patch-client tasks + the zod generator block in schema.prisma.template

KEEP: migrate.ts + retry (classic engines), all adapters, ports, extensions, tracing,
@netscript/prisma-adapter-mysql.

Acceptance criteria

  • Opt-in scaffold (--db postgres --impl prisma-next) does init/generate/seed with no
    schema-engine subprocess
    and no retry activation.
  • Scaffolded service contract.ts type-checks unchanged via the ./zod compat alias.
  • deno task e2e:cli run scaffold.runtime --cleanup --format pretty green on both the new pilot
    Postgres axis and the classic axes (classic byte-for-byte unchanged).
  • Quality trio green (root deno task check + lint + fmt:check); arch:check green (no heavy
    Node deps in the default Deno graph); type soundness (no any beyond the two accepted casts).

Staging (each a focused PR; none runs until scheduled)

  1. Research + design — DONE (this issue + spec + gap tracker).
  2. Deno-compat + control-plane spike (throwaway) → picks data-plane architecture 4a vs 4b.
  3. @netscript/prisma-next-validators (the validator consumer — unblocks everything).
  4. @netscript/database-next + PrismaNextPostgresAdapter (port-conformant, subpath-only heavy deps).
  5. Scaffolder pilot path + CLI --impl prisma-next.
  6. scaffold.runtime POSTGRES_PRISMA_NEXT axis (the expensive merge gate).
    6+. Widen per gap tracker as upstream lands each precondition.

Upstream gap tracker (watch-for — each fires a pre-scoped slice on close)

Re-check mechanism: monthly (or on any .llm/tools/deps/ dependency-review pass) fetch
api.github.com/repos/prisma/prisma-next/releases + roadmap/changelog, compare against the pinned
v0.14.0 baseline, re-run each gap's status check, flip checkboxes and schedule slices on close. Any
version bump re-runs the Phase-1 Deno-compat spike before further work.

Open questions for the user

  1. Default-flip policy — at what upstream milestone does the default scaffold move to Prisma
    Next for Postgres? (Proposal: not before beta + validator consumer + Postgres GA.)
  2. Matrix policy — is a Postgres-only Prisma Next path acceptable long-term while other engines
    stay classic (this spec's assumption), or must all engines move together?
  3. Validator branch — confirm building our own consumer (branch ii) with a delegation seam vs
    waiting for upstream. (Recommendation: build ii.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions