Token导航 LogoToken导航TokenDH.com
研究检索执行命令github未标认证来源可访问许可证需确认审计通过

code-architecture代码架构

Agent Skill

code-architecture 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,706

周安装

69

GitHub Stars

98

下载量

535
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:code-architecture(代码架构)
来源仓库:https://github.com/erichowens/some_claude_skills
仓库路径:skills/code-architecture
安装命令:
npx skills add https://github.com/erichowens/some_claude_skills --skill code-architecture
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/erichowens/some_claude_skills --skill code-architecture

简介

code-architecture 聚焦模块级代码组织与架构模式选择。

  • 适用于新项目架构选型(如 Clean、Hexagonal)或现有代码结构诊断。
  • 帮助避免控制器臃肿、循环依赖等影响可维护性的设计问题。
  • 使用时应结合具体业务场景判断是否引入抽象或等待模式自然浮现。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Code Architecture

Architecture patterns and code organization that survive contact with reality. The goal is code you can still understand, test, and change 18 months after it was written. This covers the decisions made at the module and application level — not how to split services, not how to design schemas, but how to organize the code within a single deployable unit.

When to Use

Use for:

  • Choosing an architecture pattern for a new project (clean, hexagonal, feature-based, vertical slice)
  • Diagnosing architectural problems in existing code (fat controllers, circular deps, tangled business logic)
  • Applying dependency inversion to untangle tightly coupled code
  • Deciding on folder structure and module organization
  • Applying SOLID principles at the module scale (not just class scale)
  • Setting up dependency injection containers
  • Defining module boundaries and barrel exports
  • Designing the test pyramid relative to architecture layers

NOT for:

  • Splitting a monolith into microservices (use microservices-patterns)
  • Database schema design, normalization, query optimization (use database-design-patterns)
  • Framework-specific routing or middleware setup
  • CI/CD pipeline architecture

Core Decision: Which Architecture Pattern?

flowchart TD
    Start[New project or restructuring?] --> Team{Team size?}

    Team -->|Solo / 2 dev| Size{App complexity?}
    Team -->|3-8 dev| MedComplex{Domain complexity?}
    Team -->|8+ dev| Large[Feature-based / Vertical Slice]

    Size -->|Simple CRUD, low domain logic| Simple[Flat + MVC or Feature-Based]
    Size -->|Complex domain, long-lived| Hex[Hexagonal Architecture]

    MedComplex -->|Low: thin business layer| FeatureBased[Feature-Based Organization]
    MedComplex -->|High: rich business rules| Clean[Clean Architecture]
    MedComplex -->|Mixed: CRUD + some complex| Vertical[Vertical Slice Architecture]

    Simple --> SCheck{Will it grow?}
    SCheck -->|No, short-lived| MVC[Layer-based MVC is fine]
    SCheck -->|Yes| FeatureBased

    Large --> Testing{Testing rigor?}
    Testing -->|Low: mostly E2E| Vertical
    Testing -->|High: unit + integration| Clean

    Clean --> ClNote[Entities → Use Cases → Interface Adapters → Frameworks]
    Hex --> HexNote[Domain core ↔ Ports ↔ Adapters]
    FeatureBased --> FBNote[features/X contains all layers for X]
    Vertical --> VSNote[Each slice owns its full stack top to bottom]

Clean Architecture Layers

The classic onion — each ring depends only inward, never outward.

graph TB
    subgraph Frameworks ["Frameworks & Drivers (outer)"]
        DB[(Database)]
        HTTP[HTTP Server]
        UI[UI / CLI]
        External[External APIs]
    end

    subgraph Adapters ["Interface Adapters"]
        Controllers[Controllers / Routes]
        Presenters[Presenters]
        Gateways[Repository Implementations]
        DTOs[DTOs / View Models]
    end

    subgraph UseCases ["Use Cases (Application Layer)"]
        UC1[CreateOrder]
        UC2[ProcessPayment]
        UC3[NotifyUser]
        Ports[Repository Interfaces]
    end

    subgraph Entities ["Entities (Domain)"]
        Order[Order]
        User[User]
        Payment[Payment]
        Rules[Business Rules]
    end

    HTTP --> Controllers
    Controllers --> UC1
    UC1 --> Ports
    Gateways --> Ports
    DB --> Gateways
    UC1 --> Order

