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.