feat: implementa consulta PCEMPR e correção de tipos TypeORM
Some checks failed
Deploy NestJS API / build-and-push-deploy (push) Failing after 27s

This commit is contained in:
2026-01-02 17:23:03 -05:00
parent dc32434e22
commit cd13400942
13 changed files with 705 additions and 114 deletions

View File

@@ -0,0 +1,7 @@
O Rollback via Git (Mais Seguro)
No Gitea, faça um git revert no commit que deu erro.
Dê o git push.
O Portainer detectará a mudança e atualizará o serviço para a versão estável de forma oficial.

View File

@@ -1,16 +0,0 @@
name: Rollback API
on:
workflow_dispatch:
jobs:
rollback:
runs-on: ubuntu-latest
steps:
- name: Executar Rollback via SSH
uses: https://github.com/appleboy/ssh-action@master
with:
host: 172.35.0.216
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker service rollback api_teste_service

View File

@@ -1,17 +1,40 @@
# Estágio 1: Build # Estágio 1: Build
FROM node:18-alpine AS builder FROM node:20-slim AS builder
WORKDIR /app WORKDIR /app
COPY package*.json ./ COPY package*.json ./
RUN npm install RUN npm install --legacy-peer-deps
COPY . . COPY . .
RUN npm run build RUN npm run build
# Estágio 2: Produção FROM node:20-slim
FROM node:18-alpine
# Instalar dependências do Oracle
RUN apt-get update && apt-get install -y \
libaio1 \
unzip \
wget \
&& mkdir -p /opt/oracle
# Instalar Oracle Instant Client
RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip -O /opt/oracle/client.zip && \
unzip /opt/oracle/client.zip -d /opt/oracle && \
rm /opt/oracle/client.zip && \
ln -s /opt/oracle/instantclient_* /opt/oracle/instantclient
# Configurar o sistema para encontrar as bibliotecas do Oracle
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient
RUN echo "/opt/oracle/instantclient" > /etc/ld.so.conf.d/oracle-instantclient.conf && ldconfig
WORKDIR /app WORKDIR /app
# Copiar apenas o necessário do estágio anterior
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./ COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000 # Variáveis de ambiente padrão para o driver oracledb
CMD ["node", "dist/main"] ENV OCI_LIB_DIR=/opt/oracle/instantclient
ENV OCI_INC_DIR=/opt/oracle/instantclient/sdk/include
CMD ["npm", "run", "start:prod"]

635
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,10 +21,15 @@
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^11.0.1", "@nestjs/common": "^11.0.1",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.1", "@nestjs/core": "^11.0.1",
"@nestjs/platform-express": "^11.0.1", "@nestjs/platform-express": "^11.0.1",
"@nestjs/typeorm": "^11.0.0",
"env": "^0.0.2",
"oracledb": "^6.10.0",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1" "rxjs": "^7.8.1",
"typeorm": "^0.3.28"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
@@ -35,6 +40,7 @@
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
"@types/jest": "^30.0.0", "@types/jest": "^30.0.0",
"@types/node": "^22.10.7", "@types/node": "^22.10.7",
"@types/oracledb": "^6.10.0",
"@types/supertest": "^6.0.2", "@types/supertest": "^6.0.2",
"eslint": "^9.18.0", "eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1", "eslint-config-prettier": "^10.0.1",

View File

@@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AppService } from './app.service'; import { AppService } from './oracle.service';
describe('AppController', () => { describe('AppController', () => {
let appController: AppController; let appController: AppController;

View File

@@ -1,12 +1,12 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service'; import { OracleService } from './oracle.service';
@Controller() @Controller('teste')
export class AppController { export class OracleController {
constructor(private readonly appService: AppService) {} constructor(private readonly oracleService: OracleService) {}
@Get() @Get('pcempr')
getHello(): string { async findAll() {
return this.appService.getHello(); return await this.oracleService.pcempr();
} }
} }

View File

@@ -1,10 +1,20 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { AppController } from './app.controller'; import { OracleController } from './app.controller';
import { AppService } from './app.service'; import { OracleService } from './oracle.service';
import { AppDataSource } from './config/typeorm.config';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({ @Module({
imports: [], imports: [
controllers: [AppController], ConfigModule.forRoot({
providers: [AppService], isGlobal: true,
}),
TypeOrmModule.forRootAsync({
useFactory: () => AppDataSource.options,
}),
],
controllers: [OracleController],
providers: [OracleService],
}) })
export class AppModule {} export class AppModule {}

View File

@@ -1,8 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World! ssh';
}
}

View File

@@ -0,0 +1,42 @@
import { DataSource } from 'typeorm';
import * as path from 'path';
import * as fs from 'fs';
import * as oracledb from 'oracledb';
import 'dotenv/config';
export function initializeOracleClient(): void {
try {
const oracleClientPath = process.env.ORACLE_CLIENT_PATH;
const libDir =
oracleClientPath && fs.existsSync(path.normalize(oracleClientPath))
? path.normalize(oracleClientPath)
: undefined;
oracledb.initOracleClient(libDir ? { libDir } : undefined);
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : String(err);
console.warn(
'Oracle Client Thick mode initialization failed:',
errorMessage,
);
}
}
export const AppDataSource = new DataSource({
type: 'oracle',
username: process.env.DB_USERNAME || 'simplifique',
password: process.env.DB_PASSWORD || 'simplifique',
connectString:
process.env.DB_CONNECT_STRING ||
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.35.0.250)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))',
synchronize: false,
logging: true,
entities: [__dirname + '/../**/*.{entity,view}.{js,ts}'],
subscribers: [process.env.DB_SUBSCRIBERS_PATH || 'dist/subscriber/*.js'],
extra: {
poolSize: parseInt(process.env.DB_POOL_SIZE || '10', 10),
maxRows: parseInt(process.env.DB_MAX_ROWS || '1000', 10),
},
});

View File

@@ -1,6 +1,11 @@
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import { initializeOracleClient } from './config/typeorm.config';
initializeOracleClient();
console.log('Tentando carregar Oracle de:', process.env.ORACLE_CLIENT_PATH);
console.log('Usuário DB:', process.env.DB_USERNAME);
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000); await app.listen(process.env.PORT ?? 3000);

19
src/oracle.service.ts Normal file
View File

@@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
@Injectable()
export class OracleService {
constructor(private dataSource: DataSource) {}
async pcempr() {
const query = `SELECT * FROM PCEMPR FETCH FIRST 10 ROWS ONLY`;
try {
const result = await this.dataSource.query(query);
return result;
} catch (error) {
console.error('Erro ao consultar PCEMPR:', error);
throw error;
}
}
}

View File

@@ -18,7 +18,7 @@
"skipLibCheck": true, "skipLibCheck": true,
"strictNullChecks": true, "strictNullChecks": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noImplicitAny": true, "noImplicitAny": false,
"strictBindCallApply": true, "strictBindCallApply": true,
"noFallthroughCasesInSwitch": true "noFallthroughCasesInSwitch": true
} }