diff --git a/package.json b/package.json index c83adc9..c9028df 100644 --- a/package.json +++ b/package.json @@ -10,13 +10,15 @@ }, "dependencies": { "@nestjs/common": "^10.4.22", + "@nestjs/config": "^3.2.3", "@nestjs/core": "^10.4.22", "@nestjs/platform-express": "^10.4.22", + "@nestjs/typeorm": "^10.0.2", "@stellar/stellar-sdk": "^11.0.0", "pg": "^8.11.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.2", - "typeorm": "^0.3.0" + "typeorm": "^0.3.20" }, "devDependencies": { "@nestjs/cli": "^11.0.16", diff --git a/src/app.module.ts b/src/app.module.ts index 8662803..66490a7 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { HealthModule } from './health/health.module'; @Module({ - imports: [], + imports: [HealthModule], controllers: [AppController], providers: [AppService], }) diff --git a/src/database.providers.ts b/src/database.providers.ts new file mode 100644 index 0000000..36c4cf3 --- /dev/null +++ b/src/database.providers.ts @@ -0,0 +1,21 @@ +import { DataSource } from 'typeorm'; + +export const databaseProviders = [ + { + provide: 'DATA_SOURCE', + useFactory: async () => { + const dataSource = new DataSource({ + type: 'postgres', + host: process.env.DB_HOST || 'localhost', + port: parseInt(process.env.DB_PORT) || 5432, + username: process.env.DB_USERNAME || 'postgres', + password: process.env.DB_PASSWORD || 'password', + database: process.env.DB_DATABASE || 'tradeflow', + entities: [`${__dirname}/**/*.entity{.ts,.js}`], + synchronize: process.env.NODE_ENV === 'development', + }); + + return dataSource.initialize(); + }, + }, +]; diff --git a/src/health/health.controller.ts b/src/health/health.controller.ts new file mode 100644 index 0000000..52738dd --- /dev/null +++ b/src/health/health.controller.ts @@ -0,0 +1,40 @@ +import { Controller, Get, HttpStatus, HttpException, Inject } from '@nestjs/common'; +import { DataSource } from 'typeorm'; + +@Controller() +export class HealthController { + constructor(@Inject('DATA_SOURCE') private readonly dataSource: DataSource) {} + + @Get('health') + async healthCheck() { + try { + const isConnected = this.dataSource.isInitialized; + + if (isConnected) { + return { + status: 'ok', + database: 'up', + timestamp: new Date().toISOString(), + }; + } else { + throw new HttpException( + { + status: 'error', + database: 'down', + timestamp: new Date().toISOString(), + }, + HttpStatus.SERVICE_UNAVAILABLE, + ); + } + } catch (error) { + throw new HttpException( + { + status: 'error', + database: 'down', + timestamp: new Date().toISOString(), + }, + HttpStatus.SERVICE_UNAVAILABLE, + ); + } + } +} diff --git a/src/health/health.module.ts b/src/health/health.module.ts new file mode 100644 index 0000000..ef4316b --- /dev/null +++ b/src/health/health.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { HealthController } from './health.controller'; +import { databaseProviders } from '../database.providers'; + +@Module({ + controllers: [HealthController], + providers: [...databaseProviders], +}) +export class HealthModule {} diff --git a/test-health.js b/test-health.js new file mode 100644 index 0000000..9515ba0 --- /dev/null +++ b/test-health.js @@ -0,0 +1,32 @@ +// Simple test script to verify health endpoint +const http = require('http'); + +const options = { + hostname: 'localhost', + port: 3000, + path: '/health', + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } +}; + +const req = http.request(options, (res) => { + console.log(`Status Code: ${res.statusCode}`); + console.log(`Headers: ${JSON.stringify(res.headers, null, 2)}`); + + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + console.log('Response Body:', JSON.parse(data)); + }); +}); + +req.on('error', (error) => { + console.error('Error:', error.message); +}); + +req.end();