Todos os cases
SaaS em produção · 4 repositórios · setembro de 2026

Levando um produto de um país só para o mundo

O produto não tinha noção de país, então cliente de fora não conseguia nem digitar o próprio telefone.

O que a gente não tinha

O produto não tinha noção de país.

Foi feito para um mercado, e essa premissa estava embutida no código em vez de escrita em algum lugar. O país ficava gravado em toda conta, mas nada nunca lia. Telefone era formatado por um padrão fixo de um país só.

O problema

A empresa estava abrindo o produto para clientes de outros países. A premissa de país único quebrava de três jeitos.

  • O número aparecia errado. Um celular local de outro país saía num formato que não existe em país nenhum.
  • O número não podia ser digitado. O campo reescrevia o que a pessoa digitava para o único formato suportado, enquanto ela digitava. Cliente de fora literalmente não conseguia informar o próprio telefone.
  • E oferecia SMS onde ele não chegava. A pessoa clicava em enviar e esperava por uma mensagem que nunca ia chegar.

Não era estético. O número errado aparecia em tela, em relatório, em exportação para planilha — e em documento impresso que o cliente assina e guarda.

Como eu resolvi

  • Troquei o padrão fixo pelo país real da conta, usando a libphonenumber do Google e as 245 regiões dela, em vez de padrões escritos na mão. A biblioteca é mantida conforme os países mudam a numeração; a minha expressão regular não seria.
  • Fiz a regra ser honesta sobre a incerteza. Formatar só quando o número é genuinamente válido para aquele país. Fora disso, mostrar os dígitos exatamente como estão gravados e nunca chutar um formato. Saída que parece certa mas está errada custa muito mais que saída sem formatação.
  • Formatei no servidor, não no navegador. Isso mantém uma biblioteca grande fora do bundle do front e garante que a tela e o documento impresso nunca discordem, porque o mesmo código gerou os dois.
  • Espelhei um único helper nos quatro repositórios, com regras idênticas. Eles compartilham banco, então não podem discordar sobre o que é um telefone.
  • Mantive duas listas de países separadas — uma para formato de exibição, outra para mensageria — mesmo tendo valores idênticos hoje. Elas respondem perguntas diferentes e vão divergir. Juntar é a simplificação óbvia, e seria a decisão errada.
  • Guardei cada número em partes: o que a pessoa digitou, o formato local, o país, o ramal e o formato internacional. Um provedor internacional de mensagem no futuro não precisa de mudança de interface.
  • Fiz todo fallback cair no comportamento original, para o cliente existente não ver mudança nenhuma. Esse era o maior risco do trabalho e guiou a maior parte do desenho.

Os resultados

Adicionar um país novo saiu de projeto de código para uma linha numa lista.

Escopo
4 repositórios, 171 arquivos, ~2.800 linhas, 61 commits
Entrega
4 pull requests, todos revisados e integrados no mesmo dia
Cobertura
245 países suportados, 241 verificados de ponta a ponta
Custo de performance
~1,3 ms por página — depois reduzido ~18% tirando uma busca de dentro de um laço
Verificação
17 testes unitários, mais ~40 telas conferidas na mão no navegador
Impacto no cliente existente
Nenhuma mudança, por desenho

Capacidade que veio junto no mesmo trabalho: geração automática de dados de exemplo válidos e corretos por país, para a demonstração de vendas parecer nativa do mercado do prospect.