53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { Injectable, OnModuleDestroy } from '@nestjs/common';
|
|
import { PrismaPg } from '@prisma/adapter-pg';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { requestContext } from '../common/request-context';
|
|
|
|
@Injectable()
|
|
export class PrismaService extends PrismaClient implements OnModuleDestroy {
|
|
constructor() {
|
|
const workerRole = process.env.CMPP_PROCESS_ROLE === 'worker';
|
|
const databaseUrl = workerRole
|
|
? process.env.API_WORKER_DATABASE_URL || process.env.DATABASE_URL
|
|
: process.env.DATABASE_URL;
|
|
const configuredPoolMax = Number(workerRole
|
|
? process.env.API_WORKER_DB_POOL_MAX ?? 8
|
|
: process.env.API_DB_POOL_MAX ?? 32);
|
|
const poolMax = Number.isInteger(configuredPoolMax) && configuredPoolMax > 0
|
|
? configuredPoolMax
|
|
: workerRole ? 8 : 32;
|
|
super({
|
|
adapter: new PrismaPg({
|
|
connectionString: databaseUrl
|
|
?? 'postgresql://cmpp:cmpp_password@localhost:5432/cmpp_platform?schema=public',
|
|
// API capacity must be reserved independently from the heavier Worker
|
|
// transactions; explicit bounds also protect PostgreSQL max_connections.
|
|
max: poolMax,
|
|
}),
|
|
});
|
|
const operationLog = this.operationLog;
|
|
Object.defineProperty(this, 'operationLog', {
|
|
value: new Proxy(operationLog, {
|
|
get(target, property, receiver) {
|
|
if (property === 'create') {
|
|
return (args: { data: Record<string, unknown> }) => {
|
|
const ipAddress = requestContext.getStore()?.ipAddress;
|
|
return (target.create as (input: unknown) => unknown)({
|
|
...args,
|
|
data: { ...args.data, ipAddress: typeof args.data.ipAddress === 'string' ? args.data.ipAddress : ipAddress },
|
|
});
|
|
};
|
|
}
|
|
const value = Reflect.get(target, property, receiver);
|
|
return typeof value === 'function' ? value.bind(target) : value;
|
|
},
|
|
}),
|
|
configurable: true,
|
|
});
|
|
}
|
|
|
|
async onModuleDestroy() {
|
|
await this.$disconnect();
|
|
}
|
|
}
|