Retome o pedido, traga uma pergunta
Leia esta abertura e as pausas teóricas dos atos. Em sala, voltaremos a elas conforme a dúvida aparecer.
O mesmo pedido. Uma pergunta nova. [01]
No sábado 01, construímos o serviço de Pedidos: o domínio decide, o caso de uso coordena e os adapters traduzem HTTP e banco. Hoje vamos usar Orientação a Objetos (OO) para explicar por que esse desenho ajuda e como revisar uma proposta de mudança.
O que você já pode trazer
Seu repositório, specs e testes. CriarPedido e AdicionarItem funcionando; pagamento e consulta são a tarefa anterior. Traga também o que ficou pendente, com a última prova verde.
Se não terminou a tarefa
Use a base de retomada em outra pasta. Ela consolida a referência do Cap 01 com adicionar item, pagamento simulado e consulta. Leia RETOMADA.md e compare antes de continuar.
O Pedido do Cap 01 já recusa alterações quando está fechado. Os defeitos de hoje estão em um laboratório separado: não é necessário estragar seu domínio para refatorá-lo.
O mapa das quatro horas [02]
Hoje a evidência de aprendizagem é uma decisão sustentada por código e teste. Não contamos classes nem interfaces. Um PR (pull request) é uma proposta de alteração para revisão; neste laboratório você pode comparar arquivos localmente, sem abrir um PR público.
| Início | Duração | Momento | Saída observável |
|---|---|---|---|
| 13:30 | 15 min | Diagnóstico | Prever a falha por outra entrada |
| 13:45 | 35 min | Objeto e encapsulamento | Simular e localizar a regra |
| 14:20 | 30 min | Refatoração guiada | Regressão testada pelas duas entradas |
| 14:50 | 15 min | Intervalo | Pausa |
| 15:05 | 55 min | SOLID por decisões | Vocabulário com consequência |
| 16:00 | 40 min | Revisão avaliativa | Parecer A–E com evidência |
| 16:40 | 20 min | Transferência | Spec e início de CancelarPedido |
| 17:00 | 15 min | Checklist vira skill | Revisão reproduzível |
| 17:15 | 15 min | Fechamento | Defender uma decisão |
O bloco de SOLID retoma a leitura: aprofunde os princípios que aparecerem no diagnóstico. A transferência tem 20 minutos para escrever a spec e iniciar a implementação; a conclusão pode seguir em casa.
Não altere arquivos. Leia AGENTS.md, CLAUDE.md e as specs relevantes do serviço pedidos. Identifique quais operações existem e execute os testes unitários pelo Wrapper. Separe: funcionando com evidência, falhando com causa observada, ainda não implementado. Compare com RETOMADA.md se usei uma referência. Não adicione dependências. Proponha o menor ponto de retomada. Aguarde meu OK antes de editar.
Da regra protegida à decisão explicada
Preveja, observe, nomeie, teste. O agente executa; você decide o que merece mudar.
Duas entradas, duas verdades? [03]
Uma proposta do agente protege apenas a API. O objeto tem campos privados, mas entrega a lista interna. Leia o trecho e preveja o que a importação faz com um pedido pago.
// Trecho defeituoso do laboratório: não copiar para o serviço.
public void peloController(PedidoAnemico pedido, String sku) {
if (pedido.isPago()) throw new IllegalStateException("Pedido fechado");
pedido.getItens().add(sku);
}
public void pelaImportacao(PedidoAnemico pedido, String sku) {
pedido.getItens().add(sku);
}👀 Depois da previsão: o que acontece?
A importação adiciona o item. A condição só existe no controller e getItens() devolve a coleção mutável. private limita o acesso direto ao campo; não impede modificar o objeto que a referência aponta.
Objeto não é só uma sacola de campos [04]
Estado + comportamento
Estado é o que o objeto representa agora: itens e status. Comportamento é o que ele permite fazer: adicionar, pagar, cancelar. A classe define essa forma; cada objeto é uma ocorrência concreta.
Uma regra que deve permanecer verdadeira
Invariante é uma condição que as operações precisam preservar. Aqui: um pedido fechado não aceita novos itens. Essa promessa precisa valer para API, importação e chamada direta.
Encapsular é oferecer operações que preservam essa promessa e controlar como o estado é exposto. É como um caixa que permite uma retirada validada, sem entregar acesso irrestrito ao saldo. A comparação tem limite: a proteção depende de todas as operações públicas reais do código.
public Pedido adicionarItem(ItemPedido item) {
exigirAberto();
var novosItens = new ArrayList<>(itens);
novosItens.add(item);
return new Pedido(id, clienteId, novosItens, status);
}Domínio rico reúne dados e regras que pertencem ao negócio. Um modelo anêmico deixa essas decisões espalhadas nos serviços enquanto os objetos apenas recebem setters. Isso não transforma todo objeto de dados em erro: DTOs (Data Transfer Objects, objetos de transferência de dados) transportam informações e não precisam se tornar entidades de domínio.
Laboratório: onde mora a regra? [05]
Escolha onde a guarda foi implementada. Depois teste uma entrada com o pedido já pago. A importação desta simulação chama diretamente o objeto; ela pode contornar o service.
Em tela estreita, deslize o diagrama para os lados. Pelo teclado, foque a área e use as setas.
Preveja: a importação encontra a mesma guarda?
Simulação de chamadas, sem banco. Cada tentativa parte do estado escolhido; adiciona 1 café de R$ 18,90. Nada é persistido. Uma arquitetura que obriga todas as entradas a passar pelo service também centraliza a guarda; aqui investigamos o objeto que continua vulnerável a chamadas diretas.
Agora existe um comando de terminal que chama Pedido diretamente. O que protege a promessa?
Escolha e justifique antes de ler o retorno.
Record não congela tudo sozinho [06]
O record fixa as referências dos componentes. Se um componente aponta para uma lista mutável, outra pessoa ainda pode mudar essa lista. Imutabilidade superficial é diferente de congelar todo o grafo de objetos.
public record Pedido(List<ItemPedido> itens) {
public Pedido {
itens = List.copyOf(itens);
}
}List.copyOf produz uma lista não modificável com os elementos atuais. Alterar a lista de origem depois não muda essa lista. Os elementos continuam sendo referências: se fossem mutáveis, poderiam mudar por dentro. No nosso caso, ItemPedido usa String, int e BigDecimal, sem componentes mutáveis.
Adicionar um item cria outro Pedido; quem chamou precisa usar o retorno. Imutabilidade facilita raciocinar, mas não impede duas requisições concorrentes de sobrescrever dados. Isso pede outra decisão de persistência.
A origem recebe um novo item depois da construção com List.copyOf. O Pedido deve mudar?
Escolha e justifique antes de ler o retorno.
Referência: Record no Java 21 e List.copyOf.
Refatore uma falha que você consegue provar [07]
Refatorar é reorganizar o código sem mudar seu comportamento observável. Aqui também vamos corrigir um bug: a importação passará a recusar algo que aceitava indevidamente. Registre a mudança da regra separadamente da reorganização.
Baixe o laboratório independente, abra outra pasta e leia RETOMADA.md. Comece por src/main/java/br/com/revisao/EntradaAlternativa.java. As classes aninhadas deixam o exemplo concentrado em um arquivo; não são uma organização obrigatória para o serviço real.
- Diagnostique. Rode CaracterizacaoTest. Ele fica verde ao reproduzir a falha conhecida; verde aqui não significa regra aprovada.
- Escreva a expectativa nova. Pago deve recusar item pela API e pela importação. Aberto aceita e preserva o original.
- Peça um plano. Centralizar a regra em uma operação e impedir a lista externa de alterar o objeto. Preserve os dois pontos de entrada.
- Autorize e revise. Atualize a expectativa do teste de falha para a regra desejada, sem simplesmente apagar o cenário. Execute e confira o diff.
Leia as instruções deste projeto e EntradaAlternativa.java com seus testes. Não edite ainda. Explique o caminho que permite adicionar a um pedido pago. Proponha uma spec curta e um plano restrito a esse exemplo e aos testes: - pago recusa nas duas entradas; - aberto aceita e o original permanece igual; - lista de origem e lista exposta não permitem alterar o Pedido; - sem Spring, banco, nova dependência ou mudança nos casos A–E. Mostre quais testes atuais caracterizam defeitos e como mudar a expectativa. Aguarde meu OK.
👀 Refatoração-modelo, depois de tentar
public Pedido pelaImportacao(Pedido pedido, String sku) {
return pedido.adicionar(sku);
}As duas entradas chamam a mesma operação. A guarda e a criação do novo estado ficam em Pedido. A lista é copiada no construtor. No serviço real, esse desenho já existe: compare com adicionarItem em vez de renomear seu domínio para coincidir com o exemplo.
O que deve mudar junto? [08]
Um teste unitário verifica um comportamento sem exigir a aplicação inteira ou serviços externos. Um fake é uma implementação simples usada no teste, como um repositório em memória. Ele permite observar o contrato; não prova que o banco real funciona. Essa segunda evidência vem do teste de integração.
Coesão descreve quanto as partes de um módulo colaboram para uma responsabilidade clara. Acoplamento descreve quanto uma parte depende de outra. Precisamos de colaboração; o objetivo é tornar as dependências deliberadas e as mudanças compreensíveis.
Juntar pelo mesmo motivo
Adicionar, pagar e cancelar preservam o ciclo de vida de Pedido. Ter vários métodos não torna a classe ruim. Eles operam o mesmo estado e suas regras.
Separar por mudança independente
A equipe comercial altera cálculo; comunicação altera a mensagem; infraestrutura altera a conexão. Uma edição de texto não deveria exigir revisar a regra monetária.
Um método curto pode estar no lugar errado. Um arquivo grande pode conter uma responsabilidade coesa. Procure o motivo e o efeito da mudança, não um limite mágico de linhas.
Reutilizar não exige virar um subtipo [09]
Herança cria uma relação de subtipo: quem espera a classe base também pode receber a derivada. Reaproveitar algumas linhas não basta para justificar essa promessa. Composição faz um objeto colaborar com outro, recebido por construtor, sem afirmar que um é uma versão do outro.
// Ideia problemática: Pix herda a promessa de parcelar do cartão.
class PagamentoPix extends PagamentoCartao { /* ... */ }
// Colaboração: o caso de uso recebe quem sabe autorizar.
public AutorizarPedido(Autorizador autorizador) {
this.autorizador = autorizador;
}Interface declara operações disponíveis. O contrato completo também inclui entradas aceitas, resultados e falhas permitidas. Polimorfismo permite chamar a mesma operação por esse contrato e obter o comportamento da implementação recebida.
Usamos cartão e Pix como simulações. Neste sistema, ambos autorizam, mas só cartão parcela. Em outro produto, as capacidades podem ser diferentes. Composição também tem custo: mais objetos para montar e mais relações para entender.
Laboratório: a promessa sobrevive à troca? [10]
O cliente foi escrito com uma expectativa. Troque quem atende e observe se ele continua conseguindo fazer a mesma chamada válida.
parcelar(2)
Preveja antes de executar.
Resultados locais fixos. “Autorizar” aqui ilustra uma capacidade; não faz cobrança, rede ou validação financeira.
S · Uma razão de mudança por responsabilidade [11]
Um recibo reúne dois trabalhos: calcular o preço promocional e escrever o e-mail. A equipe comercial muda a promoção; comunicação muda a saudação. Os motivos são independentes, embora ambos mencionem Pedido.
Coisas que mudam pelo mesmo motivo tendem a ficar juntas. Mudanças de atores distintos pedem uma fronteira clara. “Responsabilidade única” não significa um método por classe.
class ResumoPedido {
BigDecimal total(BigDecimal subtotal) { /* regra comercial */ }
String email(String cliente) { /* texto de comunicação */ }
}👀 Refatoração e consequência
Extraia PrecoPromocional e MensagemPedido. Um coordenador pode chamar ambos; ele não precisa escrever o texto nem recalcular a regra. Mudar “Olá” agora alcança a mensagem, sem editar o cálculo.
Experimente uma mudança de texto
Comunicação pediu trocar “Olá” por “Oi”. Selecione a organização e veja onde essa edição cai.
Uma classe Pedido tem adicionar, pagar e cancelar. Devemos separar só por ter três métodos?
Escolha e justifique antes de ler o retorno.
Leitura de origem: Single Responsibility Principle. O caso de Pedidos e os critérios acima são a aplicação didática deste capítulo.
O · Uma variação com um lugar para entrar [12]
Uma campanha oferece 10%; outra desconta R$ 5. O time precisa variar o abatimento sem repetir a conta final, seu arredondamento e suas validações.
Escolha uma fronteira estável para uma variação conhecida. A regra comum usa um contrato; outra implementação acrescenta um comportamento. Algum lugar ainda precisa selecionar e montar essa implementação.
interface Desconto {
BigDecimal abatimento(BigDecimal subtotal);
}
// A calculadora recebe Desconto e faz a parte comum:
return subtotal.subtract(abatimento).setScale(2, RoundingMode.HALF_UP);👀 Refatoração e consequência
Com subtotal 100, dez por cento produz 90.00; cinco reais produz 95.00. Com subtotal 3, o desconto fixo limita o abatimento a 3 e resulta em 0.00. OCP não exige abstrair cada if: um conjunto pequeno e estável pode continuar explícito.
Troque a campanha, preserve a conta
A escolha da política muda na montagem. A calculadora permanece a mesma. O resultado final é arredondado para duas casas; o Java usa BigDecimal. HALF_UP aproxima para o valor mais próximo e, no empate, afasta do zero: 0.045 vira 0.05. Arredondamos o total final, não cada etapa intermediária.
A única promoção está estável há anos. O agente propõe um registro de plugins. O que revisar?
Escolha e justifique antes de ler o retorno.
Leitura de origem: Open–Closed Principle. O caso de Pedidos e os critérios acima são a aplicação didática deste capítulo.
L · Trocar a implementação sem quebrar a promessa [13]
O cliente recebe PagamentoCartao e chama parcelar(2), permitido de 1 a 12 vezes. PagamentoPix herda cartão, mas lança UnsupportedOperationException para essa chamada.
Uma implementação substituta deve respeitar o contrato esperado pelo cliente: não pode exigir condições mais fortes nem enfraquecer o resultado prometido. O compilador verificar tipos não prova o comportamento.
PagamentoCartao pagamento = new PagamentoPix();
pagamento.parcelar(2); // compila; a promessa falha em execução👀 Refatoração e consequência
Compartilhe apenas autorizar por MeioPagamento; mantenha parcelar no cartão. Uma recusa de negócio prevista no contrato é diferente de não implementar uma operação prometida. Tipos relacionados no mundo real não são automaticamente bons subtipos no código.
O contrato permite retornar Recusado por limite insuficiente. Isso viola LSP?
Escolha e justifique antes de ler o retorno.
Leitura de origem: Liskov Substitution Principle. O caso de Pedidos e os critérios acima são a aplicação didática deste capítulo.
I · O cliente depende só do que precisa [14]
Consulta precisa de buscar. Recebe um Repositorio que também obriga salvar e exportarTodos. Até o fake de consulta precisa conhecer capacidades que não usa.
Forme contratos pelas necessidades dos clientes. Uma classe concreta pode implementar mais de um contrato. Segregar não exige um serviço, uma classe e uma implantação separados para cada método.
interface ConsultaPedidos { String buscar(String id); }
interface GravacaoPedidos { void salvar(String id); }
interface ExportacaoPedidos { List<String> exportarTodos(); }
// Consulta recebe apenas ConsultaPedidos.👀 Refatoração e consequência
Agora o teste da consulta fornece só buscar; exportação pode evoluir sem ampliar esse contrato. O port Pedidos do Cap 01 tem buscar e salvar usados juntos pelos casos de uso: isso não exige dividi-lo automaticamente.
Monte apenas o fake da consulta
Buscar e salvar são usados pelos mesmos clientes e mudam juntos. Separar é obrigatório?
Escolha e justifique antes de ler o retorno.
Leitura de origem: Interface Segregation Principle. O caso de Pedidos e os critérios acima são a aplicação didática deste capítulo.
D · Quem escolhe o detalhe externo? [15]
O caso de uso cria new GatewayHttp(). Ao testar uma aprovação, já ficamos presos ao serviço externo. O detalhe técnico passou a decidir como a regra pode ser executada.
A política de alto nível depende de um contrato adequado à sua necessidade. O adapter externo implementa esse contrato. A montagem escolhe o concreto e entrega ao caso de uso.
interface Autorizador { boolean autorizar(String id); }
public AutorizarPedido(Autorizador autorizador) {
this.autorizador = autorizador;
}👀 Refatoração e consequência
No teste, um fake devolve aprovado ou recusado sem rede. Na aplicação real, config monta o adapter. Injeção pelo construtor é uma técnica; DIP é a direção das dependências. Receber GatewayHttp pelo construtor ainda prende o cliente ao tipo concreto.
Consigo testar uma recusa sem rede?
O desenho mostra dependências declaradas. Criar o objeto na configuração é necessário, mas não basta: o tipo recebido pelo núcleo também importa.
Um service recebe GatewayHttp no construtor. O que já sabemos?
Escolha e justifique antes de ler o retorno.
Leitura de origem: Dependency Inversion Principle. O caso de Pedidos e os critérios acima são a aplicação didática deste capítulo.
Agora você é o revisor [16]
Abra Propostas.java no ZIP do laboratório. Os cinco casos abaixo são independentes; seu trabalho é produzir um parecer e dirigir uma correção. Tente antes de abrir o diagnóstico-modelo.
Caso A · O resumo ganhou dois trabalhos
class ResumoPedido {
BigDecimal total(BigDecimal subtotal) { /* promoção */ }
String email(String cliente) { /* comunicação */ }
}Caso B · Chegou uma campanha nova
if (campanha.equals("DEZ")) { /* 10% */ }
if (campanha.equals("SEM")) return subtotal;
throw new IllegalArgumentException("Campanha desconhecida");Caso C · A implementação trocada
class PagamentoPix extends PagamentoCartao {
public String parcelar(int vezes) {
throw new UnsupportedOperationException("Pix não parcela aqui");
}
}Caso D · A consulta trouxe bagagem
interface Repositorio {
String buscar(String id);
void salvar(String id);
List<String> exportarTodos();
}Caso E · O detalhe nasceu no caso de uso
class AutorizarPedido {
private final GatewayHttp gateway = new GatewayHttp();
}| Critério em cada caso | Pontos |
|---|---|
| Localiza e nomeia o princípio com justificativa | 0,5 |
| Explica a consequência no contexto fornecido | 0,5 |
| Propõe correção pequena e reconhece seu custo | 0,5 |
| Indica teste ou comparação observável | 0,5 |
Há sobreposição entre princípios: aceite outro enquadramento bem demonstrado. A avaliação mede julgamento. Na revisão do próprio projeto, não invente cinco problemas para preencher esta tabela.
Leia Propostas.java, RETOMADA.md e os testes. Não edite arquivos. Para cada caso A–E, mostre: arquivo/linha, contrato afetado, consequência reproduzível, princípio com justificativa, menor correção e teste que a sustentaria. Diferencie falha observada, risco inferido e preferência de estilo. Não exija uma interface por classe. Não transforme simulação em integração real. Entregue o parecer. Escolherei um caso e pedirei o plano antes de autorizar código.
Uma correção pequena também precisa de prova [17]
👀 Diagnóstico e refatoração-modelo A–E
- A · SRP. PrecoPromocional e MensagemPedido isolam motivos distintos. Preserve 100 → 90.00 e o texto esperado. Um teste de saída não prova separação: confira também o diff.
- B · OCP. Desconto informa abatimento; Calculadora valida limites, subtrai e arredonda. Percentual de 10%: 37.80 → 34.02. Fixo de 5: 3 → 0.00. A composição escolhe a política.
- C · LSP. Cartão e Pix implementam apenas o contrato comum MeioPagamento.autorizar. Parcelar continua específico do cartão. Teste as implementações pelo mesmo tipo.
- D · ISP. Consulta depende de ConsultaPedidos. Uma implementação ainda pode oferecer gravação e exportação. Teste a consulta com um fake que só busca.
- E · DIP. AutorizarPedido recebe Autorizador. Fakes aprovam/recusam sem rede. Não transferir a decisão de negócio para um DTO do fornecedor.
Referência completa para comparar após a tentativa: laboratório resolvido. Execute os testes em outra pasta. O ZIP não é uma refatoração automática do seu serviço.
Refatoração reorganiza código preservando comportamento observável. Corrigir uma regra ou adicionar cancelamento muda comportamento e precisa ser nomeado como mudança funcional. No caso B, preservamos campanhas existentes e acrescentamos uma variação: registre ambas as partes.
O agente criou sete interfaces para um cálculo estável de três linhas. Qual evidência pedir?
Escolha e justifique antes de ler o retorno.
Transfira: cancelar sem espalhar a regra [18]
Seu domínio já tem Pedido.cancelar(): ABERTO passa a CANCELADO; fechado recusa. Agora exponha essa operação pelo mesmo caminho de aplicação, port e adapter do Cap 01. É uma funcionalidade nova, não apenas refatoração.
| Antes | Resposta | Persistência |
|---|---|---|
| ABERTO | 200 · CANCELADO | Mesmo UUID, itens e total; salva uma vez |
| PAGO ou CANCELADO | 409 | Não salva |
| Não existe | 404 | Não salva |
Cancelar de novo retorna 409 neste contrato. Não inclui estorno, autenticação, eventos ou garantia de concorrência. O total do café continua 37.80: cancelamento altera status, não apaga histórico.
- Escreva a spec em um novo arquivo livre da sua pasta .specs/. Declare resultado, limites e evidências.
- Revise o plano: CancelarPedido/Service, método REST, bean de montagem e testes. Reutilize Pedidos e as exceções existentes.
- Prove primeiro com fake em memória. Depois ligue HTTP e valide 200/404/409 com Postgres e releitura.
Dica 1 · quem faz o quê?
O service busca, chama atual.cancelar() e salva o retorno. Controller traduz HTTP; config injeta o caso de uso. A regra do estado permanece em Pedido.
Dica 2 · plano para o agente
Leia minhas instruções, spec de cancelamento e o código existente. Não edite ainda.
POST /pedidos/{id}/cancelamento sem corpo: aberto -> 200/CANCELADO;
pago ou cancelado -> 409; ausente -> 404. Preservar UUID, itens e total.
Não gravar em recusas. Reutilize Pedido.cancelar(), Pedidos e handler existentes.
Sem nova dependência, DTO sem necessidade, evento, estorno ou tabela.
Proponha testes unitários e HTTP/JPA que provem os critérios e preservem as operações anteriores.
Mostre arquivos a alterar e aguarde meu OK.👀 Depois de tentar: núcleo da solução
Pedido atual = pedidos.buscar(pedidoId)
.orElseThrow(() -> new PedidoNaoEncontradoException(pedidoId));
Pedido cancelado = atual.cancelar();
return pedidos.salvar(cancelado);() -> é a função executada se a busca estiver vazia. A IDE pode desenhar uma seta; digite - seguido de >. Fonte completa e testes: checkpoint de cancelamento, para comparar em outra pasta.
Seu checklist vira uma skill [19]
Uma skill empacota instruções reutilizáveis para uma tarefa. Aqui ela não “sabe SOLID” por mágica: orienta o agente a ler a spec, examinar evidências e produzir um parecer consistente. Ela também pode errar; revise o resultado.
Comece salvando o SKILL.md de revisar-solid. No Claude Code, a skill de projeto fica em .claude/skills/revisar-solid/SKILL.md e pode ser chamada por /revisar-solid. Para outro agente, peça explicitamente que leia o arquivo e siga o roteiro; confirme o mecanismo nativo de descoberta da ferramenta antes de depender dele.
---
name: revisar-solid
description: Revisar mudanças Java por contratos, encapsulamento e SOLID, com evidência e correção mínima. Use ao pedir revisão de um diff do serviço de Pedidos.
---
Leia as instruções do projeto e a spec da mudança. Identifique o diff a revisar;
se ele não foi indicado, peça o intervalo ou os arquivos antes de concluir.
Não edite arquivos, não faça commit, push nem abra PR durante a revisão.
1. Resuma o comportamento prometido e os limites da mudança.
2. Confira quem protege cada invariante e se outra entrada a contorna.
3. Examine SOLID pelo contexto: motivos de mudança, variação real,
substituição, necessidade dos clientes e direção das dependências.
4. Para cada achado, informe arquivo/linha, consequência, princípio,
evidência observada (ou hipótese explícita), correção mínima e teste.
5. Não invente um achado por letra. Não exija interface por classe.
6. Execute apenas testes locais pertinentes dentro das permissões do projeto;
diga quais rodaram e quais não rodaram. Não use serviços pagos ou produção.
7. Separe defeitos, riscos e preferências. Se não houver achados, diga isso e
registre os limites da revisão. Termine com uma decisão que merece ser mantida.
Saída: resumo do contrato, achados priorizados, testes/evidências e limites.
Aguarde uma solicitação de implementação antes de corrigir qualquer coisa.
Leia o arquivo revisar-solid/SKILL.md no caminho em que o salvei e siga suas instruções. Revise apenas meu diff de CancelarPedido em relação ao commit anterior à implementação. Se não identificar esse intervalo com segurança, pergunte antes de revisar. Não altere arquivos. Confronte 200/404/409, UUID/itens/total e ausência de gravação em recusas. Não invente problemas para preencher as cinco letras. Mostre evidências e limites.
Formato e descoberta no Claude Code: documentação oficial de skills. O roteiro de revisão é específico desta aula.
Defenda uma decisão, não uma quantidade de classes [20]
Compare as duas pranchetas. Escolha um trecho do seu parecer e explique a cadeia: mudança → risco → princípio → correção → prova. O colega deve conseguir reconstruir seu argumento sem decorar a sigla.
“Mudei para uma interface, então ficou SOLID.” O que falta?
Escolha e justifique antes de ler o retorno.
Concluir, revisar e trazer evidências
O seu serviço evolui; a revisão passa a ser um artefato que outra pessoa consegue conferir.
O que trazer para o sábado 03 [21]
Use o caderno para registrar o que não concluiu e a última evidência verde. Exportar um backup evita depender apenas do armazenamento deste navegador. Leituras e materiais do Cap 03 serão incorporados quando estiverem disponíveis; o tema é padrões, Testcontainers e Flyway.