Validar uma mudança de contrato de API proposta por AI
Este tutorial ensina a separar uma proposta gerada por AI da decisão de contrato e da evidência de execução. Ao final, você terá uma baseline Mule testada, uma proposta preservada, uma decisão explícita e um resultado MUnit que outra pessoa pode conferir. O artigo em português e sua versão em inglês discutem o significado dessas decisões; aqui o foco é reproduzir o exercício. Este tutorial também tem uma versão em inglês.
Escopo da evidência: baseline, proposta da AI, decisão humana e MUnit parametrizado foram executados em 27 de setembro de 2026. O repositório público contém os artefatos. O teste HTTP de ponta a ponta ainda está pendente; este tutorial ensina a verificar o contrato e o handler.
Preparar o laboratório
Clone o ai-assisted-engineering-lab. Ele parte de uma fixture sintética de consulta de clientes e não depende de backend, credencial ou ambiente de deploy. Para reproduzir os comandos, é preciso Java 17, Maven e as dependências Mule disponíveis no cache local ou nos repositórios configurados. O MUnit precisa abrir portas locais dinâmicas.
git clone https://github.com/brunosouzas/ai-assisted-engineering-lab.git
cd ai-assisted-engineering-lab
A baseline é o commit 82eb3332c889d31e75351df58c69948d4d50fcc1. A implementação revisada está em 394490d1df171e75f7a0851e3c5c09cc1b3f6f64. Compare as duas refs sem depender de capturas de tela:
git diff 82eb3332c889d31e75351df58c69948d4d50fcc1 394490d1df171e75f7a0851e3c5c09cc1b3f6f64 -- src/main src/test pom.xml
Confirme a versão do Java antes do build:
JAVA_HOME=/caminho/para/jdk-17 mvn -version
Para executar a baseline, selecione o commit inicial e rode o build no diretório do repositório:
git switch --detach 82eb3332c889d31e75351df58c69948d4d50fcc1
JAVA_HOME=/caminho/para/jdk-17 mvn -o clean package
Depois, volte para a versão atual e repita o build:
git switch main
JAVA_HOME=/caminho/para/jdk-17 mvn -o clean package
Se as dependências não estiverem no cache, retire -o. Verifique no resultado BUILD SUCCESS, a contagem de testes, falhas e erros. Em 27 de setembro de 2026, a baseline local passou com seis testes e 60% de cobertura da aplicação. Depois da mudança, os sete testes inicialmente escritos com valores fixos passaram; em seguida foram consolidados em seis execuções parametrizadas, que também passaram, com 42,86% de cobertura. Não compare essas porcentagens isoladamente: os testes chamam o handler diretamente e a alteração acrescentou componentes de roteamento e tratamento de erros que a suíte não cobre. O primeiro build da baseline falhou porque o terminal usava Java 25; selecionar Java 17 resolveu a incompatibilidade.
Ler o contrato antes de pedir código
Abra src/main/resources/api/customer-lookup-api.raml, src/main/mule/customer-lookup-api.xml e as suítes src/test/munit/customer-lookup-*-parameterized-suite.xml. Para examinar os testes da baseline, consulte o commit indicado acima. Compare três coisas:
- Quais respostas o RAML declara para
GET /customers/{customerId}. - Qual ramo do fluxo Mule produz cada resposta.
- Qual assertion MUnit falharia se esse comportamento mudasse.
Na baseline, CUST-001 retornava 200, um identificador inválido retornava 400, um identificador válido mas desconhecido retornava 404 e CUST-500 simulava um 500 sanitizado. O 404 de negócio é justamente um ponto corrigido pela decisão de contrato: agora o cliente desconhecido retorna 400, e 404 fica reservado para endpoint inexistente.
Registrar a proposta da AI
O primeiro exercício adiciona CUST-002 com status INACTIVE. O prompt e a resposta completa da rodada somente de leitura estão no registro da proposta. A AI propôs 200 com o formato já previsto pelo RAML e identificou uma suposição: o contrato permitia o status INACTIVE, mas não dizia se esse cliente deveria ficar visível na consulta.
Leia a decisão humana no registro do experimento antes de examinar o código final. Bruno reservou 404 para endpoint inexistente, 400 para erros de negócio e 500 para falhas de sistema. O laboratório também usa o corpo de erro consolidado { "error": { "code": número, "reason": texto, "message": texto } } e mantém o correlation ID no header. Compare essa decisão com a proposta da AI e com o caso inactive-customer no YAML de MUnit.
Executar e interpretar
Execute novamente o build com Java 17 e confira a saída. Compare o RAML, o flow customer-lookup-process e os testes no diff entre a baseline e a revisão final. Verifique especialmente três mudanças: CUST-002 gera erro de negócio 400; CUST-999, antes mapeado como 404, também gera 400; e os erros seguem o formato compartilhado. A configuração APIKit reserva 404 para rota ausente e usa 405, 406 e 415 para os demais erros de protocolo. As suítes customer-lookup-*-parameterized-suite.xml leem casos em src/test/resources/munit/; confira na saída do MUnit os nomes dos dois casos de sucesso/correlação e dos quatro casos de erro.
Ao relatar o exercício, separe quatro afirmações: o que a AI propôs, o que o engenheiro decidiu, o que o código implementou e o que o MUnit verificou. Neste caso, o MUnit aprovou seis execuções parametrizadas do handler, mas não verificou a resposta HTTP real para uma rota inexistente. O comando mvn mule:run não está disponível no Mule Maven Plugin 4.9.1 usado aqui; a verificação HTTP de ponta a ponta continua pendente. O resultado não mede produtividade nem autoriza concluir que uma ocupação inteira será ou não substituída.