Quase todo fabricante de software de gestão tem na lista uma integração que ninguém quer pegar: um sistema que está na operação de boa parte dos clientes, não publica API para parceiro e volta todo trimestre no motivo das vendas perdidas.

Ela costuma ficar parada pelo mesmo motivo. Ninguém sabe ao certo como esse sistema conversa com o próprio servidor, e descobrir isso lendo código decompilado e tráfego na mão toma semanas de um time que já está ocupado com o produto. O REA, projeto de engenharia reversa com agentes de IA que passou de 390 mil estrelas no GitHub, encurta bastante essa parte: o agente faz a pergunta, o REA lê o sistema e devolve cada conclusão junto com a prova de onde ela saiu.

Neste texto eu levo o REA para uma integração com um WMS sem API, na ordem em que ela acontece de verdade. Primeiro vem o que o REA lê e como ele marca o que viu, o que deduziu e o que não conseguiu responder. Depois, a leitura do app Android que roda nos coletores do armazém, a captura do tráfego desse app e a comparação entre duas versões dele, para saber o que mudou quando o fornecedor atualizar.

A descoberta é a parte que o REA deixa mais leve, e quem já fez integração assim sabe que o problema costuma aparecer depois, em produção. A segunda metade mostra onde a primeira versão de uma integração dessas quebra e como cada etiqueta de evidência vira uma regra de código: consulta pela referência antes de criar, conferência do que só estava no código, revisão humana com prazo e polling com limite. No fim, você sai com uma tabela de decisão para levar ao próximo sistema sem API que o comercial pedir.

Prefere conteúdo em vídeo? Abaixo nosso vídeo completo sobre o tema:

01

O que é o REA e o que ele lê

O REA (Reverse Engineer Anything) é um servidor MCP com uma CLI, publicado em github.com/morluto/rea com licença MIT. A análise roda na sua máquina, e ele conversa com o agente que você já usa: o npx rea-agents setup registra o servidor MCP no Claude Code, no Codex, no Cursor, no Gemini CLI e em outros agentes, e instala as instruções de uso que o agente segue. Para usar a CLI direto no terminal, o pacote também instala com npm.

terminal · instalação do REA
$ npx rea-agents setup
# reinicie o agente depois do setup
$ npm install --global rea-agents
$ rea --help

Em outubro de 2026 o repositório tinha 393,8 mil estrelas, e a maior parte do que circula sobre ele mostra como clonar um app ou abrir um jogo. O uso deste texto é outro: integrar com um sistema que o seu cliente já usa e do qual tem licença.

O trabalho com o REA segue um ciclo de quatro passos. O agente faz uma pergunta sobre um sistema, o REA escolhe a ferramenta certa, inspeciona o alvo e traça o código que interessa, e devolve o achado junto com a evidência que o sustenta. Com isso em mãos, o agente explica o comportamento ou escreve e testa uma implementação.

AGENTEClaude Codecomo esse app falacom o servidor?explica ou escreve e testaREA · MCP + CLIJADXApktoolmitmdumproda na sua máquinaALVOapp.apkcódigo e tráfegoperguntainspecionatraça ocódigoachado eevidência
O agente pergunta, o REA aciona o analisador certo sobre o alvo e devolve o achado com a evidência.

A lista do que o REA lê é longa: binário nativo, com Ghidra, Hopper ou IDA, app em JavaScript e Electron, assembly .NET, executável PyInstaller, APK de Android, firmware, site, banco SQLite, captura de tráfego e de pacotes, e ainda GPU, modelo de IA e formatos de jogo. Para quem faz software de gestão, o que interessa é o grupo que mostra o que um sistema faz por dentro e o que ele troca com outros sistemas, porque é com isso que se integra.

Para APK, o REA usa o JADX, que devolve as declarações do manifesto, as classes e os métodos decompilados, e o Apktool, para os recursos do app. Para tráfego, ele lê arquivos HAR, capturas SAZ do Fiddler Everywhere e, no Linux, o mitmdump.

O próprio projeto diz para que serve: pesquisa legítima, educação, interoperabilidade, preservação de software e análise de software que você tem ou está autorizado a examinar. Integração entra em interoperabilidade, e tudo o que vem a seguir parte de um app licenciado pelo próprio cliente.

02

Observado, inferido e sem resposta

