import type { MikroOrmModuleAsyncOptions } from '@mikro-orm/nestjs'; import { ConfigService } from '@nestjs/config'; import { PostgreSqlDriver } from '@mikro-orm/postgresql'; // import { defineConfig } from '@mikro-orm/postgresql'; import type { Logger } from '@nestjs/common'; import { MIKRO_ORM_QUERY_LOGGER } from '../common/constants'; import { mikroOrmQueryLoggerProvider } from '../common/providers/mikro-orm-logger.provider'; const dataBaseConfig: MikroOrmModuleAsyncOptions = { // entities: ['dist/**/*.entity.js'], // entitiesTs: ['src/**/*.entity.ts'], // dbName: 'your_db_name', // type: 'postgresql', // user: 'your_user', // password: 'your_password', // host: 'localhost', // port: 5432, // debug: true, inject: [ConfigService, MIKRO_ORM_QUERY_LOGGER], providers: [mikroOrmQueryLoggerProvider], useFactory: (configService: ConfigService, logger: Logger) => { const DB_PASS = configService.getOrThrow('DB_PASS'); const DB_USER = configService.getOrThrow('DB_USER'); const DB_HOST = configService.getOrThrow('DB_HOST'); const DB_PORT = configService.getOrThrow('DB_PORT'); const DB_NAME = configService.getOrThrow('DB_NAME'); const encodedPassword = encodeURIComponent(DB_PASS); const isProduction = configService.getOrThrow('NODE_ENV') === 'production'; return ({ // entities: ['dist/**/*.entity.js'], entitiesTs: ['src/**/*.entity.ts'], driver: PostgreSqlDriver, autoLoadEntities: true, dbName: DB_NAME, debug: !isProduction, clientUrl: `postgres://${DB_USER}:${encodedPassword}@${DB_HOST}:${DB_PORT}`, ensureDatabase: isProduction ? false : { forceCheck: true, create: true, schema: 'update', }, forceUtcTimezone: true, pool: { min: isProduction ? 5 : 2, max: isProduction ? 20 : 10, idleTimeoutMillis: 30000, acquireTimeoutMillis: 30000, reapIntervalMillis: 1000, createTimeoutMillis: 15000, destroyTimeoutMillis: 5000, }, logger: isProduction ? message => logger.log(message) : message => logger.debug(message), schemaGenerator: { // createForeignKey: !isProduction, disableForeignKeys: false, // createIndex: true, }, migrations: { path: './database/migrations', pathTs: './database/migrations', tableName: 'migrations', transactional: true, allOrNothing: true, dropTables: false, safe: true, emit: 'ts', }, connect: true, allowGlobalContext: true, driverOptions: { connection: { keepAlive: true, keepAliveInitialDelayMillis: 10000, statement_timeout: 60000, query_timeout: 60000, idle_in_transaction_session_timeout: 60000, connectionTimeoutMillis: 10000, application_name: configService.getOrThrow('DB_NAME'), }, connectionRetries: 5, connectionRetryDelay: 3000, validateConnection: (connection: any) => { try { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return !!(connection && !connection.closed); } catch (e: unknown) { logger.error(`Connection validation failed: ${(e as Error).message}`); return false; } }, poolErrorHandler: (err: Error) => { logger.error(`PostgreSQL pool error: ${err.message}`); if (err.message.includes('ECONNRESET') || err.message.includes('Connection terminated unexpectedly')) { logger.warn('Connection reset detected, will attempt to reconnect'); return true; } return false; }, }, }); }, }; export default dataBaseConfig;