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>
90 lines
4.1 KiB
Markdown
90 lines
4.1 KiB
Markdown
# Fluxo Operacional
|
|
|
|
## 1. Fluxo do ciclo (`main`)
|
|
|
|
1. `processErrorController`
|
|
2. `processTicketsController`
|
|
3. `processTicketLifecycleController` (se `ENABLE_GLPI_CLOSE_CRON=true`) — motor de regras unico
|
|
pra status/fechamento/reabertura, ver secao 4.
|
|
4. `processCommentsController`
|
|
|
|
## 2. Fluxo SN -> GLPI
|
|
|
|
1. Coleta incidentes/requisicoes no SN por watermark.
|
|
2. UPSERT em `tickets_sn`.
|
|
3. Cria/atualiza `ticket_sync` com estados iniciais.
|
|
4. Cria ticket no GLPI quando `pending_check`.
|
|
5. Grava `glpi_ticket_id` em `ticket_sync`.
|
|
6. Atualiza campo "Ticket Externo" no SN com ID GLPI.
|
|
7. Se falhar atualizar "Ticket Externo", agenda retry em `ticket_updates`.
|
|
|
|
## 3. Fluxo de comentarios/tasks
|
|
|
|
### 3.1 SN -> GLPI
|
|
|
|
1. Busca `comments` e `work_notes` no SN.
|
|
2. Persiste em `ticket_updates` (idempotente por `source_id`).
|
|
3. Envia:
|
|
- `comment` -> followup GLPI
|
|
- `task` -> task GLPI
|
|
|
|
### 3.2 GLPI -> SN
|
|
|
|
1. Busca followups GLPI.
|
|
2. Sanitiza conteudo HTML/imagens.
|
|
3. Envia comentario para SN evitando duplicidade.
|
|
4. Atualiza `destiny_id` para rastrear espelhamento.
|
|
|
|
## 4. Motor de regras unico (`processTicketLifecycleController`)
|
|
|
|
Substitui os antigos `processGlpiClosureController` + `processStatusController`. Nao ha mais dois
|
|
controladores decidindo o mesmo ticket, e nenhuma decisao depende de `source_last` (campo mantido
|
|
so como rastro de auditoria). Roda pra todo ticket com `glpi_ticket_id` que nao esteja
|
|
`closed`/`ignored`/`error_permanent`:
|
|
|
|
1. **GLPI status `5` (Solucionado)**:
|
|
- se o ticket ja estava `solved` localmente, so verifica se o SN foi reaberto (ver secao 5) e
|
|
para por ai;
|
|
- senao: verifica fora de escopo; se nao for, busca nota de solucao, se SN estiver em
|
|
espera/aguardando move pra "Em Atendimento", resolve o SN **confirmando via leitura ao vivo**
|
|
antes de marcar `solved/solved` (nunca marca so por causa de um HTTP 200).
|
|
2. **GLPI status `6` (Fechado definitivamente)**:
|
|
- adiciona comentario idempotente no SN: "Chamado encerrado definitivamente. Reabertura deste
|
|
chamado nao sera atendida. Caso necessario, abra um novo chamado."
|
|
- nao altera status do chamado no SN
|
|
- marca `ticket_sync` como `closed/closed` para retirar do monitoramento
|
|
3. **GLPI ainda aberto (`< 5`) e SN resolvido/encerrado por conta propria**:
|
|
- adiciona nota idempotente no GLPI avisando o encerramento vindo do SN, sem fechar o chamado
|
|
(inclui o nome de quem encerrou no SN, buscado ao vivo: `resolved_by` -> `closed_by` ->
|
|
`sys_updated_by`, o que vier preenchido primeiro)
|
|
- (primeira vez apenas) avisa no proprio SN que a Sothis nao vai mais atender esse chamado e
|
|
transfere pra fila CAOA
|
|
- marca `ticket_sync` como `solved/solved` ou `closed/closed`
|
|
4. **GLPI ainda aberto (`< 5`) e SN tambem em status intermediario** (nenhum dos dois em
|
|
Resolvido/Encerrado): aplica o mandante, se configurado — ver secao 6.
|
|
|
|
## 5. Reabertura
|
|
|
|
1. Reabertura automatica permitida apenas para tickets em GLPI `5` — verificado a cada ciclo pelo
|
|
mesmo `processTicketLifecycleController`, sem depender de nenhuma flag.
|
|
2. Se GLPI `6`, reabertura automatica bloqueada (a regra nem entra nesse caminho).
|
|
|
|
## 6. Mandante (regras 19-22)
|
|
|
|
Espelhamento **opcional** de status intermediario (`Aguardando Atendimento`/`Em Atendimento`/
|
|
`Em Espera` no SN, equivalentes ao GLPI `1`/`2`/`4` — GLPI `3` tambem mapeia para
|
|
`Em Atendimento`). Nunca toca em status finais (5, 6, fora de escopo) — essas continuam sendo as
|
|
regras fixas das secoes 4.1-4.3, sempre ativas.
|
|
|
|
Controlado pelo env `MANDANTE`:
|
|
|
|
1. `MANDANTE=GLPI`: quando o status intermediario do GLPI muda, o SN e atualizado pra
|
|
acompanhar. Mudancas de status intermediario feitas diretamente no SN sao ignoradas.
|
|
2. `MANDANTE=SNOW`: o oposto — o SN manda, o GLPI acompanha.
|
|
3. `MANDANTE` vazio/ausente/invalido: nenhum espelhamento (comportamento padrao, igual a antes do
|
|
mandante existir).
|
|
|
|
Em qualquer configuracao, so escreve quando o valor desejado difere do atual (evita chamada de API
|
|
desnecessaria) e nunca le o status do lado seguidor pra decidir nada — o mandante so manda, nunca
|
|
escuta, entao nao ha risco de loop entre os dois sistemas.
|