Do MVP ao produto — APIs, bancos de dados, frontend e testes para construir software de verdade
Técnicas para validar demanda antes de investir em desenvolvimento: landing pages, fake doors, Wizard of Oz, concierge MVP.
42% das startups falham por falta de demanda (CB Insights). Ex: O Dropbox validou com um vídeo de 3 minutos — 75k signups em 24h antes de escrever uma linha de código. Zappos começou comprando sapatos na loja e revendendo online para provar demanda.
MVP não é "versão bugada do produto final". É a menor versão que valida a hipótese principal. Uma feature core, bem feita.
MVPs com escopo grande demais nunca lançam. Ex: O Twitter MVP era só "postar mensagens de 140 caracteres". Sem likes, sem retweets, sem threads, sem trending. Uma feature. Validou que pessoas queriam microblogging.
Para MVPs, use tecnologia que seu time domina. Nada de experimentar no MVP. Rails, Django, Next.js, Supabase — o que for mais rápido.
Startups morrem de lentidão, não de escolha de stack. Ex: Airbnb começou com Rails. Instagram com Django + PostgreSQL. Figma com C++ no core + React no front. Nenhum usou a "melhor" tecnologia — usaram a que conheciam.
Instrumentação básica desde o primeiro deploy: page views, signups, conversão, retenção, NPS. Não precisa de data warehouse — Google Analytics + Mixpanel bastam.
"Tá funcionando" não é métrica. Ex: Um MVP com 10k signups parece sucesso. Mas se a retenção D7 é 2%, o produto não resolve o problema. Métrica que importa no MVP: retenção, não aquisição.
Ciclos curtos de build-measure-learn. Deploy diário. Feature flags para testar. Feedback loop com usuários reais.
A primeira versão nunca está certa. A velocidade de iteração é a vantagem competitiva. Ex: O Instagram mudou de Burbn (check-in app com fotos) para Instagram (só fotos) em 8 semanas — perceberam que 80% do uso era nas fotos, pivotaram rápido.
Montar stack 100% free tier: Vercel/Netlify (hosting), Supabase free (DB + auth), Cloudflare (CDN + DNS), GitHub (código), n8n self-hosted (automação).
Gastar com infra antes de validar é queimar dinheiro. Ex: A INEMA hospeda cursos como HTML estático via CDN — custo: R$0/mês. Supabase free tier: 500MB de DB, 1GB de storage, 50k MAUs de auth. Mais que suficiente para validar.
Sinais de que o MVP validou e é hora de investir: retenção consistente, willingness to pay, feature requests repetidos, product-market fit score >40%.
Investir antes do fit é desperdício. Depois do fit, cada dia sem investir é oportunidade perdida. Ex: Sean Ellis test — "Como você se sentiria se não pudesse mais usar este produto?" Se >40% dizem "muito desapontado", você tem product-market fit. Hora de escalar.
Boas práticas: nomes no plural (/users, /orders), HTTP verbs corretos, status codes semânticos, paginação, filtros, sorting.
API mal desenhada gera dúvidas infinitas e integrações frágeis. Ex: Stripe é referência em API design — /v1/charges, /v1/customers, POST para criar, GET para listar. Tão intuitiva que devs integram sem ler docs.
Autenticação (identidade) via JWT, OAuth2, API keys. Autorização (permissões) via RBAC, ABAC, scopes.
Auth errada é a brecha #1 em APIs. Ex: Em 2019, a API do Facebook tinha bug de autorização — permitia buscar tokens de amigos de amigos. 50M de contas expostas. Multa de US$5B da FTC.
OpenAPI (Swagger) é o padrão para documentar APIs REST. Schema define endpoints, parâmetros, responses. Gera docs interativas e SDKs automaticamente.
API sem docs é API sem usuários. Ex: A Twilio gasta mais em docs que em marketing. Resultado: devs integram em minutos, conversão 10x maior que APIs com docs ruins.
Estratégias para evoluir APIs sem breaking changes: URL versioning (/v1/, /v2/), header versioning, additive changes, deprecation policy.
Breaking change em API pública = clientes furiosos e integrações quebradas. Ex: O Twitter v1 → v2 foi um desastre — mudaram tudo de uma vez, quebraram milhares de apps. Stripe faz diferente: versionamento por data (2023-10-16), backward compatible, deprecation com 12 meses de aviso.
Padrões para lidar com falhas em APIs externas: retry com exponential backoff, circuit breaker, timeout, fallback, bulkhead.
Se seu sistema depende de API que cai, seu sistema cai junto. Ex: O Netflix tem o Hystrix (circuit breaker) — quando a API de recomendação cai, mostra "Top 10 do Brasil" (fallback estático) em vez de erro. Usuário nem percebe.
Como implementar webhooks (producer): endpoint público, retry policy, signature (HMAC), logging. Como consumir (consumer): validação, idempotência, processamento async.
Webhooks são como APIs externas chamam VOCÊ. Ex: Stripe envia webhook quando pagamento confirma. Seu n8n recebe, valida assinatura HMAC, processa idempotentemente (não libera acesso 2x se o webhook chega 2x).
Proxy reverso que centraliza: autenticação, rate limiting, caching, logging, transformação de requests. Kong, AWS API Gateway, Traefik.
Sem gateway, cada serviço reimplementa cross-cutting concerns. Ex: Com API Gateway: auth uma vez, rate limit centralizado, logging unificado. Sem: cada microsserviço tem sua implementação (bugada e inconsistente) de auth e logging.
Banco relacional open-source com extensões para JSON (jsonb), full-text search, geoespacial (PostGIS), vetores (pgvector). É o "canivete suíço" dos bancos.
PostgreSQL cobre 90% dos casos de uso sem precisar de outro banco. Ex: O Instagram usou PostgreSQL puro (sem NoSQL) para escalar a 1B de fotos. O Supabase é PostgreSQL com API REST automática. pgvector transforma em vector database para IA.
Normalização evita redundância (3NF). Desnormalização otimiza leitura. Na prática, use normalização por padrão e desnormalize seletivamente para performance.
Modelo errado gera queries lentas e bugs de consistência. Ex: Tabela "pedidos" com endereço do cliente inline (desnormalizado) — quando o cliente muda de endereço, pedidos antigos mostram o novo endereço. Bug clássico de desnormalização sem snapshots.
Versionamento de schema com ferramentas de migration (Alembic, Flyway, Prisma Migrate). Cada mudança é um script versionado que roda em sequência.
ALTER TABLE em produção sem migration = desastre. Ex: Adicionar coluna NOT NULL sem default em tabela com 100M de rows trava o banco por horas. Migration correta: (1) add column nullable, (2) backfill, (3) add NOT NULL constraint.
Bancos não-relacionais para casos específicos: MongoDB (documentos), Redis (cache/sessões), DynamoDB (key-value escalável), Neo4j (grafos).
Usar NoSQL onde relacional basta é over-engineering. Usar relacional onde NoSQL brilha é tortura. Ex: Grafo social (quem segue quem) em PostgreSQL exige JOINs recursivos caros. Em Neo4j, é uma query de 1 linha: MATCH (a)-[:FOLLOWS*1..3]->(b) RETURN b.
Armazenar resultados frequentes em memória (Redis, Memcached) ou CDN. Reduz carga no banco e latência para o usuário.
Cache bem implementado pode reduzir carga no banco em 90%+. Ex: O Twitter armazena timelines em Redis — sem cache, cada refresh geraria queries em centenas de tabelas. Com cache, serve de memória em <5ms.
Índices aceleram leitura ao custo de escrita mais lenta e mais espaço. B-tree (default), Hash (igualdade), GIN (full-text/jsonb), GiST (geoespacial).
Query sem índice adequado = full table scan = timeout. Ex: Tabela com 10M de rows. SELECT * WHERE email = 'x' sem índice: 15 segundos. Com índice B-tree em email: 0.5ms. 30.000x mais rápido.
Plataforma BaaS open-source baseada em PostgreSQL. API REST automática (PostgREST), auth built-in, storage, realtime subscriptions, edge functions.
Substitui semanas de setup por minutos. Ex: CRUD completo com auth: criar projeto no Supabase → definir tabelas → Row Level Security → frontend conecta via SDK. Zero backend code para operações padrão.
Páginas HTML puras servidas via CDN. Zero JavaScript obrigatório. Carrega em <1s em qualquer conexão. Custo zero de hosting.
SPA é overkill para 80% dos sites. Ex: A documentação do Tailwind CSS é HTML estático gerado — serve milhões de page views/mês via CDN por centavos. A INEMA serve cursos como HTML estático: zero bundle, zero build, zero framework.
Single Page Applications para UIs com muita interatividade: dashboards, editores, apps real-time. React/Next.js, Vue/Nuxt, Svelte/SvelteKit.
SPA adiciona complexidade (build, bundle, hydration, state management). Só vale quando a interatividade exige. Ex: Figma PRECISA ser SPA — é um editor visual com colaboração real-time. Um blog não precisa.
Biblioteca de componentes padronizados: botões, forms, modais, cards. Compartilhados entre projetos. Documentados com Storybook.
Sem design system, cada tela reinventa o botão. Ex: O Material UI do Google tem 80+ componentes. Resultado: qualquer app Google tem look consistente. Qualquer dev novo produz UI consistente no dia 1.
Layouts que se adaptam a qualquer tela: mobile, tablet, desktop. Mobile-first: design para mobile, depois expande para desktop.
60%+ do tráfego web é mobile. Site que não funciona no celular perde maioria dos usuários. Ex: O Google penaliza sites não-responsivos no ranking de busca. Core Web Vitals incluem mobile performance como fator de ranking.
Web Content Accessibility Guidelines (WCAG): contraste, navegação por teclado, screen readers, alt text, ARIA labels.
15% da população tem alguma deficiência. Acessibilidade é requisito legal em muitos países. Ex: Domino's Pizza perdeu processo de US$10M por site não-acessível a deficientes visuais. Em 2024, 97% dos top 1M sites tem erros de acessibilidade (WebAIM).
Métricas do Google: LCP (Largest Contentful Paint), FID (First Input Delay), CLS (Cumulative Layout Shift). Afetam SEO e experiência.
53% dos usuários mobile abandonam se o site leva >3s para carregar (Google). Ex: O Pinterest reduziu loading time em 40% e viu aumento de 15% no signup e 44% na receita de ads. Performance = dinheiro.
Suporte a dark/light mode com toggle e detecção automática de preferência do sistema. CSS variables ou Tailwind dark: prefix.
Dark mode reduz fadiga visual e economiza bateria em OLED. 82% dos usuários mobile usam dark mode (Android Authority, 2023). Ex: Nosso próprio curso usa dark mode como padrão com toggle — Tailwind dark: prefix + class strategy + localStorage.
Distribuição ideal: 70% unitários (rápidos, baratos), 20% integração (médios), 10% E2E (lentos, caros). Base larga, topo estreito.
Pirâmide invertida (muitos E2E, poucos unitários) = CI lento e flaky. Ex: O Google tem 80% de testes unitários, 15% de integração, 5% E2E. Suite roda em <5 minutos. Spotify tinha pirâmide invertida — CI levava 45 minutos e falhava 20% das vezes por flaky tests.
Ciclo Red-Green-Refactor: escreve teste que falha → escreve código mínimo para passar → refatora. O teste guia o design.
TDD produz código mais testável e com menos bugs. Ex: Kent Beck (criador do TDD) relata que equipes com TDD tem 40-80% menos bugs em produção (IBM Research). O custo é 15-35% mais tempo de desenvolvimento — que se paga em manutenção.
Testa interação entre componentes: API + banco, serviço A + serviço B. Usa banco real (não mock), APIs reais ou containers.
Mocks podem mascarar problemas reais. Ex: Testes unitários com mock do banco passaram, mas em produção a migration não rodou e a coluna não existia. Teste de integração com banco real teria pego.
Automação de browser que simula interação real: login, navegação, formulários, checkout. Playwright, Cypress, Selenium.
É a última linha de defesa antes do usuário. Ex: O Playwright testa o checkout completo: adiciona produto → preenche dados → confirma pagamento → verifica confirmação. Se qualquer step quebra, o teste falha antes do deploy.
Verifica que a API respeita seu contrato (schema, tipos, formato). Consumer-driven: o consumidor define o que espera, o producer garante.
Em microsserviços, mudança no producer quebra o consumer. Contract tests pegam isso antes do deploy. Ex: O Pact framework: frontend define "espero GET /users retorne [{id: number, name: string}]". Se o backend muda o tipo de id para string, o teste falha na CI do backend.
Pipeline automatizado: commit → lint → unit tests → integration tests → E2E → deploy. GitHub Actions, GitLab CI, CircleCI.
Testes que não rodam automaticamente são ignorados. Ex: GitHub Actions workflow: push → roda 500 unit tests em 30s → 50 integration tests em 2min → 10 E2E em 3min → deploy. Se qualquer step falha, PR não merges.
Coverage mostra quanto código é testado. Mutation testing mostra se os testes realmente validam. Métricas de qualidade guiam investimento em testes.
100% coverage com assertions fracas é ilusão de segurança. Ex: Mutation testing (Stryker, mutmut) modifica o código e verifica se testes pegam a mutação. Se trocar > por >= e nenhum teste falha, o teste é fraco. Meta: mutation score >80%.