Consolida os dois controladores legados que decidiam status/fechamento de forma concorrente (processGlpiClosureController + processStatusController) em um único processTicketLifecycleController, eliminando a dependência do campo source_last (mantido só como rastro de auditoria) e a flag ENABLE_STATUS_SYNC (removida). Isso corrige o bug de reabertura: chamados reabertos no SN voltavam a ser fechados no GLPI porque a regra de precedência de finalização do fluxo legado forçava o status do GLPI de volta pro SN. Correções de bugs encontrados em teste (Frente 1): - Constraint UNIQUE em ticket_sync.sn_ticket_id + ON CONFLICT DO NOTHING na criação do registro, prevenindo duplicação de tickets. - Fechamento no SN agora é confirmado por leitura ao vivo do status antes de marcar o ticket como solved/closed, em vez de confiar só no HTTP 200 (a API do SN pode retornar sucesso e silenciosamente ignorar um valor de estado inválido — descoberto e corrigido também no mandante). - Nota de encerramento do SN pro GLPI agora é idempotente e criada uma única vez por ticket. - Erros de sincronização passam a ter um limite de tentativas (MAX_ERROR_RETRIES) antes de marcar o ticket como error_permanent, exigindo intervenção manual em vez de tentar para sempre. - Chamados criados no GLPI passam a gravar o número do ticket do SN no campo externalid. Nova funcionalidade (Frente 2): quando o SN resolve/encerra um chamado por conta própria antes do GLPI, além da nota informativa no GLPI (agora com o nome de quem encerrou, buscado ao vivo via resolved_by/closed_by/ sys_updated_by), o próprio SN recebe um aviso de que a Sothis não vai mais atender aquele chamado e ele é transferido pra fila de TI da CAOA. Nova funcionalidade (Mandante, regras 19-22): espelhamento opcional e configurável de status intermediário (Aguardando Atendimento/Em Atendimento/Em Espera) entre os dois sistemas, controlado pela env MANDANTE=GLPI|SNOW. Sem essa env configurada, mantém o comportamento atual (nenhum espelhamento de status intermediário). Nunca afeta os status finais (resolvido/encerrado/fora de escopo), que continuam regidos pelas regras fixas de fechamento. Corrigido também o workflow de deploy (.gitea/workflows/deploy-production.yml), que ainda validava os controladores antigos (já removidos) e exigia ENABLE_STATUS_SYNC=true, o que quebraria o próximo deploy em produção. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
229 lines
9.4 KiB
Markdown
229 lines
9.4 KiB
Markdown
# Regras de Negocio Completas
|
|
|
|
## 1. Escopo funcional da integracao
|
|
|
|
1. A origem oficial de novos chamados e o ServiceNow (SN).
|
|
2. O GLPI recebe chamados criados no SN e passa a participar do atendimento.
|
|
3. A integracao cobre:
|
|
- criacao/vinculo de chamados SN -> GLPI
|
|
- sincronizacao de comentarios (SN <-> GLPI)
|
|
- sincronizacao de tasks (SN -> GLPI via `work_notes`)
|
|
- fechamento definitivo GLPI -> SN (status GLPI = 6)
|
|
4. Sincronizacao legada bidirecional de status existe, mas deve ficar desligada no modelo novo (por flag).
|
|
|
|
## 2. Governanca e responsabilidade entre sistemas
|
|
|
|
1. SN e a origem da demanda.
|
|
2. GLPI e o sistema tecnico de atendimento e encerramento final.
|
|
3. Banco intermediario (PostgreSQL) e a fonte de controle operacional da integracao.
|
|
|
|
## 3. Orquestracao do ciclo
|
|
|
|
1. O ciclo roda por `cron`.
|
|
2. Ordem de execucao:
|
|
- `processErrorController`
|
|
- `processTicketsController`
|
|
- `processTicketLifecycleController` (motor de regras unico de status/fechamento/reabertura, se habilitado)
|
|
- `processCommentsController`
|
|
3. Ha protecao para evitar execucao concorrente do mesmo ciclo no mesmo processo.
|
|
4. Nao ha mais dois controladores decidindo status do mesmo ticket — o fluxo legado
|
|
(`processStatusController`) foi removido e sua logica util (nota SN->GLPI, fora de escopo) foi
|
|
absorvida pelo motor unico.
|
|
|
|
## 4. Feature flags e comportamento
|
|
|
|
1. `ENABLE_GLPI_CLOSE_CRON`
|
|
- `true`: executa o motor de regras de status/fechamento/reabertura (`processTicketLifecycleController`).
|
|
- `false`: desliga o motor inteiro.
|
|
2. `ENABLE_GLPI_WEBHOOK`
|
|
- reservado para rollout por evento (planejado), sem obrigatoriedade no fluxo atual.
|
|
|
|
## 5. Regras de coleta de tickets no ServiceNow
|
|
|
|
1. Busca incidentes e requisicoes por `assignment_group` e `sys_updated_on >= watermark`.
|
|
2. Watermark vem de `sync_control`.
|
|
3. Novo watermark usa maior `sys_updated_on` encontrado no ciclo.
|
|
4. Watermark salvo aplica margem de seguranca de 6 horas para tras.
|
|
5. Se nao houver tickets novos/atualizados, watermark nao e alterado.
|
|
|
|
## 6. Regras de persistencia local (`tickets_sn`)
|
|
|
|
1. UPSERT por `ticket_number`.
|
|
2. `sys_id` e unico.
|
|
3. Campos de incidente e requisicao tem mapeamento diferente.
|
|
4. Para requisicao, pode haver enriquecimento por variaveis de catalogo:
|
|
- justificativa
|
|
- telefone
|
|
5. `updated_at` e atualizado automaticamente (trigger no banco).
|
|
|
|
## 7. Regras de criacao de estado de sincronizacao (`ticket_sync`)
|
|
|
|
1. Novo ticket entra com `sn_ticket_id` vinculado.
|
|
2. Se status SN vier final (`Encerrado` ou `Encerrado - Omitido`):
|
|
- `sn_sync_status = closed`
|
|
- `glpi_sync_status = ignored`
|
|
3. Se status SN vier aberto:
|
|
- `sn_sync_status = collected`
|
|
- `glpi_sync_status = pending_check`
|
|
4. `source_last` existe no schema e continua sendo gravado como rastro de auditoria, mas nao e mais lido em nenhum lugar do codigo para decidir status.
|
|
|
|
## 8. Regras de criacao/vinculo no GLPI
|
|
|
|
1. Apenas tickets com `glpi_sync_status = pending_check` entram na criacao/vinculo.
|
|
2. Se `glpi_ticket_id` ja existir no banco intermediario:
|
|
- manter `synced/synced`
|
|
3. Se nao houver `glpi_ticket_id` local:
|
|
- procurar ticket no GLPI por numero SN no titulo/conteudo
|
|
4. Se encontrar ticket no GLPI:
|
|
- vincular `glpi_ticket_id`
|
|
- se status GLPI=6, marcar `ignored/closed` e nao monitorar
|
|
- caso contrario, marcar `synced/synced`
|
|
5. Se nao encontrar:
|
|
- criar ticket no GLPI
|
|
- vincular e marcar `synced/synced`
|
|
6. Erro de criacao:
|
|
- marcar estado de erro para reprocessamento.
|
|
|
|
## 9. Regras de formatacao ao criar ticket no GLPI
|
|
|
|
1. Titulo segue padrao: tipo + entidade + short_description.
|
|
2. Entidade vem de `location_mapping`; fallback para entidade padrao.
|
|
3. Descricao e montada em HTML com dados de solicitante.
|
|
4. Requisicao sem justificativa/descricao pode usar valores default configurados.
|
|
5. Prioridade, categoria e SLA usam mapeamentos predefinidos.
|
|
|
|
## 10. Regra do campo "Ticket Externo" no SN
|
|
|
|
1. Ao criar/vincular ticket no GLPI, escrever ID GLPI no SN.
|
|
2. Campo usado e configuravel por `SERVICENOW_EXTERNAL_TICKET_FIELD` (default `u_external_ticket`).
|
|
3. Se a escrita falhar, nao recriar ticket no GLPI.
|
|
4. Falha gera pendencia de retry idempotente em `ticket_updates` (`update_type=external_link`).
|
|
5. Retry processa pendencias com `destiny_id IS NULL`.
|
|
6. Ao sucesso, `destiny_id` da pendencia vira `done`.
|
|
|
|
## 11. Regras de sincronizacao de comentarios SN -> GLPI
|
|
|
|
1. Busca journal entries `comments` e `work_notes` do SN.
|
|
2. Ordena cronologicamente antes de enviar.
|
|
3. Idempotencia por `ticket_updates.source_id` (sys_id do journal).
|
|
4. `comments` viram followup no GLPI.
|
|
5. `work_notes` viram task no GLPI.
|
|
6. Conteudo enviado para GLPI e formatado com card visual e autor.
|
|
7. Em falha de envio, registra estado de erro para novo ciclo.
|
|
|
|
## 12. Regras de sincronizacao de comentarios GLPI -> SN
|
|
|
|
1. Busca followups do GLPI ignorando usuario padrao tecnico da integracao.
|
|
2. Sanitiza HTML, metadados e imagens.
|
|
3. Evita duplicidade com verificacao local e remota.
|
|
4. Atualiza mapeamento origem/destino em `ticket_updates.destiny_id`.
|
|
5. Ao final, evita deixar ticket preso em estado transitorio de comentario.
|
|
|
|
## 13. Regras de filtro de usuario padrao no SN (ambiente de teste)
|
|
|
|
1. `SERVICENOW_DEFAULT_USER` define usuario da integracao.
|
|
2. `SERVICENOW_IGNORE_DEFAULT_USER_JOURNAL`:
|
|
- `true` (padrao): ignora journals desse usuario para evitar loop.
|
|
- `false`: nao ignora (util para dev com usuario unico).
|
|
|
|
## 14. Regras de fechamento e resolucao
|
|
|
|
1. Fechamento definitivo GLPI `status=6` e refletido no SN via `processTicketLifecycleController`.
|
|
2. Ao detectar GLPI=6:
|
|
- enviar comentario no SN:
|
|
- "Chamado encerrado definitivamente. Reabertura deste chamado nao sera atendida. Caso necessario, abra um novo chamado."
|
|
- nao alterar status do chamado no SN
|
|
- marcar `ticket_sync` como `closed/closed` para retirar do monitoramento
|
|
3. Aviso de encerramento definitivo no SN e idempotente por `source_id` em `ticket_updates`.
|
|
4. Quando o SN resolve/encerra por conta propria e o GLPI ainda nao chegou em 5/6: nota idempotente
|
|
no GLPI + aviso no SN (Sothis nao vai mais atender) + transferencia pra fila CAOA — ver
|
|
`docs/fluxo.md` secao 4.3. Nao depende de `source_last` nem de nenhuma flag de sincronizacao
|
|
legada (removida).
|
|
|
|
## 15. Regras de fora do escopo (Sothis)
|
|
|
|
1. Quando solucao no GLPI usa `solutiontypes_id = GLPI_OOS_SOLUTION_TYPE_ID`:
|
|
- envia justificativa ao SN em nota
|
|
- nao segue fluxo normal de atendimento
|
|
- estado final esperado no intermediario:
|
|
- `glpi_sync_status = closed`
|
|
- `sn_sync_status = ignored`
|
|
2. Chamado sai do monitoramento automatico.
|
|
|
|
## 16. Regras de estados monitorados vs terminais
|
|
|
|
### 16.1 Monitorados
|
|
|
|
1. `pending_check`
|
|
2. `synced`
|
|
3. `solved`
|
|
4. `error` e variantes de erro para reprocesso
|
|
|
|
### 16.2 Terminais
|
|
|
|
1. `closed`
|
|
2. `ignored`
|
|
3. `error_permanent` — ticket excedeu `MAX_ERROR_RETRIES` tentativas automaticas de reprocessamento
|
|
e exige intervencao manual.
|
|
|
|
Regra geral: `closed`, `ignored` e `error_permanent` nao participam das rotinas normais de
|
|
sincronizacao.
|
|
|
|
## 17. Regra de reabertura
|
|
|
|
1. Reabertura automatica permitida apenas quando GLPI estiver em `5` (solved).
|
|
2. Se GLPI estiver em `6` (fechado definitivo), reabertura automatica nao e permitida.
|
|
|
|
## 18. Regras de idempotencia e rastreabilidade
|
|
|
|
1. `ticket_updates.source_id` e unico.
|
|
2. Toda sincronizacao relevante registra origem e destino quando possivel.
|
|
3. `ticket_sync.last_sn_sync` e `last_glpi_sync` registram ultima interacao por sistema.
|
|
|
|
## 19. Regras de erro e reprocessamento
|
|
|
|
1. Inicio de ciclo executa reset de estados de erro processaveis.
|
|
2. Erro em etapa nao deve causar duplicidade de criacao.
|
|
3. Tickets em erro voltam para fila valida de processamento conforme tipo do erro.
|
|
|
|
## 20. Regras de monitoramento operacional
|
|
|
|
1. Logs devem permitir rastrear:
|
|
- criacao de ticket
|
|
- sincronizacao de comentario/task
|
|
- fechamento definitivo
|
|
- falhas e retries
|
|
2. Rollout deve ser faseado por flag e com possibilidade de rollback.
|
|
|
|
## 21. Regras de schema (situacao atual)
|
|
|
|
1. Nao remover colunas legadas neste momento.
|
|
2. Nao criar tabela nova para eventos nesta fase.
|
|
3. Reaproveitar `ticket_updates` para pendencias e idempotencia.
|
|
|
|
## 22. Criterios de sucesso de negocio
|
|
|
|
1. Ticket fechado definitivamente no GLPI nao permanece aberto no SN.
|
|
2. Comentarios e tasks nao duplicam.
|
|
3. Tickets fora do escopo saem de monitoramento com estado final correto.
|
|
4. Integracao nao entra em loop por status intermediario.
|
|
|
|
## 23. Regras de mandante (espelhamento de status intermediario)
|
|
|
|
1. Existe um sistema "mandante" configuravel via env `MANDANTE` (`GLPI`, `SNOW` ou vazio) cujo
|
|
status intermediario (`Aguardando Atendimento`/`Em Atendimento`/`Em Espera` no SN, GLPI
|
|
`1`/`2`/`3`/`4`) e espelhado automaticamente no outro sistema.
|
|
2. Nunca se aplica aos status finais (GLPI `5`/`6`, fora de escopo) - essas continuam sendo as
|
|
regras fixas 10-15, sempre ativas independente do mandante.
|
|
3. `MANDANTE` vazio, ausente ou com valor invalido mantem o comportamento padrao: nenhum
|
|
espelhamento de status intermediario (equivalente ao que a regra de contencao ja fazia antes do
|
|
mandante existir).
|
|
4. O mandante e unidirecional: so escreve no sistema seguidor, nunca le o status do seguidor para
|
|
decidir algo - evita loop de espelhamento entre os dois sistemas.
|
|
5. So escreve quando o valor espelhado realmente difere do atual, para nao gerar chamada de API
|
|
desnecessaria a cada ciclo.
|
|
|
|
|
|
|
|
|