Existe uma diferença grande entre construir uma aplicação que funciona e construir uma aplicação que você consegue sustentar depois que ela entra em produção.
Durante boa parte do desenvolvimento, nosso foco está naturalmente na criação.
A interface precisa funcionar.
Os fluxos precisam fazer sentido.
As regras precisam estar corretas.
A experiência precisa ser boa.
Quando tudo isso acontece, existe uma sensação bastante legítima de conclusão.
A feature está pronta.
O problema é que, para o produto, aquele momento não representa exatamente o fim.
Na maioria das vezes, representa o começo.
Quando o ambiente deixa de ser controlado
Enquanto estamos desenvolvendo, existe uma quantidade razoável de controle sobre o que está acontecendo.
Conhecemos os caminhos principais da aplicação. Testamos determinados cenários. Sabemos quais dados estamos usando e, quando alguma coisa quebra, normalmente conseguimos abrir o console, reproduzir o problema e investigar.
Produção muda essa dinâmica.
Agora existem usuários diferentes, dispositivos diferentes, conexões diferentes e comportamentos que ninguém antecipou.
Uma chamada pode falhar.
Uma integração externa pode ficar indisponível.
Um erro pode acontecer somente em uma combinação específica de navegador, estado da aplicação e dados.
Uma nova versão pode corrigir um problema e introduzir outro.
E talvez o mais importante: tudo isso pode estar acontecendo sem que você saiba.
É nesse momento que construir software deixa de ser apenas sobre implementação.
Passa a ser também sobre operação.
Fazer deploy não é o mesmo que conseguir entregar
Colocar uma aplicação no ar é relativamente simples hoje.
Existem plataformas que transformaram deploy em uma etapa quase invisível. Você conecta um repositório, configura algumas variáveis e poucos minutos depois existe uma aplicação acessível na internet.
Mas existe uma diferença importante entre conseguir fazer um deploy e ter um processo de entrega saudável.
A pergunta deixa de ser:
Consigo colocar essa versão em produção?
E passa a ser:
O que acontece quando eu precisar fazer isso dezenas ou centenas de vezes?
É aí que integração contínua, deploy contínuo, ambientes de preview, verificações automatizadas e estratégias de rollback começam a fazer sentido.
Não porque todo projeto precisa de uma infraestrutura sofisticada.
Mas porque mudanças continuarão acontecendo.
Você vai corrigir bugs. Vai ajustar comportamento. Vai remover coisas. Vai experimentar novas ideias.
Se cada mudança depender de um processo frágil ou excessivamente manual, o custo de evoluir o produto começa a aumentar.
A infraestrutura de entrega não serve apenas para publicar código.
Ela reduz a fricção entre descobrir um problema e conseguir resolvê-lo.
O problema que você não vê continua sendo um problema
Existe outra mudança importante quando uma aplicação começa a ser utilizada por pessoas reais.
Durante o desenvolvimento, erros aparecem na nossa frente.
Em produção, não.
Um usuário pode encontrar uma falha, atualizar a página e seguir em frente.
Outro pode simplesmente abandonar o fluxo.
Talvez alguém envie uma mensagem dizendo que “não está funcionando”.
Talvez ninguém diga nada.
Por isso, depender exclusivamente de relatos de usuários é uma estratégia bastante limitada para entender a saúde de um produto.
Ferramentas de monitoramento de erros, como o Sentry, existem justamente para diminuir essa distância.
Elas ajudam a responder perguntas que, sem algum nível de instrumentação, ficam praticamente invisíveis:
Qual erro aconteceu?
Quantas pessoas foram afetadas?
Em qual versão ele começou?
Em que contexto aconteceu?
Qual fluxo levou até ali?
Isso muda bastante a relação do time com bugs.
Você deixa de descobrir problemas apenas quando alguém reclama e passa a ter mecanismos para perceber que alguma coisa está errada.
Mas detectar o erro ainda é apenas uma parte da história.
Observabilidade é conseguir investigar
Saber que algo quebrou é útil.
Entender por que quebrou é muito mais importante.
Imagine receber um alerta dizendo que determinada requisição começou a falhar.
Sem contexto, você sabe que existe um problema.
Mas ainda precisa descobrir muita coisa:
A falha veio da aplicação?
De uma API?
Do banco de dados?
De um serviço externo?
Ela acontece com todos os usuários?
Somente com alguns?
Começou depois do último deploy?
É exatamente aqui que logs, métricas, traces e outras formas de observabilidade começam a ganhar valor.
Não é sobre instalar várias ferramentas porque uma arquitetura moderna “deveria” ter observabilidade.
É sobre reduzir o tempo entre perceber um comportamento inesperado e entender sua causa.
Existe um princípio simples por trás disso:
Se um sistema pode falhar de uma forma que você não consegue enxergar, em algum momento você provavelmente terá dificuldade para operá-lo.
Funcionar tecnicamente não significa funcionar como produto
Existe ainda uma camada que costuma ser confundida com monitoramento, mas responde a perguntas completamente diferentes.
Uma ferramenta de error tracking pode dizer se um botão está quebrando.
Ela dificilmente vai dizer se alguém considera aquele botão útil.
Esse é outro ponto em que analytics entra na construção do produto.
Depois que uma feature chega aos usuários, surgem perguntas que o código sozinho não consegue responder.
As pessoas estão encontrando essa funcionalidade?
Elas começam o fluxo?
Conseguem terminá-lo?
Em qual etapa abandonam?
Voltaram a utilizar a funcionalidade depois?
Essas respostas ajudam a separar dois tipos de sucesso que muitas vezes parecem a mesma coisa durante o desenvolvimento.
O primeiro é técnico:
a feature funciona.
O segundo é de produto:
a feature produz algum resultado.
Uma funcionalidade pode estar perfeitamente implementada, sem erros aparentes, e ainda assim ter pouca utilização.
Pode ser difícil de descobrir.
Pode ter uma copy pouco clara.
Pode resolver um problema que não é tão relevante quanto imaginávamos.
Pode adicionar etapas demais a um fluxo.
Nenhum desses problemas aparece necessariamente no console.
O trabalho ao redor da feature
Quanto mais tempo você constrói produtos reais, mais percebe que uma parte importante do trabalho acontece fora do componente que está sendo implementado.
Uma nova funcionalidade pode exigir uma mudança no processo de deploy.
Pode exigir novos eventos de analytics.
Pode exigir uma estratégia para monitorar erros.
Pode precisar de métricas específicas.
Talvez precise de um feature flag para ser liberada gradualmente.
Talvez exija uma forma segura de desabilitá-la caso algo dê errado.
Essas decisões raramente aparecem quando olhamos apenas para a interface final.
Mas são elas que tornam possível colocar aquela interface diante de usuários reais com algum nível de segurança.
É por isso que existe uma diferença importante entre desenvolver uma feature e operar um produto.
A feature tem uma entrega.
O produto continua depois dela.
Isso não significa adicionar ferramentas para tudo
Existe um risco do outro lado dessa discussão.
Quando começamos a perceber todas essas camadas, é fácil transformar maturidade técnica em uma coleção de ferramentas.
Mais monitoramento.
Mais dashboards.
Mais pipelines.
Mais serviços.
Mais alertas.
Só que infraestrutura também tem custo.
Cada ferramenta precisa ser configurada, entendida, mantida e, em algum nível, incorporada ao processo do time.
Um projeto pequeno provavelmente não precisa da mesma estrutura operacional de uma plataforma com milhares de usuários.
Uma aplicação interna não precisa necessariamente do mesmo nível de observabilidade de um produto responsável por transações financeiras.
O objetivo não é adicionar complexidade antecipadamente.
É conseguir responder às perguntas importantes para o estágio atual do produto.
Se algo quebrar, vamos perceber?
Se precisarmos corrigir, conseguimos publicar uma nova versão com segurança?
Se uma feature não estiver funcionando para os usuários, teremos alguma evidência disso?
Se o produto crescer, conseguiremos entender onde estão os problemas?
As ferramentas vêm depois dessas perguntas.
Não antes.
Uma mudança de perspectiva
No começo, é natural pensar principalmente em criação.
Você recebe um problema, desenha uma solução, implementa e entrega.
Existe começo e fim.
Produtos reais são um pouco diferentes.
Eles permanecem.
Continuam recebendo usuários, mudanças, dados, integrações e novas decisões muito depois da primeira versão.
E isso muda o que significa dizer que algo está pronto.
Uma aplicação não está pronta apenas porque sua interface funciona.
Ela precisa conseguir ser entregue novamente.
Precisa conseguir mostrar quando algo está errado.
Precisa produzir informação suficiente para que problemas possam ser investigados.
E precisa ajudar o time a entender se aquilo que foi construído realmente está criando valor.
Não significa que todo projeto precisa de uma infraestrutura enorme.
Significa apenas que construir é uma parte do trabalho.
A criação termina em algum momento.
A responsabilidade sobre o que foi criado não.
Compartilhar em:
Sem spam. Só conteúdo que vale abrir.