31 Commits

Author SHA1 Message Date
ca43de8756 fix: use harbor domain instead of ip to fix ssl error
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 20s
2026-01-29 13:31:20 -03:00
bb21ca33e4 fix: update registry url to oci.simplifiquehc.com.br
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 22s
2026-01-29 13:26:13 -03:00
48d6e64ada fix: update registry url to oci.simplifiquehc.com.br
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 24s
2026-01-29 13:24:58 -03:00
e0731db836 fix: update registry url to oci.simplifiquehc.com.br
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 34s
2026-01-29 13:17:15 -03:00
d2265390bd chore: organize project and update service
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 23s
2026-01-29 12:55:15 -03:00
a34c7c415c fix: update workflow to support homolog branch
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 25s
2026-01-29 12:50:47 -03:00
4975d5547d chore: organize project and update service
Some checks failed
Build (develop) / Promote (main) / build-and-push-deploy (push) Failing after 24s
2026-01-29 12:44:11 -03:00
fa6f0e0f49 chore: organize project and update service 2026-01-29 12:43:41 -03:00
c9335a27e5 Merge branch 'docs/k8s-workflow' into homolog 2026-01-29 12:42:01 -03:00
f2b629eaad chore: organize project and update service
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m13s
2026-01-29 11:49:01 -03:00
3b8b079123 docs: add kubernetes and workflow documentation
Some checks failed
Deploy NestJS API / build-and-push-deploy (push) Failing after 8s
2026-01-29 11:28:35 -03:00
1270c04a2c Update deploy-api.yaml workflow 2026-01-29 02:17:39 -03:00
Luis Eduardo Estevao
ca892daffa feat: implement SalesService for product retrieval, filtering, pagination, and caching.
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m9s
2026-01-26 06:36:09 -03:00
8e09813741 Atualizar src/main.ts
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m18s
2026-01-20 18:17:02 -05:00
4003aab9e0 Merge pull request 'homolog' (#1) from homolog into main
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 54s
Reviewed-on: http://172.35.0.216:3000/simplifique/Vendaweb-api/pulls/1
2026-01-12 14:55:38 -05:00
Luis Eduardo Estevao
6c1599fbaa Ajustes para simplifique
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m9s
2026-01-12 16:19:11 -03:00
Luis Eduardo Estevao
2b9868bf6d feat: add app controller with endpoints for application version and health checks.
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m19s
2026-01-07 20:23:23 -03:00
90366c21e5 fix: update health check response status message
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m10s
2026-01-05 20:32:26 -05:00
bda9f0f13b fix: correct health check response message
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m30s
2026-01-05 20:13:29 -05:00
ce988e93b1 fix: update database host in TypeORM configuration
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 1m57s
2026-01-05 19:30:19 -05:00
19d34ea672 fix: correct health check response message typo
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m8s
2026-01-05 19:21:22 -05:00
91f3e857a0 fix: refactor AppService to ProductsService and implement product management methods
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m4s
2026-01-05 19:15:40 -05:00
e2a008e9a9 fix: update health check response to return version 3
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 1m59s
2026-01-05 18:45:48 -05:00
a3021a545c fix: update health check response to include versioning
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 2m13s
2026-01-05 18:35:07 -05:00
2ff13691b0 fix: update server port from 8067 to 8065
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 1m59s
2026-01-02 19:38:20 -05:00
f9ba12c43f fix: update Redis connection details to use hardcoded values
Some checks failed
Deploy NestJS API / build-and-push-deploy (push) Has been cancelled
2026-01-02 19:37:51 -05:00
699a9191e2 feat: configure Redis connection and update server port
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 1m56s
2026-01-02 19:23:49 -05:00
d400a3febb :ok configuração das variaveis do redis
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 3m29s
2026-01-02 19:03:18 -05:00
e1159acdf0 :ok
All checks were successful
Deploy NestJS API / build-and-push-deploy (push) Successful in 3m38s
2026-01-02 18:38:52 -05:00
dfd6c0ef8a first
Some checks failed
Deploy NestJS API / build-and-push-deploy (push) Failing after 7s
2026-01-02 18:37:24 -05:00
7a9a40e859 first
Some checks failed
Deploy NestJS API / build-and-push-deploy (push) Failing after 19s
2026-01-02 18:31:38 -05:00
24 changed files with 738 additions and 264 deletions

13
.env Normal file
View File

@@ -0,0 +1,13 @@
ORACLE_CLIENT_PATH='/usr/lib/oracle/21/client64/lib'
###REDIS
REDIS_HOST='172.35.0.217'
REDIS_PORT='6379'
####ORACLE
PORT='8065'
DB_USERNAME='simplifique'
DB_PASSWORD='simplifique'
DB_CONNECT_STRING='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.35.0.250)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)))'

View File

@@ -0,0 +1,118 @@
name: Build (develop) / Promote (main)
on:
push:
branches: [main, develop, homolog]
jobs:
build-and-push-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Free disk space
run: |
df -h
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc || true
sudo apt-get clean || true
docker system prune -af --volumes || true
df -h
- name: Build (develop) / Promote (main)
env:
REGISTRY: 172.35.0.216
DEV_PROJECT: vendaweb-dev
PROD_PROJECT: vendaweb-prod
IMAGE_REPO: vendaweb-api
PROMOTE_LEGACY: 'false'
HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }}
HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }}
HARBOR_DEV_USERNAME: ${{ secrets.HARBOR_DEV_USERNAME }}
HARBOR_DEV_PASSWORD: ${{ secrets.HARBOR_DEV_PASSWORD }}
HARBOR_PROD_USERNAME: ${{ secrets.HARBOR_PROD_USERNAME }}
HARBOR_PROD_PASSWORD: ${{ secrets.HARBOR_PROD_PASSWORD }}
HARBOR_LEGACY_USERNAME: ${{ secrets.HARBOR_LEGACY_USERNAME }}
HARBOR_LEGACY_PASSWORD: ${{ secrets.HARBOR_LEGACY_PASSWORD }}
run: |
set -euo pipefail
BRANCH="${GITHUB_REF_NAME:-${GITEA_REF_NAME:-}}"
if [ -z "$BRANCH" ] && [ -n "${GITHUB_REF:-}" ]; then
BRANCH="${GITHUB_REF#refs/heads/}"
fi
DEV_IMAGE="$REGISTRY/$DEV_PROJECT/$IMAGE_REPO"
PROD_IMAGE="$REGISTRY/$PROD_PROJECT/$IMAGE_REPO"
LEGACY_IMAGE="$REGISTRY/library/$IMAGE_REPO"
DEV_USER="${HARBOR_DEV_USERNAME:-$HARBOR_USERNAME}"
DEV_PASS="${HARBOR_DEV_PASSWORD:-$HARBOR_PASSWORD}"
PROD_USER="${HARBOR_PROD_USERNAME:-$HARBOR_USERNAME}"
PROD_PASS="${HARBOR_PROD_PASSWORD:-$HARBOR_PASSWORD}"
LEGACY_USER="${HARBOR_LEGACY_USERNAME:-$PROD_USER}"
LEGACY_PASS="${HARBOR_LEGACY_PASSWORD:-$PROD_PASS}"
# --- Lógica para DEVELOP / HOMOLOG (Build) ---
if [ "$BRANCH" = "develop" ] || [ "$BRANCH" = "homolog" ]; then
TAG=$(echo ${{ gitea.sha }} | cut -c1-7)
echo "$DEV_PASS" | docker login "$REGISTRY" -u "$DEV_USER" --password-stdin
docker build -t "$DEV_IMAGE:$TAG" -f ./Dockerfile .
docker push "$DEV_IMAGE:$TAG"
docker tag "$DEV_IMAGE:$TAG" "$DEV_IMAGE:develop"
docker push "$DEV_IMAGE:develop"
exit 0
fi
# --- Lógica para MAIN (Promoção via Skopeo) ---
if [ "$BRANCH" = "main" ]; then
sudo apt-get update -y
sudo apt-get install -y skopeo
if [ -z "${DEV_USER:-}" ] || [ -z "${DEV_PASS:-}" ]; then
echo "Missing Harbor DEV credentials." >&2
exit 1
fi
PARENTS="$(git rev-list --parents -n 1 HEAD)"
set -- $PARENTS
SOURCE_SHA="${3:-${1:-}}"
TAG="$(echo "$SOURCE_SHA" | cut -c1-7)"
# Inspecionar imagem na origem (DEV) ignorando TLS
skopeo inspect --src-tls-verify=false --creds "$DEV_USER:$DEV_PASS" "docker://$DEV_IMAGE:$TAG" >/dev/null
# Listar tags no destino (PROD) ignorando TLS
skopeo list-tags --tls-verify=false --creds "$PROD_USER:$PROD_PASS" "docker://$PROD_IMAGE" >/dev/null
# Copiar imagem de DEV para PROD (Promoção) ignorando TLS em ambos
skopeo copy --all \
--src-tls-verify=false \
--dest-tls-verify=false \
--src-creds "$DEV_USER:$DEV_PASS" \
--dest-creds "$PROD_USER:$PROD_PASS" \
"docker://$DEV_IMAGE:$TAG" \
"docker://$PROD_IMAGE:$TAG"
# Promoção para Legacy (se ativado)
if [ "${PROMOTE_LEGACY:-false}" = "true" ]; then
skopeo copy --all --src-tls-verify=false --dest-tls-verify=false \
--src-creds "$DEV_USER:$DEV_PASS" \
--dest-creds "$LEGACY_USER:$LEGACY_PASS" \
"docker://$DEV_IMAGE:$TAG" \
"docker://$LEGACY_IMAGE:$TAG"
skopeo copy --all --src-tls-verify=false --dest-tls-verify=false \
--src-creds "$DEV_USER:$DEV_PASS" \
--dest-creds "$LEGACY_USER:$LEGACY_PASS" \
"docker://$DEV_IMAGE:$TAG" \
"docker://$LEGACY_IMAGE:latest"
fi
exit 0
fi
echo "Unsupported branch: $BRANCH" >&2
exit 1

