Skip to content

Merge main into preprod: Prisma 7 + mesh 2.0 migration + test-infra fixes#269

Open
QSchlegel wants to merge 13 commits into
preprodfrom
staging/preprod-prisma7-mesh2
Open

Merge main into preprod: Prisma 7 + mesh 2.0 migration + test-infra fixes#269
QSchlegel wants to merge 13 commits into
preprodfrom
staging/preprod-prisma7-mesh2

Conversation

@QSchlegel

Copy link
Copy Markdown
Collaborator

Brings main into preprod and completes the two breaking dependency upgrades main introduced, plus the test-infra work needed to keep the suite green. This unblocks PR #229 (preprod → main), which currently can't merge due to conflicts.

All gates green

  • tsc --noEmit: 0 errors
  • test:ci: CJS 357 + ESM 48 passed, 0 failures
  • next build: success

What's included

Conflict resolution (16 files) — workflows, jest config, package.json, prisma schema, several test + component files. Notable calls: kept preprod's backwards-compat nostrKey, defensive txJson parse (#211), extracted buildStakingActionConfigs; combined async getTxBuilder (cost models) with useCslSerializer; dropped unused @hookform/resolvers + @jinglescode/nostr-chat-plugin.

Prisma 6 → 7 migration (main bumped the version but never migrated):

  • prisma.config.ts for CLI connection URLs; removed url/directUrl from schema
  • @prisma/adapter-pg driver wired into src/server/db.ts (Prisma 7 requires an adapter)
  • shared createPrismaClient() factory for 6 CI scenario scripts that constructed new PrismaClient() directly
  • fixed the @prisma/client/runtime/library Decimal import

Mesh react 2.0 (redesigned, incompatible wallet API): a useMeshWallet bridge sources a 1.9 IWallet from react 2.0's connection so all signing/tx code keeps the exact 1.9 API — deliberately avoiding the signData(payload, address)signData(address, data) argument-swap footgun. Null-guards added at call sites.

