snglpi/docs/regrasdenegocio.md

229 lines
9.4 KiB
Markdown
Raw Permalink Normal View History

# 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`
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
- `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.
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
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
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
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`
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
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
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
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`.
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
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`
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
3. `error_permanent` — ticket excedeu `MAX_ERROR_RETRIES` tentativas automaticas de reprocessamento
e exige intervencao manual.
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
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.
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
## 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.