feat(v2.3): 完成关系表写入闭环

This commit is contained in:
Script Generator
2026-07-03 13:28:59 +08:00
parent e9ff986bac
commit bba02775dc
17 changed files with 732 additions and 18 deletions

View File

@@ -0,0 +1,29 @@
import { resolvePrismaSlowQueryThreshold, shouldLogPrismaQuery } from './prisma-monitoring';
describe('prisma monitoring helpers', () => {
const originalEnv = process.env.PRISMA_SLOW_QUERY_MS;
afterEach(() => {
process.env.PRISMA_SLOW_QUERY_MS = originalEnv;
});
it('uses a safe default threshold when env is missing or invalid', () => {
delete process.env.PRISMA_SLOW_QUERY_MS;
expect(resolvePrismaSlowQueryThreshold()).toBe(300);
process.env.PRISMA_SLOW_QUERY_MS = '-1';
expect(resolvePrismaSlowQueryThreshold()).toBe(300);
});
it('uses a positive configured threshold', () => {
process.env.PRISMA_SLOW_QUERY_MS = '750';
expect(resolvePrismaSlowQueryThreshold()).toBe(750);
});
it('detects slow query events at or above the threshold', () => {
expect(shouldLogPrismaQuery(299, 300)).toBe(false);
expect(shouldLogPrismaQuery(300, 300)).toBe(true);
expect(shouldLogPrismaQuery(450, 300)).toBe(true);
});
});

View File

@@ -0,0 +1,11 @@
const DEFAULT_PRISMA_SLOW_QUERY_MS = 300;
export function resolvePrismaSlowQueryThreshold(): number {
const parsed = Number(process.env.PRISMA_SLOW_QUERY_MS);
if (!Number.isFinite(parsed) || parsed <= 0) return DEFAULT_PRISMA_SLOW_QUERY_MS;
return Math.floor(parsed);
}
export function shouldLogPrismaQuery(durationMs: number, thresholdMs: number): boolean {
return durationMs >= thresholdMs;
}

View File

@@ -1,11 +1,24 @@
import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { resolvePrismaSlowQueryThreshold, shouldLogPrismaQuery } from './prisma-monitoring';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
private readonly logger = new Logger(PrismaService.name);
private readonly slowQueryThresholdMs = resolvePrismaSlowQueryThreshold();
private connected = false;
constructor() {
super({
log: [{ emit: 'event', level: 'query' }],
});
(this as any).$on('query', (event: { duration: number; query: string }) => {
if (!shouldLogPrismaQuery(event.duration, this.slowQueryThresholdMs)) return;
this.logger.warn(`Slow Prisma query: ${event.duration}ms ${event.query}`);
});
}
async onModuleInit() {
try {
await this.$connect();