O que você vê e o que está escondido

A superfície de um app é apenas a ponta do iceberg

Quando alguém cria um aplicativo com uma ferramenta de IA ou um framework moderno, o que aparece na tela parece simples: um formulário, uma lista, um botão. Mas esse visual limpo esconde uma infraestrutura inteira que o código gerado raramente menciona. Autenticação segura, validação de dados, conexão com banco de dados, tratamento de erros, logs, monitoramento, cache, filas, segurança contra ataques — cada um desses elementos existe abaixo da superfície. São invisíveis até o momento em que alguém tenta usá-los de verdade.

Autenticação e autorização: quem pode fazer o quê

Login funcional não é o mesmo que autenticação segura

Um formulário de login que "funciona" pode esconder falhas graves. Senhas armazenadas em texto simples, tokens que nunca expiram, ausência de controle de tentativas de acesso, sessões não invalidadas no logout — são detalhes que não aparecem no prompt inicial mas que qualquer sistema em produção precisa resolver. Além do login, há autorização: cada rota da API precisa verificar não só se o usuário está autenticado, mas se ele tem permissão para executar aquela ação específica. Um usuário não deve conseguir acessar dados de outro. Um cliente não deve conseguir executar ações de administrador.

Banco de dados: muito além do CRUD básico

Conectar e salvar é a parte fácil

O código gerado por IA geralmente cria operações básicas de leitura e escrita no banco. O que ele não cria: índices adequados para queries rápidas, paginação para evitar carregar milhares de registros de uma vez, transações para garantir consistência em operações que precisam ser atômicas, tratamento de conflitos em operações concorrentes e estratégias de backup e recuperação de dados. Em produção real, um banco sem indexação adequada trava quando os dados crescem. Uma operação sem transação pode corromper dados se interrompida no meio. Esses problemas não aparecem no ambiente de desenvolvimento com dez registros de teste.

Caching: aceleração que o usuário nunca vê

A mesma requisição não precisa refazer todo o trabalho

Quando um usuário abre uma página, várias informações já foram calculadas antes — categorias de produtos, configurações do sistema, dados que não mudam com frequência. Sem cache, cada requisição refaz todo o trabalho: consulta ao banco, transformação dos dados, serialização da resposta. Com cache, a resposta pronta é entregue diretamente. O que parece um detalhe de otimização é, na prática, o componente que decide se o sistema aguentará cem usuários simultâneos ou travará na primeira enxurrada real de acessos. O código básico gerado por IA nunca implementa cache — porque não é isso que os tutoriais pedem.

Filas e processamento assíncrono: o que não pode acontecer em tempo real

Nem toda operação pode esperar o usuário

Enviar um email de confirmação, processar um pagamento, gerar um relatório pesado, enviar uma notificação push, redimensionar uma imagem enviada — nenhuma dessas operações deve acontecer dentro da requisição HTTP que o usuário fez. Se o sistema de email estiver lento, o usuário não pode ficar esperando. Se o processamento de imagem demorar dez segundos, o upload não pode travar por dez segundos. Filas de mensagens resolvem isso: a tarefa é colocada em uma fila, o usuário recebe a confirmação imediata, e a tarefa é processada por um worker separado em segundo plano. Esse padrão não existe no código básico gerado por IA.

Segurança: o que o usuário não vê mas os atacantes procuram

Toda entrada de dados é uma porta potencial de ataque

Cada campo de formulário, cada parâmetro de URL, cada cabeçalho HTTP que o usuário pode controlar é um vetor potencial de ataque. Injeção de SQL, cross-site scripting (XSS), injeção de comandos, manipulação de IDs, execução de arquivos enviados por upload — são vulnerabilidades que surgem quando dados externos não são validados, sanitizados e tratados com desconfiança. O código de tutorial assume que o usuário vai inserir dados válidos. O código de produção precisa ser paranóico: validar formato, tamanho, tipo, origem e intenção de cada dado que chega de fora do sistema.

Observabilidade: enxergar o que acontece por dentro

Sem logs e métricas, você está operando no escuro

Em produção, problemas acontecem sem aviso prévio: uma rota começa a retornar erros, o banco de dados fica lento, um serviço externo fica indisponível. Sem logs estruturados, métricas de performance e alertas configurados, você descobre o problema quando um usuário reclama — não quando ele começa. Observabilidade é a capacidade de enxergar o estado interno do sistema através de dados externos: tempo de resposta das rotas, taxa de erros, uso de memória, fila de processamento, latência das queries. Nada disso existe no código básico gerado por IA. É uma camada inteira que precisa ser construída separadamente.

