📝 ☕ 🐘
Sábado 01 · 13h30–17h30 · Bloco 1

SDD na prática:
um backend Spring hexagonal, do papel ao Postgres

Você cria apenas o esqueleto no Spring Initializr, abre no IntelliJ e conduz todo o restante pelo agente no terminal da própria IDE. Nada é implementado antes de ser especificado; nada é aceito antes de ser testado e revisado.

Claude Code · Codex · Antigravity 💡 IntelliJ IDEA Spring Boot 3 Java 21 Postgres Docker ⬡ hexagonal

Na sala, acompanhe a voz do professor. Animações, jogos e legendas continuam funcionando.

📓Meu caderno livreAnote decisões e rascunhe arquiteturas ↗
📖
Zona 1 · em casa · antes do sábado

Antes da aula

Leia o Capítulo 0 primeiro. Depois, prepare o ambiente, gere o projeto-base e entenda o caso. A teoria de cada tema aparece no ponto em que a prática precisa dela.
~90 min
+ Cap 0 (~1h30)
1
Prepare a bancada antes da aula [01]
O aluno instala as ferramentas uma vez; durante o lab, quem executa Maven, testes e Docker é o agente
🧰

Chegue com cinco itens prontos

Java 21, IntelliJ, Git, Docker Desktop e um agente CLI autenticado. O roteiro detalhado por sistema operacional continua no Sábado 0.

☕

Java 21

Configure como Project SDK do IntelliJ. O terminal da IDE deve enxergar esse mesmo Java.

💡

IntelliJ IDEA

IDE da aula. O plugin Terminal já vem habilitado. Abra com View → Tool Windows → Terminal.

🌿

Git + GitHub

O agente usa o diff como evidência. Nome, e-mail e autenticação do GitHub precisam estar prontos.

🐳

Docker Desktop

Precisa estar aberto. O Postgres será um container reproduzível, sem instalação local.

🤖

Um agente CLI

Escolha Claude Code, Codex CLI ou Google Antigravity CLI. Não precisa instalar os três.

🚫

Não instale Maven nem Postgres na máquina. O ZIP do Initializr traz mvnw/mvnw.cmd; o agente usa esse wrapper. O Postgres vem da imagem oficial pelo Docker.

Escolha o agente que vai morar no terminal do IntelliJ

Claude Code

Boa escolha quando a turma segue CLAUDE.md. Instalação nativa para macOS/Linux:

curl -fsSL https://claude.ai/install.sh | bash
iniciar: claude
documentação oficial ↗

Codex CLI

Usa AGENTS.md. Pela instalação npm, tenha Node.js disponível:

npm install -g @openai/codex
iniciar: codex
documentação oficial ↗

Google Antigravity CLI

O nome correto é Antigravity. Também reconhece AGENTS.md no workspace:

curl -fsSL https://antigravity.google/cli/install.sh | bash
iniciar: agy
documentação oficial ↗
🪪
Uma regra para os três agentes. Usaremos AGENTS.md como contrato principal. No Claude Code, um CLAUDE.md curto importa @AGENTS.md. Assim a mesma regra do projeto serve às três ferramentas.

Crie o único pedaço manual: o projeto-base

  1. 1
    Abra start.spring.io ↗. Selecione Maven, Java, Spring Boot 3.5.16 (versão da referência desta aula), Jar e Java 21.
  2. 2
    Preencha grupo br.com.pedidos, artefato e nome pedidos. Pacote: br.com.pedidos.
  3. 3
    Adicione somente Spring Web e Validation. JPA e PostgreSQL Driver entram no checkpoint 4B, depois de comprovar o banco. Não marque Lombok. Se a versão indicada não estiver no Initializr, use o projeto-base da aula.
  4. 4
    Clique Generate, descompacte o ZIP e abra a pasta pedidos/ no IntelliJ. Confirme SDK 21 e espere a importação terminar.
  5. 5
    Abra View → Tool Windows → Terminal. O prompt deve estar na raiz, ao lado de pom.xml e mvnw. Inicie claude, codex ou agy.

Por que o banco entra depois? Com JPA no classpath, o Spring tenta configurar um datasource. Sem URL ou banco embarcado, o teste de contexto pode falhar. Veja a configuração oficial do datasource.

O fluxo inteiro numa única telaClique nas etapas
pedidos/ ├── pom.xml ├── mvnw ├── mvnw.cmd └── src/

Primeiro prompt: diagnóstico sem alterar arquivos

Prompt 0 · professor e turmaProve que a bancada funciona
Estamos na raiz do projeto Spring Boot "pedidos" aberto no IntelliJ.

Nesta etapa, faça somente um diagnóstico. Não altere arquivos-fonte, configuração ou dependências. Arquivos temporários de build em target/ são esperados.
1. Leia o pom.xml e confirme Java 21, Spring Boot 3.5.16, Web e Validation. Data JPA e PostgreSQL Driver ainda não devem estar presentes.
2. Confirme que o Maven Wrapper existe. Execute os testes pelo wrapper adequado ao sistema operacional.
3. Confirme a versão de Java usada pelo build.
4. Confirme que o Docker responde, sem criar nem iniciar containers.
5. Mostre git status e informe se já estamos num repositório.

Entregue uma tabela: verificação, evidência observada e ação necessária. Se algo falhar, pare e explique o bloqueio. Não instale nada por conta própria.
O agente faz: inspeção e comandos de diagnóstico.O humano confere: fontes intactos e testes verdes sem banco.
✓ Checkpoint 0 · bancada pronta

Prova: Teste de contexto do projeto-base verde, Java 21 e Docker respondendo. Nenhuma conexão de banco é necessária.

Se travar: Confira primeiro a versão do Java no terminal. Se já incluiu JPA, compare o pom com a referência; não apague testes nem adicione H2 apenas para esconder o erro.

Baixar referência deste ponto ↗

Referências: terminal embutido do IntelliJ · Spring Initializr e Docker · documentação oficial dos três agentes nos cartões acima.

2
A história do pedido 4711 [02]
Por que passamos uma tarde inteira construindo o que "qualquer tutorial faz em vinte minutos"
Era uma terça-feira comum quando o pedido 4711 entrou. Um cliente, três itens, cartão aprovado. O serviço fez o que sempre fazia: salvou no banco, chamou o estoque, mandou o e-mail, gerou a nota. Só que naquela terça o servidor de e-mail ficou fora do ar por quatro minutos. O pedido 4711 falhou inteiro. O estoque já tinha baixado. O cliente viu "erro" na tela e comprou de novo. Dois pedidos, duas cobranças, uma reclamação, e um sábado do time de plantão.

Ninguém nesse sistema errou a sintaxe. Todo teste unitário passava. O erro era de julgamento: alguém decidiu, provavelmente sem perceber, que mandar um e-mail fazia parte de criar um pedido. E alguém decidiu que o total de um pedido era um double guardado numa coluna, e que o status era uma String. Decisões pequenas, tomadas por default, que viraram incidente.

