Skip to Content
Guia das telasTransformadores

Transformadores — /transformers

Scripts cadastrados, versão e onde cada um é usado
Scripts cadastrados, versão e onde cada um é usado

Um Transformador converte o payload entre o formato de quem envia e o formato de quem recebe: JSON ↔ XML, renomear campos, achatar estruturas, calcular valores derivados, dividir uma mensagem em várias.

O mesmo Transformador é reutilizável em Definições de Entrega, em Coletas e nos encaminhamentos de uma Coleta para várias interfaces.

Onde o Transformador entra no fluxo

  • Entrega — entre o recebimento e o envio ao destino.
  • Coleta — entre a leitura da origem e o encaminhamento para as interfaces de destino.
  • Encaminhamento — um Transformador próprio por destino, quando a mesma coleta alimenta sistemas que esperam formatos diferentes.
  • Aplicação produtora — numa Entrega que recebe de vários sistemas, um Transformador próprio por produtora, que converte o formato dela para o da Entrega e roda antes do Transformador da Entrega. Ver Transformador por Aplicação produtora.

Antes de alterar um Transformador, confira o uso consolidado que a listagem mostra. Ele cobre o uso direto em Definições e o uso indireto — via encaminhamentos de Coleta e por Aplicação produtora numa Entrega. Os dois precisam ser considerados, e é fácil esquecer o segundo.

Quem usa este Transformador

A coluna Definições usando traz, em cada linha da listagem, um chip por uso, no formato ícone da Aplicação · sigla da Aplicação — ícone de Coleta/Entrega · sigla da Definição. A cor do chip repete a do resto do sistema: verde-água para Coleta, azul para Entrega.

Clicar num chip não leva à Definição: abre a lista de usos, e é daí que você escolhe o que abrir. A coluna é a mais larga da tabela, e um toque involuntário não deve tirar você da tela.

O chip distingue as duas naturezas do vínculo:

VínculoSignifica
DiretoA própria Entrega ou Coleta transforma com este Transformador
EncaminhamentoSó um destino daquela Coleta usa este; a Definição pode usar outro, ou nenhum
Por produtorSó as mensagens de uma Aplicação produtora passam por ele, antes do Transformador da Entrega
ReferênciaA Definição está no Escopo deste Transformador: pode vir a usá-lo, mas hoje não transforma nada com ele

A distinção importa na hora de alterar: mexer num Transformador de encaminhamento afeta um ramo da Coleta, não a Coleta inteira. A linha de encaminhamento mostra o destino depois de uma seta; a Por produtor mostra a sigla da produtora ao lado de um ícone de envio — sem ela, o chip seria igual ao do uso direto da Entrega. A busca do modal de uso também encontra pela sigla da produtora.

A Referência vem em cinza, com ícone de elo, fora do par verde-água/azul que no sistema inteiro significa Coleta e Entrega em operação. Uma Definição que está no Escopo e usando conta uma vez só, como uso real. Ver Escopo não é uso.

Quando há mais usos do que cabe na coluna, o chip +N abre a mesma lista, e o modal de uso tem busca própria — um Transformador compartilhado acumula dezenas de linhas, e rolar procurando a certa não é conferir nada.

A contagem de usos não é recortada pelas suas Interfaces; a identidade de quem usa é. Um Transformador usado só por outra área mostrava “Nenhuma” e parecia livre para apagar — hoje mostra o total, e a diferença aparece como “N em Interfaces sem seu acesso”. Saber que algo está em uso não revela de quem: nem sigla de Aplicação, nem de Definição, nem id.

Excluir um Transformador em uso

Excluir um Transformador que uma Entrega, uma Coleta ou uma Aplicação produtora ainda usa é recusado, com uma mensagem que diz quantos usos restam — tire-o de lá antes. Antes, a mesma situação chegava à tela como erro genérico do servidor.

O encaminhamento não trava a exclusão: o destino que usava o Transformador excluído passa a usar o Transformador da Entrega de destino, como já acontecia.


Escrever à mão — /transformers/:id

Editor Monaco (o mesmo do VS Code), com teste imediato contra um payload de exemplo. Use new como :id para criar do zero.

O script é JavaScript. Além do payload, ele recebe um contexto:

CampoConteúdo
topicoTópico de origem, em coletas MQTT
uidIdentificador da mensagem
dataRecebimentoMomento do recebimento
varsVariáveis disponíveis: as Globais mais as da Aplicação de contexto

Uma variável de Aplicação sobrepõe uma Global de mesmo nome. É o que permite escrever um único Transformador com vars.CENTRO e instalá-lo em várias plantas — ver Variáveis.

O Resultado em tela cheia

A coluna 3. Resultado Obtido é estreita para um resultado grande. O ícone de tela cheia, ao lado do copiar, abre o resultado num popup com:

  • Original / Formatado — JSON ou XML indentado para leitura. Resultado que não é JSON nem XML válido fica só no Original.
  • Copiar original ou Copiar formatado — copia o que está na tela, e o rótulo diz qual.

Formatar é só para ler: o Transformação OK e o Modelo de Saída usam o resultado original, exatamente como o script o produziu.

Converter XML

Três funções ficam disponíveis no script, sem import:

FunçãoO que faz
xmlToJson(xml)Converte XML em objeto, convertendo o que parece número em número
xmlToJsonRaw(xml)Converte XML em objeto sem coerção de tipo: todo texto sai como string
jsonToXml(obj)Monta o XML a partir do objeto

Use xmlToJsonRaw sempre que o XML trouxer identificador. O xmlToJson come o zero à esquerda: a ordem de produção <ID>000100234567</ID> chega ao script como 100234567 — um número que não existe no ERP. Vale igual para código de material, lote, centro e CEP, e o estrago é silencioso, porque o script recebe um número plausível.

As duas funções ignoram o prefixo de namespace e preservam atributos. xmlToJson continua existindo e continua sendo o padrão de propósito: todo Transformador já escrito foi feito contra o comportamento dele, e um script que compara if (x.Qtd > 10) passaria a comparar texto se a conversão mudasse por baixo — a quebra apareceria na primeira mensagem, em produção.

O nome abre travado

Na edição, o campo Transformador vem com um cadeado. O nome não é só um rótulo: é a chave natural de importação e exportação (packs, arquivos de export, ferramentas MCP) e é por ele que a equipe reconhece o script nas Definições que o usam. Renomear faz um pack antigo criar um Transformador novo em vez de atualizar este.

Clicar no cadeado abre o aviso com os impactos; só depois de confirmar o campo libera. Na criação não há cadeado — ainda não existe nada apontando para o nome. A troca fica registrada no log de auditoria, na ação própria Alterar Nome do Transformador.

Escopo não é uso

O botão de alvo, ao lado do selo de escopo, abre a lista de Aplicação / Interface / Definição que este Transformador alcança. Essa lista é uma referência, não um vínculo: quem cria o vínculo de verdade é a própria Definição, na tela dela.

Para não deixar dúvida, cada linha do popup traz a coluna Uso real:

MarcaSignifica
Em usoA Definição — ou um encaminhamento dela, ou uma Aplicação produtora nela — aponta para este Transformador agora
Só referênciaNinguém aponta ainda; a Definição está listada apenas como candidata

Uma referência Em uso não pode ser removida daqui: desfaça o vínculo na tela da Definição primeiro — nessas linhas a lixeira aparece apagada, com o motivo no tooltip.

Remover é em duas etapas, como acrescentar. A lixeira marca a referência para sair — a linha fica destacada e o ícone vira “desfazer” —, e nada é removido até você clicar em Salvar. Fechar a janela descarta as marcações, tanto as de remoção quanto as linhas de adição preenchidas.

Se a marcação esvaziar o escopo, a tela avisa antes: sem nenhuma referência o Transformador volta a ser Global — passa a aparecer para todos e pode ser escolhido em qualquer Definição de Entrega ou de Coleta. É o único efeito de verdade de remover uma referência.

Histórico de versões

Cada alteração salva do script, dos modelos de payload ou do nome gera uma versão. No histórico:

  • a mais nova é a Atual — o retrato do que está salvo hoje;
  • as demais são Obsoletas: ficam para consulta e para restaurar, mas não são o que roda.

Restaurar esta versão pede confirmação e só mexe na tela — o script e os modelos passam a ser os da versão escolhida, mas nada é gravado até você clicar em Salvar Transformador. Para desistir, saia da tela sem salvar.

Uma versão obsoleta pode ser removida, também com confirmação; a remoção é definitiva e fica no log de auditoria. A versão Atual nunca sai — sem ela o histórico perderia a referência do que está no ar.


Levar um Transformador para outro ambiente

Um Transformador escrito e testado em homologação pode ir para produção — ou para a instalação de outro cliente — como um arquivo. Não é preciso passar pelo Importar/Exportar da Zona de Perigo, que move domínios inteiros de uma vez.

Exportar

Na listagem, o ícone de Exportar para arquivo na linha do Transformador baixa um .json com o cadastro, o script, os modelos de payload de entrada e saída e a lista de Definições do Escopo.

Ficam de fora de propósito: o histórico de versões (o destino começa a contar do zero) e a autoria da origem (quem importa passa a ser o autor). Se você só enxerga parte do Escopo, o arquivo leva só essa parte.

O Escopo é gravado pelas siglas — Aplicação · Interface · Definição —, nunca pelo número interno do registro. Os números são sequenciais e locais: o mesmo id aponta para outra coisa no ambiente de destino, e um arquivo que os carregasse amarraria o script à Definição errada sem reclamar de nada.

Importar

O botão Importar, ao lado de Novo Transformador, pede o arquivo e mostra o que vai acontecer antes de gravar qualquer coisa.

Para cada Definição do Escopo, o CMS procura a mesma trinca de siglas aqui e diz o que encontrou:

SituaçãoO que a tela mostra
A trinca existe neste ambienteexiste aqui
A Aplicação não existe aquiAplicação não existe aqui
A Aplicação existe, a Interface nãoInterface não existe aqui
A Interface existe, a Definição nãoDefinição não existe aqui
A Definição existe, mas é de uma Interface sem o seu acessoexiste, mas é de uma Interface sem seu acesso

E para cada linha você escolhe:

  • Usar esta — só aparece quando a trinca casou; aproveita a Definição encontrada;
  • Escolher outra — abre os combos de Aplicação → Interface → Definição deste ambiente, para você apontar à mão para onde aquele Escopo deve ir;
  • Ignorar — descarta a linha.

Ignorar todas as linhas (ou importar um Transformador que já era global) traz o Transformador como Global: ele fica disponível para todas as Definições, e o vínculo pode ser feito depois, na tela de cada Definição.

O import nunca sobrescreve um Transformador existente. Se já houver um com o mesmo nome aqui, o importado entra como “nome (importado)” — a tela avisa antes de gravar. Cabe a você conferir os dois e apagar o antigo, se for o caso.

Escolher outra depende das Ferramentas /applications e /interfaces: sem elas os combos ficariam vazios, e a tela mostra a opção desabilitada com o motivo. A Definição escolhida também é reconferida no servidor contra as suas Interfaces — não dá para amarrar o script a uma área que você não alcança.

Cada importação fica registrada no log de auditoria, na ação Importar Transformador, com o nome que vinha no arquivo, o nome com que foi criado e quantos vínculos de Escopo nasceram.


Gerar por IA

Quem não escreve código pode gerar o script descrevendo o resultado. É uma das formas de o CMS usar IA — ver Assistentes de configuração para o conjunto completo.

Informar os exemplos

Um payload de entrada (X) e um de saída (Y) — como exemplo real ou como JSON Schema.

Descrever a transformação

Um prompt em texto livre explicando as regras (“some as quantidades por lote”, “converta a data para ISO 8601”, “quando não vier o campo turno, use 1”).

Revisar o resultado

O backend gera o script e o executa no mesmo worker pool sandboxado usado em produção, contra o payload de exemplo. Você vê o resultado comparado (X → Y obtido), não o código — a menos que abra o ícone de código, que também mostra o histórico completo de gerações e prompts.

Ajustar ou aprovar

Se o resultado não estiver certo, ajuste o prompt e gere de novo — cada tentativa fica no histórico e pode ser restaurada. Só ao clicar em Aprovar o script passa a valer para uso real.

O provedor (Anthropic, OpenAI ou um compatível com a API OpenAI, como Ollama, Groq ou OpenRouter) é escolhido em Configurações → IA. A chave de API fica cifrada e nunca é reexibida.

A chamada à IA acontece apenas nesta tela, por ação explícita do usuário. O motor que executa os transformadores durante recebimento, entrega e coleta não depende de IA — uma indisponibilidade do provedor não afeta a entrega de mensagem nenhuma.

Ligar duas Definições que já existem

O botão Integrar duas Definições, no topo desta tela, abre o assistente que gera o Transformador entre duas pontas já configuradas no CMS, a partir do que de fato trafega em cada uma. Ver Entre Aplicações.


O motor de execução

Implementação em cms-api/src/modules/transformador/.

Isolamento

Scripts rodam em worker_threads, num pool gerenciado por TransformadorWorkerPool:

  • a thread principal da API nunca fica bloqueada por um script lento ou travado;
  • cada worker tem limite de memória via resourceLimits;
  • além do timeout do vm dentro do worker, existe um timeout externo: um worker travado é morto e substituído no pool.

O tamanho do pool vem de TRANSFORMADOR_WORKER_POOL_SIZE (padrão 4).

Na prática: um script com laço infinito derruba a própria execução daquela mensagem — não a API, não o agendador, não as outras interfaces.

A geração é desacoplada da execução

A IA vive em modules/transformador-ia/, separada do pool. Cada geração fica registrada em TransformadorGeracao com o prompt usado e pode ser restaurada.

Nunca aponte o motor de execução para o serviço de IA. A separação existe para que uma indisponibilidade do provedor não afete a entrega de mensagens.

Versões e escopo

  • TransformadorVersao — histórico de versões do script.
  • TransformadorEscopo — onde o transformador está em uso.

O uso consolidado da listagem não vem de TransformadorEscopo: ele é contado nas cinco tabelas de vínculo real (Entrega, Coleta, os dois encaminhamentos e DefinicaoTransformadorProdutor, o Transformador por Aplicação produtora). TransformadorEscopo guarda só a lista de referência do popup de escopo — a diferença entre as duas coisas é a coluna Uso real.