snglpi/docs/regrasdenegocio.md
Rafael Lopes bce9a52494 FEAT: Motor de regras único de status/fechamento + mandante configurável
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>
2026-07-10 09:45:34 -03:00

9.4 KiB

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.