Pular para o conteúdo
Skillpedia
Código em geral280 mil · #63

hexagonal-architecture

Ajuda seu agente a projetar sistemas com arquitetura hexagonal. Separa claramente as regras de negócio das outras partes do sistema, facilitando testes e manutenção.

O que ela faz

Essa habilidade ajuda a organizar o código do seu programa de forma que a lógica principal do negócio fique separada de detalhes técnicos como bancos de dados ou interfaces de usuário. Isso torna o código mais fácil de entender, testar e modificar.

Quando usar

  • ✓Ao iniciar um novo projeto que precisa ser fácil de manter.
  • ✓Quando o código atual está confuso e misturando regras de negócio com tecnologia.
  • ✓Se você precisa conectar seu programa a diferentes sistemas (como um banco de dados ou uma API) sem mudar a lógica principal.

Exemplo do que pedir para a IA

“Como posso organizar meu código para que a lógica de negócio não dependa de qual banco de dados usaremos?”

Quer saber mais? Abra as seções abaixo.

Como usar

O jeito mais fácil: copie a mensagem abaixo e cole no Claude, ChatGPT, Cursor ou outra IA. Ela lê a skill e segue as instruções.

Link da skill

https://github.com/affaan-m/ECC/blob/main/pi/core/skills/hexagonal-architecture/SKILL.md

Mensagem pronta para colar

Use esta skill para me ajudar: https://github.com/affaan-m/ECC/blob/main/pi/core/skills/hexagonal-architecture/SKILL.md Leia o arquivo SKILL.md desse link e siga as instruções dele na minha tarefa.
Como funciona

Ela funciona definindo 'portas' (contratos) para as interações externas e 'adaptadores' que implementam essas portas. A lógica principal do programa usa as portas, e os adaptadores cuidam dos detalhes técnicos.

Instalação

Jeito mais fácil: copie o link da skill e cole no Claude, ChatGPT ou Cursor pedindo para seguir as instruções.

No terminal (Claude Code, Codex, Cursor), na pasta do projeto:

npx skills add affaan-m/ECC --skill hexagonal-architecture

Ou baixe só o arquivo:

curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/hexagonal-architecture/SKILL.md -o SKILL.md
Conteúdo técnico (SKILL.md)

Tradução do texto original do autor no GitHub. Os comandos e códigos estão como no original.

Arquitetura Hexagonal

A arquitetura hexagonal (Portas e Adaptadores) mantém a lógica de negócios independente de frameworks, transporte e detalhes de persistência. O aplicativo principal depende de portas abstratas, e os adaptadores implementam essas portas nas bordas.

Quando Usar

  • Construindo novos recursos onde a manutenibilidade e a testabilidade a longo prazo são importantes.
  • Refatorando código em camadas ou com muitos frameworks, onde a lógica de domínio é misturada com preocupações de I/O.
  • Suportando múltiplas interfaces para o mesmo caso de uso (HTTP, CLI, workers de fila, jobs agendados).
  • Substituindo infraestrutura (banco de dados, APIs externas, barramento de mensagens) sem reescrever regras de negócio.

Use essa habilidade quando a solicitação envolver limites, design centrado no domínio, refatoração de serviços rigidamente acoplados ou desacoplamento da lógica da aplicação de bibliotecas específicas.

Conceitos Principais

  • Modelo de domínio: Regras de negócio e entidades/objetos de valor. Sem importações de framework.
  • Casos de uso (camada de aplicação): Orquestram o comportamento do domínio e as etapas do fluxo de trabalho.
  • Portas de entrada (inbound ports): Contratos que descrevem o que a aplicação pode fazer (comandos/consultas/interfaces de caso de uso).
  • Portas de saída (outbound ports): Contratos para dependências que a aplicação precisa (repositórios, gateways, publicadores de eventos, relógio, UUID, etc.).
  • Adaptadores: Implementações de infraestrutura e entrega de portas (controladores HTTP, repositórios de banco de dados, consumidores de fila, wrappers de SDK).
  • Raiz de composição (composition root): Local único de conexão onde adaptadores concretos são vinculados aos casos de uso.

As interfaces de porta de saída geralmente residem na camada de aplicação (ou apenas no domínio quando a abstração é verdadeiramente de nível de domínio), enquanto os adaptadores de infraestrutura as implementam.

A direção da dependência é sempre para dentro:

  • Adaptadores -> aplicação/domínio
  • Aplicação -> interfaces de porta (contratos de entrada/saída)
  • Domínio -> abstrações apenas de domínio (sem dependências de framework ou infraestrutura)
  • Domínio -> nada externo

