# 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.