Communitygithub.com

pedro-oscar/shorts-ai

Vocabulário compartilhado para projetar módulos profundos. Use quando o usuário quiser projetar ou melhorar a interface de um módulo, encontrar oportunidades de aprofundamento, decidir onde colocar uma junta, tornar o código mais testável ou navegável por IA, ou quando outra habilidade precisar do vocabulário de módulo profundo.

O que é shorts-ai?

Esta habilidade fornece uma linguagem consistente e precisa para projetar e refatorar módulos de software com foco em profundidade (deep modules), um conceito fundamental para criar sistemas modulares, testáveis e de fácil manutenção. Ao invés de termos vagos como 'componente' ou 'serviço', a habilidade define um glossário específico com termos como Módulo, Interface, Implementação, Profundidade, Junta (Seam) e Adaptador. Ela ensina como reconhecer módulos rasos (shallow) que vazam complexidade para os chamadores e como transformá-los em módulos profundos, que oferecem muito comportamento por trás de uma interface pequena e estável. A habilidade é útil para qualquer desenvolvedor que deseje melhorar a testabilidade do código, tornar a base de código mais navegável por agentes de IA e criar interfaces que maximizem o leverage (alavancagem) para quem as consome. O conteúdo é agnóstico de plataforma e se aplica a qualquer linguagem ou stack, com exemplos em TypeScript. A habilidade também referencia documentos complementares (DEEPENING.md e DESIGN-IT-TWICE.md) para aprofundamento em disciplina de juntas e exploração de alternativas de design.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pedro-oscar/shorts-ai/tree/HEAD/.claude/skills/codebase-design

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Design de Base de Código

Projete módulos profundos: muito comportamento por trás de uma interface pequena, colocada em uma junta limpa, testável através dessa interface. Use esta linguagem e estes princípios sempre que o código estiver sendo projetado ou reestruturado. O objetivo é alavancagem para os chamadores, localidade para os mantenedores e testabilidade para todos.

Glossário

Use estes termos exatamente: não substitua por "componente", "serviço", "API" ou "fronteira". Linguagem consistente é o objetivo principal.

Módulo: qualquer coisa com uma interface e uma implementação. Deliberadamente agnóstico em escala: uma função, classe, pacote ou fatia que atravessa camadas. Evite: unidade, componente, serviço.

Interface: tudo que um chamador precisa saber para usar o módulo corretamente: a assinatura de tipo, mas também invariantes, restrições de ordenação, modos de erro, configuração necessária e características de desempenho. Evite: API, assinatura (muito estreitos, referem-se apenas à superfície de tipo).

Implementação: o que está dentro de um módulo, seu corpo de código. Distinto de Adaptador: algo pode ser um adaptador pequeno com uma implementação grande (um repositório Postgres) ou um adaptador grande com uma implementação pequena (um fake em memória). Use "adaptador" quando o tópico for a junta; "implementação" caso contrário.

Profundidade: alavancagem na interface. A quantidade de comportamento que um chamador (ou teste) consegue exercer por unidade de interface que precisa aprender. Um módulo é profundo quando uma grande quantidade de comportamento está por trás de uma interface pequena, e raso quando a interface é quase tão complexa quanto a implementação.

Junta (Michael Feathers): um lugar onde você pode alterar comportamento sem editar naquele lugar; a localização onde a interface de um módulo reside. Onde colocar a junta é uma decisão de design por si só, distinta do que fica por trás dela. Evite: fronteira (sobrecarregado com contexto delimitado de DDD).

Adaptador: uma coisa concreta que satisfaz uma interface em uma junta. Descreve papel (qual slot preenche), não substância (o que tem dentro).

Alavancagem: o que os chamadores ganham com a profundidade. Mais capacidade por unidade de interface que aprendem. Uma implementação compensa em N locais de chamada e M testes.

Localidade: o que os mantenedores ganham com a profundidade. Mudança, bugs, conhecimento e verificação concentram-se em um lugar em vez de se espalharem pelos chamadores. Corrija uma vez, corrigido em todos os lugares.

Profundo vs Raso

Módulo profundo = interface pequena + muita implementação:

┌─────────────────────┐
│   Interface Pequena │  ← Poucos métodos, parâmetros simples
├─────────────────────┤
│                     │
│ Implementação Funda │  ← Lógica complexa oculta
│                     │
└─────────────────────┘

Módulo raso = interface grande + pouca implementação (evite):

┌─────────────────────────────────┐
│       Interface Grande          │  ← Muitos métodos, parâmetros complexos
├─────────────────────────────────┤
│  Implementação Fina             │  ← Apenas passa adiante
└─────────────────────────────────┘

Ao projetar uma interface, pergunte:

  • Posso reduzir o número de métodos?
  • Posso simplificar os parâmetros?
  • Posso esconder mais complexidade internamente?

Princípios

  • Profundidade é uma propriedade da interface, não da implementação. Um módulo profundo pode ser internamente composto de partes pequenas, simuláveis, trocáveis; elas simplesmente não fazem parte da interface. Um módulo pode ter juntas internas (privadas para sua implementação, usadas por seus próprios testes) bem como a junta externa em sua interface.
  • O teste de exclusão. Imagine deletar o módulo. Se a complexidade desaparecer, era um repassador. Se a complexidade reaparecer em N chamadores, ele estava ganhando seu espaço.
  • A interface é a superfície de teste. Chamadores e testes cruzam a mesma junta. Se você quiser testar além da interface, o módulo provavelmente tem o formato errado.
  • Um adaptador significa uma junta hipotética. Dois adaptadores significam uma real. Não introduza uma junta a menos que algo realmente varie através dela.

Projetando para testabilidade

Interfaces boas tornam o teste natural:

  1. Aceite dependências, não as crie.

    // Testável
    function processOrder(order, paymentGateway) {}
    
    // Difícil de testar
    function processOrder(order) {
      const gateway = new StripeGateway();
    }
    
  2. Retorne resultados, não produza efeitos colaterais.

    // Testável
    function calculateDiscount(cart): Discount {}
    
    // Difícil de testar
    function applyDiscount(cart): void {
      cart.total -= discount;
    }
    
  3. Pequena área de superfície. Menos métodos = menos testes necessários. Menos parâmetros = configuração de teste mais simples.

Relacionamentos

  • Um Módulo tem exatamente uma Interface (a superfície que apresenta aos chamadores e testes).
  • Profundidade é uma propriedade de um Módulo, medida contra sua Interface.
  • Uma Junta é onde a Interface de um Módulo reside.
  • Um Adaptador fica em uma Junta e satisfaz a Interface.
  • Profundidade produz Alavancagem para os chamadores e Localidade para os mantenedores.

Enquadramentos rejeitados

  • Profundidade como razão de linhas de implementação para linhas de interface (Ousterhout): recompensa aumentar a implementação artificialmente. Usamos profundidade-como-alavancagem.
  • "Interface" como a palavra-chave interface do TypeScript ou os métodos públicos de uma classe: muito estreito: interface aqui inclui todo fato que um chamador precisa saber.
  • "Fronteira": sobrecarregado com contexto delimitado de DDD. Diga junta ou interface.

Aprofundando

  • Aprofundando um cluster dadas suas dependências, veja DEEPENING.md: categorias de dependência, disciplina de juntas e teste de substituir-não-camada.
  • Explorando interfaces alternativas, veja DESIGN-IT-TWICE.md: gire subagentes paralelos para projetar a interface de várias maneiras radicalmente diferentes e depois compare em profundidade, localidade e posicionamento da junta.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Habilidades Relacionadas