Hoje a IA escreve a sintaxe. Ela também toma esses defaults, e toma exatamente os mesmos, porque aprendeu com milhares de serviços iguais ao do pedido 4711. O que sobra para você é decidir antes de o código existir. É isso que SDD significa na prática: a spec é o lugar onde a decisão é tomada; o código é consequência. E é isso que hexagonal significa na prática: um jeito de organizar o serviço em que "mandar e-mail" e "salvar no Postgres" ficam do lado de fora, atrás de uma porta, e o pedido no centro não sabe que eles existem.

Nesta tarde construímos, do zero, a base para evoluir o serviço do pedido 4711. Isolar as regras ainda não resolve entrega de e-mail ou cobrança duplicada: é o primeiro tijolo, feito do jeito certo. Ele cresce nos sete sábados seguintes até rodar na AWS. Cada decisão que hoje parece cerimônia demais para um CRUD vai se pagar num sábado específico, e o capítulo diz qual.

3
O agente em dois universos [03]
A mesma IA, a mesma velocidade — resultados muito diferentes
🧭
Um agente é como um motorista muito rápido. O prompt diz o destino desta viagem. As instruções do projeto explicam as regras do veículo e da estrada. A spec descreve a entrega desta vez. Sem esses três, velocidade não garante direção.

Antes da “mágica”, entenda as três peças

Esses arquivos não tornam o modelo onisciente. Eles colocam decisões úteis no contexto do agente para que o trabalho comece mais alinhado e possa ser revisado por critérios claros.

💬

Prompt

O que fazer agora. Aponta para a tarefa, informa o limite desta etapa e pede o próximo resultado: por exemplo, apenas um plano.

Leia a spec 02. Planeje. Não implemente.
🏠

CLAUDE.md / AGENTS.md

Como este projeto trabalha. Stack, comandos, arquitetura e convenções que se repetem em várias tarefas.

Java 21 · ./mvnw test · núcleo sem JPA
📋

.specs/

O comportamento desta mudança. Contexto, regras, limites e critérios que depois serão comparados com testes e diff.

pedido vazio → recusar e não salvar
pedido atual+regras do projeto+spec verificável→plano revisável
⚠️
A pasta .specs/ é uma convenção deste curso. Ela não é carregada automaticamente só por existir. O ritual registrado nas instruções manda o agente abrir a spec relevante antes de planejar.

Precisão do exemplo: o Claude Code usa CLAUDE.md como memória de projeto; o Codex descobre AGENTS.md por escopo e hierarquia; o Antigravity CLI reconhece AGENTS.md no workspace. A animação usa o mesmo personagem para representar o fluxo comum.

O teatro mostra um exemplo de revisão com dois itens. Na bancada e na prática Java abaixo, acompanhamos um único item de café com quantidade 2. As vozes ilustram o ritual de trabalho; os critérios executáveis estão nas specs de cada ato.

TEATRO INTERATIVO · PEDIDO 4711
Veja onde a produtividade nasce [04]
Lia

Uma ordem curta

CONTEXTO DISPONÍVEL AGORA
💬 prompt atual
🏠 CLAUDE.md / AGENTS.md
📋 .specs/02-criar-pedido.md
🧭 plano aprovado
📂 código existente
🧪 resultado dos testes
🔎 diff para revisão
TERMINAL DO AGENTE · SIMULAÇÃO

              
📄 CriarPedido.java📄 CriarPedidoService.java📄 Pedidos.java🧪 criaComDoisItens()🧪 recusaPedidoVazio()🔎 diff revisável
estado: prompt1 / 5
✨
O efeito “uau” não é o agente escrever muito. É você mudar uma decisão na spec, pedir um plano limitado e ver código, testes e diff surgirem coerentes sem reexplicar toda a arquitetura em cada conversa.
4
A pasta .specs/ ganha vida [05]
Da pasta vazia até uma entrega que pode ser conferida

Agora acompanhe a construção como se estivesse numa IDE. Repare que cada arquivo nasce para responder uma pergunta: o que é este projeto?, qual mudança queremos?, como saberemos que terminou?

Projeto aberto
1 / 8 etapas
💡
Documento antes do código não significa documentação pesada. Uma boa spec pode ser curta. Ela precisa deixar as decisões importantes e os exemplos de teste mais claros que um pedido solto no chat.
5
Agora você dirige o agente
Dois jogos para separar memória, tarefa e execução
0 acertos · 1/5

🏠 Onde esta regra mora? [06]

Escolha o lugar que fará a informação aparecer no momento certo sem repetir tudo em cada conversa.

0 / 8 etapas

🧭 Monte o fluxo produtivo [07]

Clique na ordem correta. O objetivo não é decorar comandos: é saber o que precisa existir antes de autorizar uma edição.

🧠
Regra que precisa sobreviver: o agente ganha produtividade quando recebe contexto útil, trabalha dentro de um plano aprovado e devolve evidência para revisão. Nenhum arquivo elimina a responsabilidade de conferir o resultado.
6
O que vamos construir [08]
O serviço de Pedidos no fim do Sábado 1, animado

Um serviço com um primeiro caso de uso completo, criar pedido, e um segundo que você faz sozinho, adicionar item. Por baixo, a estrutura que vai aguentar o curso inteiro: um domínio que não conhece framework, casos de uso atrás de portas, adapters de entrada (REST) e de saída (JPA para um Postgres num container). A bolinha é uma requisição andando.

O caso que vamos conferir em todas as etapas

Cliente c-1, produto CAFE-500, 2 unidades de R$ 18,90: total R$ 37,80. O programa gera um UUID; “4711” é o nome da história, não o ID enviado à API. Quantidade zero deve ser recusada sem salvar.

Hoje comprovamos regras e isolamento. O incidente de cobrança duplicada e e-mail exige outras decisões, estudadas no bloco de eventos.

☝️ repare na seta tracejada: o teste do caso de uso não precisa de Spring nem de banco. Isso é o hexagonal se pagando pela primeira vez, ainda hoje.

7
O mapa da tarde [09]
Como ler os marcadores, e o que trazer

O lab ocupa as quatro horas: abertura, cinco atos de construção e fechamento. Cada passo diz quem está dirigindo:

  • 👥 junto com o prof o professor cola um prompt no agente aberto dentro do IntelliJ. O agente executa; a turma lê permissões, plano, testes e diff.
  • 🧍 agora é você mesmo critério, tarefa nova. O professor circula na sala e atende o Zoom. Tem um entregável.
  • 📖 pausa teórica a teoria do tema, com o porquê e um caso real, no ponto em que o próximo passo precisa dela.
  • 📐 desenhe o pedido de desenho na prancheta. Fica salvo no seu navegador e aparece na Prancheta do curso.
Roteiro de 4 horas · ambiente preparado antes da aula
HorárioFocoTempo
13h30Abertura e desenho inicial15 min
13h45Contrato do projeto25 min
14h10Domínio: decisões, spec e testes40 min
14h50Intervalo15 min
15h05Hexagonal e caso de uso45 min
15h50Banco, persistência e HTTP45 min
16h35AdicionarItem individual25 min
17h00Retomada e revisão em dupla15 min
17h15Fechamento e próxima prática15 min

As pranchetas 2 e 3 já têm um ponto de partida: acrescente apenas a regra ou seta estudada. Complete detalhes em casa. A margem das 17h pode ser usada antes, caso a turma precise.

Traga no sábado