Test infrastructure: the suite mixes jest.mock (CJS) and unstable_mockModule (ESM) tests, which the upgrades pushed past breaking under a single jest mode. Split into two configs from a shared base (jest.shared.mjsjest.config.mjs CJS + jest.esm.config.mjs ESM), run via scripts/run-tests.mjs. Coverage is CJS-only (per-file threshold lives there; v8 coverage + native ESM crashes), and collectCoverageFrom excludes import-side-effect modules (src/server/**, src/lib/security/**) that polluted mocked tests. trpc/* DB integration tests stay in their own workflow.

Follow-ups / watch items

  • Runtime validation needed before promoting to prod: the mesh-2.0 bridge keeps the 1.9 signing API but the wallet object is re-sourced — exercise a real signing/voting flow. The Prisma 7 pg-adapter connection on Supabase + Vercel serverless should be smoke-tested (DIRECT_URL for migrations bypasses pgbouncer).
  • The bridge is a pragmatic interim; a full migration to the react-2.0 wallet API can follow later.

🤖 Generated with Claude Code

QSchlegel and others added 3 commits June 8, 2026 14:02
Snapshot on staging branch for deeper test-infra testing. Captures the full
resolution of PR #229's 16 conflicts plus two breaking dependency upgrades
from main that required migration:

- Prisma 6->7: add prisma.config.ts, drop schema url/directUrl, wire the
  @prisma/adapter-pg driver in db.ts, fix Decimal import.
- mesh react 2.0: useMeshWallet bridge sources a 1.9 IWallet from react 2.0's
  connection so signing/tx code keeps the 1.9 API (avoids the signData arg
  swap). Null-guards added at call sites.

tsc is green (0 errors). Known WIP: jest suite has an ESM/CJS mock-mode
conflict exposed by the upgrades (jest.mock vs unstable_mockModule) - test
infra fix in progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fix 6 CI-scenario `new PrismaClient()` sites that Prisma 7 rejects (no
  adapter): add scripts/ci/framework/prismaClient.ts factory and route all
  construction through it.
- Add @/env jest stub (src/__tests__/__mocks__/env.cjs) + moduleNameMapper so
  server modules load under jest without the ESM-only @t3-oss validator.
- Fix botAuth jsonwebtoken mock to expose `default` (esModuleInterop default
  import was undefined).
- Keep preprod's plain-jest invocation (revert the --experimental-vm-modules
  change, which broke jest.mock-based tests).

Bot gate now 128/132; full suite 373/421. Remaining failures are
unstable_mockModule (ESM) tests that don't apply under plain jest - mock-style
unification still pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The suite mixes two mutually-exclusive jest module modes (jest.mock = CJS,
unstable_mockModule/import.meta/ESM-deps = ESM). The mesh 2.0 + Prisma 7
upgrades tripped the ESM-loading paths that preprod's older deps avoided, so
plain jest could no longer run both. Resolved by running two jest invocations
from a shared base (jest.shared.mjs):

- jest.config.mjs (CJS, plain jest): all tests except the 8 ESM files and the
  trpc/* DB integration tests (their own workflow).
- jest.esm.config.mjs (ESM, --experimental-vm-modules): the 8 unstable_mockModule
  / import.meta files.
- scripts/run-tests.mjs runs both and forwards args; test/test:ci/test:bot:*
  go through it. --runInBand makes the gate deterministic; --coverage is
  CJS-only (v8 coverage + native ESM crashes, and the per-file threshold lives
  in the CJS config).
- collectCoverageFrom excludes src/server/** and src/lib/security/** — jest
  force-loads uncovered files for coverage and their import-time side effects
  polluted mocked tests (freeUtxos).
- Fix signTransaction.test @meshsdk/core mock to export resolveStakeKeyHash
  (ESM static linking needs it).

Result: test:ci green (CJS 357 + ESM 48, 0 failures), tsc 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
multisig Ready Ready Preview, Comment Jun 8, 2026 4:16pm

Request Review

My npm 11 lock regen deduped @simplewebauthn/browser to 13.3.0, which doesn't
satisfy @auth/core's ^9.0.1 — CI (npm 10, node 20) rejected `npm ci` as out of
sync. Rebuilt the lock with npm 10 (--package-lock-only) to restore the nested
9.0.1 entry under @auth/prisma-adapter. Key versions unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The merged setup.ts (from main) freezes the clock (Date.now/new Date) for unit
determinism. tRPC integration tests hit a real Postgres and Prisma 7 sets
createdAt client-side, so a frozen clock gives identical timestamps and breaks
ordering assertions. Run test:trpc via a dedicated config that layers a
real-timers setup over the global one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@meshsdk/core-csl 1.9 pulls whisky-evaluator, which ships a .wasm the Node
server runtime can't load when the package is externalized
(ERR_UNKNOWN_FILE_EXTENSION ".wasm" → createWallet 500). Add both to
transpilePackages so Next bundles them and applies its WebAssembly handling.

Candidate fix — needs the v1 smoke / Vercel deploy to confirm the WASM loads at
runtime (the local build still warns about the .wasm modules).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The multisig-v1-smoke ran the app via `next dev`, which mis-resolves the
@meshsdk/core-csl / whisky-evaluator WASM path at runtime (createWallet 500).
Build the app in Dockerfile.ci and serve it with `next start` so the smoke
exercises the same production output Vercel deploys (and starts instantly
instead of compiling routes on demand). Copy prisma.config.ts before npm ci so
the postinstall generate sees the Prisma 7 config; set a dummy DATABASE_URL for
build-time module evaluation (compose overrides it at runtime).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mesh 2.0's whisky-evaluator (WASM) and Prisma 7's @prisma/dev/streams-local
require node >=22. On node 20 the production `next build` fails resolving the
whisky-evaluator WASM export (and streams-local warns EBADENGINE). node 22
matches what Vercel and local builds use. Bumps the app Dockerfiles and the
node-20 workflows; the node-18 scheduled jobs are left for a separate pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The production `next build` fails under node:22-alpine resolving the
@meshsdk/core-csl / whisky-evaluator WebAssembly export
(`does not provide an export named 'js_evaluate_tx_scripts'`) — a musl/WASM
incompatibility. The same build succeeds on glibc (local macOS + Vercel).
Switch the CI Dockerfiles to node:22-slim (Debian) and apt for the postgres
client.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
webpack can't statically resolve whisky-evaluator's WASM-backed ESM named
export during `next build` on Linux (passes on macOS), so transpiling it broke
the Docker/CI build. Move whisky-evaluator + @sidan-lab/whisky-js-nodejs to
serverExternalPackages so Node `require`s their cjs/ build at runtime (loads the
WASM synchronously) and webpack never analyzes the ESM. Keep @meshsdk/core-csl
transpiled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The production build's page-data worker (and `next start`) load @meshsdk/core-csl
as a native ESM external, which `import`s whisky-evaluator's WASM-backed exports.
node's ESM loader needs --experimental-wasm-modules to resolve them, otherwise:
`whisky-evaluator does not provide an export named 'js_evaluate_tx_scripts'`.
Set via NODE_OPTIONS so it covers both `next build` and the runtime `next start`.
Validated: the Dockerfile.ci image now builds end-to-end on linux.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The app build (with the WASM-aware production next build) succeeds and the app
starts healthy — but the bootstrap step rebuilds the ci-runner service from the
same Dockerfile, re-running next build (which ci-runner doesn't need; it only
runs tsx scripts) and failing. Split Dockerfile.ci into a base stage (deps +
source) and an app stage (base + build); ci-runner targets base so the
bootstrap runs the real runtime createWallet test against the healthy app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ci-runner runs tsx scripts that import the Mesh SDK (core-csl -> whisky
WASM), so it needs --experimental-wasm-modules too — not just the app build.
Move NODE_OPTIONS to the shared base stage. Validated in a Linux container:
`@meshsdk/core-csl` now imports cleanly (was: "does not provide an export named
'js_evaluate_tx_scripts'").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant