import { PrismaClient } from '@prisma/client'; import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'; import 'dotenv/config'; declare global { // allow global `var` declarations // eslint-disable-next-line no-var var prisma: PrismaClient | undefined; } const mode = process.env.APP_MODE || 'dev'; console.log(`[Prisma] Initializing in ${mode.toUpperCase()} mode`); let dbPath: string; switch (mode) { case 'test': dbPath = process.env.DATABASE_URL_TEST || './test.db'; break; case 'prod': dbPath = process.env.DATABASE_URL_PROD || './prod.db'; break; case 'dev': default: dbPath = process.env.DATABASE_URL_DEV || './dev.db'; break; } // Remove 'file:' prefix if present if (dbPath.startsWith('file:')) { dbPath = dbPath.slice(5); } console.log('Initializing Prisma Client with database:', dbPath); let prisma: PrismaClient; // In Prisma 7, PrismaBetterSqlite3 is a factory. // We use a wrapper to intercept the connection and disable WAL mode // for NAS/Network share compatibility (journal_mode = DELETE). try { const factory = new PrismaBetterSqlite3({ url: dbPath }); const adapterWrapper = { provider: 'sqlite', adapterName: '@prisma/adapter-better-sqlite3', async connect() { const adapter = (await factory.connect()) as any; if (adapter.client) { console.log('[Prisma] Setting journal_mode = DELETE for NAS compatibility'); adapter.client.pragma('journal_mode = DELETE'); } return adapter; }, async connectToShadowDb() { const adapter = (await factory.connectToShadowDb()) as any; if (adapter.client) { adapter.client.pragma('journal_mode = DELETE'); } return adapter; } }; prisma = global.prisma || new PrismaClient({ adapter: adapterWrapper as any, }); } catch (e: any) { console.error('Failed to initialize Prisma Client:', e.message); process.exit(1); } if (process.env.NODE_ENV !== 'production') { global.prisma = prisma; } export default prisma;