.NET - Modernizando sistemas Legados com Spec-Driven Development
 Veja como migrar sistemas legados em .NET para o Desenvolvimento Orientado por Especificação (SDD) de forma segura, combinando Testes de Caracterização, Strangler Fig, YARP, ACL e agentes de IA. (Traduzido e Adaptado)

Muitos acreditam que basta colocar um agente de IA (como Claude Code, GitHub Copilot ou Gemini) para ler uma solução legada (como um monolito antigo em .NET Framework / ASP.NET MVC / WCF) e gerar a especificação de negócio diretamente do código-fonte.

Cuidado: a IA pode gerar uma especificação impecável no papel, mas completamente enganosa sobre o comportamento real do sistema. Se houver um bug esquecido há dez anos em um controller sem testes, a IA assumirá essa anomalia como regra oficial de negócio. No próximo prompt, o agente construirá novas funcionalidades sobre esse erro, culminando em incidentes graves em produção.

Modernizar um sistema legado em produção é como trocar a fiação e as fundações de um hospital com ele funcionando 24 horas por dia. Para fazer isso com previsibilidade, usamos a Brownfield Migration Factory: uma abordagem estruturada que trata a migração de bases legadas (brownfield) não como um improviso heroico, mas como uma linha de produção industrial com etapas e travas de qualidade (quality gates) bem definidas.

 

O Ponto Central: Você Tem um Oráculo de Testes?

Diante de um legado, surge o falso dilema: gerar a especificação via engenharia reversa com IA ou escrever tudo do zero?

A decisão real é outra: você possui um Teste de Caracterização antes de deixar a IA gerar a especificação?

- O que é um Teste de Caracterização: É um teste automatizado (via xUnit/NUnit) cujo objetivo exclusivo é "fotografar" e congelar o comportamento real que o código entrega hoje — incluindo bugs, retornos inesperados e exceções. Você não testa a teoria idealizada, testa a realidade atual;

- Por que ele é essencial: Ele funciona como um oráculo de validação. Sem ele, tanto a especificação gerada por IA quanto a escrita à mão são apenas palpites no escuro.

O Processo em 5 Etapas Práticas

[1. Assessment / Hotspots] 
          ↓
[2. Testes de Caracterização] 
          ↓
[3. Estratificação Incremental (Strangler Fig + YARP)] 
          ↓
[4. Camada Anticorrupção (ACL) como Spec] 
          ↓
[5. Estratégia de Virada (Cutover Seguro)]

1. Assessment (Análise de Hotspots no Git)

Não escolha onde mexer baseado na intuição do arquiteto. Analise o histórico de commits no Git: geralmente, 1% a 2% das classes e arquivos concentram mais de 70% do esforço de manutenção e das alterações. Ataque esses hotspots de alta complexidade ciclomática primeiro.

Nota: A análise de hotspots cruza o histórico de commits do Git com a complexidade do código para identificar o 1% a 2% de arquivos que mais sofrem alterações e concentram a maior parte dos bugs e manutenções do projeto.

2. Testes de Caracterização (A Rede de Segurança)

Antes de refatorar ou extrair código:
  • Isole o fluxo alvo em um teste (usando xUnit / FluentAssertions);
  • Execute o método legado, capture exatamente o valor retornado e fixe esse retorno na asserção (assert);

  • Exemplo prático: Se um método de faturamento retorna 0.00m em vez de null para clientes sem plano e o resto da empresa depende disso há anos, o teste deve cravar 0.00m. Corrigir isso sem alinhamento quebra integrações em produção.
3. Estratificação Incremental (Strangler Fig + YARP)

Reescrever o projeto inteiro do zero de uma vez é a receita clássica para prazos estourados e projetos cancelados.

- Padrão Strangler Fig (Figueira Estranguladora): Crie o sistema novo ao lado e migre uma fatia vertical (bounded context) por vez, "estrangulando" o monolito gradualmente até poder desligá-lo com segurança;

- YARP (Yet Another Reverse Proxy): Utilize a biblioteca oficial da Microsoft de proxy reverso na porta de entrada da aplicação. Requisições de rotas modernizadas (ex.:
/api/pedidos em .NET 9) são enviadas para a nova API; rotas ainda não migradas continuam sendo repassadas para o monolito legado de forma transparente para os clientes.


4. Camada Anticorrupção (ACL) como Limite da Especificação

Aplique o padrão Anti-Corruption Layer (ACL) do Domain-Driven Design (DDD) com adapters, façades e DTOs de mapeamento.

Proteja seu novo modelo de domínio limpo (Clean Architecture) contra as idiossincrasias e estruturas anêmicas do sistema antigo.

Uso com IA: Ao solicitar geração de código ou especificações para a IA, restrinja o contexto dela estritamente à interface da ACL. Como ela não enxerga os vícios internos do código antigo, não replicará más práticas no novo serviço.

5. Estratégia de Virada (Cutover) sem "Deploy na Fé"

Grandes modernizações falham frequentemente no momento exato da virada de chave operacional (cutover). Aplique mecanismos de segurança:

- Feature Flags: Chaves no código (via pacote Microsoft.FeatureManagement) para ligar, desligar ou redirecionar a execução da nova lógica em tempo de execução sem exigir novos deploys;

- Dark Launches: Colocar a funcionalidade nova em produção recebendo tráfego real, mas processando respostas em segundo plano sem exibi-las ao usuário final para testar estabilidade e carga;

- Parallel Runs: Executar tanto o código legado quanto o novo para a mesma requisição em produção e comparar as saídas em segundo plano para garantir equivalência antes da virada definitiva;

- Change Data Capture (CDC): Sincronizar o banco novo lendo diretamente os logs de transação do banco antigo (como o CDC nativo do SQL Server ou Debezium/Kafka) de forma assíncrona, mantendo ambos atualizados sem sobrecarregar a aplicação;

- Rollback Ensaiado: Tenha um plano de reversão cronometrado e testado previamente; rollback apenas documentado no papel não é rollback.

A Lei de Hyrum e o Papel das Ferramentas de IA

A Lei de Hyrum (formulada por Hyrum Wright na Google) estabelece que:

"Com um número suficiente de usuários em uma API, não importa o que o contrato promete: todos os comportamentos observáveis do sistema se tornam uma dependência para alguém."
  • Impacto nas ferramentas de IA: A IA não distingue um comportamento intencional de um efeito colateral histórico. Exija ferramentas que exponham explicitamente o nível de confiança das afirmações e destaquem lacunas (gaps) que demandam validação humana. Ferramentas que simulam certeza absoluta ocultam riscos graves.

  • A IA não atua como oráculo: Modelos que revisam as próprias alterações deixam passar desvios semânticos com frequência. O único oráculo confiável continua sendo a suíte de testes de caracterização automatizados executando no pipeline de CI/CD.
Resumo para o Próximo Projeto

  • Mapeie Hotspots via Git: Identifique o 1-2% do código que mais consome manutenção antes de refatorar;
  • Crie Testes de Caracterização: Congele o comportamento real da fatia antes de qualquer extração;
  • Migre com Strangler Fig + YARP: Isole e migre fatias verticais roteadas por proxy reverso, evitando reescritas completas do zero;
  • Isole com ACL (DDD): Use a Camada Anticorrupção para proteger sua Clean Architecture e restringir a visão da IA;
  • Implemente Cutover Seguro: Valide com Feature Flags, Parallel Runs, CDC no banco e garanta um plano de rollback cronometrado.
A escolha entre fazer engenharia reversa com IA ou escrever a especificação do zero não é uma decisão de arquitetura: é uma decisão de testes. Sem testes de caracterização atuando como oráculo, ambos os caminhos são apenas palpites no escuro. Com eles, a migração se torna um processo seguro, previsível e verificável.

E estamos conversados..

"Para que possais andar dignamente diante do Senhor, agradando-lhe em tudo, frutificando em toda a boa obra, e crescendo no conhecimento de Deus;"
Colossenses 1:10
 

Referências:


José Carlos Macoratti