Pular para o conteúdo
B
Bradata
migraçãosistema legadomodernizaçãocase

Migração de sistema legado: o caso real de um ERP Delphi para web moderna

Case de migração de sistema Delphi/VB para arquitetura web com strangler fig pattern, parallel running e estratégias de migração de dados.

Por Bradata··6 min de leitura

O sistema que ninguém queria tocar

O cliente era uma distribuidora de autopeças do interior de São Paulo. 14 anos de operação rodando um ERP escrito em Delphi 7, com banco Firebird 2.5, interface MDI cheia de grids e regras de negócio espalhadas por 380 forms. O sistema funcionava. O problema é que funcionava apenas para quem já sabia usá-lo de cor.

Novos funcionários levavam semanas para aprender o fluxo. O Firebird não aguentava mais de 25 conexões simultâneas sem degradar. Relatórios pesados travavam a operação inteira. E ninguém na empresa conseguia manter o código Delphi, porque o desenvolvedor original havia saído três anos antes.

Quando nos procuraram, o pedido era direto: "Queremos um sistema web. Mas não podemos parar a operação."

Por que não reescrevemos tudo do zero

A tentação de jogar fora o sistema antigo e começar de novo é real. Parece mais limpo, mais rápido, mais bonito. Na prática, rewrite total é uma das maiores armadilhas da engenharia de software.

O ERP tinha 12 módulos: compras, vendas, estoque, financeiro, fiscal (NF-e/NFS-e), comissões, logística, CRM básico, RH/ponto, contabilidade, BI gerencial e um módulo de garantia específico do setor. Reescrever tudo significava 18 a 24 meses sem entregar valor nenhum ao negócio. E a chance de perder regras de negócio não documentadas era alta.

A decisão: strangler fig pattern. Substituir módulo por módulo, estrangulando o sistema antigo até que ele desaparecesse.

Strangler fig na prática

O conceito vem de Martin Fowler. Assim como uma figueira estranguladora cresce ao redor de uma árvore hospedeira até substituí-la, o sistema novo cresce ao redor do antigo.

Na prática, fizemos o seguinte:

  1. Criamos uma camada de API sobre o Firebird. Um serviço Node.js que expunha os dados do banco legado via REST. Isso permitiu que os módulos novos consumissem dados do sistema antigo sem acoplamento direto.

  2. Priorizamos os módulos por dor. O financeiro e o fiscal eram os que mais causavam problemas. Começamos por eles.

  3. Cada módulo novo substituía o equivalente Delphi. Quando o módulo web ficava pronto e validado, o acesso ao módulo Delphi era bloqueado. Sem período de escolha. O usuário migrava.

  4. O roteamento ficava no proxy reverso. Um Nginx decidia, por rota, se a requisição ia para o sistema novo (React + API .NET) ou para a API de compatibilidade do legado.

A arquitetura durante a transição ficou assim:

Usuário → Nginx (proxy)
             ├── /financeiro → App Web (React + .NET API + PostgreSQL)
             ├── /estoque    → App Web (React + .NET API + PostgreSQL)
             ├── /vendas     → API Compatibilidade (Node.js + Firebird)
             └── /rh         → API Compatibilidade (Node.js + Firebird)

A cada módulo migrado, uma rota saía do lado direito e ia para o esquerdo.

Parallel running: confiança com dados reais

O módulo fiscal foi o primeiro a rodar em paralelo. Durante 30 dias, toda NF-e emitida pelo sistema novo era comparada com o que o sistema Delphi teria gerado. Criamos um job que rodava ambas as lógicas de cálculo e gravava as diferenças numa tabela de divergências.

Nas duas primeiras semanas, encontramos 47 divergências. A maioria estava em cálculos de ICMS-ST para operações interestaduais. O sistema Delphi usava uma tabela de alíquotas que não era atualizada desde 2022. O sistema novo puxava de uma API da SEFAZ. Ironicamente, o "bug" estava no sistema antigo.

