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

View File

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

View File

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