3
.gitignore vendored
View File

@@ -33,3 +33,6 @@ lerna-debug.log*
!.vscode/launch.json
!.vscode/extensions.json
# Environment variables
.env

View File

@@ -1,32 +1,39 @@
FROM node:16
# Estágio 1: Build
FROM node:16-bullseye-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install --legacy-peer-deps
COPY . .
RUN npm run build
FROM node:16-bullseye-slim
# Instalar dependências do Oracle
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
libaio1 \
unzip \
wget \
libc6 \
libncurses5 && \
mkdir -p /opt/oracle && \
wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip -O /opt/oracle/instantclient-basic-linuxx64.zip && \
unzip /opt/oracle/instantclient-basic-linuxx64.zip -d /opt/oracle && \
rm /opt/oracle/instantclient-basic-linuxx64.zip && \
ln -s /opt/oracle/instantclient_* /opt/oracle/instantclient && \
echo "/opt/oracle/instantclient" > /etc/ld.so.conf.d/oracle-instantclient.conf && \
ldconfig
&& 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
# 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/node_modules ./node_modules
COPY package*.json ./
RUN npm install --legacy-peer-deps
COPY . .
# Variáveis de ambiente padrão para o driver oracledb
ENV OCI_LIB_DIR=/opt/oracle/instantclient
ENV OCI_INC_DIR=/opt/oracle/instantclient/sdk/include
CMD ["npm", "run", "start:prod"]

76
KUBERNETES.md Normal file
View File

@@ -0,0 +1,76 @@
# Documentação do Kubernetes
Este documento descreve a infraestrutura e configuração do Kubernetes para o projeto **Vendaweb-api**, utilizando uma abordagem GitOps com ArgoCD e Kustomize.
## Estrutura de Diretórios e Arquivos
A configuração do Kubernetes está localizada no diretório `k8s/` e segue uma estrutura organizada para facilitar a manutenção e escalabilidade:
```
k8s/
├── argocd/ # Configurações do ArgoCD
│ └── application-prod.yaml # Definição da Application para o ambiente de produção
├── base/ # Recursos base do Kubernetes (Kustomize Base)
│ ├── configmap.yaml # ConfigMap base
│ ├── deployment.yaml # Deployment base da aplicação
│ ├── kustomization.yaml # Arquivo principal do Kustomize Base
│ ├── secret.yaml # Secret base
│ └── service.yaml # Service base
└── overlays/ # Sobrescritas para diferentes ambientes (Kustomize Overlays)
└── prod/ # Ambiente de produção
├── application-prod.yaml
├── deployment-image-digest-patch.yaml
├── kustomization.yaml
└── service-patch.yaml
```
## Recursos Base (`k8s/base`)
O diretório `base` contém as definições padrão dos recursos que são comuns a todos os ambientes.
### Deployment (`deployment.yaml`)
- **Nome**: `vendaweb-api`
- **Replicas**: 15 (Configuração base)
- **Imagem**: `172.35.0.216/library/vendaweb-api:latest`
- **Porta do Container**: 8065
- **Resources**:
- Requests: CPU 100m, Memory 256Mi
- Limits: CPU 500m, Memory 512Mi
- **Probes**: Liveness, Readiness e Startup probes configurados no endpoint `/v1/health`.
- **Environment**: Configurações carregadas via ConfigMap e Secret.
### Service (`service.yaml`)
- **Tipo**: ClusterIP
- **Porta**: 8065 (TCP)
## Ambientes (`k8s/overlays`)
### Produção (`k8s/overlays/prod`)
A sobreposição de produção personaliza a configuração base para o ambiente produtivo.
- **Namespace**: `vendaweb-prod`
- **Patches**: Aplica modificações específicas (ex: digest da imagem, configurações específicas de serviço) via `kustomization.yaml`.
## Deploy com ArgoCD (`k8s/argocd`)
O deploy é gerenciado pelo ArgoCD, que sincroniza o estado do cluster com o repositório Git.
### Application (`application-prod.yaml`)
- **Nome**: `vendaweb-api-prod`
- **Namespace do ArgoCD**: `argocd`
- **Origem (Source)**:
- Repositório: `https://git.simplifiquehc.com.br/simplifique/Vendaweb-api.git`
- Revisão: `main`
- Path: `k8s/overlays/prod` (Aponta para o overlay de produção)
- **Destino (Destination)**:
- Cluster: `https://kubernetes.default.svc`
- Namespace: `vendaweb-api` (Nota: O patch define `vendaweb-prod`, verifique a consistência)
- **Sync Policy**: Automatizado com `selfHeal` ativado e criação automática de namespace.
---
**Observação**: Certifique-se de que as credenciais do Harbor (`imagePullSecrets`) estejam corretamente configuradas no namespace de destino para permitir o pull da imagem.

57
WORKFLOWS.md Normal file
View File

@@ -0,0 +1,57 @@
# Documentação dos Workflows (Gitea Actions)
Este documento descreve os fluxos de trabalho de integração contínua (CI) e entrega contínua (CD) configurados no Gitea Actions para o projeto **Vendaweb-api**.
## Visão Geral
Os workflows estão definidos no diretório `.gitea/workflows/`. O principal workflow configurado é o deploy da API.
## Workflow: Deploy NestJS API
**Arquivo**: `.gitea/workflows/deploy-api.yaml`
### Gatilhos (Triggers)
Este workflow é acionado automaticamente no evento:
- `push`: Em qualquer branch (configuração atual `on: [push]`).
### Jobs
#### `build-and-push-deploy`
Este job é responsável por construir a imagem Docker e enviá-la para o registry privado (Harbor).
- **Ambiente de Execução**: `ubuntu-latest` (Runner)
#### Passos (Steps):
1. **Checkout**
- Utiliza `actions/checkout@v3` para clonar o código fonte do repositório.
2. **Login no Harbor**
- Realiza autenticação no registry Docker privado.
- **Registry**: `172.35.0.216`
- **Segredos Utilizados**:
- `HARBOR_USERNAME`: Nome de usuário do Harbor.
- `HARBOR_PASSWORD`: Senha do usuário do Harbor.
3. **Build e Push**
- Constrói a imagem Docker da aplicação.
- Tags geradas:
- `172.35.0.216/library/vendaweb-api:$TAG` (onde `$TAG` é o SHA do commit do Gitea `gitea.sha`)
- `172.35.0.216/library/vendaweb-api:latest`
- Envia ambas as tags para o registry.
## Variáveis e Segredos (Secrets)
Para que o workflow funcione corretamente, as seguintes secrets devem estar configuradas nas configurações do repositório no Gitea:
| Secret | Descrição |
| ----------------- | ------------------------------------------------------------- |
| `HARBOR_USERNAME` | Usuário com permissão de push no projeto `library` do Harbor. |
| `HARBOR_PASSWORD` | Senha ou token de acesso do usuário do Harbor. |
## Integração com Kubernetes
Após o push da imagem com a tag `latest` (e o SHA específico), o ArgoCD (configurado conforme `KUBERNETES.md`) detectará as mudanças se houver alteração nos manifestos ou se estiver configurado para pollar a imagem `latest` (dependendo da política de `imagePullPolicy` e configuração do ArgoCD Image Updater, se houver).

View File

@@ -1,14 +1,18 @@
version: '3.8'
services:
vendaweb:
image: link70/vendaweb
deploy:
replicas: 20
resources:
limits:
cpus: '0.5'
memory: 512M
vendaweb-api:
image: 172.35.0.216/library/vendaweb-api:latest
ports:
- "8065:8065"
restart: always
networks:
- simplifique-network
deploy:
replicas: 4
update_config:
order: start-first
parallelism: 1
networks:
simplifique-network:
external: true

View File

@@ -0,0 +1,19 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vendaweb-api-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://git.simplifiquehc.com.br/simplifique/Vendaweb-api.git
targetRevision: main
path: k8s/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: vendaweb-api
syncPolicy:
automated:
selfHeal: true
syncOptions:
- CreateNamespace=true

10
k8s/base/configmap.yaml Normal file
View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: vendaweb-api-config
data:
REDIS_HOST: '172.35.0.250'
REDIS_PORT: '6379'
DB_HOST: '172.35.0.250'
DB_PORT: '1521'
DB_SERVICE_NAME: 'ORCL'

62
k8s/base/deployment.yaml Normal file
View File

@@ -0,0 +1,62 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vendaweb-api
labels:
app: vendaweb-api
spec:
replicas: 15
selector:
matchLabels:
app: vendaweb-api
template:
metadata:
labels:
app: vendaweb-api
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: api
image: 172.35.0.216/library/vendaweb-api:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8067
protocol: TCP
envFrom:
- configMapRef:
name: vendaweb-api-config
- secretRef:
name: vendaweb-api-secrets
livenessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 6
readinessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 6
startupProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 24
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- configmap.yaml

8
k8s/base/secret.yaml Normal file
View File

@@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: vendaweb-api-secrets
type: Opaque
stringData:
DB_USERNAME: 'simplifique'
DB_PASSWORD: 'simplifique'

15
k8s/base/service.yaml Normal file
View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: vendaweb-api
labels:
app: vendaweb-api
spec:
type: ClusterIP
selector:
app: vendaweb-api
ports:
- name: http
port: 8067
targetPort: 8067
protocol: TCP

View File

@@ -0,0 +1,10 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vendaweb-api
spec:
template:
spec:
containers:
- name: api
image: 172.35.0.216/library/vendaweb-api@sha256:aac490fcb4ef7baa95f1df01fa50d2d44bdb4ed12b235e5dd89e1d7dc3cd0a3a

View File

@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: vendaweb-prod
resources:
- ../../base
patches:
- path: deployment-image-digest-patch.yaml
- path: service-patch.yaml

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: vendaweb-api
spec:
type: NodePort
ports:
- name: http
port: 8067
targetPort: 8067
nodePort: 30001

View File

@@ -93,7 +93,7 @@ export class UserService {
' WHERE PCEMPR.CODFILIAL = PCFILIAL.CODIGO (+)' +
' AND PCPARAMFILIAL.CODFILIAL = \'99\' ' +
' AND PCPARAMFILIAL.NOME = \'CON_CODSETORGERENTELOJA\' ' +
' AND PCEMPR.EMAIL = :username AND PCEMPR.SENHABD = CRYPT(:password, USUARIOBD)';
' AND PCEMPR.USUARIOBD = :username AND PCEMPR.SENHABD = CRYPT(:password, USUARIOBD)';
const users = await queryRunner.manager
.query(sql, [user.email, user.password]);
@@ -142,7 +142,7 @@ export class UserService {
.query(sqlDiasSemEntrega, [Number.parseInt(users[0].deliveryTime)]);
const days = Number.parseInt(deliveryDays2[0].days) +
( noDeliveryDays.length > 0 ? Number.parseInt(noDeliveryDays[0].daysNoDelivery) : 0 );
(noDeliveryDays.length > 0 ? Number.parseInt(noDeliveryDays[0].daysNoDelivery) : 0);
const userDb = users[0];
console.log(userDb);

View File

@@ -12,9 +12,9 @@ export class AppController {
}
@Get('health')
@ApiOperation({ summary: 'Health check' })
healthCheck() {
return { status: 'ok' };
}
@ApiOperation({ summary: 'Health check' })
healthCheck() {
return { status: 'SIMPLIFIQUE HOME CENTER 2026' };
}
}

View File

@@ -1,18 +1,17 @@
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ConnectionOptions } from 'typeorm';
import 'dotenv/config';
export const typeOrmConfig: TypeOrmModuleOptions = {
type: "oracle",
// host: "192.168.100.40",
// username: "LIVIA",
// password: "LIVIA",
host: "10.1.1.241",
username: "SEVEN",
password: "USR54SEV",
// username: "API",
// password: "E05H5KIEQV3YKDJR",
host: "172.35.0.250",
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)))',
port: 1521,
sid: "WINT",
sid: "ORCL",
synchronize: false,
logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'],
@@ -21,11 +20,14 @@ export const typeOrmConfig: TypeOrmModuleOptions = {
export const connectionOptions: ConnectionOptions = {
type: "oracle",
host: "10.1.1.241",
username: "SEVEN",
password: "USR54SEV",
host: "172.35.0.250",
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)))',
port: 1521,
sid: "WINT",
sid: "ORCL",
synchronize: false,
logging: false,
entities: [__dirname + '/../**/*.entity.{js,ts}'],