🏫
Zona 2 · sábado · presencial ou Zoom

O lab: do papel ao Postgres

Uma única janela: IntelliJ + terminal + agente. Os prompts ficam em cada ato; a turma aprova planos e permissões, observa a execução e revisa evidências.
13h30 → 17h30
O ritmo de cada prática

Entenda o problema → preveja a mudança → leia o plano → autorize → acompanhe a execução → confira a evidência. Os prompts estão junto de cada ato, depois da explicação.

Antes do OK: “Quais arquivos e comportamentos esperamos que mudem?” Depois: “Qual teste ou resultado comprova a regra?”

0ABERTURA

Por que julgamento, e por onde um pedido anda [10]

A história do 4711 contada ao vivo, as dúvidas que vocês trouxeram, e o primeiro desenho.
📖 teoria📐 desenhe
13:3015 min

O professor abre com as dúvidas reais que vocês trouxeram do Cap 0 ("como conferi o que a IA entregou") e conta o 4711. A pergunta que fica no ar até o fim da tarde: em que ponto do sistema cada uma daquelas decisões deveria ter sido tomada?

📐Prancheta 1: desenhe, do seu jeito, por onde um pedido anda hoje num sistema típico: do clique do cliente até o e-mail. Caixas e setas. Não consulte o desenho-alvo; o ponto é comparar no fechamento.
1ATO

O contrato do projeto: AGENTS.md, CLAUDE.md e .specs/ [11]

Antes de qualquer linha de Java, o agente precisa saber as regras da casa. Vocês escrevem juntos.
📖 teoria👥 junto
13:4525 min
📖 pausa teórica · 10 min

AGENTS.md como contrato comum, e por que ele vem antes do código

No Cap 0 você viu que regra dita na conversa cai da mesa. Aqui a consequência prática: o primeiro commit do projeto não é código, é o contrato. Para a aula funcionar com ferramentas diferentes, o conteúdo principal fica em AGENTS.md. Codex e Antigravity o reconhecem no workspace; CLAUDE.md importa @AGENTS.md para o Claude Code. Quatro seções respondem às perguntas que qualquer agente precisa resolver:

  1. Stack e comandos ("com o que eu trabalho e como rodo?"): Java 21, Spring Boot 3, Maven wrapper, Postgres via compose. Os comandos exatos: ./mvnw test, docker compose -f infra/docker-compose.yml up -d.
  2. Arquitetura ("onde cada coisa mora?"): os pacotes do hexagonal e a regra da dependência. É a seção que mais evita retrabalho, porque o default do agente é o tutorial de três camadas com @Entity no domínio.
  3. Convenções ("como se escreve aqui?"): imutabilidade, BigDecimal, exceções nomeadas, sem Lombok, sem dependência nova sem pedir.
  4. Como trabalhar ("qual é o ritual?"): ler a spec em .specs/, propor plano, esperar OK, rodar testes antes de dizer pronto, não criar arquivo fora do pedido.

A pasta .specs/ começa com um README.md de cinco linhas dizendo o que o serviço é e uma spec por tarefa. No fim do curso ela tem a história inteira das decisões, datada. É a memória que sobrevive ao contexto, ao colega novo e a você mesmo daqui a três meses.

Permissões. O agente pode pedir autorização antes de rodar comandos. O aluno lê o comando, o motivo e o alcance. Testes pelo wrapper, Docker Compose do projeto e git status/diff são esperados neste lab; instalar dependência, apagar arquivo, acessar fora do projeto ou publicar algo merece interrupção e explicação. O objetivo não é clicar “sim” depressa: é entender o que será executado.

  1. 1
    👥 junto No terminal do IntelliJ, inicie claude, codex ou agy. O projeto já foi diagnosticado pelo Prompt 0. Peça ao agente para inicializar Git se necessário e mostrar o estado, sem commit automático.
  2. 2
    👥 junto Cole o Prompt 1. Antes do OK, a turma confere se o plano contém somente AGENTS.md, CLAUDE.md e .specs/README.md.
  3. 3
    👥 junto Aprove. O agente cria o contrato e mostra o diff. Compare as regras com os rascunhos da turma: cada frase permite dizer “cumpre” ou “não cumpre” olhando código e testes?
  4. 4
    👥 junto Teste a leitura do contrato: peça “Sem alterar arquivos, avalie a proposta de adicionar Lombok. Qual regra conflita e qual decisão humana seria necessária?”. Confira se ele aponta a regra real. Uma instrução explícita para mudar a regra não é um teste de memória.
  5. 5
    👥 junto Dogfooding: o professor abre a .specs/, o AGENTS.md e o CLAUDE.md deste site. Repare que são o mesmo formato, num projeto de tamanho real.
Prompt 1 — criar o contrato portátil do projeto
Ato 1 · contexto persistenteAGENTS.md + CLAUDE.md + .specs/README.md, sem Java
Vamos preparar as regras do projeto antes do primeiro código.

Inspecione o projeto e proponha um plano curto. Depois aguarde meu OK antes de editar.

Após aprovação, crie:
1. AGENTS.md como fonte principal, com: objetivo do serviço; Java 21 e Spring Boot; comandos pelo Maven Wrapper; arquitetura hexagonal; domínio e aplicação sem Spring/JPA; dinheiro com BigDecimal; sem Lombok; nenhuma dependência nova sem pedir; ler a spec indicada, planejar, aguardar OK, testar e mostrar diff.
2. CLAUDE.md contendo uma breve apresentação e a importação @AGENTS.md, para o Claude Code receber as mesmas regras.
3. .specs/README.md explicando que cada mudança terá contexto, tarefa, regras e definição de pronto, e que a pasta só entra no contexto quando o agente é instruído a lê-la.

Não altere pom.xml nem arquivos Java. Não crie infraestrutura ainda. Não faça commit. Ao terminar, mostre git status --short, diff dos arquivos rastreados e conteúdo dos arquivos novos; relacione cada arquivo ao pedido.
Pausa antes do OK: o plano tem somente três arquivos?Evidência: diff sem Java ou dependência.
✓ Checkpoint 1 · contrato revisado

Prova: AGENTS.md, CLAUDE.md e .specs/README.md coerentes. Confira arquivos novos no editor: git diff sozinho não mostra arquivos ainda não rastreados.

Se travar: Peça ao agente para mostrar git status --short e abrir os três arquivos. Só depois autorize o commit do contrato.

AGENTS.md — contrato comum aos agentesmd
# Serviço de Pedidos — regras da casa

## Stack e comandos
- Java 21, Spring Boot 3.5.16, Maven Wrapper: `./mvnw` (macOS/Linux) ou `mvnw.cmd` (Windows).
- Postgres 16 em Docker: `docker compose -f infra/docker-compose.yml up -d`. Porta 5432, db/user/senha `pedidos`.
- Testes: JUnit 5. `./mvnw -q test` antes de dizer que terminou.

## Arquitetura: hexagonal (ports & adapters)
- `br.com.pedidos.dominio`   records, regras, exceções de domínio. Não importa nada de Spring/JPA/web.
- `br.com.pedidos.aplicacao` casos de uso (ports de entrada) e ports de saída (interfaces). Também não importa framework.
- `br.com.pedidos.adapters`  `entrada.rest` (controllers, DTOs) e `saida.jpa` (entidade JPA, repositório Spring Data, mapper).
- `br.com.pedidos.config`    classes @Configuration que ligam ports a adapters com @Bean.
- Dependências apontam para dentro: adapters conhecem aplicacao e dominio; o inverso nunca.

## Convenções
- Domínio imutável: records + List.copyOf. Sem setter. Transição de estado é método que devolve novo objeto.
- Dinheiro é BigDecimal. Identidade é String (UUID).
- Violação de regra = exceção de domínio nomeada (PedidoFechadoException). Nunca null, nunca boolean de erro.
- Sem Lombok. Sem MapStruct. Não adicione dependência ao pom sem me perguntar.

## Como trabalhar
- Antes de codar: leia a spec em .specs/ e proponha um plano curto (arquivos + testes). Só execute após meu "ok".
- Não crie arquivo que a spec não pede. Sem README, Dockerfile, DTO extra ou "melhorias".
- Ao terminar, liste os arquivos tocados e explique cada decisão de design em uma frase.
CLAUDE.md — ponte para o mesmo contratomd
# Contexto do Claude Code
@AGENTS.md
2ATO

A spec do domínio: Pedido nasce no papel [12]

A primeira spec, o primeiro plano, a primeira revisão. O Java moderno entra como critério de aceite.
📖 teoria👥 junto🧍 sozinho📐 desenhe
14:1040 min
📖 pausa teórica · 8 min

Decida a regra; depois escolha como representá-la

Nos testes de referência, () -> passa uma ação para a asserção. A IDE pode desenhar →; digite - seguido de >. Aqui os operadores ASCII ficam separados.

Antes de pedir classes ao agente, acompanhe o pedido de café. Cada pergunta abaixo precisa de uma decisão verificável.

Podemos aceitar zero unidades de café?

Não. Quantidade e preço devem ser positivos. A recusa recebe um nome: ItemInvalidoException. Teste zero e negativo.

Dois cafés de R$ 18,90, mas total informado de R$ 30. Qual valor vale?

O total é calculado pelos itens: R$ 37,80. Ele não é recebido como uma segunda verdade. BigDecimal representa os valores decimais.

E se alguém alterar a lista por fora do Pedido?

A mudança escaparia das regras. Um record fixa seus componentes, mas sozinho não protege a lista recebida. List.copyOf cria a cópia defensiva; adicionar item devolve outro Pedido.

Um pedido pago pode receber mais um item?

Não. StatusPedido nomeia ABERTO, PAGO e CANCELADO. A regra recusa alterações em pedido fechado com PedidoFechadoException.

Preveja a resposta antes de abrir. No teste, procure o mesmo caso. O estado vazio de Pedido.novo é um rascunho transitório; o caso de uso só pode salvar depois de adicionar ao menos um item.

Uma spec tem quatro partes (Cap 0): contexto, tarefa, regras, definição de pronto. O que faz dela uma spec de sênior é que cada linha da seção de regras é um item de checklist de revisão. Para representar essas decisões, escolhemos recursos do Java moderno que um sênior espera ver, e cada uma tem um porquê que o pedido 4711 explica:

  • Imutável, com record e cópia defensiva. Criou, não muda. Um pedido que passa por uma fila (Bloco 2) ou por duas threads não pode ser alterado por quem tem a referência. List.copyOf no compact constructor fecha a brecha da lista.
  • Total derivado, nunca armazenado. Duas fontes da verdade desatualizam. O 4711 tinha total guardado.
  • Dinheiro é BigDecimal. double em dinheiro é erro de arredondamento esperando a auditoria.
  • Status é tipo fechado (enum hoje, sealed quando houver dados por variante). String aceita "PAGOO". O switch exaustivo garante que um status novo quebra a compilação, não a produção.
  • Regra violada é exceção de domínio nomeada. PedidoFechadoException diz o que aconteceu; IllegalStateException diz que algo aconteceu. Nunca null, nunca boolean de sucesso.
  • Transição de estado é método que devolve novo objeto. pedido.pagar() retorna outro Pedido. Setter não existe.

Essas escolhas devem estar na spec: o agente pode sugerir soluções diferentes. Você avalia a proposta pelas regras e evidências, sem presumir que ela estará certa ou errada.

Prompt 2 — escrever a spec do domínio, ainda sem implementar
Ato 2 · especificaçãoTransformar decisões em critérios verificáveis
Leia AGENTS.md e .specs/README.md. Não implemente código.

Crie somente .specs/01-dominio-pedido.md com contexto, tarefa, regras e definição de pronto.

O domínio inicial terá Pedido, ItemPedido e StatusPedido. Use linguagem de comportamento antes de nomes de implementação. Inclua: quantidade e preço positivos; total derivado; dinheiro com BigDecimal; pedido novo começa ABERTO; adicionar item devolve novo pedido; pedido pago ou cancelado não aceita item; listas não podem ser modificadas por fora; nenhuma dependência de Spring/JPA. Pedido.novo cria um rascunho ABERTO e vazio com UUID; adicionarItem devolve outro objeto. ABERTO pode pagar ou cancelar; outras transições são recusadas. Use records e cópia defensiva. Na aula, c-1 compra CAFE-500: 2 x 18.90 = 37.80.

Na definição de pronto, transforme cada regra em caso de teste, incluindo erros. Não altere Java, pom.xml ou outros arquivos. Mostre a spec e destaque qualquer ambiguidade que eu precise decidir.
Professor pergunta: cada regra produz um teste?Evidência: só a spec foi criada.
Prompt 3 — planejar, executar e revisar o domínio
Ato 2 · primeira entregaO agente faz o trabalho mecânico; a turma segura o escopo
Leia AGENTS.md e .specs/01-dominio-pedido.md. Inspecione a estrutura atual.

Primeiro, proponha um plano com a lista exata de arquivos de produção e teste. Para cada arquivo, diga qual regra da spec ele atende. Não implemente até eu responder OK.

Após meu OK: implemente somente o domínio e seus testes; execute os testes pelo Maven Wrapper; corrija falhas sem ampliar o escopo; mostre o resultado dos testes, git diff --stat e uma revisão regra por regra da spec.

Não use Spring, JPA, Lombok, setters ou double no domínio. Não faça commit.
Pausa antes do OK: corte Service, Controller e Repository.Evidência: teste rápido sem contexto Spring.
  1. 1
    👥 junto Cole o Prompt 2. Revise no editor abaixo: toda regra tem exemplo de sucesso ou erro? Só então aceite a spec.
  2. 2
    👥 junto Cole o Prompt 3. O agente propõe arquivos e liga cada um a uma regra. Corte qualquer Controller, Service Spring, DTO ou Repository JPA.
  3. 3
    🧍 agora é você Dê o OK. O agente implementa e executa Maven. Você revisa o checklist e manda corrigir. Somente depois peça o commit feat: dominio Pedido.

O editor abaixo é um rascunho salvo neste navegador. Use “Começar do esqueleto” para ver a referência; depois copie sua versão para o agente salvar no arquivo indicado. O editor não altera seu repositório. O lint verifica a estrutura do texto, não a correção das regras.

✓ Checkpoint 2 · domínio funcionando

Prova: CAFE-500 × 2 × 18,90 = 37,80; quantidade zero recusada; pedido pago não recebe item; a lista original não altera o pedido. Testes sem Spring.

Se travar: Peça o nome do teste que falhou e compare uma regra por vez. Não aceite remover o teste ou afrouxar a regra para obter verde.

Baixar referência deste ponto ↗

🔬 Checklist de revisão do Ato 2 [13]

📐Prancheta 2: o domínio. Uma caixa por tipo (Pedido, ItemPedido, StatusPedido, as duas exceções), setas "contém" e "lança", e uma nota colada em cada caixa com a regra que mora nela. Se uma regra não tem dono, o desenho já denunciou o anemic model.
☕PAUSA

Intervalo

Pausa de verdade. Ao voltar, use o checkpoint do domínio se precisar retomar; há uma margem de recuperação no roteiro.
14:5015 min
3ATO

Hexagonal: o caso de uso atrás de uma porta [14]

Três ciclos: localizar a regra, testar o caso de uso e preparar a conexão com as tecnologias.
📖 teoria forte👥 junto📐 desenhe
15:0545 min
📖 ciclo 1 · dentro, fronteira e fora

De três camadas a ports & adapters

Comece sem o desenho. O nosso sistema tem uma parte que decide e partes que traduzem tecnologias. A regra “pedido vazio não pode ser criado” continuaria verdadeira se o Postgres virasse DynamoDB, se REST virasse uma fila ou se o Spring desaparecesse. Portanto, essa regra deve morar numa parte que não depende de nenhuma dessas escolhas.

💎 Dentro: decisões do negócio

Pedido, itens, status e casos de uso. Falam a linguagem da empresa e podem ser testados como Java puro.

🔌 Na fronteira: ports

Contratos que dizem como iniciar um caso de uso ou o que a aplicação precisa pedir ao mundo externo.

🌍 Fora: adapters e tecnologias

Controller REST, JPA, Postgres e, depois, RabbitMQ ou DynamoDB. Traduzem o mundo técnico para os ports.

🏠
Imagine uma casa com tomadas. A casa decide qual energia precisa; a tomada define o encaixe; cada aparelho tem um plugue compatível. A tomada é o port, o plugue é parte do adapter. Trocar o aparelho não exige quebrar a casa. O limite da analogia: em software, os ports representam conversas úteis ao caso de uso, não apenas formato elétrico.

O Spring que muita gente aprendeu organiza o serviço em três camadas: Controller chama Service que chama Repository. Essa organização pode funcionar. O problema aparece quando as regras passam a depender de @Entity, JpaRepository, HTTP ou do contexto do Spring. O teste então precisa subir tecnologias que não fazem parte da decisão de negócio.

Três camadas com regras acopladas
PedidoControllerPedidoService (regra + orquestração)PedidoRepository extends JpaRepository@Entity Pedido (domínio = tabela)

Tudo aponta para baixo, e o de baixo é o framework. A regra "só ABERTO paga" mora num if no service, ao lado do save() e do enviarEmail(). É o pedido 4711.

Hexagonal: fronteiras explícitas
adapters/entrada/rest → PedidoControlleraplicacao → port CriarPedido · CriarPedidoServicedominio → Pedido, regras, exceçõesaplicacao → port Pedidos (interface)adapters/saida/jpa → PedidosJpaAdapter, PedidoJpaEntity

O centro (domínio + aplicação) não importa nada de fora. Quem entra (REST) e quem sai (JPA) são adapters que implementam ou chamam ports: interfaces definidas pelo centro.

ROTEIRO VISUAL · 6 PASSOSExplique de dentro para fora
ADAPTERS
APLICAÇÃO + PORTS
PEDIDO
regras

Aprofundar: portas, pacotes e evolução nos próximos encontros
port de entrada (driving)
interface CriarPedido { Pedido executar(Comando c); }
quem chama: o controller REST hoje, um consumidor de fila no Sáb 4, uma Lambda no Sáb 6
port de entrada
interface AdicionarItem { … }
o do Ato 5, seu
⬡ o núcleo
dominio/ + aplicacao/
sem Spring, sem JPA, sem web
Pedido · CriarPedidoService
port de saída (driven)
interface Pedidos { Pedido salvar(Pedido p); Optional<Pedido> buscar(String id); }
quem implementa: JPA + Postgres hoje, DynamoDB no Sáb 7, um HashMap no teste
port de saída (futuro)
interface PublicadorDeEventos { … }
Sáb 4: é por aqui que o e-mail do 4711 deixa de derrubar o pedido

A regra da dependência. Setas de import apontam para dentro. adapters conhece aplicacao e dominio; aplicacao conhece dominio; dominio não conhece ninguém. Quem liga a interface Pedidos à classe PedidosJpaAdapter é uma classe de configuração na borda (config/), com @Bean. O núcleo nunca vê a anotação.

O que isso paga, e quando.

  • Hoje: o teste de CriarPedidoService roda com um Pedidos em memória, em milissegundos, sem Spring. Testes rápidos são testes que rodam.
  • Sáb 3: Testcontainers testa só o adapter JPA contra um Postgres real; o núcleo continua sem banco.
  • Sáb 4: "avisar o estoque" vira um port de saída; o adapter publica numa fila. O caso de uso não muda uma linha.
  • Sáb 7: o port Pedidos ganha um adapter DynamoDB. O domínio e o serviço não sabem que mudaram de banco.

O que não fazer. Hexagonal não é criar interface para tudo. Um port existe quando há uma fronteira real (entrada externa, infraestrutura, algo que você quer trocar ou testar isolado). Pedido não precisa de IPedido. O agente adora criar interface demais; a spec diz quais existem.

src/main/java/br/com/pedidos/ ├── dominio/ Pedido, ItemPedido, StatusPedido, *Exception (Ato 2) ├── aplicacao/ │ ├── CriarPedido.java port de entrada (interface) + record Comando │ ├── CriarPedidoService.java │ └── Pedidos.java port de saída (interface) ├── adapters/ │ ├── entrada/rest/ PedidoController, PedidoRequest, PedidoResponse (Ato 4) │ └── saida/jpa/ PedidoJpaEntity, ItemJpaEntity, PedidoSpringDataRepository, PedidosJpaAdapter, PedidoMapper └── config/ └── CasosDeUsoConfig.java @Bean CriarPedido criarPedido(Pedidos pedidos)

Ciclo 2 · o caso de uso funciona sem banco [15]

Leia pelas dependências: o caso de uso conhece a interface Pedidos; o adapter JPA também conhece essa interface e a implementa. A interface pertence à necessidade da aplicação, não ao banco.

núcleo primeiro, tecnologia depoisjava
// Recorte do método executar; classe completa no checkpoint 3.
public Pedido executar(Comando comando) {
  if (comando.itens() == null || comando.itens().isEmpty()) {
    throw new PedidoSemItensException();
  }
  Pedido novo = Pedido.novo(comando.clienteId());
  for (ItemComando item : comando.itens()) {
    novo = novo.adicionarItem(new ItemPedido(
        item.sku(), item.quantidade(), item.precoUnitario()));
  }
  return pedidos.salvar(novo);
}
// pedidos é o port Pedidos, recebido pelo construtor.
🧪
Por que o teste fica fácil? No teste, outra classe pequena implementa Pedidos com um HashMap. O mesmo caso de uso roda sem Spring ou Postgres. Isso prova que o adapter é substituível.

Base conceitual: artigo original de Alistair Cockburn sobre Ports & Adapters. O hexágono não representa seis camadas; a forma deixa espaço para várias portas ao redor de um dentro protegido.

Consulta opcional · Prompt 4 — entender a arquitetura do seu código
Ato 3 · aula dialogadaExplicação antes da próxima implementação
Atue como tutor de arquitetura para uma turma iniciante em hexagonal. Não altere arquivos.

Leia AGENTS.md, a spec 01 e o domínio implementado. Explique usando exatamente este projeto:
1. o que é o núcleo e por que Pedido fica nele;
2. a diferença entre port de entrada, caso de uso, port de saída e adapter;
3. quem chama quem ao criar um pedido;
4. para que lado apontam as dependências de código;
5. como testar CriarPedido sem Spring nem Postgres;
6. um exemplo de interface desnecessária que seria exagero.

Use frases curtas, mostre uma árvore de pacotes proposta e termine com cinco perguntas para a turma. Não proponha implementação ainda.
Professor usa: compare a resposta com o laboratório visual abaixo.Evidência: nenhuma mudança no git.
Prompt 5 — criar aplicação e ports sem deixar Spring entrar
Ato 3 · núcleo completoCriarPedido atravessa duas portas
Leia AGENTS.md e .specs/01-dominio-pedido.md. Antes de editar, crie .specs/02-caso-de-uso-criar-pedido.md com o contrato abaixo e mostre seu plano. Aguarde meu OK.

O caso de uso recebe cliente e itens, recusa lista vazia, cria o domínio, salva por uma interface chamada Pedidos e devolve o pedido salvo. Crie um port de entrada CriarPedido, sua implementação CriarPedidoService e o port de saída Pedidos. A aplicação não pode importar Spring, JPA, HTTP ou adapters.

Após meu OK, implemente e teste com uma implementação em memória de Pedidos dentro do teste. Execute os testes pelo Maven Wrapper. Mostre os imports de aplicacao/, o resultado dos testes e o diff. Não crie Controller, JPA, DTOs, configuração ou commit.
Pausa antes do OK: três tipos de produção + testes.Evidência: zero imports de framework no núcleo.
  1. 1
    👥 junto No código do Ato 2, localize a regra de quantidade. Preveja: ela precisa mudar se trocarmos de banco? Use o Prompt 4 apenas se precisar de outra explicação sobre seus arquivos.
  2. 2
    👥 junto Cole o Prompt 5. No plano, corte PedidoDTO, PedidoMapper, @Service e qualquer adapter: agora construímos somente o núcleo.
  3. 3
    👥 junto Dê o OK. O agente implementa e testa. A turma responde: há algum import de Spring dentro de aplicacao/? Se há, a fronteira vazou. Depois da correção, peça o commit feat: caso de uso CriarPedido.

O editor abaixo é um rascunho salvo neste navegador. Use “Começar do esqueleto” para ver a referência; depois copie sua versão para o agente salvar no arquivo indicado. O editor não altera seu repositório. O lint verifica a estrutura do texto, não a correção das regras.

✓ Checkpoint 3 · núcleo completo

Prova: CriarPedido recebe itens, devolve 37,80 e salva pelo port. Entrada vazia lança PedidoSemItensException e não chama salvar.

Se travar: Compare os imports e o teste em memória. A implementação do teste é um substituto do banco, não um servidor de banco novo.

Baixar referência deste ponto ↗

Ciclo 3 · o que muda quando a requisição vem da web?

Use a bancada para prever a tradução em cada fronteira. Depois, escolha a responsabilidade de cada componente no quiz. Essas são as peças que construiremos no Ato 4.

LABORATÓRIO VISUAL · ARQUITETURA HEXAGONAL
A bancada de tradução do Pedido 4711 · simulação [16]
entrada → núcleo → saída

Acompanhe c-1 comprando 2 unidades de CAFE-500 a 18,90. O UUID ilustrativo é o mesmo em todas as etapas; a API gera o seu. Antes de avançar, preveja o que entra, o que sai e qual tecnologia pode aparecer. A bancada é silenciosa para acompanhar a voz do professor.

📱Cliente
🎮Controller
🚪Port entrada
⚙️Caso de uso
💎Domínio
🚪Port saída
🐘JPA + Postgres
📦
🌐 HTTP + JSON💎 Java do núcleo🐘 JPA + SQL
ANTES
🤖TRADUÇÃO / DECISÃO
DEPOIS
COMO PROVAR

1 / 7
QUIZ DE FIXAÇÃO · SEM PEGADINHA

Coloque cada componente no seu lugar [17]

A pergunta central é sempre: esta peça contém regra, define uma conversa ou traduz uma tecnologia?

📐Prancheta 3: o hexágono. Três áreas (use a forma Área/camada): dominio no centro, aplicacao em volta, adapters fora. Coloque os ports na borda entre aplicação e adapters. Todas as setas de import apontam para dentro; se alguma apontar para fora, ela está errada e você acabou de encontrar um bug de arquitetura no desenho antes de encontrar no código.
4ATO

Postgres no Docker e os adapters: a requisição chega ao banco [18]

REST na entrada, JPA na saída, e a primeira linha na tabela.
📖 teoria👥 junto🧍 sozinho📐 desenhe
15:5045 min
📖 pausa teórica · 10 min

O banco num container, e a entidade JPA como adapter

Por que Docker. Um Postgres instalado na máquina é um Postgres com versão, porta e senha diferentes em cada notebook da sala. O container é o mesmo binário, a mesma versão, a mesma configuração, descrito num arquivo versionado junto com o código. docker compose up -d sobe; down derruba; o volume guarda os dados entre reinícios. No Sáb 3 o Testcontainers vai subir um desses dentro do teste, e no Sáb 4 o RabbitMQ entra no mesmo arquivo.

A entidade JPA não é o domínio. É a tentação número um, e é o que o agente faz por padrão: colocar @Entity no Pedido. As entidades JPA deste exemplo precisam de construtor sem argumentos e estado persistível; nossos records representam decisões imutáveis. A solução hexagonal é ter dois objetos: PedidoJpaEntity (mutável, anotada, mora em adapters/saida/jpa) e o record Pedido. Um PedidoMapper converte nos dois sentidos. Parece duplicação; é isolamento. Quando a tabela mudar, o domínio não muda.

O adapter de saída implementa o port Pedidos usando um JpaRepository do Spring Data por dentro. O adapter de entrada é o controller: recebe JSON num PedidoRequest, monta o Comando, chama o port CriarPedido, devolve um PedidoResponse. Ele não sabe que existe banco.

Schema. Hoje deixamos o Hibernate criar as tabelas (ddl-auto: update) para a aula andar. No padrão deste curso, produção usa migrações versionadas com Flyway, e entra no Sáb 3 junto com o Testcontainers. Anote como dívida consciente.

src/main/resources/application.ymlyaml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/pedidos
    username: pedidos
    password: pedidos
  jpa:
    hibernate:
      ddl-auto: update        # só hoje. Sáb 3: Flyway.
    open-in-view: false       # o adapter abre e fecha a sessão; o controller não

Uma fronteira por vez: 4A comprova o banco; 4B comprova o adapter; 4C comprova HTTP. Não avance enquanto a evidência anterior estiver vermelha. Os tempos de 10 + 15 + 20 minutos incluem a explicação no ponto de uso.

Prompt 6a · 4A · banco disponível · 10 min [19]
4A · banco disponível · 10 min
Leia AGENTS.md e as specs 01 e 02. Inspecione o ambiente sem editar. Proponha um plano apenas para infra/docker-compose.yml com Postgres 16, serviço postgres, db/user/senha pedidos, porta local configurável e volume nomeado. Verifique conflito na porta 5432. Aguarde meu OK.
Após aprovação, crie o compose e suba somente esse serviço. Comprove pg_isready e SELECT 1. Não altere Java, pom.xml ou application.yml. Não remova containers/volumes alheios. Pare se o banco não estiver pronto e explique o erro. Mostre arquivos novos e modificados.
Confira: Postgres responde antes de JPA entrar no projeto.
✓ Checkpoint 4A · banco disponível

Prova: pg_isready aceita conexões e SELECT 1 retorna 1.

Se travar: Confira Docker aberto, porta ocupada e logs do serviço. Se mudar a porta local, use o mesmo valor no datasource. Nunca apague volumes para “tentar de novo”.

Baixar referência deste ponto ↗
Prompt 6b · 4B · salvar e recuperar pelo adapter · 15 min [20]
4B · salvar e recuperar pelo adapter · 15 min
Leia AGENTS.md e specs 01/02. Proponha .specs/03-adapters-rest-e-jpa.md com as três provas: banco disponível; persistência pelo adapter; HTTP. Escreva a spec antes do Java. Apresente plano só do checkpoint 4B e aguarde meu OK.
Após aprovação, adicione SOMENTE Data JPA e PostgreSQL Driver ao pom. Crie entidades PedidoJpaEntity/ItemJpaEntity, repository Spring Data, mapper manual e PedidosJpaAdapter; application.yml para o Postgres local. Mantenha domínio e aplicação intactos, sem imports de framework. Não crie endpoint ainda.
Mapeie a tabela pedido; ID String/UUID do domínio, sem gerar outro ID; total derivado dos itens, sem coluna total. Cada item guarda sku, quantidade e precoUnitario. Use transação no adapter para mapear itens antes de fechar a sessão; open-in-view=false.
Preserve os testes unitários. Crie PedidosJpaAdapterIT (integração, execução explícita) e adapte o teste de contexto gerado para essa mesma convenção *IT; não o apague nem desative. Rode os testes unitários pelo Wrapper sem banco; depois execute explicitamente os *IT contra o Postgres: salvar pedido de c-1 com CAFE-500, 2 x 18.90, e recuperar por UUID, em uma nova transação. Verifique itens, status ABERTO e total 37.80. Mostre a consulta à tabela e o diff. Não crie H2, endpoint, Lombok ou MapStruct.
Confira: A ida e a volta pelo banco preservam UUID e itens; testes do núcleo continuam independentes.
✓ Checkpoint 4B · pedido persistido e recuperado

Prova: Teste de integração salva e relê o mesmo UUID em nova transação; itens e total 37,80 conferem.

Se travar: Se a conexão falha, retorne ao 4A. Se os itens somem, confira relacionamento, mapper e limite da transação. Não coloque anotações no domínio.

Baixar referência deste ponto ↗
Prompt 6c · 4C · ligar HTTP ao núcleo · 20 min [21]
4C · ligar HTTP ao núcleo · 20 min
Leia AGENTS.md e specs 01/02/03. Antes de editar, complete na spec o contrato HTTP e proponha o plano. Aguarde meu OK.
Implemente POST /pedidos com PedidoRequest, PedidoResponse, PedidoController e config/CasosDeUsoConfig. O controller chama CriarPedido; não conhece JPA. Resposta 201 com UUID, clienteId, itens, status ABERTO e total. Preços e total em JSON são números decimais.
Autorize nesta etapa um PedidoExceptionHandler em adapters/entrada/rest: ItemInvalidoException e PedidoSemItensException viram 422 com mensagem; JSON malformado ou campos obrigatórios ausentes viram 400. Use @Valid para formato e presença; a regra quantidade/preço positivos continua no domínio. Não crie outros endpoints.
Após implementar, rode unitários sem banco e os *IT com Postgres. Inicie a aplicação e registre status HTTP e corpo para: CAFE-500, quantidade 2, precoUnitario 18.90 -> 201 e total 37.80; quantidade zero -> 422; itens vazios -> 422; JSON malformado -> 400. Nas recusas, comprove que nenhuma linha foi adicionada.
Consulte o pedido pelo UUID no banco, reinicie a aplicação e comprove que a mesma linha e seus itens continuam lá. Mostre testes, arquivos novos, diff e encerre somente o processo da aplicação que você iniciou. Não faça commit.
Confira: 201 e persistência no caso válido; 422/400 e nenhuma gravação nos casos recusados.
Mesmo pedido · evidência observada pelo agenteterminal
# -i mostra também o status HTTP; o UUID real aparece na resposta.
curl -i -X POST localhost:8080/pedidos -H 'Content-Type: application/json' \
  -d '{"clienteId":"c-1","itens":[{"sku":"CAFE-500","quantidade":2,"precoUnitario":18.90}]}'
# Esperado: HTTP 201, status ABERTO, total numérico 37.80.
# 37.8 e 37.80 representam o mesmo valor numérico.
✓ Checkpoint 4C · requisição chega ao banco

Prova: 201 + UUID + total 37,80. Quantidade zero dá 422 e não grava. O pedido permanece após reiniciar a aplicação.

Se travar: 400: confira o JSON. 422: leia a regra recusada. 500: peça diagnóstico de logs e tradução da exceção, mantendo o núcleo intacto. Depois da revisão, autorize o commit dos adapters.

Baixar referência deste ponto ↗

O editor abaixo é um rascunho salvo neste navegador. Use “Começar do esqueleto” para ver a referência; depois copie sua versão para o agente salvar no arquivo indicado. O editor não altera seu repositório. O lint verifica a estrutura do texto, não a correção das regras.

📐Prancheta 4: a infra. Duplique a Prancheta 3 (ou comece do zero) e acrescente o container do Postgres, o PedidoJpaEntity dentro do adapter, o mapper entre ele e o record, e o curl batendo no controller. Setas sólidas: é tudo síncrono hoje.
5ATO

Sozinho: AdicionarItem, ponta a ponta [22]

O mesmo ciclo, sem o professor no volante. Spec, plano, seu OK, execução, revisão.
🧍 sozinho
16:3525 min
🧍
Um caso de uso inteiro, seu
port de entrada → service → port de saída → REST

POST /pedidos/{id}/itens adiciona um item a um pedido aberto. Escreva sua proposta de spec antes de abrir as ajudas. O agente deve aguardar sua revisão da spec e depois do plano.

SituaçãoResultado esperado
Pedido com 2 cafés de 18,90; adicionar 1 café de 18,90HTTP 200; mesmo UUID; total 56,70
UUID inexistenteHTTP 404; nada salvo
Pedido PAGO ou CANCELADOHTTP 409; pedido preservado
Quantidade zeroHTTP 422; pedido preservado

Teste estados fechados com fixtures nos testes: a aula ainda não tem endpoint de pagamento. Comprove também que CriarPedido continua funcionando.

Ajuda 1 · por onde começar?

Quem conhece a regra de adicionar item? Quem busca e salva? Desenhe essas duas responsabilidades antes de escolher arquivos. Na revisão, identifique o que vem do domínio e o que pertence ao caso de uso.

Ajuda 2 · peças que podem mudar

Port AdicionarItem, seu service, exceção PedidoNaoEncontradoException, controller e configuração existentes. Reutilize Pedidos e o mapper. Amplie o handler REST para 404/409/422. O service depende do port, não do JpaRepository.

Prompt 7 — prática individual: AdicionarItem
Ato 5 · transferênciaO aluno repete o ciclo sem copiar a solução
Agora faremos AdicionarItem de ponta a ponta. Leia AGENTS.md e as specs existentes.

Primeiro, escreva somente .specs/04-caso-de-uso-adicionar-item.md. Inclua: buscar pelo port Pedidos; pedido inexistente gera PedidoNaoEncontradoException; pedido fechado gera HTTP 409; quantidade inválida gera 422; adicionar item atualiza o total; salvar pelo port; endpoint POST /pedidos/{id}/itens devolve 200. Pedido inexistente vira 404. Amplie o handler REST existente, sem mudar CriarPedido. Caso verificável: 37.80 + 1 x 18.90 = 56.70, mesmo UUID; erros não gravam. Liste casos de teste e limites de arquivos. Pare para minha revisão.

Depois do meu OK na spec, proponha o plano e pare novamente. Só implemente após um segundo OK. Ao terminar, execute testes de unidade e o cenário HTTP pelo Maven Wrapper e ferramentas locais, mostre o diff e aponte qualquer import de JPA/Spring dentro de aplicacao/ ou dominio/. Não faça commit.
Dois OKs: um para a spec, outro para o plano.Evidência: novo caso sem quebrar CriarPedido.
Ajuda 3 · comparar com a spec de referência
🚨
Entregável: commit feat: caso de uso AdicionarItem e, no Caderno, uma decisão aceita com evidência e uma decisão questionada ou corrigida. Quem terminar antes: o GET /pedidos/{id}, com spec.
↺RETOMADA

Recupere o ponto de partida e troque uma revisão [23]

Uma margem para a turma chegar junta ao fechamento.
17:0015 min

Quem travou: anote a última evidência verde e use a referência desse ponto. Quem concluiu: compartilhe o repositório e comece a revisão em dupla. Se sobrar tempo, aprofunde um caso de erro.

Como retomar com um checkpoint sem perder meu trabalho?
  1. Guarde seu projeto e suas anotações. Descompacte o ZIP em outra pasta; não sobrescreva a sua.
  2. Abra a referência no IntelliJ. Peça ao agente para ler RETOMADA.md e executar as verificações indicadas.
  3. Compare com seu código e explique uma diferença. Anote que usou a referência.
  4. Continue a partir do próximo ato. Se precisar comparar novamente, seu projeto original continua disponível.

Os ZIPs incluem Wrapper e código até aquele ponto. O primeiro build baixa dependências. São referências para estudo local; não incluem solução de AdicionarItem.

Prompt retomada · diagnosticar o ponto em que parei
diagnosticar o ponto em que parei
Não altere arquivos. Leia AGENTS.md, a spec da etapa e RETOMADA.md se existir. Identifique o último checkpoint comprovado e a primeira divergência. Mostre o teste/log/arquivo que demonstra o problema. Proponha uma correção mínima, sem remover testes, apagar dados ou adiantar funcionalidades. Aguarde meu OK.
Confira: Uma causa por vez; retomar é entender o estado atual.
✓FECHO

Fechamento: os desenhos, a troca, a tarefa [24]

Prancheta 1 ao lado da 4. O que mudou na sua cabeça em quatro horas.
📐 compare🧍 revisão cruzada
17:1515 min
  1. 1
    Abra a Prancheta do curso: as quatro do dia estão lá. Compare a 1 (como você imaginava) com a 4 (o que existe). Onde o e-mail do 4711 entraria hoje? Marque com uma nota vermelha. É a ponte para o Bloco 2.
  2. 2
    🧍 duplas Troque de repositório com o colega (presencial ou Zoom, via GitHub). Cada um apresenta uma decisão aceita com evidência e uma decisão questionada ou corrigida no AdicionarItem. Código correto também merece uma justificativa; não é obrigatório inventar defeitos. Use a revisão iniciada no bloco de retomada.
  3. 3
    Cole o Prompt 8 e projete a auditoria final. O que fixou como critério: spec verificável, regra em arquivo, núcleo sem framework, entidade JPA como adapter e evidência antes de commit. A tarefa de casa vem abaixo.
Prompt 8 — auditoria final antes dos commits
Fechamento · revisãoTransformar “funciona” em evidência revisável
Faça uma auditoria final sem alterar arquivos.

1. Leia AGENTS.md e todas as specs.
2. Execute unitários pelo Maven Wrapper e, com o Postgres pronto, execute explicitamente os testes *IT. Diferencie as duas evidências.
3. Liste arquivos modificados e novos por ato.
4. Procure imports de Spring/JPA em dominio/ e aplicacao/.
5. Confira se as entidades JPA estão somente no adapter de saída.
6. Compare cada definição de pronto com uma evidência observável.
7. Mostre git status --short (incluindo novos), diff e riscos ou dívidas conscientes. Nos atos já commitados, compare também os commits correspondentes.

Não corrija nem faça commit. Entregue primeiro o relatório para revisão humana. Se aprovamos, eu enviarei comandos separados para os commits.
Professor projeta: relatório lado a lado com as specs.Decisão final: aprovar, corrigir ou rejeitar.
📝SDDSpec com regras verificáveis, plano aprovado, revisão contra a spec. Nada é digitado antes de ser decidido.
📄AGENTS.md + CLAUDE.mdStack, arquitetura, convenções e comandos. Um contrato portátil e uma ponte curta para o Claude.
⬡HexagonalNúcleo sem framework, ports nas fronteiras, adapters fora, config liga. Paga no Sáb 3, 4 e 7.
🐘Postgres no DockerInfra versionada com o código. Entidade JPA é adapter; o record é o domínio.
🏠
Zona 3 · em casa · até o próximo sábado

Até o próximo sábado [25]

O serviço cresce em casa, dirigido por você. O Cap 02 (Pedidos, Pagamentos e RabbitMQ) começa abrindo o seu repositório.
~3h
com seu agente CLI

📦
O que trazer no próximo sábado: o repositório com os commits, os pontos de revisão no Caderno, e uma pergunta real sobre onde uma regra de negócio deveria morar. O Sáb 2 começa com o seu PagarPedido no projetor.