Resiliência: o que acontece quando algo inevitavelmente falha

Sistemas robustos não evitam falhas — eles se recuperam delas

Um serviço externo vai ficar fora do ar em algum momento. O banco de dados vai ter um pico de latência. Uma dependência vai retornar um erro inesperado. Sistemas resilientes têm estratégias para cada um desses cenários: retry com backoff exponencial para falhas temporárias, circuit breaker para parar de tentar quando um serviço está claramente indisponível, fallback para oferecer uma resposta degradada em vez de erro total, timeout para não travar aguardando uma resposta que nunca vai chegar. Resiliência não é tratamento de erro básico — é arquitetura deliberada para operar em ambientes imperfeitos.

Deploy e infraestrutura: como o código chega aos usuários

O caminho do código local ao servidor de produção não é trivial

Depois de escrever o código, ele precisa chegar ao servidor com segurança, sem interromper o serviço para os usuários que estão online. Build automatizado, testes rodando antes do deploy, variáveis de ambiente separadas por ambiente, estratégia de rollback se algo der errado, zero downtime durante a atualização — cada um desses elementos existe para garantir que o processo de atualização do sistema seja seguro e controlado. O deploy manual de "arrastar arquivos para o servidor" funciona para protótipos. Para produção, cada passo precisa ser automatizado, versionado e reversível.

O que você precisa construir que o prompt não pediu

A diferença entre um app que funciona e um app que aguenta

Autenticação segura, autorização granular, banco de dados indexado e com transações, cache inteligente, filas para tarefas assíncronas, validação rigorosa de entrada, logs estruturados com alertas, resiliência a falhas externas e deploy automatizado com rollback — nada disso aparece no prompt básico. Cada um desses elementos é invisível quando está funcionando bem e devastador quando está ausente. Esta série foi criada exatamente para ensinar cada um desses componentes do iceberg que o Vibe Coder desconhece. Leia também: Fundamentos obrigatórios antes de produção.

Complexidade de Software na Prática

Conceitos-chave

Autenticação

Verificar quem é o usuário com segurança: hashing de senha, tokens com expiração, bloqueio após falhas.

Autorização

Controlar o que cada usuário pode fazer: permissões por rota, por recurso, por papel no sistema.

Caching

Armazenar resultados calculados para evitar retrabalho em cada requisição e escalar com custo baixo.

Filas assíncronas

Processar tarefas pesadas em segundo plano sem bloquear a resposta ao usuário.

Observabilidade

Logs estruturados, métricas de performance e alertas para enxergar o que acontece por dentro.

Resiliência

Retry, circuit breaker e fallback para manter o sistema funcionando mesmo quando dependências falham.

Arquitetura de Software no Instagram

@bytebytego

Reels — Sistemas e Arquitetura

@bytebytego

Arquitetura de Software no Facebook

Complexidade de Software no X (Twitter)

@mjovanovictech

Architecture testing e regras de design em software moderno

Ver post completo no X →
@mjovanovictech

Arquitetura de software com C# e .NET 8 na prática

Ver post completo no X →
@mjovanovictech

Conceitos de Vertical Slice Architecture explicados

Ver post completo no X →
@mjovanovictech

5 anos com Clean Architecture — lições aprendidas

Ver post completo no X →
@mjovanovictech

Combinando Clean, Vertical Slices e Layered Architecture

Ver post completo no X →
@mjovanovictech

Monolito vs Microsserviços — como decidir no contexto real

Ver post completo no X →

O que dizem

André L. ★★★★★

Criei um app de gestão de tarefas em um dia com IA. Funcionou perfeitamente para mim e mais cinco pessoas. Quando cheguei a cinquenta usuários, o banco travou, os emails pararam de sair e não tinha nenhum log para entender o que estava acontecendo. Esse artigo resume exatamente o que eu não sabia que precisava saber.

Patricia V. ★★★★☆

Ótima analogia do iceberg. Faltou mencionar que alguns desses componentes podem ser terceirizados — Auth0 para autenticação, Sentry para observabilidade, SQS para filas. Para quem está começando, não precisa construir tudo do zero, mas precisa entender o que está contratando.

Diego M. ★★★★★

Trabalho num time de revisão de código e o problema do iceberg é exatamente o que vejo toda semana. PRs com lógica de negócio funcionando, mas zero tratamento de erro, zero log, autenticação frágil. Este conteúdo deveria ser leitura obrigatória antes do primeiro PR.