Antes de apontar o REA para qualquer sistema, vale entender o formato do que ele devolve, porque é desse formato que saem as regras de código da segunda metade do texto. Todo resultado guarda a identidade do artefato lido e o lugar de onde saiu a conclusão, e separa o que foi observado, o que foi inferido e o que ficou sem resposta.

Um achado do REA, com o artefato, o lugar no código e as três etiquetas.
  • observadoO que o REA viu acontecer, no tráfego ou no código que ele conseguiu traçar. É a informação em que você mais pode confiar.
  • inferidoO que está escrito no código e que ninguém viu rodar. Provavelmente funciona do jeito que o código diz, mas ainda não foi exercitado.
  • sem respostaO que nem o código nem o tráfego responderam.

Os nomes das etiquetas são os que eu uso no vídeo e aqui; no registro de evidência do REA elas aparecem como observações, inferências e pontos sem resposta. Guarde as três, porque cada uma vira uma decisão diferente na hora de escrever a integração.

03

O cenário: um WMS sem API que decide a venda

Para acompanhar a integração do começo ao fim, o texto segue um processo de negócio só. A Rota é uma software house de ERP para distribuidoras, com nove devs e sem SRE, e boa parte dos clientes dela controla o armazém no Cargo WMS. O Cargo não publica API para parceiro e roda um app Android nos coletores, os aparelhos que os separadores carregam pelo armazém.

No último trimestre, a Rota perdeu dois negócios pelo mesmo motivo: o cliente usava o Cargo WMS e a Rota não integrava com ele. Agora a Serra Azul Distribuidora, com dois centros de distribuição e 18 coletores, está na mesa e só assina se a integração existir.

ROTA ERPpedido 58.21412 itens · R$ 9.870,00CARGO WMSsem API para parceiroapp Android nos coletores?1234o ERP manda o pedidopara separaçãoo WMS separa em ondas,em lote a cada 10 mino ERP fatura quandoa separação terminao ERP avisaa expediçãoa Serra Azul só assina se isso funcionar
O pedido sai da Rota e precisa chegar ao Cargo WMS, que não tem API para parceiro, e o resultado da separação precisa voltar para a Rota faturar.

A integração tem quatro partes, e o pedido 58.214 da Serra Azul, com 12 itens e R$ 9.870,00, passa por todas. O ERP manda o pedido para separação, o WMS separa em ondas, o ERP fatura quando a separação termina e, por fim, avisa a expedição. Uma onda é o lote de pedidos que o WMS manda os separadores buscarem nas prateleiras, e o Cargo processa esses lotes a cada dez minutos.

Se o sistema sem API do seu cliente for outro, como um ERP desktop, um portal de fornecedor ou um app de força de vendas, dá para trocar o WMS por ele em qualquer ponto do texto, porque a descoberta e as regras de código são as mesmas.

ANTES DE SEGUIREngenharia reversa para integração tem limite legal, e cada contrato de licença tem as próprias regras. Este texto não é aconselhamento jurídico. Antes de prometer essa feature para o comercial, passe pelo jurídico da sua empresa.

04

O REA lê o app do coletor

O primeiro alvo é o app que roda nos coletores, o cargo-coletor 8.3. O arquivo sai de um coletor da própria Serra Azul, que tem a licença do Cargo WMS, sem baixar o APK de fonte nenhuma de fora e sem contornar proteção.

Na prática, o APK instalado sai do aparelho pelo adb, a ferramenta de linha de comando do Android, com o coletor ligado no computador e a depuração USB ativa. Em coletor corporativo, essa liberação costuma passar pela TI do cliente.

terminal · máquina onde o REA roda
$ adb shell pm path com.cargo.coletor
package:/data/app/~~Qe1x/com.cargo.coletor-2/base.apk
$ adb pull /data/app/~~Qe1x/com.cargo.coletor-2/base.apk cargo-coletor-8.3.apk

O pm path devolve onde o app está instalado, e o adb pull copia o arquivo para a máquina do REA. Para o JADX funcionar, essa máquina precisa de um JDK completo.

Com o APK em mãos, o agente faz a pergunta direto, e o REA aciona o JADX para decompilar o app. Resumindo a resposta:

claude code · agente com o REA
› como o app cria e consulta uma onda de separação?
  rea · JADX em cargo-coletor-8.3.apk
  classe OndaApiClient · ev-0140
  12 operações com caminho e campos
  status: SEPARANDO, SEPARADO, PARC, CANC
  nada visto rodando: tudo inferido

