REFACTOR: Preparando WatchDog para nova feature
This commit is contained in:
parent
c1f52d741f
commit
ad28159185
232
fluxoEntidade.md
Normal file
232
fluxoEntidade.md
Normal file
@ -0,0 +1,232 @@
|
||||
# Fluxo de Resolução e Criação de Entidades (GLPI)
|
||||
|
||||
## Contexto
|
||||
|
||||
Quando um chamado de **Implantação** chega no Hub x GLPI, precisamos garantir que exista uma **Entidade** correta no GLPI para vincular o ticket.
|
||||
|
||||
Hoje, a resolução tenta encontrar a entidade pelo padrão de nome baseado em:
|
||||
- `codigoCliente`
|
||||
- `codigoServico`
|
||||
- `nomeCliente`
|
||||
|
||||
Caso não encontre, entra a feature de **criação automática via API (GLPI v2 + OAuth)**.
|
||||
|
||||
> Regra importante: **criação/alteração de entidades sempre via API**, nunca via banco do GLPI.
|
||||
|
||||
---
|
||||
|
||||
## Convenções de Nome
|
||||
|
||||
### Entidade mãe (Cliente)
|
||||
- **Formato:** `{codigoCliente} - {nomeCliente}`
|
||||
- **Exemplo:** `12345 - ACME Telecom`
|
||||
|
||||
### Entidade filha (Serviço)
|
||||
- **Formato:** `{codigoCliente} - {codigoServico} - {nomeCliente}`
|
||||
- **Exemplo:** `12345 - 67890 - ACME Telecom`
|
||||
|
||||
> Observação: O `{nomeCliente}` é repetido na filha para manter legibilidade e facilitar busca manual no GLPI.
|
||||
|
||||
---
|
||||
|
||||
## Busca de Entidades
|
||||
|
||||
### Busca por Serviço (Entidade filha)
|
||||
Procura por entidade que contenha:
|
||||
- `{codigoCliente} - {codigoServico}` (prefixo/like)
|
||||
|
||||
### Busca por Cliente (Entidade mãe)
|
||||
Procura por entidade que contenha:
|
||||
- `{codigoCliente} -` (prefixo/like)
|
||||
|
||||
---
|
||||
|
||||
## Opção A — Criação hierárquica (Mãe + Filha quando necessário)
|
||||
|
||||
### Objetivo
|
||||
Garantir hierarquia consistente no GLPI:
|
||||
- Cliente como entidade mãe
|
||||
- Serviço como entidade filha
|
||||
|
||||
### Fluxo (passo a passo)
|
||||
|
||||
1. **Tentar encontrar entidade por Serviço**
|
||||
- Busca: `{codigoCliente} - {codigoServico}*`
|
||||
- Se encontrou:
|
||||
- ✅ usar essa entidade (filha) e finalizar
|
||||
|
||||
2. **Se não encontrou por Serviço: tentar encontrar entidade por Cliente**
|
||||
- Busca: `{codigoCliente} -*`
|
||||
- Se encontrou:
|
||||
- ✅ criar **entidade filha** abaixo dessa mãe:
|
||||
- Nome: `{codigoCliente} - {codigoServico} - {nomeCliente}`
|
||||
- Parent: `{codigoCliente} - {nomeCliente}`
|
||||
- ✅ usar a entidade criada (filha) e finalizar
|
||||
|
||||
3. **Se não encontrou nem por Serviço nem por Cliente**
|
||||
- Criar **entidade mãe**:
|
||||
- Nome: `{codigoCliente} - {nomeCliente}`
|
||||
- Parent: raiz (definir entidade pai padrão, ex.: Root)
|
||||
- Criar **entidade filha** abaixo da mãe:
|
||||
- Nome: `{codigoCliente} - {codigoServico} - {nomeCliente}`
|
||||
- Parent: `{codigoCliente} - {nomeCliente}`
|
||||
- ✅ usar a entidade criada (filha) e finalizar
|
||||
|
||||
### Resultado final (Opção A)
|
||||
- Ticket sempre fica na **entidade filha** (serviço)
|
||||
- Sempre tenta manter **estrutura hierárquica** consistente
|
||||
|
||||
---
|
||||
|
||||
### Diagrama de Fluxo — Opção A (hierárquica: Mãe + Filha quando necessário)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Chamado de Implantação chega do Hub] --> B[Extrair dados<br/>codigoCliente<br/>codigoServico<br/>nomeCliente]
|
||||
|
||||
B --> C{Existe entidade<br/>por Serviço?}
|
||||
C -->|Sim| D[Usar entidade de Serviço]
|
||||
D --> Z[Fim / Continua fluxo do ticket]
|
||||
|
||||
C -->|Não| E{Existe entidade<br/>por Cliente?}
|
||||
|
||||
E -->|Sim| F[Criar entidade de Serviço<br/>via API GLPI]
|
||||
F --> G[Parent = Entidade Cliente<br/>Nome = codigoCliente-codigoServico-nomeCliente]
|
||||
G --> Z
|
||||
|
||||
E -->|Não| H[Criar entidade Cliente<br/>via API GLPI]
|
||||
H --> I[Parent = Contratos Ativos<br/>Nome = codigoCliente-nomeCliente]
|
||||
|
||||
I --> J[Criar entidade de Serviço<br/>via API GLPI]
|
||||
J --> K[Parent = Entidade Cliente<br/>Nome = codigoCliente-codigoServico-nomeCliente]
|
||||
K --> Z
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Opção B — Criação simplificada (sem forçar hierarquia)
|
||||
|
||||
### Objetivo
|
||||
Criar o mínimo possível e evitar duplicação de entidades.
|
||||
|
||||
### Fluxo (passo a passo)
|
||||
|
||||
1. **Tentar encontrar entidade por Serviço**
|
||||
- Busca: `{codigoCliente} - {codigoServico}*`
|
||||
- Se encontrou:
|
||||
- ✅ usar essa entidade e finalizar
|
||||
|
||||
2. **Se não encontrou por Serviço: tentar encontrar entidade por Cliente**
|
||||
- Busca: `{codigoCliente} -*`
|
||||
- Se encontrou:
|
||||
- ✅ usar essa entidade mãe
|
||||
- ❌ não cria entidade filha
|
||||
- Finaliza
|
||||
|
||||
3. **Se não encontrou nem por Serviço nem por Cliente**
|
||||
- Criar **uma entidade única (sem mãe)**:
|
||||
- Nome: `{codigoCliente} - {codigoServico} - {nomeCliente}`
|
||||
- Parent: raiz (ou padrão definido)
|
||||
- ✅ usar essa entidade e finalizar
|
||||
|
||||
### Resultado final (Opção B)
|
||||
- Ticket pode ficar:
|
||||
- na entidade de serviço (se existir)
|
||||
- ou na entidade de cliente (se existir)
|
||||
- ou numa entidade única criada
|
||||
- Não garante hierarquia “mãe → filha”
|
||||
|
||||
---
|
||||
|
||||
### Fluxo Opção B
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Chamado de Implantação chega do Hub] --> B[Extrair dados<br/>codigoCliente<br/>codigoServico<br/>nomeCliente]
|
||||
|
||||
B --> C{Existe entidade<br/>por Serviço?}
|
||||
C -->|Sim| D[Usar entidade de Serviço]
|
||||
D --> Z[Fim / Continua fluxo do ticket]
|
||||
|
||||
C -->|Não| E{Existe entidade<br/>por Cliente?}
|
||||
|
||||
E -->|Sim| F[Usar entidade de Cliente]
|
||||
F --> Z
|
||||
|
||||
E -->|Não| G[Criar entidade Única<br/>via API GLPI]
|
||||
G --> H[Parent = Root<br/>Nome = codigoCliente-codigoServico-nomeCliente]
|
||||
H --> Z
|
||||
```
|
||||
|
||||
## Opção C — Híbrida (Implantação cria; demais apenas resolvem)
|
||||
|
||||
### Objetivo
|
||||
- Para **Implantação**: garantir estrutura correta criando entidades quando necessário (igual Opção A).
|
||||
- Para **demais tipos de chamado**: **não criar entidades**, apenas resolver a melhor entidade existente; se não houver, usar fallback **Contratos Ativos**.
|
||||
|
||||
---
|
||||
|
||||
### Fluxo (passo a passo)
|
||||
|
||||
#### 1) Identificar tipo do chamado
|
||||
- Se `tipo == Implantação` → executar **Fluxo A (criação hierárquica)**.
|
||||
- Se `tipo != Implantação` → executar **Fluxo de Resolução sem criação**.
|
||||
|
||||
---
|
||||
|
||||
### Fluxo A (quando Implantação)
|
||||
Segue exatamente a **Opção A**:
|
||||
1. Buscar entidade por Serviço (`{codigoCliente} - {codigoServico}%`)
|
||||
2. Se não achar, buscar por Cliente (`{codigoCliente} -%`)
|
||||
3. Se achar Cliente, criar Serviço abaixo do Cliente
|
||||
4. Se não achar nenhum, criar Cliente (embaixo de Contratos Ativos) e depois criar Serviço abaixo do Cliente
|
||||
5. Retornar sempre a **entidade de Serviço**
|
||||
|
||||
---
|
||||
|
||||
### Fluxo de Resolução (quando NÃO é Implantação)
|
||||
1. Buscar entidade por Serviço (`{codigoCliente} - {codigoServico}%`)
|
||||
- Se achou: ✅ usar e finalizar
|
||||
2. Se não achou, buscar entidade por Cliente (`{codigoCliente} -%`)
|
||||
- Se achou: ✅ usar e finalizar
|
||||
3. Se não achou nenhum dos dois:
|
||||
- ✅ usar entidade **Contratos Ativos** (fallback)
|
||||
- ❌ não criar nada
|
||||
|
||||
---
|
||||
|
||||
### Resultado final (Opção C)
|
||||
- **Implantação**: sempre aponta para entidade de **Serviço**, criando Cliente/Serviço quando faltar.
|
||||
- **Demais chamados**: nunca criam entidades; ficam na melhor existente (Serviço → Cliente → Contratos Ativos).
|
||||
|
||||
---
|
||||
|
||||
### Diagrama de Fluxo — Opção C (Híbrida)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Chega chamado do Hub] --> B[Extrair dados<br/>codigoCliente<br/>codigoServico<br/>nomeCliente<br/>tipoChamado]
|
||||
|
||||
B --> C{Tipo é<br/>Implantação?}
|
||||
|
||||
%% ========== RAMO IMPLANTAÇÃO (OPÇÃO A) ==========
|
||||
C -->|Sim| IA{Existe entidade<br/>por Serviço?}
|
||||
IA -->|Sim| I1[Usar entidade de Serviço] --> Z[Fim / Continua fluxo do ticket]
|
||||
|
||||
IA -->|Não| IB{Existe entidade<br/>por Cliente?}
|
||||
IB -->|Sim| I2[Criar entidade de Serviço<br/>via API GLPI<br/>Parent = Cliente] --> I3[Usar entidade criada] --> Z
|
||||
|
||||
IB -->|Não| I4[Criar entidade Cliente<br/>via API GLPI<br/>Parent = Contratos Ativos] --> I5[Criar entidade de Serviço<br/>via API GLPI<br/>Parent = Cliente] --> I6[Usar entidade criada] --> Z
|
||||
|
||||
%% ========== RAMO NÃO IMPLANTAÇÃO (RESOLVE ONLY) ==========
|
||||
C -->|Não| NA{Existe entidade<br/>por Serviço?}
|
||||
NA -->|Sim| N1[Usar entidade de Serviço] --> Z
|
||||
|
||||
NA -->|Não| NB{Existe entidade<br/>por Cliente?}
|
||||
NB -->|Sim| N2[Usar entidade de Cliente] --> Z
|
||||
|
||||
NB -->|Não| N3[Usar entidade fallback<br/>Contratos Ativos] --> Z
|
||||
```
|
||||
@ -3,50 +3,63 @@
|
||||
const db = require('../../connections/hubglpi.pg.js');
|
||||
const { logError } = require('../../../../shared/utils/logger.js');
|
||||
|
||||
const VALID_NOTIFICATION_TYPES = new Set(['func', 'adm']);
|
||||
|
||||
function resolveNotificationType(type = 'func') {
|
||||
const normalized = String(type || 'func').toLowerCase();
|
||||
return VALID_NOTIFICATION_TYPES.has(normalized) ? normalized : 'func';
|
||||
}
|
||||
|
||||
function buildStatus(kind, type) {
|
||||
return `${kind}_${resolveNotificationType(type)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica se a notificação já foi enviada com sucesso
|
||||
* Verifica se a notificaÇõÇœo jÇ foi enviada com sucesso
|
||||
*/
|
||||
async function notificationAlreadySent(hubsoftTicketId) {
|
||||
async function notificationAlreadySentFunc(hubsoftTicketId, type = 'func') {
|
||||
const status = buildStatus('sent', type);
|
||||
const query = `
|
||||
SELECT 1
|
||||
FROM watchdog_notifications
|
||||
WHERE ticket_id = $1
|
||||
AND status = 'SENT'
|
||||
AND status = $2
|
||||
LIMIT 1;
|
||||
`;
|
||||
|
||||
try {
|
||||
const { rowCount } = await db.query(query, [hubsoftTicketId]);
|
||||
const { rowCount } = await db.query(query, [hubsoftTicketId, status]);
|
||||
return rowCount > 0;
|
||||
} catch (error) {
|
||||
logError('Erro ao verificar notificação já enviada', error);
|
||||
logError('Erro ao verificar notificaÇõÇœo jÇ enviada', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Marca tickets como pendente de notificação
|
||||
* Marca tickets como pendente de notificaÇõÇœo
|
||||
*/
|
||||
async function markNotificationsAsPending(hubsoftTicketIds) {
|
||||
async function markNotificationsAsPendingFunc(hubsoftTicketIds, type = 'func') {
|
||||
if (!hubsoftTicketIds || hubsoftTicketIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const status = buildStatus('pending', type);
|
||||
const query = `
|
||||
INSERT INTO watchdog_notifications (ticket_id, notified_at, status)
|
||||
SELECT
|
||||
unnest($1::bigint[]),
|
||||
NOW(),
|
||||
'pending'
|
||||
$2
|
||||
ON CONFLICT (ticket_id)
|
||||
DO UPDATE SET
|
||||
notified_at = EXCLUDED.notified_at,
|
||||
status = 'pending';
|
||||
status = $2;
|
||||
`;
|
||||
|
||||
try {
|
||||
await db.query(query, [hubsoftTicketIds]);
|
||||
await db.query(query, [hubsoftTicketIds, status]);
|
||||
} catch (error) {
|
||||
logError('Erro ao marcar notificações como falha', error);
|
||||
logError('Erro ao marcar notificaÇõÇæes como falha', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -55,65 +68,68 @@ async function markNotificationsAsPending(hubsoftTicketIds) {
|
||||
/**
|
||||
* Marca tickets como notificados com sucesso
|
||||
*/
|
||||
async function markNotificationsAsSent(hubsoftTicketIds) {
|
||||
async function markNotificationsAsSentFunc(hubsoftTicketIds, type = 'func') {
|
||||
const ids = (hubsoftTicketIds || [])
|
||||
.map(id => Number(id))
|
||||
.filter(Number.isFinite);
|
||||
|
||||
if (ids.length === 0) return;
|
||||
|
||||
const status = buildStatus('sent', type);
|
||||
const query = `
|
||||
INSERT INTO watchdog_notifications (ticket_id, notified_at, status)
|
||||
SELECT
|
||||
unnest($1::bigint[]),
|
||||
NOW(),
|
||||
'sent'
|
||||
$2
|
||||
ON CONFLICT (ticket_id)
|
||||
DO UPDATE SET
|
||||
notified_at = EXCLUDED.notified_at,
|
||||
status = 'sent';
|
||||
status = $2;
|
||||
`;
|
||||
|
||||
try {
|
||||
await db.query(query, [ids]);
|
||||
await db.query(query, [ids, status]);
|
||||
} catch (error) {
|
||||
logError('[WATCHDOG][REPOSITORY] Erro ao marcar notificações como enviadas', error);
|
||||
logError('[WATCHDOG][REPOSITORY] Erro ao marcar notificaÇõÇæes como enviadas', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marca tickets como falha de notificação
|
||||
* Marca tickets como falha de notificaÇõÇœo
|
||||
*/
|
||||
async function markNotificationsAsFailed(hubsoftTicketIds) {
|
||||
async function markNotificationsAsFailedFunc(hubsoftTicketIds, type = 'func') {
|
||||
const ids = (hubsoftTicketIds || [])
|
||||
.map(id => Number(id))
|
||||
.filter(Number.isFinite);
|
||||
|
||||
if (ids.length === 0) return;
|
||||
|
||||
const status = buildStatus('failed', type);
|
||||
const query = `
|
||||
INSERT INTO watchdog_notifications (ticket_id, notified_at, status)
|
||||
SELECT
|
||||
unnest($1::bigint[]),
|
||||
NOW(),
|
||||
'sent'
|
||||
$2
|
||||
ON CONFLICT (ticket_id)
|
||||
DO UPDATE SET
|
||||
notified_at = EXCLUDED.notified_at,
|
||||
status = 'failed';
|
||||
status = $2;
|
||||
`;
|
||||
|
||||
try {
|
||||
await db.query(query, [ids]);
|
||||
await db.query(query, [ids, status]);
|
||||
} catch (error) {
|
||||
logError('[WATCHDOG][REPOSITORY] Erro ao marcar notificações como enviadas', error);
|
||||
logError('[WATCHDOG][REPOSITORY] Erro ao marcar notificaÇõÇæes como enviadas', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function getPendingTicketsForNotification() {
|
||||
async function getPendingTicketsForNotificationFunc(type = 'func') {
|
||||
const status = buildStatus('pending', type);
|
||||
const query = `
|
||||
SELECT
|
||||
wn.ticket_id AS hubsoft_ticket_id,
|
||||
@ -126,22 +142,22 @@ async function getPendingTicketsForNotification() {
|
||||
ON wn.ticket_id = sd.hubsoft_ticket_id
|
||||
INNER JOIN hubsoft_tickets ht
|
||||
ON wn.ticket_id = ht.id_atendimento
|
||||
WHERE wn.status = 'pending';
|
||||
WHERE wn.status = $1;
|
||||
`;
|
||||
|
||||
try {
|
||||
const { rows } = await db.query(query);
|
||||
const { rows } = await db.query(query, [status]);
|
||||
return rows;
|
||||
} catch (error) {
|
||||
logError('Erro ao buscar tickets pendentes para notificação', error);
|
||||
logError('Erro ao buscar tickets pendentes para notificaÇõÇœo', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
notificationAlreadySent,
|
||||
markNotificationsAsSent,
|
||||
markNotificationsAsFailed,
|
||||
markNotificationsAsPending,
|
||||
getPendingTicketsForNotification
|
||||
notificationAlreadySent: notificationAlreadySentFunc,
|
||||
markNotificationsAsSent: markNotificationsAsSentFunc,
|
||||
markNotificationsAsFailed: markNotificationsAsFailedFunc,
|
||||
markNotificationsAsPending: markNotificationsAsPendingFunc,
|
||||
getPendingTicketsForNotification: getPendingTicketsForNotificationFunc
|
||||
};
|
||||
|
||||
@ -8,9 +8,6 @@ const cancelamentoService = require('../services/cancelamento.service.js')
|
||||
//const sacService = require('../services/sac.service.js') //TODO
|
||||
const trocaTitularidadeService = require('../services/trocaTitularidade.service.js') //TODO
|
||||
|
||||
const getAuthToken = require('../../../infra/api/hubsoft.auth.js')
|
||||
|
||||
|
||||
const ticketShared = require('../services/createTickets.service.js')
|
||||
const { logInfo, logError } = require('../../../shared/utils/logger.js')
|
||||
|
||||
|
||||
@ -8,38 +8,40 @@ const model = require('../model/email.model.js')
|
||||
|
||||
async function runWatchdog() {
|
||||
|
||||
logInfo('[WATCHDOG] [JOB] Coletando chamados fechados há 31 minutos')
|
||||
logInfo('[WATCHDOG] [JOB] Coletando chamados fechados hÇ 31 minutos')
|
||||
|
||||
const thresholdDate = new Date(Date.now() - 31 * 60 * 1000)
|
||||
|
||||
const closedTickets = await repository.getClosedTicketsSince(thresholdDate)
|
||||
logInfo(`[WATCHDOG] [JOB] Encontrados ${closedTickets.length} chamados fechados`)
|
||||
|
||||
let notificationType = 'func'
|
||||
|
||||
for (const ticket of closedTickets) {
|
||||
|
||||
const hubGlpiTicket = await repository.checkTicketInHubGlpi(ticket.id_atendimento)
|
||||
|
||||
if (!hubGlpiTicket.exists) {
|
||||
logInfo(`[WATCHDOG] [JOB] Chamado ${ticket.id_atendimento} não encontrado no HubGlpi. Ignorando.`)
|
||||
logInfo(`[WATCHDOG] [JOB] Chamado ${ticket.id_atendimento} nao encontrado no HubGlpi. Ignorando.`)
|
||||
continue
|
||||
}
|
||||
|
||||
if (hubGlpiTicket.status === 'closed') {
|
||||
logInfo(`[WATCHDOG] [JOB] Chamado ${ticket.id_atendimento} já está fechado no HubGlpi. Ignorando.`)
|
||||
logInfo(`[WATCHDOG] [JOB] Chamado ${ticket.id_atendimento} ja esta fechado no HubGlpi. Ignorando.`)
|
||||
continue
|
||||
}
|
||||
if (await repository.notificationAlreadySent(ticket.id_atendimento)) {
|
||||
logInfo(`[WATCHDOG] [JOB] Notificação já enviada para o chamado ${ticket.id_atendimento}.`)
|
||||
if (await repository.notificationAlreadySent(ticket.id_atendimento, notificationType)) {
|
||||
logInfo(`[WATCHDOG] [JOB] NotificaÇõÇœo jÇ enviada para o chamado ${ticket.id_atendimento}.`)
|
||||
continue
|
||||
}
|
||||
await repository.markNotificationsAsPending([ticket.id_atendimento])
|
||||
await repository.markNotificationsAsPending([ticket.id_atendimento], notificationType)
|
||||
|
||||
}
|
||||
const ticketsToNotify = await repository.getPendingTicketsForNotification()
|
||||
logInfo(`[WATCHDOG] [JOB] ${ticketsToNotify.length} chamados pendentes para notificação.`)
|
||||
const ticketsToNotify = await repository.getPendingTicketsForNotification(notificationType)
|
||||
logInfo(`[WATCHDOG] [JOB] ${ticketsToNotify.length} chamados pendentes para notificaÇõÇœo.`)
|
||||
|
||||
if (!ticketsToNotify.length) {
|
||||
logInfo('[WATCHDOG] [JOB] Nenhum chamado pendente para notificação')
|
||||
logInfo('[WATCHDOG] [JOB] Nenhum chamado pendente para notificaÇõÇœo')
|
||||
return
|
||||
}
|
||||
|
||||
@ -50,13 +52,13 @@ async function runWatchdog() {
|
||||
await repository.sendClosureNotifications(payload)
|
||||
|
||||
|
||||
await repository.markNotificationsAsSent(hubsoftTicketIds)
|
||||
await repository.markNotificationsAsSent(hubsoftTicketIds, notificationType)
|
||||
} catch (err) {
|
||||
logError('[WATCHDOG] Erro ao enviar notificações', err)
|
||||
await repository.markNotificationsAsFailed(hubsoftTicketIds)
|
||||
logError('[WATCHDOG] Erro ao enviar notificaÇõÇæes', err)
|
||||
await repository.markNotificationsAsFailed(hubsoftTicketIds, notificationType)
|
||||
}
|
||||
|
||||
logInfo(`[WATCHDOG] [JOB] Enviadas ${ticketsToNotify.length} notificações`)
|
||||
logInfo(`[WATCHDOG] [JOB] Enviadas ${ticketsToNotify.length} notificaÇõÇæes`)
|
||||
}
|
||||
|
||||
|
||||
@ -64,4 +66,4 @@ runWatchdog().catch((error) => {
|
||||
logError('[WATCHDOG] [JOB] Erro ao executar o job do Watchdog', error)
|
||||
})
|
||||
|
||||
module.exports = { runWatchdog}
|
||||
module.exports = { runWatchdog}
|
||||
|
||||
@ -35,8 +35,8 @@ async function checkTicketInHubGlpi(hubsoftTicketId) {
|
||||
/**
|
||||
* Verifica se a notificação de encerramento já foi enviada
|
||||
*/
|
||||
async function notificationAlreadySent(hubsoftTicketId) {
|
||||
return wdRepository.notificationAlreadySent(hubsoftTicketId);
|
||||
async function notificationAlreadySent(hubsoftTicketId, type = 'func') {
|
||||
return wdRepository.notificationAlreadySent(hubsoftTicketId, type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,26 +49,26 @@ async function sendClosureNotifications(payload) {
|
||||
/**
|
||||
* Marca notificações como enviadas com sucesso
|
||||
*/
|
||||
async function markNotificationsAsSent(hubsoftTicketIds) {
|
||||
return wdRepository.markNotificationsAsSent(hubsoftTicketIds);
|
||||
async function markNotificationsAsSent(hubsoftTicketIds, type = 'func') {
|
||||
return wdRepository.markNotificationsAsSent(hubsoftTicketIds, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marca notificações como falhas
|
||||
*/
|
||||
async function markNotificationsAsFailed(hubsoftTicketIds, error = null) {
|
||||
return wdRepository.markNotificationsAsFailed(hubsoftTicketIds, error);
|
||||
async function markNotificationsAsFailed(hubsoftTicketIds, type = 'func', error = null) {
|
||||
return wdRepository.markNotificationsAsFailed(hubsoftTicketIds, type, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marca notificações como pendentes
|
||||
*/
|
||||
async function markNotificationsAsPending(hubsoftTicketId, error = null) {
|
||||
return wdRepository.markNotificationsAsPending(hubsoftTicketId, error);
|
||||
async function markNotificationsAsPending(hubsoftTicketId, type = 'func', error = null) {
|
||||
return wdRepository.markNotificationsAsPending(hubsoftTicketId, type, error);
|
||||
}
|
||||
|
||||
async function getPendingTicketsForNotification() {
|
||||
return wdRepository.getPendingTicketsForNotification();
|
||||
async function getPendingTicketsForNotification(type = 'func') {
|
||||
return wdRepository.getPendingTicketsForNotification(type);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user