2025-10-17 16:58:14 -03:00
|
|
|
const ticketSyncModel = require('./ticketSyncModel');
|
2025-09-24 20:34:34 -03:00
|
|
|
const pool = require('../data/database');
|
|
|
|
|
const { logError } = require('../utils/logger');
|
|
|
|
|
|
2025-10-17 16:58:14 -03:00
|
|
|
|
2025-09-24 20:34:34 -03:00
|
|
|
class TicketUpdateModel {
|
|
|
|
|
|
|
|
|
|
static async insert(updateData) {
|
|
|
|
|
const query = `
|
2025-09-30 15:23:20 -03:00
|
|
|
INSERT INTO ticket_updates (ticket_sync_id, update_type, source_system, content, author, created_at, updated_at, source_id, destiny_id)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
2025-10-10 08:12:26 -03:00
|
|
|
ON CONFLICT (source_id) DO UPDATE SET
|
2025-11-19 16:01:37 -03:00
|
|
|
ticket_sync_id = EXCLUDED.ticket_sync_id,
|
|
|
|
|
update_type = EXCLUDED.update_type,
|
|
|
|
|
source_system = EXCLUDED.source_system,
|
|
|
|
|
content = EXCLUDED.content,
|
|
|
|
|
author = EXCLUDED.author,
|
|
|
|
|
created_at = EXCLUDED.created_at,
|
|
|
|
|
updated_at = EXCLUDED.updated_at,
|
|
|
|
|
destiny_id = EXCLUDED.destiny_id
|
2025-10-17 16:58:14 -03:00
|
|
|
RETURNING *;
|
2025-09-24 20:34:34 -03:00
|
|
|
`;
|
|
|
|
|
const values = [
|
|
|
|
|
updateData.ticket_sync_id,
|
2025-10-29 14:20:21 -03:00
|
|
|
updateData.update_type,
|
2025-09-25 15:59:52 -03:00
|
|
|
updateData.source_system,
|
2025-09-24 20:34:34 -03:00
|
|
|
updateData.content,
|
2025-10-10 08:12:26 -03:00
|
|
|
updateData.author,
|
2025-09-24 20:34:34 -03:00
|
|
|
updateData.created_at,
|
|
|
|
|
updateData.updated_at,
|
2025-09-30 15:23:20 -03:00
|
|
|
updateData.source_id,
|
|
|
|
|
updateData.destiny_id
|
2025-09-24 20:34:34 -03:00
|
|
|
];
|
|
|
|
|
try {
|
|
|
|
|
const { rows } = await pool.query(query, values);
|
|
|
|
|
return { success: true, newId: rows[0].id };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logError(error, '❌ Erro ao inserir ticket_update');
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-23 17:30:03 -03:00
|
|
|
static async getBySourceId(sourceId) {
|
2025-10-10 08:12:26 -03:00
|
|
|
try {
|
2025-10-23 17:30:03 -03:00
|
|
|
const query = 'SELECT * FROM ticket_updates WHERE source_id = $1';
|
2025-10-10 08:12:26 -03:00
|
|
|
const { rows } = await pool.query(query, [sourceId]);
|
2025-09-24 20:34:34 -03:00
|
|
|
return rows[0] || null;
|
|
|
|
|
} catch (error) {
|
2025-10-23 17:30:03 -03:00
|
|
|
logError(error, `❌ Erro ao buscar ticket_update por source_id: ${sourceId}`);
|
2025-09-24 20:34:34 -03:00
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-02 10:16:56 -03:00
|
|
|
static async getDestinyIdBySourceId(sourceId) {
|
|
|
|
|
try {
|
|
|
|
|
const query = `
|
|
|
|
|
SELECT destiny_id FROM ticket_updates
|
|
|
|
|
WHERE source_id = $1
|
|
|
|
|
`;
|
|
|
|
|
const { rows } = await pool.query(query, [sourceId]);
|
|
|
|
|
return rows[0] ? rows[0].destiny_id : null;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logError(error, '❌ Erro ao buscar destiny_id por source_id');
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static async updateDestinyId(sourceId, destinyId) {
|
|
|
|
|
try {
|
|
|
|
|
const query = `
|
|
|
|
|
UPDATE ticket_updates
|
|
|
|
|
SET destiny_id = $1
|
|
|
|
|
WHERE source_id = $2
|
|
|
|
|
`;
|
|
|
|
|
await pool.query(query, [destinyId, sourceId]);
|
|
|
|
|
return { success: true, destiny_id: destinyId };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logError(error, '❌ Erro ao atualizar destiny_id por source_id');
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-23 17:30:03 -03:00
|
|
|
static async getLatestUpdate(ticketSyncId, sourceSystem, updateType = null) {
|
|
|
|
|
try {
|
|
|
|
|
let query = `
|
|
|
|
|
SELECT * FROM ticket_updates
|
|
|
|
|
WHERE ticket_sync_id = $1 AND source_system = $2
|
|
|
|
|
`;
|
|
|
|
|
const values = [ticketSyncId, sourceSystem];
|
|
|
|
|
|
|
|
|
|
if (updateType) {
|
|
|
|
|
query += ` AND update_type = $3`;
|
|
|
|
|
values.push(updateType);
|
|
|
|
|
}
|
|
|
|
|
query += ` ORDER BY created_at DESC LIMIT 1`;
|
|
|
|
|
|
|
|
|
|
const { rows } = await pool.query(query, values);
|
|
|
|
|
return rows[0] || null;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logError(error, `❌ Erro ao buscar último update para ticket_sync_id: ${ticketSyncId}`);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-02 10:16:56 -03:00
|
|
|
}
|
2025-10-29 14:20:21 -03:00
|
|
|
|
|
|
|
|
module.exports = TicketUpdateModel;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @module TicketUpdateModel
|
|
|
|
|
* @description Este módulo gerencia a tabela `ticket_updates`, que serve como um log persistente de todas as atualizações (comentários, mudanças de status, etc.)
|
|
|
|
|
* que ocorrem em ambos os sistemas. Ele é fundamental para a sincronização de comentários e para evitar a duplicação de dados.
|
|
|
|
|
*
|
|
|
|
|
* Funcionalidades:
|
|
|
|
|
* - `insert(updateData)`: Insere ou atualiza (UPSERT) um registro de atualização. A cláusula `ON CONFLICT` é usada para evitar duplicatas com base no `source_id`.
|
|
|
|
|
* - `getBySourceId(sourceId)`: Verifica se uma atualização específica (ex: um comentário com um determinado ID) já foi registrada no banco de dados.
|
|
|
|
|
* - `updateDestinyId(sourceId, destinyId)`: Após uma atualização ser sincronizada com o sistema de destino, este método armazena o ID gerado no destino, completando o ciclo de mapeamento.
|
|
|
|
|
* - `getLatestUpdate(...)`: Busca a atualização mais recente para um determinado ticket, útil para obter notas de fechamento, por exemplo.
|
|
|
|
|
*/
|