feat: Initialize NestJS application with Oracle database integration, connection pooling, Swagger setup, and a new orders service.

This commit is contained in:
JuruSysadmin 2026-01-07 18:18:18 -03:00
parent 51d85aeb9a
commit af7e62cdf2
3 changed files with 35 additions and 36 deletions

View File

@ -17,13 +17,13 @@ export class DatabaseService implements OnModuleInit {
} }
async onModuleInit() { async onModuleInit() {
this.logger.log('🚀 Inicializando pool de conexões Oracle...'); this.logger.log('Inicializando pool de conexões Oracle...');
try { try {
await this.getOrCreatePool(); await this.getOrCreatePool();
this.logger.log('Pool Oracle inicializado com sucesso!'); this.logger.log('Pool Oracle inicializado com sucesso!');
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
'Erro ao inicializar pool Oracle:', 'Erro ao inicializar pool Oracle:',
error instanceof Error ? error.message : String(error), error instanceof Error ? error.message : String(error),
); );
} }
@ -35,7 +35,7 @@ export class DatabaseService implements OnModuleInit {
!process.env.ORACLE_PASSWORD || !process.env.ORACLE_PASSWORD ||
!process.env.ORACLE_CONNECTION_STRING !process.env.ORACLE_CONNECTION_STRING
) { ) {
this.logger.warn('⚠️ Variáveis de ambiente do Oracle não configuradas.'); this.logger.warn('Variáveis de ambiente do Oracle não configuradas.');
this.logger.warn(' Configure as seguintes variáveis no arquivo .env:'); this.logger.warn(' Configure as seguintes variáveis no arquivo .env:');
this.logger.warn(' - ORACLE_USER'); this.logger.warn(' - ORACLE_USER');
this.logger.warn(' - ORACLE_PASSWORD'); this.logger.warn(' - ORACLE_PASSWORD');
@ -60,11 +60,11 @@ export class DatabaseService implements OnModuleInit {
poolIncrement: 1, poolIncrement: 1,
queueTimeout: 60000, queueTimeout: 60000,
}); });
this.logger.log('Pool Oracle criada com sucesso!'); this.logger.log('Pool Oracle criada com sucesso!');
return pool; return pool;
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
'Erro ao criar pool Oracle:', 'Erro ao criar pool Oracle:',
error instanceof Error ? error.message : String(error), error instanceof Error ? error.message : String(error),
); );
throw new Error('Falha ao criar pool Oracle'); throw new Error('Falha ao criar pool Oracle');
@ -84,10 +84,10 @@ export class DatabaseService implements OnModuleInit {
try { try {
this.pool = await this.poolCreationPromise; this.pool = await this.poolCreationPromise;
this.logger.log('Pool Oracle recriada com sucesso!'); this.logger.log('Pool Oracle recriada com sucesso!');
return this.pool; return this.pool;
} catch (error) { } catch (error) {
this.logger.error('Erro ao recriar pool Oracle:', error); this.logger.error('Erro ao recriar pool Oracle:', error);
this.poolCreationPromise = null; this.poolCreationPromise = null;
throw error; throw error;
} finally { } finally {
@ -105,7 +105,7 @@ export class DatabaseService implements OnModuleInit {
this.inactivityTimer = setTimeout(() => { this.inactivityTimer = setTimeout(() => {
this.closePoolIfInactive().catch((error) => { this.closePoolIfInactive().catch((error) => {
this.logger.error( this.logger.error(
'Erro no timer de inatividade:', 'Erro no timer de inatividade:',
error instanceof Error ? error.message : String(error), error instanceof Error ? error.message : String(error),
); );
}); });
@ -116,14 +116,14 @@ export class DatabaseService implements OnModuleInit {
const timeSinceLastActivity = Date.now() - this.lastActivityTime; const timeSinceLastActivity = Date.now() - this.lastActivityTime;
if (timeSinceLastActivity >= this.INACTIVITY_TIMEOUT && this.pool) { if (timeSinceLastActivity >= this.INACTIVITY_TIMEOUT && this.pool) {
this.logger.log('🔄 Fechando pool por inatividade (20s)...'); this.logger.log('Fechando pool por inatividade (20s)...');
try { try {
await this.pool.close(20); await this.pool.close(20);
this.pool = null; this.pool = null;
this.logger.log('Pool fechada por inatividade'); this.logger.log('Pool fechada por inatividade');
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
'Erro ao fechar pool:', 'Erro ao fechar pool:',
error instanceof Error ? error.message : String(error), error instanceof Error ? error.message : String(error),
); );
} }
@ -137,7 +137,7 @@ export class DatabaseService implements OnModuleInit {
// Verifica se a pool está saudável // Verifica se a pool está saudável
const isHealthy = await this.isPoolHealthy(); const isHealthy = await this.isPoolHealthy();
if (!isHealthy) { if (!isHealthy) {
this.logger.log('🔄 Pool não está saudável, recriando...'); this.logger.log('Pool não está saudável, recriando...');
this.pool = null; this.pool = null;
const newPool = await this.getOrCreatePool(); const newPool = await this.getOrCreatePool();
this.updateInactivityTimer(); this.updateInactivityTimer();
@ -147,10 +147,10 @@ export class DatabaseService implements OnModuleInit {
this.updateInactivityTimer(); this.updateInactivityTimer();
return await pool.getConnection(); return await pool.getConnection();
} catch (error) { } catch (error) {
this.logger.error('Erro ao obter conexão da pool:', error); this.logger.error('Erro ao obter conexão da pool:', error);
// Se a pool estiver fechada, tenta recriar // Se a pool estiver fechada, tenta recriar
if (this.pool === null) { if (this.pool === null) {
this.logger.log('🔄 Tentando recriar pool...'); this.logger.log('Tentando recriar pool...');
this.pool = null; this.pool = null;
const newPool = await this.getOrCreatePool(); const newPool = await this.getOrCreatePool();
this.updateInactivityTimer(); this.updateInactivityTimer();
@ -174,14 +174,14 @@ export class DatabaseService implements OnModuleInit {
...options, ...options,
}); });
} catch (error) { } catch (error) {
this.logger.error('Erro ao executar query:', error); this.logger.error('Erro ao executar query:', error);
throw error; throw error;
} finally { } finally {
if (conn) { if (conn) {
try { try {
await conn.close(); await conn.close();
} catch (closeError) { } catch (closeError) {
this.logger.error('Erro ao fechar conexão:', closeError); this.logger.error('Erro ao fechar conexão:', closeError);
} }
} }
} }
@ -197,10 +197,10 @@ export class DatabaseService implements OnModuleInit {
await conn.close(); await conn.close();
return 'Conexão com Oracle bem-sucedida!'; return 'Conexão com Oracle bem-sucedida!';
} catch (err) { } catch (err) {
this.logger.error('Erro no teste de conexão:', err); this.logger.error('Erro no teste de conexão:', err);
throw new Error( throw new Error(
'Falha ao conectar no Oracle: ' + 'Falha ao conectar no Oracle: ' +
(err instanceof Error ? err.message : String(err)), (err instanceof Error ? err.message : String(err)),
); );
} }
} }
@ -212,7 +212,7 @@ export class DatabaseService implements OnModuleInit {
} }
return !!this.pool; return !!this.pool;
} catch (error) { } catch (error) {
this.logger.error('Erro ao verificar disponibilidade da pool:', error); this.logger.error('Erro ao verificar disponibilidade da pool:', error);
return false; return false;
} }
} }
@ -228,7 +228,7 @@ export class DatabaseService implements OnModuleInit {
await conn.close(); await conn.close();
return true; return true;
} catch (error) { } catch (error) {
this.logger.error('Pool não está saudável:', error); this.logger.error('Pool não está saudável:', error);
return false; return false;
} }
} }
@ -240,14 +240,14 @@ export class DatabaseService implements OnModuleInit {
} }
if (this.pool) { if (this.pool) {
this.logger.log('🔄 Fechando pool forçadamente...'); this.logger.log('Fechando pool forçadamente...');
try { try {
await this.pool.close(20); await this.pool.close(20);
this.pool = null; this.pool = null;
this.logger.log('Pool fechada forçadamente'); this.logger.log('Pool fechada forçadamente');
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
'Erro ao fechar pool:', 'Erro ao fechar pool:',
error instanceof Error ? error.message : String(error), error instanceof Error ? error.message : String(error),
); );
} }
@ -272,7 +272,7 @@ export class DatabaseService implements OnModuleInit {
inactivityTimeout: this.INACTIVITY_TIMEOUT, inactivityTimeout: this.INACTIVITY_TIMEOUT,
}; };
} catch (error) { } catch (error) {
this.logger.error('Erro ao obter estatísticas da pool:', error); this.logger.error('Erro ao obter estatísticas da pool:', error);
return { return {
status: 'error', status: 'error',
error: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error.message : String(error),

View File

@ -1,9 +1,10 @@
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common'; import { ValidationPipe, Logger } from '@nestjs/common';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() { async function bootstrap() {
const logger = new Logger('Bootstrap');
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
// Habilitar CORS // Habilitar CORS
@ -51,18 +52,16 @@ async function bootstrap() {
app.enableShutdownHooks(); app.enableShutdownHooks();
await app.listen(process.env.PORT ?? 3001, '0.0.0.0'); await app.listen(process.env.PORT ?? 3001, '0.0.0.0');
console.log(`Server is running on port ${process.env.PORT ?? 3001}`); logger.log(`Server is running on port ${process.env.PORT ?? 3001}`);
console.log( logger.log(
`Swagger documentation available at http://localhost:${process.env.PORT ?? 3001}/api`, `Swagger documentation available at http://localhost:${process.env.PORT ?? 3001}/api`,
); );
} }
process.on('SIGINT', () => { process.on('SIGINT', () => {
console.log('Recebido SIGINT. Encerrando aplicação...');
process.exit(0); process.exit(0);
}); });
process.on('SIGTERM', () => { process.on('SIGTERM', () => {
console.log('Recebido SIGTERM. Encerrando aplicação...');
process.exit(0); process.exit(0);
}); });

View File

@ -68,7 +68,7 @@ interface PermissaoResult {
@Injectable() @Injectable()
export class OrdersService { export class OrdersService {
constructor(private readonly databaseService: DatabaseService) {} constructor(private readonly databaseService: DatabaseService) { }
async getNotaFiscal(chaveNota: string): Promise<NotaFiscalComItens> { async getNotaFiscal(chaveNota: string): Promise<NotaFiscalComItens> {
const sqlNotaFiscal = ` const sqlNotaFiscal = `
@ -165,9 +165,9 @@ AND PCNFSAID.CHAVENFE=:chaveNota`;
QT: item.QT, QT: item.QT,
URLIMAGEM: item.URLIMAGEM URLIMAGEM: item.URLIMAGEM
? item.URLIMAGEM.split(';')[0].replace( ? item.URLIMAGEM.split(';')[0].replace(
'http://167.249.211.178:8001', 'http://167.249.211.178:8001',
'http://10.1.1.191', 'http://10.1.1.191',
) )
: '', : '',
}; };
}), }),
@ -241,7 +241,7 @@ AND PCNFSAID.CHAVENFE=:chaveNota`;
chaveNota, chaveNota,
])) as DatabaseResult; ])) as DatabaseResult;
console.log(result);
// Verificar se algum registro foi afetado // Verificar se algum registro foi afetado
if (result.rowsAffected === 0) { if (result.rowsAffected === 0) {
@ -266,7 +266,7 @@ AND PCNFSAID.CHAVENFE=:chaveNota`;
[entrega.NUMTRANSVENDA, imagem.TIPO, imagem.URLIMAGEM], [entrega.NUMTRANSVENDA, imagem.TIPO, imagem.URLIMAGEM],
)) as DatabaseResult; )) as DatabaseResult;
console.log(resultImagem);
if (resultImagem.rowsAffected === 0) { if (resultImagem.rowsAffected === 0) {
throw new NotFoundException( throw new NotFoundException(