Como Funciona

Passo 1: Modele um limite de caso de uso

Defina um único caso de uso com um DTO de entrada e saída claros. Mantenha os detalhes de transporte (Express req, GraphQL context, wrappers de payload de job) fora desse limite.

Passo 2: Defina as portas de saída primeiro

Identifique todos os efeitos colaterais como uma porta:

  • persistência (UserRepositoryPort)
  • chamadas externas (BillingGatewayPort)
  • cross-cutting (LoggerPort, ClockPort)

As portas devem modelar capacidades, não tecnologias.

Passo 3: Implemente o caso de uso com orquestração pura

A classe/função do caso de uso recebe portas via construtor/argumentos. Ela valida invariantes em nível de aplicação, coordena regras de domínio e retorna estruturas de dados simples.

Passo 4: Construa adaptadores na borda

  • O adaptador de entrada converte a entrada do protocolo para a entrada do caso de uso.
  • O adaptador de saída mapeia contratos de aplicação para APIs concretas/ORM/construtores de consulta.
  • O mapeamento permanece nos adaptadores, não dentro dos casos de uso.

Passo 5: Conecte tudo em uma raiz de composição

Instancie adaptadores e, em seguida, injete-os nos casos de uso. Mantenha essa conexão centralizada para evitar comportamento oculto de localizador de serviço.

Passo 6: Teste por limite

  • Testes unitários de casos de uso com portas falsas.
  • Testes de integração de adaptadores com dependências reais de infraestrutura.
  • Testes E2E de fluxos voltados para o usuário através de adaptadores de entrada.

Diagrama de Arquitetura

flowchart LR
  Client["Client (HTTP/CLI/Worker)"] --> InboundAdapter["Inbound Adapter"]
  InboundAdapter -->|"calls"| UseCase["UseCase (Application Layer)"]
  UseCase -->|"uses"| OutboundPort["OutboundPort (Interface)"]
  OutboundAdapter["Outbound Adapter"] -->|"implements"| OutboundPort
  OutboundAdapter --> ExternalSystem["DB/API/Queue"]
  UseCase --> DomainModel["DomainModel"]

Layout de Módulos Sugerido

Use organização orientada a recursos (feature-first) com limites explícitos:

src/
  features/
    orders/
      domain/
        Order.ts
        OrderPolicy.ts
      application/
        ports/
          inbound/
            CreateOrder.ts
          outbound/
            OrderRepositoryPort.ts
            PaymentGatewayPort.ts
        use-cases/
          CreateOrderUseCase.ts
      adapters/
        inbound/
          http/
            createOrderRoute.ts
        outbound/
          postgres/
            PostgresOrderRepository.ts
          stripe/
            StripePaymentGateway.ts
      composition/
        ordersContainer.ts

Exemplo em TypeScript

Definições de porta

export interface OrderRepositoryPort {
  save(order: Order): Promise<void>;
  findById(orderId: string): Promise<Order | null>;
}

export interface PaymentGatewayPort {

…
Perguntas frequentes

O que são 'portas' e 'adaptadores'?

Portas são como contratos que definem o que o programa precisa fazer ou quais serviços externos ele vai usar. Adaptadores são as implementações concretas desses contratos, cuidando da comunicação com bancos de dados, APIs, etc.

Por que isso é chamado de 'arquitetura hexagonal'?

O nome vem da ideia de que a lógica principal do negócio pode ser vista como um hexágono, com as portas em cada lado para se conectar a diferentes adaptadores (como um teclado, monitor, etc., em um computador).

Isso é mais complicado de implementar?

No início, pode parecer um pouco mais complexo, mas a longo prazo, torna o desenvolvimento e a manutenção muito mais fáceis e seguros, especialmente em projetos grandes.

Detalhes

Descrição original do autor

Design, implement, and refactor Ports & Adapters systems with clear domain boundaries, dependency inversion, and testable use-case orchestration across TypeScript, Java, Kotlin, and Go services. Use when introducing or refactoring toward Ports and Adapters, or when domain logic has become entangled with I/O.

repo: affaan-m/ECC

Popularidade

Estrelas no GitHub
280 mil
Posição no ranking
#63
Licença
MIT
Atualizada em
15/10/2026

Essa skill é útil?

0

Entre para votar.

Comentários

  • …

Mais skills deste repositório

Skills parecidas