feat: Initialize NestJS application with Oracle database integration, connection pooling, Swagger setup, and a new orders service.
This commit is contained in:
parent
51d85aeb9a
commit
af7e62cdf2
|
|
@ -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,7 +197,7 @@ 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),
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = `
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue