Trilha 0 · Abertura · ~14 min · pleno/sênior

A pergunta que separa dois profissionais

Numa entrevista técnica, duas pessoas recebem o mesmo enunciado: "nosso checkout está lento e o time trava a cada release; o que você faria?"

A primeira responde com uma lista de ações: colocar cache, criar índice no banco, quebrar em microserviços, adotar Clean Architecture. Tudo plausível. Tudo dito sem uma única pergunta antes.

A segunda começa perguntando: quantas pessoas mexem nesse código por semana? O que exatamente está lento — o p50 ou o p99? Quando o time "trava", trava esperando review, esperando build, ou esperando outro time? Existe SLA acordado, ou "lento" é percepção? Só depois de três ou quatro respostas ela arrisca uma direção — e a direção vem com um custo declarado junto.

Não é que a segunda saiba mais tecnologias. É que ela sabe uma coisa que a primeira ainda não: solução sem restrição no ar é chute com vocabulário técnico. Esse curso existe para levar você da primeira resposta para a segunda.

Feature vs. sistema: a mudança de altitude

Quem entrega feature responde a uma pergunta de cada vez: como faço isso funcionar? É uma pergunta legítima, e boa parte da carreira se sustenta em respondê-la bem.

Quem projeta sistema responde a uma pergunta diferente: o que essa decisão vai custar daqui a dezoito meses, com o dobro de gente no time? A feature de hoje é um ponto; o sistema é a trajetória.

A diferença aparece no vocabulário. Compare:

Altitude de feature Altitude de sistema
"Vou colocar uma fila aqui." "Ganho absorção de pico e resiliência; pago consistência eventual e um broker para operar."
"Isso está acoplado." "O acoplamento é do tipo stamp, entre módulos distintos — força alta a distância grande, a combinação cara."
"Vamos para microserviços." "Dois times estão bloqueando um ao outro no deploy; a evidência justifica extrair um serviço, e este."

Repare que a coluna da direita nunca é mais longa por enfeite. Ela é mais longa porque nomeia o custo. A frase que não nomeia o custo é sempre uma frase incompleta — e este curso vai insistir nisso até virar reflexo.

O método: TEORIA ↔ PRÁTICA ↔ TRADEOFFS

Nenhum conceito entra aqui sem passar pelos três vértices:

  • Teoria — a definição precisa. Sem ela, você repete jargão sem saber a fronteira do conceito.
  • Prática — o conceito aplicado em código que roda, no FakeFlix. Sem ela, a teoria não gruda.
  • Tradeoffs — o que aquilo custa, e em que contexto não compensa. Sem esse terceiro vértice, o material vira catálogo de padrões, e catálogo de padrões produz cargo cult: aplicar a forma sem entender a força que a justificava.

O terceiro vértice é o que a maior parte do material técnico omite, e é o que separa engenharia de moda. Toda aula deste curso tem uma seção explícita de tradeoffs, e ela existe para dizer quando não usar o que a aula acabou de ensinar.

O projeto: FakeFlix

Todo conceito é aplicado num clone modular de streaming que evolui ao longo do curso. Ele nasce como monolito modular e termina preparado para eventos e deploy seletivo — sem nunca ter passado por uma reescrita.

Três bounded contexts:

  • Identity — autenticação, usuários, emissão e validação de JWT.
  • Billing — planos, assinaturas, pagamentos, status de cobrança.
  • Content — catálogo, área administrativa, processamento de vídeo.

A estrutura física de cada módulo é sempre a mesma, e ela não é decorativa: cada pasta corresponde a um papel arquitetural que as aulas vão justificar.

src/module/billing/
├── billing.module.ts
├── core/                 # regra de negócio pura — não conhece framework nem banco
│   └── service/subscription.service.ts
├── http/                 # adaptador de entrada (REST)
│   └── rest/controller/subscription.controller.ts
└── persistence/          # adaptador de saída (banco)
    ├── entity/
    └── repository/

O código está em TypeScript com NestJS, e isso merece uma ressalva: você não precisa saber NestJS. Ele aparece porque torna as fronteiras de módulo explícitas na sintaxe — o que é exatamente o que queremos discutir. Cada padrão mostrado é traduzível para Java, C#, Go, Kotlin ou Python orientado a objetos sem perda. Se você lê uma classe com construtor e injeção de dependência, você lê o código deste curso.

As quatro trilhas, e por que nesta ordem

Trilha 1 — Fundamentos e mentalidade. Estabelece a ferramenta de raciocínio: tradeoff como método, DDD estratégico para achar fronteiras, Arquitetura Hexagonal para defendê-las, e uma leitura honesta da Clean Architecture — o que aproveitar e o que ignorar.

Trilha 2 — Modularização e complexidade. O coração do curso. Complexidade essencial versus acidental, carga cognitiva como métrica, as três dimensões do acoplamento, coesão como o outro lado da moeda, e os dez princípios que resumem tudo isso em regras operacionais.

Trilha 3 — Do conceito à produção. Onde a teoria vira sistema que aguenta: comunicação entre módulos por contrato, isolamento de estado na persistência, transações e consistência, governança automatizada por fitness functions, e o aparato de produção (testes com factories, logging, JWT atravessando módulos).

Trilha 4 — Escala e evolução. Comunicação assíncrona, o critério honesto para migrar (ou não) para microserviços, event-driven na prática com Transactional Outbox e sagas, e monorepos modulares para separar limite lógico de limite de deploy.

Trilha bônus — IA aplicada à arquitetura. Duas aulas sobre usar IA onde ela é forte — varrer legado, medir acoplamento, propor recortes — e sobre onde a decisão precisa continuar humana.

A ordem importa porque cada trilha é o pré-requisito da seguinte. Discutir microserviços antes de saber medir acoplamento é discutir a cura antes do diagnóstico: você vai extrair o serviço errado, no momento errado, e chamar isso de arquitetura.

Para quem é — e para quem não é

É para você se: tem três anos ou mais de código, já sente que "sabe fazer feature" mas trava quando precisa justificar uma decisão de estrutura, e quer parar de escolher padrão por preferência.

Não é para você se: está começando a programar. Não porque o conteúdo seja difícil, mas porque tradeoff só faz sentido para quem já pagou o preço de algumas decisões. Sem essa bagagem, as aulas viram uma lista de regras — exatamente o que este curso tenta desfazer.

Pré-requisitos técnicos: uma linguagem orientada a objetos, HTTP e REST, banco relacional, testes automatizados.

O pré-requisito real, porém, não é técnico: é aceitar que a resposta certa quase sempre começa com "depende" — e que o trabalho de engenharia é dizer de que depende.

Como aproveitar

  • Leia as aulas na ordem. Elas se referenciam pelo título, e a Trilha 2 assume a Trilha 1.
  • Faça os exercícios antes de abrir a resposta. Eles são de decisão, não de memória — errar neles é a parte útil.
  • Quando uma aula ensinar um padrão, force a pergunta do terceiro vértice antes de seguir: no meu sistema atual, isso compensaria? Qual evidência eu teria que ver primeiro?

Cola mental

  • Feature responde "como faço funcionar"; sistema responde "o que isso custa daqui a dezoito meses".
  • Frase que não nomeia o custo é frase incompleta.
  • Teoria sem tradeoff vira cargo cult; tradeoff é o vértice que a maioria omite.
  • O FakeFlix evolui — ele nunca é reescrito. Esse é o argumento do curso em forma de projeto.
  • A ordem das trilhas é diagnóstico antes de cura.

Referências para Aprofundamento

Livros que sustentam o curso

Fundamentos que voltam o curso inteiro

Documentação técnica

  • NestJS — documentação oficial — Só o necessário: módulos, providers e injeção de dependência. Não é preciso ler além disso para acompanhar o curso.
  • TypeScript Handbook — Referência para quem vem de outra linguagem OO e quer só destravar a leitura da sintaxe.

Exercícios

Exercício 1 — Traduza para a altitude de sistema

Um colega afirma numa reunião: "a gente devia migrar esse módulo para uma arquitetura em camadas, fica mais organizado". A frase está na altitude de feature. Reescreva-a na altitude de sistema — e diga o que precisaria saber antes de conseguir reescrevê-la de verdade.

Ver resposta

✓ Resposta: A frase original só nomeia o benefício, e ainda por cima um benefício subjetivo ("mais organizado"). Na altitude de sistema ela precisaria nomear ganho, custo e a restrição que motiva: "Camadas nos dariam uma fronteira explícita entre regra e persistência, o que reduz o risco de uma mudança de schema quebrar regra de negócio. Pagamos com indireção — mais arquivos por operação e um salto a mais para ler qualquer fluxo. Vale se o módulo muda com frequência e já quebrou por vazamento de persistência; não vale se é um CRUD estável." O que você precisaria saber antes: com que frequência esse módulo muda, se já houve incidente causado por acoplamento com o banco, quantas pessoas mexem nele e se existe alguma restrição real (SLA, regulação) em jogo. Sem esses dados, qualquer reescrita da frase continua sendo chute — só que mais bem vestido.

Exercício 2 — Ache o vértice que falta

Uma aula hipotética ensina o padrão Repository assim: define o que é, mostra a interface, mostra a implementação com ORM e termina com "pronto, agora seu domínio está desacoplado do banco". Segundo o método deste curso, o que está faltando? Escreva o parágrafo ausente.

Ver resposta

✓ Resposta: Falta o terceiro vértice: os tradeoffs. A aula tem teoria (a definição) e prática (o código), mas não diz o que o padrão custa nem quando não usá-lo — que é justamente o que impede o cargo cult. Um parágrafo ausente plausível: "O Repository custa uma indireção por operação e, com ORMs modernos, frequentemente duplica uma abstração que o próprio ORM já oferece. Ele compensa quando a regra de negócio é rica e precisa ser testada sem banco, ou quando há chance real de trocar a fonte de dados. Não compensa num CRUD que só repassa campos: ali o repositório vira uma classe que reescreve o método do ORM com outro nome, e você pagou legibilidade por uma flexibilidade que nunca vai exercer." O ponto do exercício é perceber que uma aula sem esse parágrafo ensina a forma sem ensinar a força — e forma sem força é o que produz onze arquivos para adicionar um campo.

Exercício 3 — Justifique a ordem

Um leitor propõe: "a Trilha 4 é a parte interessante; vou começar por ela e volto às outras depois". Dê dois argumentos concretos, ancorados no conteúdo das trilhas, para explicar por que isso costuma dar errado.

Ver resposta

✓ Resposta: (1) Decisão de extração sem instrumento de medida. A Trilha 4 discute quando migrar para microserviços, e o critério honesto é evidência de acoplamento e de bloqueio entre times. Medir acoplamento é conteúdo da Trilha 2 (força, distância, tempo; coacoplamento no histórico do repositório). Sem esse instrumento, a decisão de extrair vira preferência, e o serviço extraído tende a ser o errado — normalmente o mais visível, não o mais bloqueante. (2) Fronteira inexistente para cortar. Extrair um serviço pressupõe que já exista uma fronteira contratual por onde cortar; construí-la é conteúdo das Trilhas 1 e 3 (bounded context, hexágono, Public API Provider, isolamento de estado). Quem pula direto para a Trilha 4 tenta cortar um módulo que ainda lê a tabela do vizinho — e o resultado não é um microserviço, é um monolito distribuído: mesmo acoplamento, agora com latência de rede e falha parcial no meio. Em resumo: a ordem das trilhas é diagnóstico antes de cura, e a Trilha 4 é toda cura.

Exercício 4 — Classifique o pré-requisito

Cinco pessoas querem fazer o curso. Para cada uma, diga se o pré-requisito real está atendido e justifique em uma frase: (a) dev com 6 meses de carreira, sabe React e Node, nunca discutiu decisão de estrutura; (b) dev Java com 8 anos, nunca escreveu TypeScript; (c) tech lead com 5 anos, acha que "depende" é resposta de quem não sabe; (d) dev Python com 4 anos, orientação a objetos e testes no dia a dia; (e) arquiteto com 12 anos que já decidiu que microserviços são sempre o caminho certo.

Ver resposta

✓ Resposta: (a) Não atendido — não por falta de tecnologia, mas por falta de bagagem: tradeoff só significa algo para quem já pagou o preço de uma decisão ruim; sem isso, as aulas viram lista de regras. (b) Atendido — o pré-requisito é ler classe com construtor e injeção de dependência, e 8 anos de Java cobrem isso com folga; o TypeScript do curso é sintaxe, não conteúdo. (c) Não atendido — é o único caso em que o obstáculo é explícito: o pré-requisito real é aceitar que a resposta começa com "depende" e que o trabalho é dizer de que depende; quem rejeita isso vai ler o curso inteiro procurando a regra final que ele não dá. (d) Atendido — OO, testes e quatro anos de estrada são exatamente o perfil descrito; a linguagem diferente não é obstáculo. (e) Não atendido enquanto a convicção durar — a bagagem técnica sobra, mas "sempre o caminho certo" é dogma, e o curso inteiro é uma argumentação contra respostas que não perguntam pela restrição. O padrão das respostas: em quatro dos cinco casos o que decide não é a stack, é a disposição de raciocinar por custo.

Exercício 5 — Desafio: escreva sua linha de base

Pegue um sistema real em que você trabalha hoje e escreva três linhas: (1) uma decisão de estrutura que ele carrega; (2) o custo que essa decisão está cobrando agora; (3) a evidência objetiva que você usaria para justificar mudá-la — ou para justificar deixá-la como está. Guarde esse texto: ele é sua linha de base para reler ao terminar o curso.

Ver resposta

✓ Resposta: Não há gabarito único, mas há um formato que indica que o exercício foi feito direito. Exemplo de resposta bem construída: "(1) Nosso módulo de pedidos lê direto a tabela de estoque, sem contrato. (2) Custo hoje: toda alteração de schema em estoque exige varrer pedidos, e já tivemos dois incidentes em produção por isso; além disso, ninguém consegue rodar os testes de pedidos sem subir o banco inteiro. (3) Evidência para decidir: o percentual de commits que tocam os dois módulos juntos no último semestre — se estiver alto, confirma o acoplamento na prática e não só na estrutura; e a contagem de imports de pedidos para dentro de estoque, que idealmente seria zero." Os três sinais de que a resposta está no nível certo: a decisão é descrita como decisão (não como "o código é ruim"); o custo é concreto e observável (incidentes contados, testes que não rodam), não uma sensação; e a evidência proposta é mensurável antes de agir — um número que você poderia extrair nesta semana. Se a sua linha (3) foi "a gente sente que está ruim", ela ainda está na altitude de feature: refaça até virar algo que possa ser contado.