Dependency rule: Source code dependencies point inward only. Entities know nothing about use cases. Use cases know nothing about controllers. Controllers know nothing about database drivers.

What belongs where:

LayerContainsExamples
EntitiesEnterprise business rulesOrder, Payment, domain events, value objects
Use CasesApplication-specific business logicCreateOrderUseCase, RefundPaymentUseCase
Interface AdaptersConvert data between use cases and external formsControllers, Presenters, Repository implementations
FrameworksExternal tools, databases, UI frameworksExpress, Postgres, React

Hexagonal Architecture (Ports and Adapters)

Simpler mental model than clean architecture for many teams: everything connects through ports (interfaces), and adapters implement them.

graph LR
    subgraph Domain ["Domain (Hexagon)"]
        Logic[Business Logic]
        DPorts[Driven Ports<br/>interfaces the domain calls]
    end

    subgraph Driving ["Driving Adapters<br/>(what drives the app)"]
        HTTP2[HTTP Controller]
        CLI2[CLI Command]
        Test[Test Harness]
    end

    subgraph Driven ["Driven Adapters<br/>(what the app drives)"]
        DB2[(PostgreSQL Adapter)]
        Email[SendGrid Adapter]
        Cache[Redis Adapter]
    end

    HTTP2 -->|calls| Logic
    CLI2 -->|calls| Logic
    Test -->|calls| Logic
    Logic -->|calls port| DPorts
    DPorts -.->|implemented by| DB2
    DPorts -.->|implemented by| Email
    DPorts -.->|implemented by| Cache

When hexagonal beats clean: When you need to swap infrastructure easily (test with in-memory, prod with Postgres), or when your business logic is rich enough to warrant isolation but doesn't need the full layer separation of clean architecture.


Feature-Based vs Layer-Based Organization

Layer-Based (Traditional MVC)

src/
  controllers/
    user.controller.ts
    order.controller.ts
    payment.controller.ts
  services/
    user.service.ts
    order.service.ts
    payment.service.ts
  repositories/
    user.repository.ts
    order.repository.ts
  models/
    user.model.ts
    order.model.ts

Problem: Adding or modifying the "orders" feature requires touching files in four directories. Understanding the orders domain requires context-switching across folders.

Feature-Based (Recommended for Growing Apps)

src/
  features/
    orders/
      orders.controller.ts
      orders.service.ts
      orders.repository.ts
      orders.schema.ts
      orders.types.ts
      orders.test.ts
      index.ts           ← public API (barrel export)
    users/
      users.controller.ts
      users.service.ts
      ...
      index.ts
    payments/
      ...
  shared/
    database/
    logger/
    config/

Benefits: All order-related code is co-located. Deleting a feature is one folder deletion. Onboarding a developer to the orders domain is one directory.

Rule: Features import from shared/ and from each other's public index.ts only. They never reach into each other's internals.


Anti-Pattern: Business Logic in Controllers (Fat Controller)

Novice: "Controllers are where requests come in, so I'll put the logic there too. It's convenient."

// Fat controller — don't do this
app.post('/orders', async (req, res) => {
  const { userId, items } = req.body;

  // Business logic #1: calculate total
  const total = items.reduce((sum, item) => sum + item.price * item.qty, 0);

  // Business logic #2: apply discount
  const user = await db.users.findById(userId);
  const discount = user.memberSince < oneYearAgo ? 0.1 : 0;
  const finalTotal = total * (1 - discount);

  // Business logic #3: check inventory
  for (const item of items) {
    const stock = await db.inventory.findById(item.productId);
    if (stock.quantity < item.qty) {
      return res.status(409).json({ error: 'Out of stock' });
    }
  }

  // Side effects mixed in
  const order = await db.orders.create({ userId, items, total: finalTotal });
  await emailService.send(user.email, 'order-confirmation', { order });
  await inventory.decrement(items);

  res.json(order);
});

Expert: Controllers are HTTP adapters. They translate HTTP → domain, call a use case or service, then translate domain → HTTP response. All business logic belongs in a use case or domain service that can be tested without an HTTP context.

// Lean controller
app.post('/orders', async (req, res) => {
  try {
    const command = CreateOrderCommand.fromRequest(req.body);  // Validate + map
    const order = await createOrderUseCase.execute(command);   // All logic here
    res.status(201).json(OrderPresenter.toJSON(order));        // Map to response
  } catch (error) {
    errorHandler(res, error);
  }
});

// Use case: testable, framework-agnostic
class CreateOrderUseCase {
  constructor(
    private readonly orderRepo: OrderRepository,
    private readonly inventoryService: InventoryService,
    private readonly discountPolicy: DiscountPolicy,
    private readonly notifications: NotificationPort,
  ) {}

  async execute(command: CreateOrderCommand): Promise<Order> {
    const user = await this.orderRepo.findUser(command.userId);
    const discount = this.discountPolicy.calculate(user);
    await this.inventoryService.reserveItems(command.items);
    const order = Order.create(command.items, discount);
    await this.orderRepo.save(order);
    await this.notifications.orderCreated(order, user);
    return order;
  }
}

Detection: Controllers with more than ~20 lines of logic, controllers that import database models directly, controllers with nested if-else business conditions.


Anti-Pattern: Architecture Astronaut (Abstraction for Its Own Sake)

Novice: "I'll add a Repository interface, a Repository implementation, a Service, a ServiceInterface, a Factory to create the Service, an EventBus, and a CQRS command handler. This is enterprise-grade."

Expert: Every abstraction has a cost: more files, more indirection, harder onboarding, more to maintain. Abstractions are investments that pay off when they enable testing, swappability, or code reuse. If you're adding a UserServiceInterface with one implementation that will never change, you've paid the abstraction cost without collecting the benefit.

Ask: "What does this abstraction enable that I couldn't do otherwise?"

  • Repository interface → swap real DB for in-memory in tests. Pays off immediately.
  • Service interface → if there's only ever one service, this is ceremony.
  • Factory pattern → pays off when object creation is complex or has multiple strategies.
  • Event bus → pays off when many components need to react to domain events without knowing about each other.

Detection: Files named *Interface.ts, *Abstract.ts, *Factory.ts that have only one implementer and one caller, and that implementer never changes.

Timeline: Enterprise Java (2005-2015) made abstract-everything the default. Spring Framework encouraged this. The post-2015 Node.js and Go communities pushed back with "boring technology" principles. In 2026, the right level of abstraction is contextual — neither zero nor maximum.


Anti-Pattern: Circular Dependencies

Novice: "The Order module needs to know about Users, and the User module needs to check their orders. So I'll import each from the other."

// orders/order.service.ts
import { UserService } from '../users/user.service';   // Order → User

// users/user.service.ts
import { OrderService } from '../orders/order.service'; // User → Order

// Node.js will silently give you `undefined` at runtime
// Jest will give you cryptic "Cannot access before initialization" errors

Expert: Circular dependencies indicate a domain modeling problem. Two modules that genuinely need each other should either be merged into one module, or share a third module that both depend on, or communicate via events/interfaces.

Resolution strategies:

  1. Merge: If Order and User are truly inseparable, put them in accounts/
  2. Extract shared: Create order-summary/ that both can import from
  3. Invert with interface: User module defines OrderSummaryPort interface; Orders implements it; User never imports from Orders
  4. Event-driven: User reacts to OrderCreated event rather than calling OrderService directly
