From cd33f445ce8727bafaedfb6e42f0965eee3d77c1 Mon Sep 17 00:00:00 2001 From: tulioperdigao <116309232+tulioperdigao@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:53:04 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Adiciona=20coment=C3=A1rio=20para=20a=20fun?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20consulta=20de=20atendimentos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/hubsoftServices.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/hubsoftServices.js b/services/hubsoftServices.js index 29ade98..1d2a735 100644 --- a/services/hubsoftServices.js +++ b/services/hubsoftServices.js @@ -12,6 +12,8 @@ async function getAuthToken() { } } +// Função para consultar atendimentos + const consultarAtendimento = async () => { try { const token = await getAuthToken(); From 2625c45d91df4ff668be39af4a785b3473ca3b69 Mon Sep 17 00:00:00 2001 From: Rafael Lopes Date: Mon, 6 Oct 2025 20:11:54 -0300 Subject: [PATCH 2/2] FEAT: Banco de dados MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adiciona configuração de conexão com o banco de dados PostgreSQL - Implementa logger para registro de eventos - Adiciona script usado no banco de dados --- .env | 11 +++++- data/hubglpiDataBase.js | 31 +++++++++++++++ scripts/data/database.sql | 56 ++++++++++++++++++++++++++ utils/logger.js | 82 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 data/hubglpiDataBase.js create mode 100644 scripts/data/database.sql create mode 100644 utils/logger.js diff --git a/.env b/.env index e2732b3..bdfa4c2 100644 --- a/.env +++ b/.env @@ -4,4 +4,13 @@ HUBSOFT_CLIENT_SECRET=1s62YsDijmzLz17NaKbnK1AUCKAx10RSDPMOtVcN HUBSOFT_USERNAME=contato@vexvigilancia.com.br HUBSOFT_PASSWORD="19T(6Jnp*" HUBSOFT_GRANT_TYPE=password -HUBSOFT_CONSULTAR_ATENDIMENTO_URL="https://api.sothis.hubsoft.com.br/api/v1/integracao/atendimento/todos?pagina=0&itens_por_pagina=500&" \ No newline at end of file +HUBSOFT_CONSULTAR_ATENDIMENTO_URL="https://api.sothis.hubsoft.com.br/api/v1/integracao/atendimento/todos?pagina=0&itens_por_pagina=500&" + +# Banco HUBGLPI (PostgreSQL) +HUBGLPI_DB_HOST=10.0.120.75 +HUBGLPI_DB_PORT=5432 +HUBGLPI_DB_NAME=hubglpi +HUBGLPI_DB_USER=desenvolvimento +HUBGLPI_DB_PASSWORD=Ut@2S@$M9Xs@@W + +NODE_ENV=development \ No newline at end of file diff --git a/data/hubglpiDataBase.js b/data/hubglpiDataBase.js new file mode 100644 index 0000000..9ddf9a3 --- /dev/null +++ b/data/hubglpiDataBase.js @@ -0,0 +1,31 @@ +// src/data/hubglpiDataBase.js +// Configuração da conexão com o banco de dados PostgreSQL +const { logInfo, logError } = require('../utils/logger'); + +const { Pool } = require('pg'); + +const pool = new Pool({ + host: process.env.HUBGLPI_DB_HOST, + port: process.env.HUBGLPI_DB_PORT, + database: process.env.HUBGLPI_DB_NAME, + user: process.env.HUBGLPI_DB_USER, + password: process.env.HUBGLPI_DB_PASSWORD, +}); + +// Teste de conexão +pool.on('connect', () => { + logInfo('Conexão com o banco de dados PostgreSQL estabelecida com sucesso.'); +}); + +pool.on('error', (err) => { + logError('Erro na conexão com o banco de dados PostgreSQL', err); +}); + + + +module.exports = pool; + +/** + * @module hubglpiDataBase + * @description Este módulo configura e exporta a conexão com o banco de dados PostgreSQL usado para armazenar dados sincronizados entre HubSoft e GLPI. +*/ \ No newline at end of file diff --git a/scripts/data/database.sql b/scripts/data/database.sql new file mode 100644 index 0000000..f4b225b --- /dev/null +++ b/scripts/data/database.sql @@ -0,0 +1,56 @@ +-- ============================================= +-- BANCO DE DADOS: hubglpi +-- DESCRIÇÃO: Sistema de integração entre HubSoft e GLPI +-- OBS: Chamados sempre são abertos pelo HubSoft +-- ============================================= + + +-- ============================================= +-- TABELA: hubsoft_tickets +-- DESCRIÇÃO: Armazena os chamados originados do HubSoft +-- ============================================= +CREATE TABLE hubsoft_tickets ( + id SERIAL PRIMARY KEY, + protocolo VARCHAR(50) UNIQUE NOT NULL, + descricao_abertura TEXT NOT NULL, + descricao_fechamento TEXT, + tipo_atendimento VARCHAR(100), + cliente_codigo INTEGER NOT NULL, + cliente_nome VARCHAR(255) NOT NULL, + servico_id VARCHAR(50), + servico_nome VARCHAR(255), + data_abertura TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + data_fechamento TIMESTAMP, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- ============================================= +-- TABELA: sync_data +-- DESCRIÇÃO: Armazena o estado da sincronização entre HubSoft e GLPI +-- ============================================= + +CREATE TABLE sync_logs ( + id SERIAL PRIMARY KEY, + hubsoft_ticket_id INTEGER NOT NULL REFERENCES hubsoft_tickets(id), + glpi_ticket_id INTEGER, + source_last source_last_enum DEFAULT 'hubsoft', + status_sync status_sync_enum DEFAULT 'pending_create', + sync_metadata JSONB, + last_sync_attempt TIMESTAMP, + sync_error_message TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE (hubsoft_ticket_id, glpi_ticket_id) +); + +CREATE TYPE source_last_enum AS ENUM ('hubsoft', 'glpi'); +CREATE TYPE status_sync_enum AS ENUM ( + 'pending_create', + 'created_glpi', + 'pending_close', + 'closed_glpi', + 'sync_error', + 'need_update' +); + diff --git a/utils/logger.js b/utils/logger.js new file mode 100644 index 0000000..1aec85a --- /dev/null +++ b/utils/logger.js @@ -0,0 +1,82 @@ +const winston = require('winston'); +const path = require('path'); +const fs = require('fs'); + +// verifica se a pasta de logs existe, se não, cria +const logsDir = path.join(__dirname, '../../logs'); +if (!fs.existsSync(logsDir)) { + fs.mkdirSync(logsDir, { recursive: true }); +} + +// Configuração do logger com winston +const logger = winston.createLogger({ + level: 'info', + format: winston.format.combine( + winston.format.timestamp({ + format: 'YYYY-MM-DD HH:mm:ss' + }), + winston.format.errors({ stack: true }), // ← Mostra stack trace de erros + winston.format.json() + ), + transports: [ + // Log geral da aplicação + new winston.transports.File({ + filename: path.join(logsDir, 'app.log'), + maxsize: 5242880, // 5MB + maxFiles: 5 + }), + // Log de erros + new winston.transports.File({ + filename: path.join(logsDir, 'error.log'), + level: 'error', + maxsize: 5242880, + maxFiles: 3 + }), + ], +}); + +// Log no console em desenvolvimento +if (process.env.NODE_ENV !== 'production') { + logger.add(new winston.transports.Console({ + format: winston.format.combine( + winston.format.colorize(), + winston.format.printf(({ timestamp, level, message, stack }) => { + return `${timestamp} [${level}]: ${stack || message}`; + }) + ) + })); +} + +// Funções utilitárias +const logError = (error, context = '') => { + if (error instanceof Error) { + logger.error(`${context} - ${error.message}`, { stack: error.stack }); + } else { + logger.error(`${context} - ${error}`); + } +}; + +const logInfo = (message, meta = {}) => { + logger.info(message, meta); +}; + +const logWarning = (message, meta = {}) => { + logger.warn(message, meta); +}; + +// Log de sincronização específico +const logSync = (service, count, type) => { + logger.info(`SYNC: ${service} - ${count} ${type} sincronizados`, { + service, + count, + type + }); +}; + +module.exports = { + logger, + logError, + logInfo, + logWarning, + logSync +}; \ No newline at end of file