chore(deps): upgrade Prisma 6.19 -> 7.8.0 (Rust-free client + mariadb adapter)

prisma / @prisma/client 6.19.2 -> 7.8.0; added @prisma/adapter-mariadb 7.8.0 and
mariadb 3.5.2 (the runtime driver).

Prisma 7 breaking changes handled (verified via Prisma's own tooling — the
official upgrade-guide summary had hallucinated package names, so I confirmed
everything against `prisma validate`/`generate` and the installed type defs):

- The Rust query engine is removed; the runtime connection is now made through a
  driver adapter. src/config/database.ts wires PrismaMariaDb, parsing
  DATABASE_URL into an explicit mariadb pool config so the literal `@` in our
  password (which a naive connection-string parser mishandles) is correct.
- datasource `url` is no longer allowed in schema.prisma -> moved to a new
  prisma.config.ts (schema + datasource.url + migrations.seed). Prisma 7 no
  longer auto-loads .env, so the config does `import "dotenv/config"`.
- The deprecated package.json#prisma seed config was removed (now in the config).
- seed.ts and the two maintenance scripts now use the shared adapter-wired client.

The legacy `prisma-client-js` generator STILL works under v7 (generates to
@prisma/client as before), so NO import-path changes were needed across the 16
@prisma/client import sites — switching to the new prisma-client/output generator
is not required for us. No prisma.$use() middleware exists. Node 24 / TS 5.9
exceed the v7 minimums (20.19 / 5.4).

No migrations were run (your DBs are untouched); removing datasource.url is a
config change, not DDL, so this phase needs no new migration.

Gates: tsc 0 | build 0 | vitest 247/247 against app_test (proves the mariadb
adapter works at runtime, incl. raw SELECT...FOR UPDATE locking and Decimal/VAT)
| eslint 0 errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-09 07:06:02 +02:00
parent 6147131aad
commit 63192dc781
8 changed files with 808 additions and 173 deletions

916
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,9 +25,6 @@
"format": "prettier --write .", "format": "prettier --write .",
"format:check": "prettier --check ." "format:check": "prettier --check ."
}, },
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
@@ -47,7 +44,8 @@
"@fastify/static": "^9.0.0", "@fastify/static": "^9.0.0",
"@mui/material": "^7.3.11", "@mui/material": "^7.3.11",
"@mui/x-date-pickers": "^8.29.0", "@mui/x-date-pickers": "^8.29.0",
"@prisma/client": "^6.19.2", "@prisma/adapter-mariadb": "^7.8.0",
"@prisma/client": "^7.8.0",
"@tanstack/react-query": "^5.100.5", "@tanstack/react-query": "^5.100.5",
"@types/jsdom": "^28.0.1", "@types/jsdom": "^28.0.1",
"bcryptjs": "^3.0.3", "bcryptjs": "^3.0.3",
@@ -60,10 +58,11 @@
"jsdom": "^29.0.2", "jsdom": "^29.0.2",
"jsonwebtoken": "^9.0.3", "jsonwebtoken": "^9.0.3",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"mariadb": "^3.5.2",
"node-cron": "^4.2.1", "node-cron": "^4.2.1",
"nodemailer": "^8.0.2", "nodemailer": "^8.0.2",
"otpauth": "^9.5.0", "otpauth": "^9.5.0",
"prisma": "^6.19.2", "prisma": "^7.8.0",
"puppeteer": "^24.40.0", "puppeteer": "^24.40.0",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "^19.2.7", "react": "^19.2.7",

16
prisma.config.ts Normal file
View File

@@ -0,0 +1,16 @@
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
// Prisma 7 moved the datasource connection URL and seed config out of
// schema.prisma / package.json into this file. `import "dotenv/config"` is
// required because Prisma 7 no longer auto-loads .env. The runtime database
// connection itself is made via the driver adapter in src/config/database.ts.
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
migrations: {
seed: "tsx prisma/seed.ts",
},
});

View File

@@ -4,7 +4,6 @@ generator client {
datasource db { datasource db {
provider = "mysql" provider = "mysql"
url = env("DATABASE_URL")
} }
model attendance { model attendance {

View File

@@ -1,7 +1,8 @@
import { PrismaClient } from "@prisma/client"; import "dotenv/config";
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
// Use the shared, adapter-wired client (Prisma 7 needs a driver adapter).
const prisma = new PrismaClient(); // dotenv is imported first so DATABASE_URL is set before database.ts reads it.
import prisma from "../src/config/database";
const PERMISSIONS: { const PERMISSIONS: {
name: string; name: string;

View File

@@ -6,10 +6,9 @@
import "../src/config/env"; import "../src/config/env";
import fs from "fs"; import fs from "fs";
import { PrismaClient } from "@prisma/client";
import { nasFinancialsManager } from "../src/services/nas-financials-manager"; import { nasFinancialsManager } from "../src/services/nas-financials-manager";
// Shared adapter-wired client (Prisma 7 needs a driver adapter).
const prisma = new PrismaClient(); import prisma from "../src/config/database";
async function main() { async function main() {
if (!nasFinancialsManager.isConfigured()) { if (!nasFinancialsManager.isConfigured()) {

View File

@@ -1,7 +1,7 @@
import { PrismaClient } from "@prisma/client"; import "dotenv/config";
import { decryptWithKey, encryptWithKey } from "../src/utils/encryption"; import { decryptWithKey, encryptWithKey } from "../src/utils/encryption";
// Shared adapter-wired client (Prisma 7 needs a driver adapter).
const prisma = new PrismaClient(); import prisma from "../src/config/database";
// Reuse the dual-format decrypt/encrypt from src/utils/encryption.ts so this // Reuse the dual-format decrypt/encrypt from src/utils/encryption.ts so this
// script handles BOTH wire formats: the TS `hex:hex:hex` form and the // script handles BOTH wire formats: the TS `hex:hex:hex` form and the

View File

@@ -1,6 +1,27 @@
import { PrismaClient } from "@prisma/client"; import { PrismaClient } from "@prisma/client";
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
// Prisma 7 removed the Rust query engine; the runtime DB connection is now made
// through a driver adapter. PrismaMariaDb wraps the `mariadb` driver (which is
// MySQL-wire compatible). We parse DATABASE_URL ourselves and pass an explicit
// pool config rather than the raw connection string, so a literal `@` in the
// password (which a naive connection-string parser would mishandle) is handled
// correctly.
function mariadbAdapterFromUrl(rawUrl: string): PrismaMariaDb {
const u = new URL(rawUrl);
return new PrismaMariaDb({
host: u.hostname,
port: u.port ? Number(u.port) : 3306,
user: decodeURIComponent(u.username),
password: decodeURIComponent(u.password),
database: u.pathname.replace(/^\//, ""),
});
}
const adapter = mariadbAdapterFromUrl(process.env.DATABASE_URL as string);
const prisma = new PrismaClient({ const prisma = new PrismaClient({
adapter,
log: process.env.APP_ENV === "local" ? ["warn", "error"] : ["error"], log: process.env.APP_ENV === "local" ? ["warn", "error"] : ["error"],
}); });