Dentro do pacote com.cargo.coletor, o REA acha a classe que fala com o servidor, a OndaApiClient, e dela saem doze operações, cada uma com o caminho e os campos que manda: criar onda, consultar onda, consultar pela referência do pedido, cancelar onda, reabrir separação, confirmar expedição e outras seis. O REA também encontra os quatro status que uma onda pode ter no Cargo:

SEPARANDOSEPARADOPARCCANC

SEPARANDO é a onda em andamento e SEPARADO, a separação completa. PARC é a separação parcial, que acontece quando falta item no estoque, e CANC é a onda cancelada. O PARC vai dar trabalho mais para a frente.

Por enquanto, as doze operações estão marcadas como inferidas. O REA leu o código do app, mas não viu nenhuma dessas chamadas acontecer, e para isso ele precisa do tráfego.

05

O tráfego confirma o contrato

Para ver as chamadas acontecerem, a Serra Azul separa três pedidos de teste num coletor de homologação, com o mitmdump no meio do caminho entre o app e o servidor do Cargo. O mitmdump é a versão de linha de comando do mitmproxy, um proxy que registra cada requisição e cada resposta que passam por ele, e desde a versão 10.1 ele grava a captura direto em HAR.

terminal · captura em homologação
$ mitmdump --set hardump=homologacao-3-pedidos.har
# o arquivo HAR é gravado quando o mitmdump encerra

O coletor precisa usar esse proxy e confiar no certificado do mitmproxy, instalado no aparelho de homologação. Se o app fixar o certificado do servidor, o que se chama de certificate pinning, a captura não abre o conteúdo das chamadas, e aí sobra conversar com o fornecedor ou seguir só com o que o código mostrou.

O REA lê o HAR, e cada requisição vira uma entrada com o método, o caminho, o corpo enviado e a resposta que voltou. Com essa prova, nove das doze operações passam de inferidas para observadas.

# OPERAÇÃO CAMINHO EVIDÊNCIA
01 criar onda POST /v2/ondas observado
02 consultar onda GET /v2/ondas/{id} observado
03 consultar pela referência GET /v2/ondas?ref={pedido} observado
04 listar itens da onda GET /v2/ondas/{id}/itens observado
05 iniciar separação POST /v2/ondas/{id}/inicio observado
06 registrar item separado POST /v2/ondas/{id}/itens/{i} observado
07 registrar falta de item POST /v2/ondas/{id}/faltas observado
08 finalizar separação POST /v2/ondas/{id}/fim observado
09 saldo do endereço GET /v2/enderecos/{cod}/saldo observado
10 cancelar onda DELETE /v2/ondas/{id} inferido
11 reabrir separação POST /v2/ondas/{id}/reabrir inferido
12 confirmar expedição POST /v2/expedicoes inferido

As três que continuam inferidas não apareceram nos testes de homologação: cancelar onda, reabrir separação e confirmar expedição. Elas estão no código e ninguém as viu rodar. Também ficaram três perguntas que nem o código nem o tráfego responderam:

  • sem respostaO POST que cria a onda aceita chave de idempotência?
  • sem respostaExiste algum webhook que avise quando a onda termina?
  • sem respostaO que o status PARC devolve nas quantidades?
OPERAÇÕES12levantadas no APK
OBSERVADAS9vistas no tráfego
INFERIDAS3só no código
SEM RESPOSTA3perguntas abertas

Um achado da tabela segura a integração inteira: a consulta de onda pela referência do pedido foi observada. Se o POST de criar onda não aceita chave de idempotência, é essa consulta que permite saber se a onda de um pedido já existe antes de criar outra, e ela volta na seção 8.

O contrato todo fica num pacote de evidência. O rea evidence-export grava a forma canônica desse pacote num JSON, que a Rota versiona no repositório junto com o código da integração. Se o arquivo de destino já existir, ele é mantido, a menos que você passe --overwrite.

terminal · exportar o contrato
$ rea evidence-export /srv/rota/rea/cargo-coletor-8.3.json \
    /srv/rota/integracao-cargo/contrato/contrato-8.3.json

06

Quando o WMS atualiza

Um sistema fechado muda sem avisar ninguém: semanas depois da descoberta, o Cargo publica a versão 8.4 do app do coletor, e a Rota roda a mesma análise no APK novo e exporta a evidência dele. O rea compare põe as duas evidências lado a lado, com a saída em TOON por padrão ou em JSON com --json, que dá para guardar ou ler num script.

terminal · comparar as versões
$ rea compare /srv/rota/integracao-cargo/contrato/contrato-8.3.json \
    /srv/rota/integracao-cargo/contrato/contrato-8.4.json
Resumo da comparação entre as evidências das versões 8.3 e 8.4 do app do coletor.

Se a integração mandasse o campo prioridade no POST de criar onda, ela quebraria sem erro aparente na primeira separação de um cliente que atualizasse o coletor. A rotina que isso cria é simples: a cada versão nova do app, a Rota roda a análise e a comparação antes de o cliente atualizar, e descobre a mudança no ritmo dela, sem esperar o chamado no suporte.

07

A primeira versão da integração e onde ela quebra

Com o contrato em mãos, dá para escrever a integração, e é nesse ponto que muito time monta uma versão parecida com esta. O ERP chama o Cargo WMS dentro da própria requisição e, como a chamada pode falhar, entra uma fila para segurar os retries. O WMS separa em lote e demora, então entra um job que consulta o status a cada cinco minutos e uma tabela de controle para lembrar em que passo cada pedido está e quantas vezes já tentou. Quando a separação termina, um segundo job fatura e avisa a expedição.

ROTA ERPpedido 58.214CARGO WMSsem APIfila de retriesjob de pollinga cada 5 mintabela de controlepedido · onda · statusjob de faturamentonota e expediçãochamada na requisição1234
A primeira versão tem cinco peças para um processo só, e os números marcam as quatro falhas descritas a seguir.

São cinco peças, cada uma com um jeito próprio de falhar, e as quatro falhas que aparecem em produção voltam, uma por uma, para uma etiqueta da descoberta.

1. O timeout que cria uma segunda onda sem resposta

O POST que cria a onda estoura o timeout de 30 segundos, e a fila manda de novo. Como ninguém sabe se esse POST aceita chave de idempotência, a integração não manda chave nenhuma, e o WMS cria a onda 3392 para o mesmo pedido que já estava na onda 3391. No armazém, dois separadores saem atrás dos mesmos 12 itens.

2. O status parcial tratado como erro inferido

O PARC estava no código do app e nunca apareceu nos testes. Quando a separação do pedido volta parcial, o job de polling não tem um caso para esse status, trata como erro, e o pedido fica parado até alguém perceber.

3. A consulta que não sabe quando parar sem resposta

Como não existe webhook, o job consulta o WMS a cada cinco minutos, só que o WMS processa o lote a cada dez. Metade das consultas não tem novidade para trazer, e nada no job diz quando ele deve desistir de um pedido que travou.

4. A expedição confirmada que não saiu inferido

Confirmar expedição era outra operação que só existia no código. A chamada falha de um jeito que ninguém previu, ninguém confere o resultado, e o pedido fica marcado como enviado sem ter saído do armazém.

As quatro falhas vêm do que a descoberta não conseguiu garantir, e trocar a fila por outra não resolve nenhuma delas. A correção começa pelas etiquetas.

08

Uma regra de código para cada etiqueta

Daqui em diante entra o skail, e eu faço parte da skail, então leia esta parte sabendo disso. O skail é uma plataforma de execução durável: o processo de negócio vira uma função escrita de cima para baixo, e a plataforma guarda o estado da execução e retoma de onde parou quando a aplicação cai, é reiniciada ou passa horas esperando alguma coisa.

Dois tipos de método fazem esse trabalho. A function orquestra os passos e decide o que vem em seguida. Os commands fazem as operações de I/O, como chamar o WMS, gravar no banco ou emitir a nota, e o resultado de cada command fica gravado no histórico da execução. Um command que falha é retentado até o retryCount dele, que é 5 por padrão, e um command que já gravou resultado não roda de novo quando a execução é retomada. A página Functions e commands explica as regras de cada um.

A integração com o Cargo WMS vira a function SepararNoWms, que recebe o id do pedido. A Rota dispara cada execução com um POST no endereço da function, como /trigger/integracao/v1.0.0/SepararNoWms/58214, usando o id do pedido como id da execução, do jeito que mostra Disparar uma função pela API. A fila, os dois jobs e a tabela de controle saem, e cada etiqueta da descoberta vira uma decisão escrita no código:

SepararNoWms · C#
[SkailFunction]
public async SkailTask SepararNoWms(string pedidoId)
{
    var pedido = await CarregarPedido(pedidoId);
    var onda = await CriarOndaNoWms(pedidoId, pedido.Itens);

    // sem webhook: consulta com intervalo crescente e limite
    var intervalo = TimeSpan.FromSeconds(30);
    StatusOnda status;
    for (var tentativa = 1; ; tentativa++)
    {
        await SkailTask.Delay(intervalo);
        status = await ConsultarOnda(onda.Referencia);
        if (status != StatusOnda.Separando) break;
        if (tentativa == 20)
        {
            await MarcarAnaliseManual(pedidoId);
            return;
        }
        intervalo = intervalo * 2 < TimeSpan.FromMinutes(10)
            ? intervalo * 2 : TimeSpan.FromMinutes(10);
    }

    if (status == StatusOnda.Cancelada)
    {
        await MarcarAnaliseManual(pedidoId);
        return;
    }

    // status parcial: uma pessoa decide, com prazo
    if (status == StatusOnda.Parcial)
    {
        await AtualizarStatus(pedidoId, "aguardando decisão");
        var decisao = SkailTask.WaitForEvent<DecisaoParcial>(
            "DECISAO_PARCIAL", pedidoId);
        var prazo = SkailTask.Delay(TimeSpan.FromHours(4));
        if (await SkailTask.WhenAny(decisao, prazo) == prazo)
        {
            await MarcarAnaliseManual(pedidoId);
            return;
        }
        if (!(await decisao).Faturar)
        {
            await AtualizarStatus(pedidoId, "aguardando reposição");
            return;
        }
    }

    var nota = await EmitirNota(pedidoId);
    await AvisarExpedicao(pedidoId, nota.Numero);

    // operação inferida: lê de volta no WMS e confere
    try
    {
        await ConferirExpedicao(pedidoId);
    }
    catch (ExpedicaoNaoConfirmada)
    {
        await MarcarAnaliseManual(pedidoId);
    }
}

Observado, mas sem chave de idempotência

Criar onda foi observado no tráfego, mas a pergunta sobre chave de idempotência ficou sem resposta. O command CriarOndaNoWms usa o achado que segurava a integração: antes de criar, ele consulta a onda pela referência do pedido e, se ela já existe, devolve a que existe. O timeout de 30 segundos é o do cliente HTTP dentro do command, e quando ele estoura, o runtime tenta o command de novo sozinho.

A página Escrever commands idempotentes trata desse caso no terceiro exemplo, o do sistema externo que não aceita chave, e recomenda usar a consulta por referência externa quando o sistema oferece uma.

Sem webhook: polling com limite

Não apareceu webhook, então a function consulta. O laço começa com 30 segundos de espera e dobra até o teto de 10 minutos, com limite de 20 consultas, o que cobre perto de 2 h 45 min. Entre uma consulta e outra, a execução hiberna sem ocupar a aplicação. Quando o limite estoura, o pedido vai para análise manual num command, que fica registrado e aparece no Monitor. O padrão é o da página Polling de sistema externo. A onda que volta cancelada também vai para análise manual.

Inferido: o status parcial vai para uma pessoa, com prazo

Quando a onda volta PARC, a function grava “aguardando decisão” e espera o evento DECISAO_PARCIAL com o id do pedido ou o prazo de 4 horas, o que vier primeiro, com WaitForEvent, Delay e WhenAny. Quem decide é uma pessoa, na tela de separação parcial da Rota, e o clique dispara um POST /api/v1/fire/DECISAO_PARCIAL/58214 que acorda a execução. Se ninguém decidir em 4 horas, o pedido vai para análise manual. O padrão está em Esperar um evento com prazo, e o disparo, em Disparar um evento pela API.

Inferido: o que só estava no código é conferido

Confirmar expedição nunca foi visto rodando. Depois de avisar a expedição, o command ConferirExpedicao lê o status de volta no WMS. Se a expedição não aparece confirmada, ele lança exceção e tenta de novo até três vezes, porque o WMS pode levar um instante para refletir a mudança. Se as tentativas acabam, a exceção chega à function, que marca o pedido para análise manual em vez de seguir como se ele tivesse saído. Essa regra é deste exemplo: a doc não tem uma página só para ela, e o ConferirExpedicao é um command escrito do mesmo jeito que os outros.

