[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70NNM8XAND3YZAB2AMJ98AY":3,"skill-same:01M70NNM8XAND3YZAB2AMJ98AY":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M70NNM8XAND3YZAB2AMJ98AY","architecture-patterns",null,"Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use when architecting complex backend systems or refactoring existing applications for better maintainability.","shengdabai\u002FTony-Claude-Code-Skills","shengdabai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F116417419?v=4","01M70F6D2WY5PQV5A92BKYJQEW","Tony Sheng","01M70F6D3GAAAYZ5H4CC1G8VXM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fwshobson-agents\u002Fplugins\u002Fbackend-development\u002Fskills\u002Farchitecture-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"patterns","architecture patterns","architecture","driven","systems","maintainability","refactoring","clean architecture","backend","hexagonal","implement","when","Existing","use","hexagonal architecture","design","clean","applications","for","domain","2026-11-10 10:12:30",false,"---\nname: architecture-patterns\ndescription: Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use when architecting complex backend systems or refactoring existing applications for better maintainability.\n---\n\n# Architecture Patterns\n\nMaster proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design to build maintainable, testable, and scalable systems.\n\n## When to Use This Skill\n\n- Designing new backend systems from scratch\n- Refactoring monolithic applications for better maintainability\n- Establishing architecture standards for your team\n- Migrating from tightly coupled to loosely coupled architectures\n- Implementing domain-driven design principles\n- Creating testable and mockable codebases\n- Planning microservices decomposition\n\n## Core Concepts\n\n### 1. Clean Architecture (Uncle Bob)\n\n**Layers (dependency flows inward):**\n- **Entities**: Core business models\n- **Use Cases**: Application business rules\n- **Interface Adapters**: Controllers, presenters, gateways\n- **Frameworks & Drivers**: UI, database, external services\n\n**Key Principles:**\n- Dependencies point inward\n- Inner layers know nothing about outer layers\n- Business logic independent of frameworks\n- Testable without UI, database, or external services\n\n### 2. Hexagonal Architecture (Ports and Adapters)\n\n**Components:**\n- **Domain Core**: Business logic\n- **Ports**: Interfaces defining interactions\n- **Adapters**: Implementations of ports (database, REST, message queue)\n\n**Benefits:**\n- Swap implementations easily (mock for testing)\n- Technology-agnostic core\n- Clear separation of concerns\n\n### 3. Domain-Driven Design (DDD)\n\n**Strategic Patterns:**\n- **Bounded Contexts**: Separate models for different domains\n- **Context Mapping**: How contexts relate\n- **Ubiquitous Language**: Shared terminology\n\n**Tactical Patterns:**\n- **Entities**: Objects with identity\n- **Value Objects**: Immutable objects defined by attributes\n- **Aggregates**: Consistency boundaries\n- **Repositories**: Data access abstraction\n- **Domain Events**: Things that happened\n\n## Clean Architecture Pattern\n\n### Directory Structure\n```\napp\u002F\n├── domain\u002F           # Entities & business rules\n│   ├── entities\u002F\n│   │   ├── user.py\n│   │   └── order.py\n│   ├── value_objects\u002F\n│   │   ├── email.py\n│   │   └── money.py\n│   └── interfaces\u002F   # Abstract interfaces\n│       ├── user_repository.py\n│       └── payment_gateway.py\n├── use_cases\u002F        # Application business rules\n│   ├── create_user.py\n│   ├── process_order.py\n│   └── send_notification.py\n├── adapters\u002F         # Interface implementations\n│   ├── repositories\u002F\n│   │   ├── postgres_user_repository.py\n│   │   └── redis_cache_repository.py\n│   ├── controllers\u002F\n│   │   └── user_controller.py\n│   └── gateways\u002F\n│       ├── stripe_payment_gateway.py\n│       └── sendgrid_email_gateway.py\n└── infrastructure\u002F   # Framework & external concerns\n    ├── database.py\n    ├── config.py\n    └── logging.py\n```\n\n### Implementation Example\n\n```python\n# domain\u002Fentities\u002Fuser.py\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom typing import Optional\n\n@dataclass\nclass User:\n    \"\"\"Core user entity - no framework dependencies.\"\"\"\n    id: str\n    email: str\n    name: str\n    created_at: datetime\n    is_active: bool = True\n\n    def deactivate(self):\n        \"\"\"Business rule: deactivating user.\"\"\"\n        self.is_active = False\n\n    def can_place_order(self) -> bool:\n        \"\"\"Business rule: active users can order.\"\"\"\n        return self.is_active\n\n# domain\u002Finterfaces\u002Fuser_repository.py\nfrom abc import ABC, abstractmethod\nfrom typing import Optional, List\nfrom domain.entities.user import User\n\nclass IUserRepository(ABC):\n    \"\"\"Port: defines contract, no implementation.\"\"\"\n\n    @abstractmethod\n    async def find_by_id(self, user_id: str) -> Optional[User]:\n        pass\n\n    @abstractmethod\n    async def find_by_email(self, email: str) -> Optional[User]:\n        pass\n\n    @abstractmethod\n    async def save(self, user: User) -> User:\n        pass\n\n    @abstractmethod\n    async def delete(self, user_id: str) -> bool:\n        pass\n\n# use_cases\u002Fcreate_user.py\nfrom domain.entities.user import User\nfrom domain.interfaces.user_repository import IUserRepository\nfrom dataclasses import dataclass\nfrom datetime import datetime\nimport uuid\n\n@dataclass\nclass CreateUserRequest:\n    email: str\n    name: str\n\n@dataclass\nclass CreateUserResponse:\n    user: User\n    success: bool\n    error: Optional[str] = None\n\nclass CreateUserUseCase:\n    \"\"\"Use case: orchestrates business logic.\"\"\"\n\n    def __init__(self, user_repository: IUserRepository):\n        self.user_repository = user_repository\n\n    async def execute(self, request: CreateUserRequest) -> CreateUserResponse:\n        # Business validation\n        existing = await self.user_repository.find_by_email(request.email)\n        if existing:\n            return CreateUserResponse(\n                user=None,\n                success=False,\n                error=\"Email already exists\"\n            )\n\n        # Create entity\n        user = User(\n            id=str(uuid.uuid4()),\n            email=request.email,\n            name=request.name,\n            created_at=datetime.now(),\n            is_active=True\n        )\n\n        # Persist\n        saved_user = await self.user_repository.save(user)\n\n        return CreateUserResponse(\n            user=saved_user,\n            success=True\n        )\n\n# adapters\u002Frepositories\u002Fpostgres_user_repository.py\nfrom domain.interfaces.user_repository import IUserRepository\nfrom domain.entities.user import User\nfrom typing import Optional\nimport asyncpg\n\nclass PostgresUserRepository(IUserRepository):\n    \"\"\"Adapter: PostgreSQL implementation.\"\"\"\n\n    def __init__(self, pool: asyncpg.Pool):\n        self.pool = pool\n\n    async def find_by_id(self, user_id: str) -> Optional[User]:\n        async with self.pool.acquire() as conn:\n            row = await conn.fetchrow(\n                \"SELECT * FROM users WHERE id = $1\", user_id\n            )\n            return self._to_entity(row) if row else None\n\n    async def find_by_email(self, email: str) -> Optional[User]:\n        async with self.pool.acquire() as conn:\n            row = await conn.fetchrow(\n                \"SELECT * FROM users WHERE email = $1\", email\n            )\n            return self._to_entity(row) if row else None\n\n    async def save(self, user: User) -> User:\n        async with self.pool.acquire() as conn:\n            await conn.execute(\n                \"\"\"\n                INSERT INTO users (id, email, name, created_at, is_active)\n                VALUES ($1, $2, $3, $4, $5)\n                ON CONFLICT (id) DO UPDATE\n                SET email = $2, name = $3, is_active = $5\n                \"\"\",\n                user.id, user.email, user.name, user.created_at, user.is_active\n            )\n            return user\n\n    async def delete(self, user_id: str) -> bool:\n        async with self.pool.acquire() as conn:\n            result = await conn.execute(\n                \"DELETE FROM users WHERE id = $1\", user_id\n            )\n            return result == \"DELETE 1\"\n\n    def _to_entity(self, row) -> User:\n        \"\"\"Map database row to entity.\"\"\"\n        return User(\n            id=row[\"id\"],\n            email=row[\"email\"],\n            name=row[\"name\"],\n            created_at=row[\"created_at\"],\n            is_active=row[\"is_active\"]\n        )\n\n# adapters\u002Fcontrollers\u002Fuser_controller.py\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom use_cases.create_user import CreateUserUseCase, CreateUserRequest\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass CreateUserDTO(BaseModel):\n    email: str\n    name: str\n\n@router.post(\"\u002Fusers\")\nasync def create_user(\n    dto: CreateUserDTO,\n    use_case: CreateUserUseCase = Depends(get_create_user_use_case)\n):\n    \"\"\"Controller: handles HTTP concerns only.\"\"\"\n    request = CreateUserRequest(email=dto.email, name=dto.name)\n    response = await use_case.execute(request)\n\n    if not response.success:\n        raise HTTPException(status_code=400, detail=response.error)\n\n    return {\"user\": response.user}\n```\n\n## Hexagonal Architecture Pattern\n\n```python\n# Core domain (hexagon center)\nclass OrderService:\n    \"\"\"Domain service - no infrastructure dependencies.\"\"\"\n\n    def __init__(\n        self,\n        order_repository: OrderRepositoryPort,\n        payment_gateway: PaymentGatewayPort,\n        notification_service: NotificationPort\n    ):\n        self.orders = order_repository\n        self.payments = payment_gateway\n        self.notifications = notification_service\n\n    async def place_order(self, order: Order) -> OrderResult:\n        # Business logic\n        if not order.is_valid():\n            return OrderResult(success=False, error=\"Invalid order\")\n\n        # Use ports (interfaces)\n        payment = await self.payments.charge(\n            amount=order.total,\n            customer=order.customer_id\n        )\n\n        if not payment.success:\n            return OrderResult(success=False, error=\"Payment failed\")\n\n        order.mark_as_paid()\n        saved_order = await self.orders.save(order)\n\n        await self.notifications.send(\n            to=order.customer_email,\n            subject=\"Order confirmed\",\n            body=f\"Order {order.id} confirmed\"\n        )\n\n        return OrderResult(success=True, order=saved_order)\n\n# Ports (interfaces)\nclass OrderRepositoryPort(ABC):\n    @abstractmethod\n    async def save(self, order: Order) -> Order:\n        pass\n\nclass PaymentGatewayPort(ABC):\n    @abstractmethod\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        pass\n\nclass NotificationPort(ABC):\n    @abstractmethod\n    async def send(self, to: str, subject: str, body: str):\n        pass\n\n# Adapters (implementations)\nclass StripePaymentAdapter(PaymentGatewayPort):\n    \"\"\"Primary adapter: connects to Stripe API.\"\"\"\n\n    def __init__(self, api_key: str):\n        self.stripe = stripe\n        self.stripe.api_key = api_key\n\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        try:\n            charge = self.stripe.Charge.create(\n                amount=amount.cents,\n                currency=amount.currency,\n                customer=customer\n            )\n            return PaymentResult(success=True, transaction_id=charge.id)\n        except stripe.error.CardError as e:\n            return PaymentResult(success=False, error=str(e))\n\nclass MockPaymentAdapter(PaymentGatewayPort):\n    \"\"\"Test adapter: no external dependencies.\"\"\"\n\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        return PaymentResult(success=True, transaction_id=\"mock-123\")\n```\n\n## Domain-Driven Design Pattern\n\n```python\n# Value Objects (immutable)\nfrom dataclasses import dataclass\nfrom typing import Optional\n\n@dataclass(frozen=True)\nclass Email:\n    \"\"\"Value object: validated email.\"\"\"\n    value: str\n\n    def __post_init__(self):\n        if \"@\" not in self.value:\n            raise ValueError(\"Invalid email\")\n\n@dataclass(frozen=True)\nclass Money:\n    \"\"\"Value object: amount with currency.\"\"\"\n    amount: int  # cents\n    currency: str\n\n    def add(self, other: \"Money\") -> \"Money\":\n        if self.currency != other.currency:\n            raise ValueError(\"Currency mismatch\")\n        return Money(self.amount + other.amount, self.currency)\n\n# Entities (with identity)\nclass Order:\n    \"\"\"Entity: has identity, mutable state.\"\"\"\n\n    def __init__(self, id: str, customer: Customer):\n        self.id = id\n        self.customer = customer\n        self.items: List[OrderItem] = []\n        self.status = OrderStatus.PENDING\n        self._events: List[DomainEvent] = []\n\n    def add_item(self, product: Product, quantity: int):\n        \"\"\"Business logic in entity.\"\"\"\n        item = OrderItem(product, quantity)\n        self.items.append(item)\n        self._events.append(ItemAddedEvent(self.id, item))\n\n    def total(self) -> Money:\n        \"\"\"Calculated property.\"\"\"\n        return sum(item.subtotal() for item in self.items)\n\n    def submit(self):\n        \"\"\"State transition with business rules.\"\"\"\n        if not self.items:\n            raise ValueError(\"Cannot submit empty order\")\n        if self.status != OrderStatus.PENDING:\n            raise ValueError(\"Order already submitted\")\n\n        self.status = OrderStatus.SUBMITTED\n        self._events.append(OrderSubmittedEvent(self.id))\n\n# Aggregates (consistency boundary)\nclass Customer:\n    \"\"\"Aggregate root: controls access to entities.\"\"\"\n\n    def __init__(self, id: str, email: Email):\n        self.id = id\n        self.email = email\n        self._addresses: List[Address] = []\n        self._orders: List[str] = []  # Order IDs, not full objects\n\n    def add_address(self, address: Address):\n        \"\"\"Aggregate enforces invariants.\"\"\"\n        if len(self._addresses) >= 5:\n            raise ValueError(\"Maximum 5 addresses allowed\")\n        self._addresses.append(address)\n\n    @property\n    def primary_address(self) -> Optional[Address]:\n        return next((a for a in self._addresses if a.is_primary), None)\n\n# Domain Events\n@dataclass\nclass OrderSubmittedEvent:\n    order_id: str\n    occurred_at: datetime = field(default_factory=datetime.now)\n\n# Repository (aggregate persistence)\nclass OrderRepository:\n    \"\"\"Repository: persist\u002Fretrieve aggregates.\"\"\"\n\n    async def find_by_id(self, order_id: str) -> Optional[Order]:\n        \"\"\"Reconstitute aggregate from storage.\"\"\"\n        pass\n\n    async def save(self, order: Order):\n        \"\"\"Persist aggregate and publish events.\"\"\"\n        await self._persist(order)\n        await self._publish_events(order._events)\n        order._events.clear()\n```\n\n## Resources\n\n- **references\u002Fclean-architecture-guide.md**: Detailed layer breakdown\n- **references\u002Fhexagonal-architecture-guide.md**: Ports and adapters patterns\n- **references\u002Fddd-tactical-patterns.md**: Entities, value objects, aggregates\n- **assets\u002Fclean-architecture-template\u002F**: Complete project structure\n- **assets\u002Fddd-examples\u002F**: Domain modeling examples\n\n## Best Practices\n\n1. **Dependency Rule**: Dependencies always point inward\n2. **Interface Segregation**: Small, focused interfaces\n3. **Business Logic in Domain**: Keep frameworks out of core\n4. **Test Independence**: Core testable without infrastructure\n5. **Bounded Contexts**: Clear domain boundaries\n6. **Ubiquitous Language**: Consistent terminology\n7. **Thin Controllers**: Delegate to use cases\n8. **Rich Domain Models**: Behavior with data\n\n## Common Pitfalls\n\n- **Anemic Domain**: Entities with only data, no behavior\n- **Framework Coupling**: Business logic depends on frameworks\n- **Fat Controllers**: Business logic in controllers\n- **Repository Leakage**: Exposing ORM objects\n- **Missing Abstractions**: Concrete dependencies in core\n- **Over-Engineering**: Clean architecture for simple CRUD\n","# Architecture Patterns\n\nMaster proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design to build maintainable, testable, and scalable systems.\n\n## When to Use This Skill\n\n- Designing new backend systems from scratch\n- Refactoring monolithic applications for better maintainability\n- Establishing architecture standards for your team\n- Migrating from tightly coupled to loosely coupled architectures\n- Implementing domain-driven design principles\n- Creating testable and mockable codebases\n- Planning microservices decomposition\n\n## Core Concepts\n\n### 1. Clean Architecture (Uncle Bob)\n\n**Layers (dependency flows inward):**\n- **Entities**: Core business models\n- **Use Cases**: Application business rules\n- **Interface Adapters**: Controllers, presenters, gateways\n- **Frameworks & Drivers**: UI, database, external services\n\n**Key Principles:**\n- Dependencies point inward\n- Inner layers know nothing about outer layers\n- Business logic independent of frameworks\n- Testable without UI, database, or external services\n\n### 2. Hexagonal Architecture (Ports and Adapters)\n\n**Components:**\n- **Domain Core**: Business logic\n- **Ports**: Interfaces defining interactions\n- **Adapters**: Implementations of ports (database, REST, message queue)\n\n**Benefits:**\n- Swap implementations easily (mock for testing)\n- Technology-agnostic core\n- Clear separation of concerns\n\n### 3. Domain-Driven Design (DDD)\n\n**Strategic Patterns:**\n- **Bounded Contexts**: Separate models for different domains\n- **Context Mapping**: How contexts relate\n- **Ubiquitous Language**: Shared terminology\n\n**Tactical Patterns:**\n- **Entities**: Objects with identity\n- **Value Objects**: Immutable objects defined by attributes\n- **Aggregates**: Consistency boundaries\n- **Repositories**: Data access abstraction\n- **Domain Events**: Things that happened\n\n## Clean Architecture Pattern\n\n### Directory Structure\n```\napp\u002F\n├── domain\u002F           # Entities & business rules\n│   ├── entities\u002F\n│   │   ├── user.py\n│   │   └── order.py\n│   ├── value_objects\u002F\n│   │   ├── email.py\n│   │   └── money.py\n│   └── interfaces\u002F   # Abstract interfaces\n│       ├── user_repository.py\n│       └── payment_gateway.py\n├── use_cases\u002F        # Application business rules\n│   ├── create_user.py\n│   ├── process_order.py\n│   └── send_notification.py\n├── adapters\u002F         # Interface implementations\n│   ├── repositories\u002F\n│   │   ├── postgres_user_repository.py\n│   │   └── redis_cache_repository.py\n│   ├── controllers\u002F\n│   │   └── user_controller.py\n│   └── gateways\u002F\n│       ├── stripe_payment_gateway.py\n│       └── sendgrid_email_gateway.py\n└── infrastructure\u002F   # Framework & external concerns\n    ├── database.py\n    ├── config.py\n    └── logging.py\n```\n\n### Implementation Example\n\n```python\n# domain\u002Fentities\u002Fuser.py\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom typing import Optional\n\n@dataclass\nclass User:\n    \"\"\"Core user entity - no framework dependencies.\"\"\"\n    id: str\n    email: str\n    name: str\n    created_at: datetime\n    is_active: bool = True\n\n    def deactivate(self):\n        \"\"\"Business rule: deactivating user.\"\"\"\n        self.is_active = False\n\n    def can_place_order(self) -> bool:\n        \"\"\"Business rule: active users can order.\"\"\"\n        return self.is_active\n\n# domain\u002Finterfaces\u002Fuser_repository.py\nfrom abc import ABC, abstractmethod\nfrom typing import Optional, List\nfrom domain.entities.user import User\n\nclass IUserRepository(ABC):\n    \"\"\"Port: defines contract, no implementation.\"\"\"\n\n    @abstractmethod\n    async def find_by_id(self, user_id: str) -> Optional[User]:\n        pass\n\n    @abstractmethod\n    async def find_by_email(self, email: str) -> Optional[User]:\n        pass\n\n    @abstractmethod\n    async def save(self, user: User) -> User:\n        pass\n\n    @abstractmethod\n    async def delete(self, user_id: str) -> bool:\n        pass\n\n# use_cases\u002Fcreate_user.py\nfrom domain.entities.user import User\nfrom domain.interfaces.user_repository import IUserRepository\nfrom dataclasses import dataclass\nfrom datetime import datetime\nimport uuid\n\n@dataclass\nclass CreateUserRequest:\n    email: str\n    name: str\n\n@dataclass\nclass CreateUserResponse:\n    user: User\n    success: bool\n    error: Optional[str] = None\n\nclass CreateUserUseCase:\n    \"\"\"Use case: orchestrates business logic.\"\"\"\n\n    def __init__(self, user_repository: IUserRepository):\n        self.user_repository = user_repository\n\n    async def execute(self, request: CreateUserRequest) -> CreateUserResponse:\n        # Business validation\n        existing = await self.user_repository.find_by_email(request.email)\n        if existing:\n            return CreateUserResponse(\n                user=None,\n                success=False,\n                error=\"Email already exists\"\n            )\n\n        # Create entity\n        user = User(\n            id=str(uuid.uuid4()),\n            email=request.email,\n            name=request.name,\n            created_at=datetime.now(),\n            is_active=True\n        )\n\n        # Persist\n        saved_user = await self.user_repository.save(user)\n\n        return CreateUserResponse(\n            user=saved_user,\n            success=True\n        )\n\n# adapters\u002Frepositories\u002Fpostgres_user_repository.py\nfrom domain.interfaces.user_repository import IUserRepository\nfrom domain.entities.user import User\nfrom typing import Optional\nimport asyncpg\n\nclass PostgresUserRepository(IUserRepository):\n    \"\"\"Adapter: PostgreSQL implementation.\"\"\"\n\n    def __init__(self, pool: asyncpg.Pool):\n        self.pool = pool\n\n    async def find_by_id(self, user_id: str) -> Optional[User]:\n        async with self.pool.acquire() as conn:\n            row = await conn.fetchrow(\n                \"SELECT * FROM users WHERE id = $1\", user_id\n            )\n            return self._to_entity(row) if row else None\n\n    async def find_by_email(self, email: str) -> Optional[User]:\n        async with self.pool.acquire() as conn:\n            row = await conn.fetchrow(\n                \"SELECT * FROM users WHERE email = $1\", email\n            )\n            return self._to_entity(row) if row else None\n\n    async def save(self, user: User) -> User:\n        async with self.pool.acquire() as conn:\n            await conn.execute(\n                \"\"\"\n                INSERT INTO users (id, email, name, created_at, is_active)\n                VALUES ($1, $2, $3, $4, $5)\n                ON CONFLICT (id) DO UPDATE\n                SET email = $2, name = $3, is_active = $5\n                \"\"\",\n                user.id, user.email, user.name, user.created_at, user.is_active\n            )\n            return user\n\n    async def delete(self, user_id: str) -> bool:\n        async with self.pool.acquire() as conn:\n            result = await conn.execute(\n                \"DELETE FROM users WHERE id = $1\", user_id\n            )\n            return result == \"DELETE 1\"\n\n    def _to_entity(self, row) -> User:\n        \"\"\"Map database row to entity.\"\"\"\n        return User(\n            id=row[\"id\"],\n            email=row[\"email\"],\n            name=row[\"name\"],\n            created_at=row[\"created_at\"],\n            is_active=row[\"is_active\"]\n        )\n\n# adapters\u002Fcontrollers\u002Fuser_controller.py\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom use_cases.create_user import CreateUserUseCase, CreateUserRequest\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass CreateUserDTO(BaseModel):\n    email: str\n    name: str\n\n@router.post(\"\u002Fusers\")\nasync def create_user(\n    dto: CreateUserDTO,\n    use_case: CreateUserUseCase = Depends(get_create_user_use_case)\n):\n    \"\"\"Controller: handles HTTP concerns only.\"\"\"\n    request = CreateUserRequest(email=dto.email, name=dto.name)\n    response = await use_case.execute(request)\n\n    if not response.success:\n        raise HTTPException(status_code=400, detail=response.error)\n\n    return {\"user\": response.user}\n```\n\n## Hexagonal Architecture Pattern\n\n```python\n# Core domain (hexagon center)\nclass OrderService:\n    \"\"\"Domain service - no infrastructure dependencies.\"\"\"\n\n    def __init__(\n        self,\n        order_repository: OrderRepositoryPort,\n        payment_gateway: PaymentGatewayPort,\n        notification_service: NotificationPort\n    ):\n        self.orders = order_repository\n        self.payments = payment_gateway\n        self.notifications = notification_service\n\n    async def place_order(self, order: Order) -> OrderResult:\n        # Business logic\n        if not order.is_valid():\n            return OrderResult(success=False, error=\"Invalid order\")\n\n        # Use ports (interfaces)\n        payment = await self.payments.charge(\n            amount=order.total,\n            customer=order.customer_id\n        )\n\n        if not payment.success:\n            return OrderResult(success=False, error=\"Payment failed\")\n\n        order.mark_as_paid()\n        saved_order = await self.orders.save(order)\n\n        await self.notifications.send(\n            to=order.customer_email,\n            subject=\"Order confirmed\",\n            body=f\"Order {order.id} confirmed\"\n        )\n\n        return OrderResult(success=True, order=saved_order)\n\n# Ports (interfaces)\nclass OrderRepositoryPort(ABC):\n    @abstractmethod\n    async def save(self, order: Order) -> Order:\n        pass\n\nclass PaymentGatewayPort(ABC):\n    @abstractmethod\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        pass\n\nclass NotificationPort(ABC):\n    @abstractmethod\n    async def send(self, to: str, subject: str, body: str):\n        pass\n\n# Adapters (implementations)\nclass StripePaymentAdapter(PaymentGatewayPort):\n    \"\"\"Primary adapter: connects to Stripe API.\"\"\"\n\n    def __init__(self, api_key: str):\n        self.stripe = stripe\n        self.stripe.api_key = api_key\n\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        try:\n            charge = self.stripe.Charge.create(\n                amount=amount.cents,\n                currency=amount.currency,\n                customer=customer\n            )\n            return PaymentResult(success=True, transaction_id=charge.id)\n        except stripe.error.CardError as e:\n            return PaymentResult(success=False, error=str(e))\n\nclass MockPaymentAdapter(PaymentGatewayPort):\n    \"\"\"Test adapter: no external dependencies.\"\"\"\n\n    async def charge(self, amount: Money, customer: str) -> PaymentResult:\n        return PaymentResult(success=True, transaction_id=\"mock-123\")\n```\n\n## Domain-Driven Design Pattern\n\n```python\n# Value Objects (immutable)\nfrom dataclasses import dataclass\nfrom typing import Optional\n\n@dataclass(frozen=True)\nclass Email:\n    \"\"\"Value object: validated email.\"\"\"\n    value: str\n\n    def __post_init__(self):\n        if \"@\" not in self.value:\n            raise ValueError(\"Invalid email\")\n\n@dataclass(frozen=True)\nclass Money:\n    \"\"\"Value object: amount with currency.\"\"\"\n    amount: int  # cents\n    currency: str\n\n    def add(self, other: \"Money\") -> \"Money\":\n        if self.currency != other.currency:\n            raise ValueError(\"Currency mismatch\")\n        return Money(self.amount + other.amount, self.currency)\n\n# Entities (with identity)\nclass Order:\n    \"\"\"Entity: has identity, mutable state.\"\"\"\n\n    def __init__(self, id: str, customer: Customer):\n        self.id = id\n        self.customer = customer\n        self.items: List[OrderItem] = []\n        self.status = OrderStatus.PENDING\n        self._events: List[DomainEvent] = []\n\n    def add_item(self, product: Product, quantity: int):\n        \"\"\"Business logic in entity.\"\"\"\n        item = OrderItem(product, quantity)\n        self.items.append(item)\n        self._events.append(ItemAddedEvent(self.id, item))\n\n    def total(self) -> Money:\n        \"\"\"Calculated property.\"\"\"\n        return sum(item.subtotal() for item in self.items)\n\n    def submit(self):\n        \"\"\"State transition with business rules.\"\"\"\n        if not self.items:\n            raise ValueError(\"Cannot submit empty order\")\n        if self.status != OrderStatus.PENDING:\n            raise ValueError(\"Order already submitted\")\n\n        self.status = OrderStatus.SUBMITTED\n        self._events.append(OrderSubmittedEvent(self.id))\n\n# Aggregates (consistency boundary)\nclass Customer:\n    \"\"\"Aggregate root: controls access to entities.\"\"\"\n\n    def __init__(self, id: str, email: Email):\n        self.id = id\n        self.email = email\n        self._addresses: List[Address] = []\n        self._orders: List[str] = []  # Order IDs, not full objects\n\n    def add_address(self, address: Address):\n        \"\"\"Aggregate enforces invariants.\"\"\"\n        if len(self._addresses) >= 5:\n            raise ValueError(\"Maximum 5 addresses allowed\")\n        self._addresses.append(address)\n\n    @property\n    def primary_address(self) -> Optional[Address]:\n        return next((a for a in self._addresses if a.is_primary), None)\n\n# Domain Events\n@dataclass\nclass OrderSubmittedEvent:\n    order_id: str\n    occurred_at: datetime = field(default_factory=datetime.now)\n\n# Repository (aggregate persistence)\nclass OrderRepository:\n    \"\"\"Repository: persist\u002Fretrieve aggregates.\"\"\"\n\n    async def find_by_id(self, order_id: str) -> Optional[Order]:\n        \"\"\"Reconstitute aggregate from storage.\"\"\"\n        pass\n\n    async def save(self, order: Order):\n        \"\"\"Persist aggregate and publish events.\"\"\"\n        await self._persist(order)\n        await self._publish_events(order._events)\n        order._events.clear()\n```\n\n## Resources\n\n- **references\u002Fclean-architecture-guide.md**: Detailed layer breakdown\n- **references\u002Fhexagonal-architecture-guide.md**: Ports and adapters patterns\n- **references\u002Fddd-tactical-patterns.md**: Entities, value objects, aggregates\n- **assets\u002Fclean-architecture-template\u002F**: Complete project structure\n- **assets\u002Fddd-examples\u002F**: Domain modeling examples\n\n## Best Practices\n\n1. **Dependency Rule**: Dependencies always point inward\n2. **Interface Segregation**: Small, focused interfaces\n3. **Business Logic in Domain**: Keep frameworks out of core\n4. **Test Independence**: Core testable without infrastructure\n5. **Bounded Contexts**: Clear domain boundaries\n6. **Ubiquitous Language**: Consistent terminology\n7. **Thin Controllers**: Delegate to use cases\n8. **Rich Domain Models**: Behavior with data\n\n## Common Pitfalls\n\n- **Anemic Domain**: Entities with only data, no behavior\n- **Framework Coupling**: Business logic depends on frameworks\n- **Fat Controllers**: Business logic in controllers\n- **Repository Leakage**: Exposing ORM objects\n- **Missing Abstractions**: Concrete dependencies in core\n- **Over-Engineering**: Clean architecture for simple CRUD\n",{"name":5,"description":7},"main","7850740bd837adb32f0a109ab2af82482196c6f2","skills\u002Fwshobson-agents\u002Fplugins\u002Fbackend-development\u002Fskills\u002Farchitecture-patterns",1,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills","https:\u002F\u002Fzturnsgo.com","https:\u002F\u002Fgithub.com\u002Fshengdabai","https:\u002F\u002Fzturnsgo.com\u002F","AI × education creator — producer, not consumer. Taught 6,000+ learners; shipping learning tools & daily essays with Claude Code, practicing @xiaolai's way 🥋","2026-11-01 21:28:23",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add shengdabai\u002FTony-Claude-Code-Skills --skill architecture-patterns",{"tool":65,"command":66},"bunx","bunx skills add shengdabai\u002FTony-Claude-Code-Skills --skill architecture-patterns",{"tool":68,"command":69},"pnpm","pnpm dlx skills add shengdabai\u002FTony-Claude-Code-Skills --skill architecture-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fwshobson-agents\u002Fplugins\u002Fbackend-development\u002Fskills\u002Farchitecture-patterns\u002FSKILL.md",true,[],[74,91,124,149,171,191],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":83,"publishedAt":44},"01M70P17DAD4C1C47NPH6A96EM","xiaolai-methodology","以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 \"李笑来\"、\"笑来\"、\"笑来老师\"、\"扮演李笑来\"、\"找笑来聊聊\"、\"笑来怎么看\"、\"xiaolai\"、\"把时间当作朋友\"、\"通往财富自由之路\"、\"定投改变命运\"、\"韭菜的自我修养\"、\"自学是门手艺\"、\"让时间陪你慢慢变富\"、\"七年就是一辈子\"、\"元认知\"、\"活在未来\"、\"复利\u002F长期主义\"、\"践行\"、\"痴迷改进\"、\"个人商业模式\u002F出售时间\"、\"睡后收入\"、\"定投\"、\"财富自由\"、\"操作系统升级\"、\"最少必要知识\"、\"北极星提示词\"、\"用 AI 该怎么学\u002F思考\" 等任一触发词,或当用户带着关于创业\u002F赚钱\u002F投资\u002F学习\u002F职业\u002F重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fxiaolai-methodology\u002FSKILL.md",[80],{"categoryNo":81,"categoryName":82,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",[84,85,86,87,88,89,90],"methodology","xiaolai","xiaolai methodology","朋友","投资","writing","收入",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":105,"publishedAt":44},"01M70P13NB9YP7ACJR1S861CDS","zread","Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `.\u002F.zread\u002Fwiki\u002F`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module\u002Fpackage explanations, or \"what does this repo do\"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread \u002F zread.ai directly. Also use it proactively before diving into a large unknown repo — if `.\u002F.zread\u002Fwiki\u002Fcurrent` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word \"zread\".","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fzread\u002FSKILL.md",[97,100],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":101,"categoryName":102,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[93,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,26,121,122,123],"knowledge","wiki","explore","walkthrough","project","get","knowledge base","run","generate","intent","cli","map","documentation","project wiki","disk","code","unknown","generated",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":134,"publishedAt":44},"01M70P10S4SWMZQ8BJAFBFDRW3","youtube","Launch the YouTube Creator Agent to auto-generate videos.\nUse when: user types \u002Fyoutube, wants to create YouTube videos,\ngenerate video content, or upload to YouTube.\nKeywords: youtube, video, 视频, 创作视频, 发布视频","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[130,131],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":132,"categoryName":133,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000036","内容创作者",[126,135,136,137,138,139,140,141,114,142,143,144,35,37,145,146,147,148],"user","content","视频","creator","generate video","videos","launch","video content","create","upload","auto","types","Video","创作",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":156,"publishedAt":44},"01M70P0YE95D8BACZCGV8BK90K","youtube-script-sync","Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新\u002F同步\u002F优化 Youtube视频逐字稿知识库”, or says “更新\u002F同步\u002F优化该知识库” while this knowledge base is the active context.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-sync\u002FSKILL.md",[155],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[157,158,126,159,160,147,161,162,163,164,165,166,167,168,112,169,35,37,106,170],"sync","script","youtube script sync","recording","shorts","first","base","person","update","active","child","optimize","idempotent","long",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":181,"publishedAt":44},"01M70P0WMV5XT0EEC0N445PW07","writing-skills","How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-skills\u002FSKILL.md",[177,178,179,180],{"categoryNo":81,"categoryName":82,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":101,"categoryName":102,"taxonomyType":103,"taxonomyTypeDesc":104},{"categoryNo":132,"categoryName":133,"taxonomyType":103,"taxonomyTypeDesc":104},[182,89,183,184,185,186,121,35,37,187,188,189,190],"writing skills","how","teach","write skill","write","claude code skills","files","how to","trigger",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":199,"publishedAt":44},"01M70P0SJFR4YVJQBGMHKGSKXT","writing-rules","How to write .claude\u002Frules\u002F files that Claude actually follows. Use when creating, improving, or reviewing project rules.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-rules\u002FSKILL.md",[197,198],{"categoryNo":81,"categoryName":82,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":132,"categoryName":133,"taxonomyType":103,"taxonomyTypeDesc":104},[200,89,201,110,202,188,35,183,186,37,189],"Rules","writing rules","project rules"]