# Detect circular deps
npx madge --circular src/
npx dpdm --circular src/index.ts

# ESLint rule (add to .eslintrc)
# "import/no-cycle": "error"

Detection: Runtime errors where a module value is undefined at startup, ESLint import/no-cycle violations, madge circular output.


Dependency Inversion in Practice

The D in SOLID: depend on abstractions, not concretions. Applied at module scale:

// Bad: Use case is coupled to Postgres
class CreateOrderUseCase {
  constructor(private readonly db: PostgresConnection) {}

  async execute(cmd: CreateOrderCommand) {
    await this.db.query('INSERT INTO orders ...');
  }
}

// Good: Use case depends on an interface
interface OrderRepository {
  save(order: Order): Promise<void>;
  findById(id: OrderId): Promise<Order | null>;
}

class CreateOrderUseCase {
  constructor(private readonly orderRepo: OrderRepository) {}

  async execute(cmd: CreateOrderCommand) {
    const order = Order.create(cmd);
    await this.orderRepo.save(order);  // No SQL, no Postgres, no coupling
  }
}

// Production: Postgres implements the interface
class PostgresOrderRepository implements OrderRepository {
  async save(order: Order): Promise<void> { /* Postgres SQL */ }
  async findById(id: OrderId): Promise<Order | null> { /* Postgres SQL */ }
}

// Tests: in-memory implements the same interface
class InMemoryOrderRepository implements OrderRepository {
  private orders = new Map<string, Order>();
  async save(order: Order) { this.orders.set(order.id, order); }
  async findById(id: OrderId) { return this.orders.get(id) ?? null; }
}

When DI containers are worth it: When you have many dependencies that need wiring, and wiring manually becomes error-prone or repetitive. NestJS, InversifyJS (TypeScript), Python's dependency-injector, Spring (Java).

When DI containers are overkill: Simple scripts, small services with few dependencies, serverless functions, Go projects (constructor injection is idiomatic and sufficient).


Module Boundaries and Barrel Exports

Each feature/module should expose a public API via index.ts:

// features/orders/index.ts — public API
export { CreateOrderUseCase } from './create-order.use-case';
export { OrderRepository } from './order.repository.interface';
export type { Order, OrderStatus } from './order.entity';
// NOT exported: internal helpers, SQL queries, implementation details

// Other modules import from the public API only
import { CreateOrderUseCase } from '@/features/orders';
// NOT: import from '@/features/orders/create-order.use-case'

Enforce with ESLint:

// .eslintrc
{
  "rules": {
    "import/no-internal-modules": ["error", {
      "allow": ["**/*.test.ts", "**/index.ts"]
    }]
  }
}

Testing Architecture (Test Pyramid Placement)

Each architecture layer has a natural test type:

LayerTest TypeSpeedCoverage
Entities / DomainUnit testsInstant90%+
Use Cases / ApplicationUnit tests with mocksFast80%+
Interface AdaptersIntegration testsMedium70%+
Frameworks / ExternalE2E / contract testsSlowKey paths

Rule: Business logic tests should not require starting a server, connecting to a database, or making network calls. If your use case tests require a real database, your architecture has leaked infrastructure concerns into the domain.


References

  • references/architecture-patterns.md — Consult for detailed patterns: clean architecture layers, hexagonal ports and adapters, vertical slice, feature-based organization with worked examples
  • references/dependency-inversion.md — Consult for IoC containers in TypeScript and Python, constructor injection patterns, when DI is overkill, common DI anti-patterns

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.39%
按下载量换算179

Claude

30.3%
按下载量换算162

Cursor

19.57%
按下载量换算105

Gemini CLI

10.09%
按下载量换算54

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 npx skills add https://github.com/erichowens/some_claude_skills --skill code-architecture 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills