Skip to content

Commit 422f16f

Browse files
Merge pull request RyanCNP#103 from RyanCNP/feature/monitoramento
Feature/monitoramento
2 parents f297721 + 2ced7fe commit 422f16f

28 files changed

Lines changed: 602 additions & 137 deletions

.github/workflows/develop-actions.yml

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: CI / CD - develop (preview)
22

33
on:
44
push:
5-
branches:
5+
branches:
66
- develop
77

88
jobs:
@@ -111,21 +111,26 @@ jobs:
111111
username: ${{ secrets.DOCKER_USERNAME }}
112112
password: ${{ secrets.DOCKER_PASSWORD }}
113113

114-
- name: Extrai metadatas para o Docker
115-
id: meta
114+
# Docker Image Back-DEV
115+
116+
- name: Extrai metadatas para a Imagem Back-Dev
117+
id: metaDev
116118
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
117119
with:
118-
images: saneasp/sanea-back
120+
images: saneasp/front-back-dev
121+
tags: |
122+
type=raw,value=${{ steps.version.outputs.new_version }}
123+
type=raw,value=latest
119124
120-
- name: Build e publicação da imagem Docker
121-
id: push
125+
- name: Build e publicação da Imagem Back-Dev
126+
id: pushDev
122127
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
123128
with:
124129
context: .
125-
file: ./Dockerfile
130+
file: ./Dockerfile.dev
126131
push: true
127-
tags: ${{ steps.meta.outputs.tags }}
128-
labels: ${{ steps.meta.outputs.labels }}
132+
tags: ${{ steps.metaDev.outputs.tags }}
133+
labels: ${{ steps.metaDev.outputs.labels }}
129134
env:
130135
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
131136

@@ -137,7 +142,6 @@ jobs:
137142
if: failure()
138143

139144
steps:
140-
141145
# --- Checkout do código ---
142146
- name: Checkout code
143147
uses: actions/checkout@v3
@@ -175,4 +179,4 @@ jobs:
175179
subject: "🚨 Falha no Pipeline - ${{ github.ref_name }}"
176180
to: "${{ secrets.TEAM_EMAILS }}"
177181
from: "CI/CD SaneaSP <no-reply@saneasp.com>"
178-
html_body: ${{ steps.template.outputs.html }}
182+
html_body: ${{ steps.template.outputs.html }}

.github/workflows/main-actions.yml

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ jobs:
3131
3232
echo "✔ Mensagem válida."
3333
34-
3534
# --- Instalar dependências ---
3635
- name: Instalar dependências
3736
run: npm ci
@@ -144,35 +143,106 @@ jobs:
144143
draft: false
145144
prerelease: false
146145
env:
147-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
146+
GITHUB_TOKEN:
147+
${{ secrets.GITHUB_TOKEN }}
148148

149-
# ---- Imagem Docker -----
149+
# Docker Login
150150
- name: Login Docker Hub
151151
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
152152
with:
153153
username: ${{ secrets.DOCKER_USERNAME }}
154154
password: ${{ secrets.DOCKER_PASSWORD }}
155155

156-
- name: Extrai metadatas para o Docker
157-
id: meta
156+
# Docker Image Back-PROD
157+
- name: Extrai metadatas para a Imagem Back-Prod
158+
id: metaProd
158159
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
159160
with:
160-
images: saneasp/back-sanea
161+
images: ${{ secrets.DOCKER_USERNAME }}/back-sanea-prod
161162
tags: |
162163
type=raw,value=${{ steps.version.outputs.new_version }}
163164
type=raw,value=latest
164165
165-
- name: Build e publicação da imagem Docker
166-
id: push
166+
- name: Build e publicação da Imagem Back-Prod
167+
id: pushProd
167168
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
168169
with:
169170
context: .
170171
file: ./Dockerfile
171172
push: true
172-
tags: ${{ steps.meta.outputs.tags }}
173-
labels: ${{ steps.meta.outputs.labels }}
173+
tags: ${{ steps.metaProd.outputs.tags }}
174+
labels: ${{ steps.metaProd.outputs.labels }}
175+
env:
176+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
177+
178+
# Docker Image Back-DEV
179+
180+
- name: Extrai metadatas para a Imagem Back-Dev
181+
id: metaDev
182+
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
183+
with:
184+
images: ${{ secrets.DOCKER_USERNAME }}/back-sanea-dev
185+
tags: |
186+
type=raw,value=${{ steps.version.outputs.new_version }}
187+
type=raw,value=latest
188+
189+
- name: Build e publicação da Imagem Back-Dev
190+
id: pushDev
191+
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
192+
with:
193+
context: .
194+
file: ./Dockerfile.dev
195+
push: true
196+
tags: ${{ steps.metaDev.outputs.tags }}
197+
labels: ${{ steps.metaDev.outputs.labels }}
174198
env:
175199
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
200+
# --- Deploy automático via Render ---
201+
- name: Deploy via Render API
202+
env:
203+
RENDER_API_KEY: ${{secrets.RENDER_API_KEY}}
204+
SERVICE_ID: ${{secrets.SERVICE_ID}}
205+
REPO_NAME: ${{secrets.REPO_NAME_PROD}}
206+
run: |
207+
echo "Criando payload para deploy da versão latest"
208+
209+
PAYLOAD=$(jq -n \
210+
--arg image "docker.io/${{ secrets.DOCKER_USERNAME }}/$REPO_NAME:latest" \
211+
--arg version "latest" \
212+
'{
213+
clearCache: "clear",
214+
imageUrl: $image,
215+
overrideImage: true,
216+
imagePullPolicy: "Always"
217+
}'
218+
)
219+
220+
echo "Payload JSON gerado:"
221+
echo "$PAYLOAD" | jq .
222+
223+
echo "Iniciando deploy no Render..."
224+
225+
RESPONSE=$(curl -i -s -X POST \
226+
"https://api.render.com/v1/services/$SERVICE_ID/deploys" \
227+
-H "Accept: application/json" \
228+
-H "Content-Type: application/json" \
229+
-H "Authorization: Bearer $RENDER_API_KEY" \
230+
-d "$PAYLOAD"
231+
)
232+
233+
echo "Resposta completa:"
234+
echo "$RESPONSE"
235+
236+
HTTP_STATUS=$(echo "$RESPONSE" | grep HTTP | awk '{print $2}')
237+
238+
echo "Status da resposta HTTP: $HTTP_STATUS"
239+
240+
if [[ "$HTTP_STATUS" =~ ^2[0-9]{2}$ ]]; then
241+
echo "Deploy iniciado com sucesso!"
242+
else
243+
echo "Falha no deploy!"
244+
exit 1
245+
fi
176246
177247
# --- Enviar e-mail em caso de falha ---
178248
notify_failure:
@@ -182,7 +252,6 @@ jobs:
182252
if: failure()
183253

184254
steps:
185-
186255
# --- Checkout do código ---
187256
- name: Checkout code
188257
uses: actions/checkout@v3
@@ -220,4 +289,4 @@ jobs:
220289
subject: "🚨 Falha no Pipeline - ${{ github.ref_name }}"
221290
to: "${{ secrets.TEAM_EMAILS }}"
222291
from: "CI/CD SaneaSP <no-reply@saneasp.com>"
223-
html_body: ${{ steps.template.outputs.html }}
292+
html_body: ${{ steps.template.outputs.html }}

Dockerfile

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
# Usar a imagem do Node.js
2-
FROM node:16-alpine
3-
4-
# Criar diretório de trabalho
1+
# Etapa 1: Build Angular
2+
FROM node:20 AS build
53
WORKDIR /app
64

7-
# Copiar apenas package.json para instalar dependências
85
COPY package*.json ./
9-
10-
# Instalar dependências
116
RUN npm install
127

13-
# Copiar restante do código
148
COPY . .
9+
RUN npm run build
1510

16-
# Expor a porta da API
1711
EXPOSE 3000
1812

19-
# Rodar em modo desenvolvimento
20-
CMD ["npm", "run", "dev"]
13+
CMD [ "npm","run","start" ]

Dockerfile.dev

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Usar a imagem do Node.js
2+
FROM node:16-alpine
3+
4+
# Criar diretório de trabalho
5+
WORKDIR /app
6+
7+
# Copiar apenas package.json para instalar dependências
8+
COPY package*.json ./
9+
10+
# Instalar dependências
11+
RUN npm install
12+
13+
# Copiar restante do código
14+
COPY . .
15+
16+
# Expor a porta da API
17+
EXPOSE 3000
18+
19+
# Rodar em modo desenvolvimento
20+
CMD ["npm", "run", "dev"]

app.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ import bodyParser from "body-parser";
1919
import stripeRoutes from "./src/routes/stripe.routes";
2020
import RegistroRoutes from './src/routes/registro.routes';
2121
import VisitasRoutes from './src/routes/visita.routes';
22+
import { logHandler } from "./src/middlewares/log.middleware";
2223

2324
const app = express();
2425

2526
app.use(cors());
26-
2727
app.use('/api/stripe/webhook', bodyParser.raw({ type: 'application/json' }));
2828

2929
app.use(express.json());
3030

3131
setupSwagger(app);
3232

33+
app.use(logHandler);
3334
app.use("/categoria", categoriaRoutes);
3435
app.use("/denuncia", denunciaRoutes);
3536
app.use("/user", userRoutes);

config/config.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ const env = process.env.NODE_ENV || "development";
44

55
let config;
66

7-
if (env === "development") {
7+
if (env === "test") {
8+
config = {
9+
dialect: "sqlite",
10+
storage: "database.sqlite",
11+
logging: false,
12+
};
13+
}
14+
else if (env === "development") {
815
config = {
916
url: process.env.DEV_DATABASE_URL,
1017
dialect: "postgres",

docker-compose.yaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,24 @@ services:
33
container_name: postgres
44
image: postgres:latest
55
ports:
6-
- '5423:5432'
6+
- '5432:5432'
77
environment:
88
POSTGRES_PASSWORD: "1234"
99
POSTGRES_USER: postgres
1010
POSTGRES_DB: sanea
11+
back:
12+
image: saneasp/back-sanea-prod:latest
13+
ports:
14+
- '3000:3000'
15+
env_file:
16+
- ./.env
17+
environment:
18+
- NODE_ENV=development
19+
- DEV_DATABASE_URL=postgresql://postgres:1234@banco:5432/postgres
20+
depends_on:
21+
- banco
22+
23+
front:
24+
image: saneasp/front-sanea-prod:latest
25+
ports:
26+
- '4200:80'

logger-winston.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
import winston from "winston";
3+
import { Logtail } from '@logtail/node';
4+
import { LogtailTransport } from "@logtail/winston";
5+
6+
const log = process.env.LOGTAIL_TOKEN;
7+
let logtail!: Logtail;
8+
if (log) {
9+
logtail = new Logtail(log, {
10+
endpoint: process.env.LOGTAIL_URI,
11+
});
12+
}
13+
14+
logtail.info('teste');
15+
16+
/** Criando a instância base com formatação */
17+
const baseLogger = winston.createLogger({
18+
level: 'debug',
19+
format: winston.format.combine(
20+
winston.format.timestamp(),
21+
winston.format.printf(({ level, message, timestamp, ...rest }) => {
22+
const meta = Object.keys(rest).length ? JSON.stringify(rest) : '';
23+
return `[${timestamp}] ${level.toUpperCase()}: ${message} ${meta}`;
24+
})
25+
),
26+
transports: [new LogtailTransport(logtail)],
27+
});
28+
29+
/** Métodos personalizados */
30+
const logger = {
31+
info: (msg:string, meta = {}) => baseLogger.info(msg, meta),
32+
warn: (msg:string, meta = {}) => baseLogger.warn(msg, meta),
33+
error: (msg:string, meta = {}) => baseLogger.error(msg, meta),
34+
debug: (msg:string, meta = {}) => baseLogger.debug(msg, meta),
35+
alert: (msg:string, meta = {}) => baseLogger.log('alert', msg, meta), // nível customizado (precisa configurar abaixo)
36+
};
37+
38+
// Adicionando nível "alert" (opcional)
39+
baseLogger.levels['alert'] = 0;
40+
baseLogger.add(new winston.transports.Console()); // Adiciona log no console também, se quiser
41+
42+
export default logger;

migrations/20250925202854-alter-table-usuario-endereco.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = {
3838
await queryInterface.removeColumn("usuario", "cidade");
3939
await queryInterface.removeColumn("usuario", "bairro");
4040
await queryInterface.removeColumn("usuario", "cep");
41-
await queryInterface.removeColumn("usuario", "complmento");
41+
await queryInterface.removeColumn("usuario", "complemento");
4242
await queryInterface.removeColumn("usuario", "numero");
4343

4444
await queryInterface.addColumn("usuario", "endereco", {

migrations/20251120145923-alter-table-denuncia-status-endereco.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
module.exports = {
55
async up (queryInterface, Sequelize) {
66
// Alterar status para string e default 'aberto'
7-
await queryInterface.changeColumn('denuncia', 'status', {
7+
await queryInterface.removeColumn('denuncia','status');
8+
await queryInterface.addColumn('denuncia', 'status', {
89
type: Sequelize.STRING(50),
910
allowNull: false,
1011
defaultValue: 'aberto'
@@ -31,11 +32,8 @@ module.exports = {
3132

3233
async down (queryInterface, Sequelize) {
3334
// Reverter status para integer e default 0
34-
await queryInterface.changeColumn('denuncia', 'status', {
35-
type: Sequelize.INTEGER,
36-
allowNull: true,
37-
defaultValue: 0
38-
});
35+
36+
//await queryInterface.removeColumn('denuncia','status');
3937

4038
// Reverter campos para allowNull true
4139
await queryInterface.changeColumn('denuncia', 'cep', {

0 commit comments

Comments
 (0)