O parallel running gerou confiança real. Quando mostramos ao diretor financeiro que o sistema novo acertava mais do que o antigo, a resistência caiu pela metade.

Migração de dados: a parte que todo mundo subestima

Migrar de Firebird para PostgreSQL parece simples. Não é.

Problemas que encontramos

  • Encoding. O Firebird armazenava texto em WIN1252. Tinham caracteres corrompidos em 8% dos registros de clientes.
  • Tipos de dados. Campos NUMERIC(18,4) do Firebird que na verdade armazenavam inteiros. Campos VARCHAR(500) usados como JSON informal com pipes como separador.
  • Chaves estrangeiras inexistentes. O Firebird tinha constraints declaradas, mas desabilitadas. A integridade era mantida "pelo código Delphi". Encontramos 12.400 registros órfãos no estoque.
  • Stored procedures com lógica de negócio. 63 procedures que calculavam preços, comissões e impostos. Tudo isso precisou ser reescrito e validado.

Estratégia de migração

Usamos migração incremental em três camadas:

CamadaO queComoValidação
EstruturalSchema DDLScripts de conversão Firebird → PostgreSQL com mapeamento de tiposComparação de contagem e tipos
Dados mestresClientes, produtos, fornecedoresETL com Python (pandas) + limpeza de encodingAmostragem manual de 5%
Dados transacionaisNF-e, pedidos, movimentaçõesMigração em lotes de 100k registros por noiteChecksums + reconciliação de totais

No total, migramos 2.3 milhões de registros ao longo de 6 semanas. Os dados mestres foram primeiro. Os transacionais vieram depois, sempre no horário da madrugada para não impactar a operação.

Quando reescrever, quando refatorar

Depois desse projeto e de outros similares, minha opinião sobre rewrite vs. refactor ficou mais clara. Não é uma questão filosófica. É uma conta.

Reescreva quando:

  • O sistema antigo não tem testes e ninguém entende o código
  • A tecnologia está morta (sem comunidade, sem atualizações de segurança, sem desenvolvedores disponíveis no mercado)
  • A arquitetura não suporta o que o negócio precisa (ex: desktop que precisa virar multi-tenant web)
  • O banco de dados está num estado que impede qualquer evolução

Refatore quando:

  • O código é ruim, mas a linguagem/framework ainda é viável
  • O sistema tem boa cobertura de testes
  • O problema é de organização do código, não de capacidade da plataforma
  • A equipe conhece a base e consegue evoluí-la

No caso da distribuidora, a reescrita fez sentido porque Delphi 7 não tem ecossistema. Tentar refatorar um sistema Delphi 7 para torná-lo web-friendly seria mais caro do que reescrever com strangler fig.

Os números finais

MétricaValor
Duração total do projeto11 meses
Módulos migrados12
Registros migrados2.3M
Divergências no parallel running47 (todas resolvidas)
Tempo médio de onboarding (novo funcionário)De 3 semanas para 4 dias
Conexões simultâneas suportadasDe 25 para 500+
Downtime durante migraçãoZero

O que aprendemos

A parte mais difícil não foi técnica. Foi convencer o gerente de vendas a largar o atalho F7 que ele usava há 9 anos para abrir a tela de pedidos. Resistência à mudança é real e precisa ser tratada com treinamento, não com imposição.

No lado técnico, o strangler fig pattern funcionou porque nos deu entregas parciais. A cada módulo migrado, o cliente via valor. Isso manteve o projeto vivo politicamente dentro da empresa. Projetos de migração que tentam entregar tudo de uma vez morrem de inanição antes de terminar.

Se você tem um sistema legado que ainda funciona, mas está limitando o crescimento, a migração incremental é o caminho mais seguro. Comece pela API de compatibilidade. Mapeie os dados. Escolha o módulo que mais dói. E execute.


A Bradata é uma software house brasileira especializada em modernização de sistemas. Se tem um legado que precisa evoluir, fale conosco.

Precisa de um talento tech agora?

Fale com a Bradata e receba uma proposta em 24 horas úteis.