commands da integração · C#
[SkailCommand]
public async SkailTask<Onda> CriarOndaNoWms(string pedidoId, List<ItemPedido> itens)
{
    // achado observado: a consulta pela referência do pedido
    var existente = await _wms.ConsultarOndaPorReferencia(pedidoId);
    if (existente is not null) return existente;   // já criada: devolve a mesma
    return await _wms.CriarOnda(pedidoId, itens);
}

[SkailCommand(retryCount: 3)]
public async SkailTask<StatusOnda> ConsultarOnda(string referencia)
    => await _wms.ConsultarStatus(referencia);

[SkailCommand(retryCount: 3)]
public async SkailTask ConferirExpedicao(string pedidoId)
{
    // operação inferida: o WMS pode levar um instante para refletir
    var status = await _wms.ConsultarExpedicao(pedidoId);
    if (status != "confirmada") throw new ExpedicaoNaoConfirmada(pedidoId);
}

[SkailCommand]
public async SkailTask<Pedido> CarregarPedido(string pedidoId)
    => await _rota.Carregar(pedidoId);

O corpo dos commands não está na documentação, e eu completei no mesmo estilo dela. AtualizarStatus, EmitirNota, AvisarExpedicao e MarcarAnaliseManual chamam a Rota do mesmo jeito que o CarregarPedido.

09

O pedido 58.214 no Monitor

Na quinta-feira, 12 de novembro, às 09:14:05, a Rota dispara a SepararNoWms para o pedido 58.214, e o Monitor mostra cada passo da execução sem nenhuma instrumentação no código: argumentos, resultados, duração e tentativas de cada command.

O CarregarPedido conclui, e o CriarOndaNoWms estoura os 30 segundos na primeira tentativa. O runtime tenta de novo sozinho, a execução continua com um passo só, e o número de tentativas desse passo sobe para 2. Na segunda tentativa, às 09:14:36, a consulta pela referência acha a onda 3391, que a primeira tentativa já tinha criado no WMS, e o passo devolve essa onda sem criar outra.

Em seguida vêm as consultas de status, com intervalos de 30 segundos, 1, 2, 4, 8 e 10 minutos. As cinco primeiras voltam SEPARANDO, e entre elas a execução hiberna. Às 09:40:08, a sexta consulta volta PARC, com 11 dos 12 itens, porque faltou um item no estoque.

SepararNoWms58214 · workload integracao v1.0.0ConcluídoDuração E2E 1h 8minHORÁRIOPASSORESULTADO09:14:0509:14:0509:14:3609:40:0909:40:0910:22:0010:22:0010:22:0110:22:02CarregarPedidoconcluído · 12 itensCriarOndaNoWmsonda 3391, já existiaTentativas: 2. A primeira estourou o timeout de 30 s.ConsultarOnda × 6PARC · 11 de 12intervalos de 30 s a 10 min · 5 vezes SEPARANDOAtualizarStatus“aguardando decisão”WhenAnyDECISAO_PARCIAL · 58214 ou prazo de 4 h (13:40)evento recebidofaturar parcial, escolhido na tela da RotaEmitirNotanota 104.387AvisarExpedicaoconcluídoConferirExpedicaoexpedição confirmada
Representação simplificada da execução do pedido 58.214 no Monitor, das 09:14:05 às 10:22:05.

O fluxo grava “aguardando decisão” às 09:40:09 e entra na espera: o evento DECISAO_PARCIAL do pedido 58214 ou o prazo de 4 horas, que venceria às 13:40. Enquanto isso, a execução aparece no Monitor como aguardando evento, com o nome e o id esperados, e nada da aplicação fica preso a esse pedido.

Às 10:22, a Juliana Reis, coordenadora comercial da Serra Azul, abre a tela de separação parcial da Rota e escolhe faturar os 11 itens que saíram. O clique dispara o fire, a execução acorda, a nota 104.387 sai, a expedição é avisada e conferida, e a execução termina às 10:22:05.

ONDAS CRIADAS1nenhuma duplicada, depois de 2 tentativas
PONTA A PONTA1 h 08das 09:14:05 às 10:22:05
ESPERANDO A DECISÃO42 minsem ocupar a aplicação

Dos 68 minutos da execução, 26 foram de separação no armazém e 42 de espera pela decisão da Juliana, sem nenhum job rodando no vazio nesse tempo.

10

O que muda na arquitetura

Comparando com a primeira versão, saíram a fila, o job de polling, a tabela de controle e o job de faturamento. Ficaram a Rota disparando a execução, a function SepararNoWms e o Cargo WMS, e o que estava espalhado em cinco peças, com o estado numa tabela, passou a estar num método que se lê de cima para baixo.

