FEAT: Banco de dados

- 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
This commit is contained in:
Rafael Alves Lopes 2025-10-06 20:11:54 -03:00
parent cd33f445ce
commit 2625c45d91
4 changed files with 179 additions and 1 deletions

9
.env
View File

@ -5,3 +5,12 @@ 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&"
# 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

31
data/hubglpiDataBase.js Normal file
View File

@ -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.
*/

56
scripts/data/database.sql Normal file
View File

@ -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'
);

82
utils/logger.js Normal file
View File

@ -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
};