import { PrismaClient } from '@prisma/client'; import { execSync } from 'node:child_process'; const TEST_DATABASE_URL = process.env['DATABASE_URL'] ?? 'postgresql://mcpctl:mcpctl_test@localhost:5433/mcpctl_test'; let prisma: PrismaClient | undefined; let schemaReady = false; export function getTestClient(): PrismaClient { if (!prisma) { prisma = new PrismaClient({ datasources: { db: { url: TEST_DATABASE_URL } }, }); } return prisma; } export async function setupTestDb(): Promise { const client = getTestClient(); // Only push schema once per process (multiple test files share the worker) if (!schemaReady) { execSync('npx prisma db push --force-reset --skip-generate', { cwd: new URL('..', import.meta.url).pathname, env: { ...process.env, DATABASE_URL: TEST_DATABASE_URL, // Consent required when Prisma detects AI agent context. // This targets the ephemeral test database (tmpfs-backed, port 5433). PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION: 'yes', }, stdio: 'pipe', }); schemaReady = true; } return client; } export async function cleanupTestDb(): Promise { if (prisma) { await prisma.$disconnect(); prisma = undefined; } } export async function clearAllTables(client: PrismaClient): Promise { // Delete in order respecting foreign keys await client.auditLog.deleteMany(); await client.mcpInstance.deleteMany(); await client.secret.deleteMany(); await client.session.deleteMany(); await client.project.deleteMany(); await client.mcpServer.deleteMany(); await client.mcpTemplate.deleteMany(); await client.user.deleteMany(); }