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>
9.4 KiB
9.4 KiB
Regras de Negocio Completas
1. Escopo funcional da integracao
- A origem oficial de novos chamados e o ServiceNow (SN).
- O GLPI recebe chamados criados no SN e passa a participar do atendimento.
- 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)
- Sincronizacao legada bidirecional de status existe, mas deve ficar desligada no modelo novo (por flag).
2. Governanca e responsabilidade entre sistemas
- SN e a origem da demanda.
- GLPI e o sistema tecnico de atendimento e encerramento final.
- Banco intermediario (PostgreSQL) e a fonte de controle operacional da integracao.
3. Orquestracao do ciclo
- O ciclo roda por
cron. - Ordem de execucao:
processErrorControllerprocessTicketsControllerprocessTicketLifecycleController(motor de regras unico de status/fechamento/reabertura, se habilitado)processCommentsController
- Ha protecao para evitar execucao concorrente do mesmo ciclo no mesmo processo.
- 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
ENABLE_GLPI_CLOSE_CRONtrue: executa o motor de regras de status/fechamento/reabertura (processTicketLifecycleController).false: desliga o motor inteiro.
ENABLE_GLPI_WEBHOOK- reservado para rollout por evento (planejado), sem obrigatoriedade no fluxo atual.
5. Regras de coleta de tickets no ServiceNow
- Busca incidentes e requisicoes por
assignment_groupesys_updated_on >= watermark. - Watermark vem de
sync_control. - Novo watermark usa maior
sys_updated_onencontrado no ciclo. - Watermark salvo aplica margem de seguranca de 6 horas para tras.
- Se nao houver tickets novos/atualizados, watermark nao e alterado.
6. Regras de persistencia local (tickets_sn)
- UPSERT por
ticket_number. sys_ide unico.- Campos de incidente e requisicao tem mapeamento diferente.
- Para requisicao, pode haver enriquecimento por variaveis de catalogo:
- justificativa
- telefone
updated_ate atualizado automaticamente (trigger no banco).
7. Regras de criacao de estado de sincronizacao (ticket_sync)
- Novo ticket entra com
sn_ticket_idvinculado. - Se status SN vier final (
EncerradoouEncerrado - Omitido):sn_sync_status = closedglpi_sync_status = ignored
- Se status SN vier aberto:
sn_sync_status = collectedglpi_sync_status = pending_check
source_lastexiste 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
- Apenas tickets com
glpi_sync_status = pending_checkentram na criacao/vinculo. - Se
glpi_ticket_idja existir no banco intermediario:- manter
synced/synced
- manter
- Se nao houver
glpi_ticket_idlocal:- procurar ticket no GLPI por numero SN no titulo/conteudo
- Se encontrar ticket no GLPI:
- vincular
glpi_ticket_id - se status GLPI=6, marcar
ignored/closede nao monitorar - caso contrario, marcar
synced/synced
- vincular
- Se nao encontrar:
- criar ticket no GLPI
- vincular e marcar
synced/synced
- Erro de criacao:
- marcar estado de erro para reprocessamento.
9. Regras de formatacao ao criar ticket no GLPI
- Titulo segue padrao: tipo + entidade + short_description.
- Entidade vem de
location_mapping; fallback para entidade padrao. - Descricao e montada em HTML com dados de solicitante.
- Requisicao sem justificativa/descricao pode usar valores default configurados.
- Prioridade, categoria e SLA usam mapeamentos predefinidos.
10. Regra do campo "Ticket Externo" no SN
- Ao criar/vincular ticket no GLPI, escrever ID GLPI no SN.
- Campo usado e configuravel por
SERVICENOW_EXTERNAL_TICKET_FIELD(defaultu_external_ticket). - Se a escrita falhar, nao recriar ticket no GLPI.
- Falha gera pendencia de retry idempotente em
ticket_updates(update_type=external_link). - Retry processa pendencias com
destiny_id IS NULL. - Ao sucesso,
destiny_idda pendencia viradone.
11. Regras de sincronizacao de comentarios SN -> GLPI
- Busca journal entries
commentsework_notesdo SN. - Ordena cronologicamente antes de enviar.
- Idempotencia por
ticket_updates.source_id(sys_id do journal). commentsviram followup no GLPI.work_notesviram task no GLPI.- Conteudo enviado para GLPI e formatado com card visual e autor.
- Em falha de envio, registra estado de erro para novo ciclo.
12. Regras de sincronizacao de comentarios GLPI -> SN
- Busca followups do GLPI ignorando usuario padrao tecnico da integracao.
- Sanitiza HTML, metadados e imagens.
- Evita duplicidade com verificacao local e remota.
- Atualiza mapeamento origem/destino em
ticket_updates.destiny_id. - Ao final, evita deixar ticket preso em estado transitorio de comentario.
13. Regras de filtro de usuario padrao no SN (ambiente de teste)
SERVICENOW_DEFAULT_USERdefine usuario da integracao.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
- Fechamento definitivo GLPI
status=6e refletido no SN viaprocessTicketLifecycleController. - 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_synccomoclosed/closedpara retirar do monitoramento
- enviar comentario no SN:
- Aviso de encerramento definitivo no SN e idempotente por
source_idemticket_updates. - 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.mdsecao 4.3. Nao depende desource_lastnem de nenhuma flag de sincronizacao legada (removida).
15. Regras de fora do escopo (Sothis)
- 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 = closedsn_sync_status = ignored
- Chamado sai do monitoramento automatico.
16. Regras de estados monitorados vs terminais
16.1 Monitorados
pending_checksyncedsolvederrore variantes de erro para reprocesso
16.2 Terminais
closedignorederror_permanent— ticket excedeuMAX_ERROR_RETRIEStentativas 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
- Reabertura automatica permitida apenas quando GLPI estiver em
5(solved). - Se GLPI estiver em
6(fechado definitivo), reabertura automatica nao e permitida.
18. Regras de idempotencia e rastreabilidade
ticket_updates.source_ide unico.- Toda sincronizacao relevante registra origem e destino quando possivel.
ticket_sync.last_sn_syncelast_glpi_syncregistram ultima interacao por sistema.
19. Regras de erro e reprocessamento
- Inicio de ciclo executa reset de estados de erro processaveis.
- Erro em etapa nao deve causar duplicidade de criacao.
- Tickets em erro voltam para fila valida de processamento conforme tipo do erro.
20. Regras de monitoramento operacional
- Logs devem permitir rastrear:
- criacao de ticket
- sincronizacao de comentario/task
- fechamento definitivo
- falhas e retries
- Rollout deve ser faseado por flag e com possibilidade de rollback.
21. Regras de schema (situacao atual)
- Nao remover colunas legadas neste momento.
- Nao criar tabela nova para eventos nesta fase.
- Reaproveitar
ticket_updatespara pendencias e idempotencia.
22. Criterios de sucesso de negocio
- Ticket fechado definitivamente no GLPI nao permanece aberto no SN.
- Comentarios e tasks nao duplicam.
- Tickets fora do escopo saem de monitoramento com estado final correto.
- Integracao nao entra em loop por status intermediario.
23. Regras de mandante (espelhamento de status intermediario)
- Existe um sistema "mandante" configuravel via env
MANDANTE(GLPI,SNOWou vazio) cujo status intermediario (Aguardando Atendimento/Em Atendimento/Em Esperano SN, GLPI1/2/3/4) e espelhado automaticamente no outro sistema. - 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. MANDANTEvazio, 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).- 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.
- So escreve quando o valor espelhado realmente difere do atual, para nao gerar chamada de API desnecessaria a cada ciclo.