- **Sincronização Inteligente:** O sistema agora detecta mudanças de estado em qualquer uma das plataformas e propaga a atualização para a outra, respeitando a 'fonte da verdade' (`source_last`). - **Regra 'Fora do Escopo':** Implementada a regra de negócio para tickets marcados como 'Fora do Escopo' no GLPI (solutiontypes_id = 27). Esses tickets agora são ignorados na sincronização, têm seu status finalizado no GLPI e uma nota informativa é adicionada no ServiceNow. - **Watermark (Marca d'água):** A coleta de novos tickets do ServiceNow foi otimizada com um sistema de marca d'água, buscando apenas registros atualizados desde a última execução bem-sucedida, o que melhora significativamente a performance. - **Resiliência:** Adicionado um `processErrorController` que reseta tickets com status de erro, permitindo que sejam reprocessados automaticamente no próximo ciclo. Testes de fluxo foram realizados com sucesso, validando a criação, resolução (SN <-> GLPI) e a regra 'Fora do Escopo'. Pendências para a próxima fase: 1. Validar melhor o fluxo de reabertura de chamados em ambas as direções. 2. Garantir que a `work_note` enviada para o ServiceNow na regra 'Fora do Escopo' seja devidamente sanitizada."
38 lines
1.4 KiB
JavaScript
38 lines
1.4 KiB
JavaScript
// src/models/syncControlModel.js
|
|
const pool = require('../data/database');
|
|
const { logError, logInfo } = require('../utils/logger');
|
|
|
|
class SyncControlModel {
|
|
static async getWatermark(systemName) {
|
|
try {
|
|
const query = 'SELECT last_watermark FROM sync_control WHERE system_name = $1';
|
|
const { rows } = await pool.query(query, [systemName]);
|
|
if (rows.length === 0) {
|
|
throw new Error(`Watermark para o sistema '${systemName}' não encontrada no banco de dados.`);
|
|
}
|
|
// Retorna no formato que o ServiceNow espera: 'YYYY-MM-DD HH:MM:SS'
|
|
return rows[0].last_watermark.toISOString().replace('T', ' ').substring(0, 19);
|
|
} catch (error) {
|
|
logError(error, `Erro ao buscar watermark para ${systemName}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async setWatermark(systemName, watermark) {
|
|
try {
|
|
const query = `
|
|
UPDATE sync_control
|
|
SET last_watermark = $1, last_run_at = NOW(), last_run_status = 'success'
|
|
WHERE system_name = $2
|
|
`;
|
|
await pool.query(query, [watermark, systemName]);
|
|
logInfo(`🌊 Nova marca d'água para '${systemName}' definida para: ${watermark}`);
|
|
} catch (error) {
|
|
logError(error, `Erro ao definir watermark para ${systemName}`);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = SyncControlModel;
|