View File

@@ -1622,8 +1622,8 @@ export class Pcclient {
@Column({ name: 'CODCONDCOMERCIAL' })
codcondcomercial: string;
@Column({ name: 'MEIOCOMUNICACAO' })
meiocomunicacao: string;
// @Column({ name: 'MEIOCOMUNICACAO' })
// meiocomunicacao: string;
@Column({ name: 'CODGRUPOCOMERCIALMED' })
codgrupocomercialmed: number;

View File

@@ -16,10 +16,10 @@ async function bootstrap() {
do cadastro de parceiros, consulta de venda de movimentação e pagamentos, e fechamento das comissões dos parceiros.`)
.setVersion("2023.1.2")
.addTag("VendaWeb")
.addTag("Autenticação")
.addTag("Auth")
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup("docs", app, document);
await app.listen(8065);
await app.listen(8067);
}
bootstrap();

View File

@@ -1,12 +1,23 @@
import { Provider } from '@nestjs/common';
import Redis = require('ioredis');
export const redisProvider: Provider = {
provide: 'REDIS_CLIENT',
useFactory: () => {
return new Redis({
host: '10.1.1.109',
host: '172.35.0.217',
port: 6379,
});
},
};

View File

@@ -44,7 +44,7 @@ export class CustomerService {
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
// ' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
@@ -102,14 +102,14 @@ export class CustomerService {
' ,pcclient.telent as "phone" ' +
' ,pcclient.telcelent as "cellPhone" ' +
' ,pcclient.ieent as "numberState" ' +
' ,pcclient.codcategoria as "categoryId" ' +
' ,pcclient.codsubcategoria as "subCategoryId" ' +
// ' ,pcclient.codcategoria as "categoryId" ' +
// ' ,pcclient.codsubcategoria as "subCategoryId" ' +
' ,pcclient.codpraca as "placeId" ' +
' ,pcclient.codusur1 as "sellerId" ' +
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
// ' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
@@ -158,7 +158,7 @@ export class CustomerService {
' ,pccidade.codibge as "ibgeCode" ' +
' ,pcclient.dtnasc as "birthdate" ' +
' ,pcclient.codatv1 as "ramoId" ' +
' ,pcclient.meiocomunicacao as "communicate" ' +
//' ,pcclient.meiocomunicacao as "communicate" ' +
' ,pcclient.latitude as "latitude" ' +
' ,pcclient.longitude as "longitude" ' +
' ,pcclient.codmunicipio as "ibgeCode" ' +
@@ -173,7 +173,7 @@ export class CustomerService {
FROM PCPRACA
WHERE PCPRACA.CODPRACA = ${customer[0].placeId}`);
return {...customer[0], place: place[0]};
return { ...customer[0], place: place[0] };
} catch (error) {
console.log(error);
throw error;
@@ -267,15 +267,15 @@ export class CustomerService {
newCustomer.telcelent = customer.cellPhone;
newCustomer.celularwhatsapp = customer.cellPhone;
newCustomer.codusur1 = customer.sellerId;
newCustomer.codatv1 = ( customer.ramo != null && customer.ramo.id > 0 ) ? customer.ramo.id : newCustomer.codatv1;
newCustomer.codatv1 = (customer.ramo != null && customer.ramo.id > 0) ? customer.ramo.id : newCustomer.codatv1;
//Endereço de entrega
newCustomer.cepent = customer.zipCode;
newCustomer.enderent = customer.address.toUpperCase();
newCustomer.numeroent = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementoent = customer.complement.substring(0, 80 ).toUpperCase();
if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementoent = customer.complement.substring(0, 80).toUpperCase();
} else {
if ( customer.complement != null ) {
if (customer.complement != null) {
newCustomer.complementoent = customer.complement.toUpperCase();
}
}
@@ -286,10 +286,10 @@ export class CustomerService {
newCustomer.cepcom = customer.zipCode;
newCustomer.endercom = customer.address.toUpperCase();
newCustomer.numerocom = customer.addressNumber.toUpperCase();
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementocom = customer.complement.substring(0, 80 ).toUpperCase();
if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementocom = customer.complement.substring(0, 80).toUpperCase();
} else {
if ( customer.complement != null ) {
if (customer.complement != null) {
newCustomer.complementocom = customer.complement.toUpperCase();
}
}
@@ -300,10 +300,10 @@ export class CustomerService {
newCustomer.cepcob = customer.zipCode;
newCustomer.endercob = customer.address.toUpperCase();
newCustomer.numerocob = customer.addressNumber;
if ( customer.complement !== null && customer.complement.length > 80 ) {
newCustomer.complementocob = customer.complement.substring(0, 80 ).toUpperCase();
if (customer.complement !== null && customer.complement.length > 80) {
newCustomer.complementocob = customer.complement.substring(0, 80).toUpperCase();
} else {
if ( customer.complement ) {
if (customer.complement) {
newCustomer.complementocob = customer.complement.toUpperCase();
}
}
@@ -317,7 +317,7 @@ export class CustomerService {
newCustomer.codmunicipio = Number.parseInt(customer.ibgeCode);
newCustomer.codcidadecom = newCustomer.codcidade;
newCustomer.dtnasc = customer.birthdate;
newCustomer.meiocomunicacao = customer.communicate;
// newCustomer.meiocomunicacao = customer.communicate;
newCustomer.codfunccad = customer.idUser;
newCustomer.codfunccadastro = customer.idUser;
newCustomer.codfuncultalter = customer.idUser;
@@ -341,7 +341,7 @@ export class CustomerService {
city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory,
place: customer.place, ramo: customer.ramo, meiocomunicacao: customer.communicate,
place: customer.place, ramo: customer.ramo, /*meiocomunicacao: customer.communicate,*/
latitude: customer.latitude, longitude: customer.longitude, ibgeCode: customer.ibgeCode,
addressType: customer.addressType,
};
@@ -361,7 +361,7 @@ export class CustomerService {
city: customer.city, state: customer.state,
allowMessage: customer.allowMessage, cellPhone: customer.cellPhone,
category: customer.category, subCategory: customer.subCategory,
place: customer.place, meiocomunicacao: customer.communicate,
place: customer.place, /*meiocomunicacao: customer.communicate,*/
ramo: customer.ramo, latitude: customer.latitude, longitude: customer.longitude,
ibgeCode: customer.ibgeCode, addressType: customer.addressType,
};
@@ -378,7 +378,7 @@ export class CustomerService {
await queryRunner.connect();
await queryRunner.startTransaction();
try {
console.log("MEIO DE COMUNICACAO: " + client.meiocomunicacao);
//console.log("MEIO DE COMUNICACAO: " + client.meiocomunicacao);
await queryRunner.manager
.createQueryBuilder()
.update(Pcclient)
@@ -419,7 +419,7 @@ export class CustomerService {
codcidadecom: client.codcidade,
dtnasc: client.dtnasc,
codatv1: client.codatv1,
meiocomunicacao: client.meiocomunicacao,
// meiocomunicacao: client.meiocomunicacao,
codfuncultalter: client.codfuncultalter,
dtultalter: client.dtultalter,
latitude: client.latitude,
@@ -434,7 +434,7 @@ export class CustomerService {
await queryRunner.rollbackTransaction();
throw err;
} finally {
if ( queryRunner.isTransactionActive) {
if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
await queryRunner.release();
@@ -566,14 +566,14 @@ export class CustomerService {
} catch (err) {
// since we have errors let's rollback changes we made
if ( queryRunner.isTransactionActive) {
if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
console.log(err);
return -1;
} finally {
if ( queryRunner.isTransactionActive) {
if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
// you need to release query runner which is manually created:
@@ -603,7 +603,7 @@ export class CustomerService {
console.log(err);
throw err;
} finally {
if ( queryRunner.isTransactionActive) {
if (queryRunner.isTransactionActive) {
await queryRunner.rollbackTransaction();
}
await queryRunner.release();

View File

@@ -23,7 +23,7 @@ export class SalesService {
constructor(
@Inject('REDIS_CLIENT') private readonly redisClient: Redis.Redis,
private readonly customerService: CustomerService
) {}
) { }
async GetProducts2(store: string, pageSize: number, pageNumber: number, filter: FilterProduct = null,) {
@@ -1211,15 +1211,15 @@ export class SalesService {
const lockKey = 'departments_lock';
const lockTimeout = 30;
try {
const cachedDepartments = await this.redisClient.get(cacheKey);
if (cachedDepartments) {
console.log('Buscando departamentos no Redis');
return JSON.parse(cachedDepartments);
}
} catch (err) {
console.error('Erro ao acessar o Redis (cache):', err);
}
// try {
// const cachedDepartments = await this.redisClient.get(cacheKey);
// if (cachedDepartments) {
// console.log('Buscando departamentos no Redis');
// return JSON.parse(cachedDepartments);
// }
// } catch (err) {
// console.error('Erro ao acessar o Redis (cache):', err);
// }
const lockValue = Date.now() + lockTimeout * 1000 + 1;
const acquiredLock = await this.redisClient.set(lockKey, lockValue, 'NX', 'EX', lockTimeout);
@@ -1234,7 +1234,7 @@ export class SalesService {
.getRepository(Esvdepartamento)
.createQueryBuilder('Esvdepartamento')
.innerJoinAndSelect('Esvdepartamento.secoes', 'secoes')
.innerJoinAndSelect('secoes.categorias', 'categorias')
.leftJoinAndSelect('secoes.categorias', 'categorias')
.where('"Esvdepartamento".tituloecommerce is not null')
.orderBy('"Esvdepartamento".tituloecommerce, "secoes".tituloecommerce, "categorias".tituloecommerce')
.getMany();
@@ -1448,7 +1448,7 @@ export class SalesService {
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
const sql = 'SELECT ESVCALCULOFRETE.CODTABELAFRETE as "id" ' +
/*const sql = 'SELECT ESVCALCULOFRETE.CODTABELAFRETE as "id" ' +
' ,ESVCALCULOFRETE.CODFILIAL as "store" ' +
' ,ESVCALCULOFRETE.CODCIDADE as "cityId" ' +
' ,PCCIDADE.NOMECIDADE as "cityName" ' +
@@ -1462,7 +1462,22 @@ export class SalesService {
' AND ESVCALCULOFRETE.CODCIDADE = PCCIDADE.CODCIDADE ' +
' AND ESVCALCULOFRETE.CODCIDADE = :1 ' +
' AND ESVCALCULOFRETE.IDCART = :2 ' +
' ORDER BY VLFRETE';
' ORDER BY VLFRETE';*/
const sql = `SELECT 0 as "id"
,'1' as "store"
,ESVCALCULOFRETE.CODCIDADE as "cityId"
,PCCIDADE.NOMECIDADE as "cityName"
,NULL as "carrierId"
,'SIMPLIFIQUE HOMECENTER' as "carrierName"
,0 as "minSale"
,ESVCALCULOFRETE.VLFRETE as "deliveryValue"
,NULL as "deliveryTime"
FROM ESVCALCULOFRETE, PCCIDADE
WHERE ESVCALCULOFRETE.CODCIDADE = PCCIDADE.CODCIDADE
AND ESVCALCULOFRETE.CODCIDADE = :1
AND ESVCALCULOFRETE.IDCART = :2
ORDER BY VLFRETE`;
const deliveryTaxTable = await queryRunner.manager
.query(sql, [cityId, cartId]);
@@ -1514,7 +1529,22 @@ export class SalesService {
const queryRunner = connectionDb.createQueryRunner();
await queryRunner.connect();
try {
const sql = 'SELECT ESVCALCULOFRETE.CODTABELAFRETE as "id" ' +
const sql = `SELECT 0 as "id"
,'1' as "store"
,ESVCALCULOFRETE.CODCIDADE as "cityId"
,PCCIDADE.NOMECIDADE as "cityName"
,NULL as "carrierId"
,'SIMPLIFIQUE HOMECENTER' as "carrierName"
,0 as "minSale"
,ESVCALCULOFRETE.VLFRETE as "deliveryValue"
,NULL as "deliveryTime"
FROM ESVCALCULOFRETE, PCCIDADE
WHERE ESVCALCULOFRETE.CODCIDADE = PCCIDADE.CODCIDADE
AND ESVCALCULOFRETE.CODCIDADE = :1
AND ESVCALCULOFRETE.IDCART = :2
ORDER BY VLFRETE`;
/*const sql = 'SELECT ESVCALCULOFRETE.CODTABELAFRETE as "id" ' +
' ,ESVCALCULOFRETE.CODFILIAL as "store" ' +
' ,ESVCALCULOFRETE.CODCIDADE as "cityId" ' +
' ,PCCIDADE.NOMECIDADE as "cityName" ' +
@@ -1528,7 +1558,7 @@ export class SalesService {
' AND ESVCALCULOFRETE.CODCIDADE = PCCIDADE.CODCIDADE ' +
' AND ESVCALCULOFRETE.CODCIDADE = :1 ' +
' AND ESVCALCULOFRETE.IDCART = :2 ' +
' ORDER BY VLFRETE';
' ORDER BY VLFRETE';*/
let deliveryTaxTable = await queryRunner.manager
.query(sql, [dataDeliveryTax.cityId, dataDeliveryTax.cartId]);