import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; import { InjectRedis } from '@nestjs-modules/ioredis'; import Redis from 'ioredis'; export interface SystemHealthResponse { status: 'ok' | 'error'; timestamp: string; environment: string; database: { host: string; port: number; database: string; user: string; status: 'connected' | 'disconnected'; error?: string; }; redis: { host: string; port: number; status: 'connected' | 'disconnected'; error?: string; }; } @Injectable() export class SystemService { constructor( private configService: ConfigService, @InjectDataSource() private dataSource: DataSource, @InjectRedis() private redis: Redis, ) {} async getHealth(): Promise { const dbHealth = await this.checkDatabase(); const redisHealth = await this.checkRedis(); return { status: dbHealth.status === 'connected' && redisHealth.status === 'connected' ? 'ok' : 'error', timestamp: new Date().toISOString(), environment: this.configService.get('NODE_ENV') || 'development', database: dbHealth, redis: redisHealth, }; } private async checkDatabase() { const config = { host: this.configService.get('POSTGRES_HOST') || 'unknown', port: parseInt(this.configService.get('POSTGRES_PORT')) || 5432, database: this.configService.get('POSTGRES_DB') || 'unknown', user: this.configService.get('POSTGRES_USER') || 'unknown', }; try { await this.dataSource.query('SELECT 1'); return { ...config, status: 'connected' as const }; } catch (error) { return { ...config, status: 'disconnected' as const, error: error.message }; } } private async checkRedis() { const redisUrl = this.configService.get('REDIS_URL') || ''; let host = this.configService.get('REDIS_HOST') || 'unknown'; let port = parseInt(this.configService.get('REDIS_PORT')) || 6379; if (redisUrl) { try { const url = new URL(redisUrl); host = url.hostname; port = parseInt(url.port) || 6379; } catch {} } try { const pong = await this.redis.ping(); return { host, port, status: pong === 'PONG' ? 'connected' as const : 'disconnected' as const, }; } catch (error) { return { host, port, status: 'disconnected' as const, error: error.message }; } } }