PRIMEIRA VERSÃO · CINCO PEÇASchamada na requisiçãofila de retriesjob de pollingtabela de controlejob de faturamentoquatro peças saem, a chamada vira triggerCOM EXECUÇÃO DURÁVELROTA ERPpedido 58.214triggerEXECUÇÃO DURÁVELSepararNoWmscada passo aparece no MonitorcommandsCARGO WMSsem APIo WMS continua sem API, e o rea compare avisa quando ele mudar
Em cima, as cinco peças da primeira versão, e embaixo a Rota disparando a function, que fala com o Cargo WMS por commands.

O Cargo WMS continua sem API oficial, e isso nenhuma plataforma muda. O que muda é que a integração ficou num código que dá para ler e acompanhar, e o rea compare avisa quando o WMS mudar por baixo.

A tabela abaixo resume o que fazer com cada etiqueta quando você levantar o contrato do próximo sistema sem API:

ETIQUETA NO CÓDIGO ONDE ESTÁ O PADRÃO
observado Chave de idempotência quando o sistema aceita, ou consulta pela referência antes de criar quando não aceita. Escrever commands idempotentes
inferido Um command que lê o resultado de volta e confere, com análise manual se não bater. Um command a mais, no mesmo padrão dos outros
sem resposta Revisão humana com prazo, nunca uma espera sem fim. Esperar um evento com prazo
sem webhook Polling com intervalo crescente, teto e limite de consultas. Polling de sistema externo

FAQ

Perguntas frequentes

O que é o REA (Reverse Engineer Anything)?

É um servidor MCP com uma CLI, de licença MIT, que faz engenharia reversa com agentes de IA. O agente pergunta sobre um sistema, o REA escolhe a ferramenta certa, analisa o alvo na sua máquina e devolve cada achado com a evidência de onde ele saiu. A instalação é pelo npx rea-agents setup, que registra o servidor no Claude Code, no Codex, no Cursor e em outros agentes.

O REA consegue ler um APK de Android?

Sim: para APK, ele usa o JADX, que devolve o manifesto, as classes e os métodos decompilados, e o Apktool, para os recursos do app. O JADX precisa de um JDK completo na máquina onde o REA roda. O tráfego do app entra por arquivo HAR, que o mitmdump grava com --set hardump.

Como integrar com um sistema que não tem API?

Comece levantando o contrato que o próprio sistema usa, a partir de um artefato licenciado pelo cliente, como o app do coletor, e de uma captura do tráfego em homologação. Separe cada operação em observada, inferida ou sem resposta e escreva a integração com uma regra para cada etiqueta: idempotência para o observado, conferência para o inferido e revisão humana com prazo para o que ficou sem resposta. Antes de prometer a integração, passe pelo jurídico, porque cada contrato de licença tem as próprias regras.

Como evitar pedido duplicado quando a API não aceita chave de idempotência?

Consulte pela referência do pedido antes de criar e, se o registro já existir, devolva o que existe. Quando o sistema não oferece nem essa consulta, a saída é guardar no seu banco os efeitos já aplicados e consultar antes de chamar. Os dois casos estão na página Escrever commands idempotentes, da documentação do skail.

O que o rea compare faz?

Compara dois pacotes de evidência do REA, como os contratos de duas versões do mesmo app, e mostra o que mudou, o que apareceu e o que ficou igual. O resultado vem em TOON por padrão e em JSON com --json. Rodar a comparação a cada versão nova do sistema fechado mostra a mudança antes de o cliente atualizar.

PRÓXIMO PASSO

Por onde começar

Escolha o sistema sem API que o seu comercial mais pede e comece pela descoberta: um artefato licenciado pelo cliente, como o APK do coletor ou o client desktop, uma captura em homologação e o pacote de evidência exportado e versionado junto com o código. Com as etiquetas em mãos, a tabela da seção 10 diz como escrever cada operação.

Se fizer sentido levar a integração para execução durável, o caso de uso Modernizar um sistema legado mostra o fluxo de um ERP antigo numa função linear, e o guia Migrar código existente mostra como tirar um fluxo de jobs, fila e tabela de controle sem reescrever o sistema. São exemplos para adaptar ao seu caso.

Para ver a descoberta e a execução no Monitor passo a passo, assista ao vídeo REA na prática.