arch-guard

進行代碼重構或新增模組時觸發。確保程式碼符合 Clean Architecture + DDD + CQRS 的層次關係,防止架構腐化。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "arch-guard" with this command: npx skills add knowlet/skills/knowlet-skills-arch-guard

Architecture Guard Skill

觸發時機

  • 進行代碼重構時
  • 新增模組或類別時
  • 修改現有程式碼的依賴關係時
  • AI 生成新代碼前的架構審查

核心任務

確保程式碼放對位置,嚴格遵守領域驅動設計 (DDD) 與 Clean Architecture 的層次關係。

架構層次定義

┌─────────────────────────────────────────────────┐
│              Presentation Layer                  │
│         (Controllers, Views, DTOs)               │
├─────────────────────────────────────────────────┤
│              Application Layer                   │
│    (Use Cases, Application Services, Commands)   │
├─────────────────────────────────────────────────┤
│               Domain Layer                       │
│  (Entities, Value Objects, Domain Services,      │
│   Aggregates, Domain Events, Repositories IF)    │
├─────────────────────────────────────────────────┤
│            Infrastructure Layer                  │
│  (Repository Impl, External Services, DB, MQ)    │
└─────────────────────────────────────────────────┘

依賴規則 (Dependency Rule)

核心原則:依賴只能向內指向,內層不能知道外層的存在

允許的依賴方向

Presentation → Application → Domain ← Infrastructure

禁止的依賴

禁止情況說明違規範例
Domain → Infrastructure領域層不能依賴基礎設施Domain Entity import JDBC
Domain → Application領域層不能依賴應用層Entity import UseCase
Domain → Presentation領域層不能依賴展示層Entity import Controller
Application → Presentation應用層不能依賴展示層UseCase import DTO

違規檢測規則

🚫 嚴重違規 (必須立即修正)

  1. Domain 層引用資料庫驅動

    // ❌ 違規:Domain 層出現 JDBC/JPA 實作
    package com.example.domain.entity;
    import java.sql.Connection;  // 禁止!
    import javax.persistence.EntityManager;  // 禁止!
    
  2. Domain 層引用 Spring Framework

    // ❌ 違規:Domain 層出現 Spring 註解
    package com.example.domain.service;
    import org.springframework.stereotype.Service;  // 禁止!
    import org.springframework.beans.factory.annotation.Autowired;  // 禁止!
    
  3. Domain 層引用外部 HTTP 客戶端

    // ❌ 違規:Domain 層直接呼叫外部服務
    package com.example.domain.service;
    import org.springframework.web.client.RestTemplate;  // 禁止!
    

⚠️ 中度違規 (應該重構)

  1. Application 層包含業務邏輯

    • Application Layer 應只負責編排 (Orchestration)
    • 複雜業務邏輯應下沉到 Domain Layer
  2. Repository 實作暴露在 Domain 層

    • Domain 層只應定義 Repository 介面
    • 實作應在 Infrastructure 層

💡 建議改進

  1. 使用 Port/Adapter 模式
    • Domain 定義 Port (介面)
    • Infrastructure 提供 Adapter (實作)

標準目錄結構

src/main/java/com/example/
├── presentation/           # 展示層
│   ├── controller/
│   ├── dto/
│   │   ├── request/
│   │   └── response/
│   └── assembler/
│
├── application/            # 應用層
│   ├── command/           # CQRS Command
│   │   └── handler/
│   ├── query/             # CQRS Query
│   │   └── handler/
│   ├── service/           # Application Services
│   └── port/              # 輸出埠口定義
│       ├── inbound/
│       └── outbound/
│
├── domain/                 # 領域層 (純 POJO)
│   ├── model/
│   │   ├── aggregate/
│   │   ├── entity/
│   │   └── valueobject/
│   ├── service/           # Domain Services
│   ├── event/             # Domain Events
│   ├── repository/        # Repository 介面
│   └── exception/         # Domain Exceptions
│
└── infrastructure/         # 基礎設施層
    ├── persistence/
    │   ├── repository/    # Repository 實作
    │   └── entity/        # JPA/ORM Entities
    ├── messaging/
    ├── external/          # 外部服務整合
    └── config/            # 技術配置

審查檢查清單

新增類別時

  • 類別放在正確的層次?
  • import 語句是否違反依賴規則?
  • Domain 層是否為純 POJO(無框架依賴)?
  • Repository 介面與實作是否分離?

重構時

  • 是否引入新的跨層依賴?
  • 是否破壞現有的層次邊界?
  • 是否需要透過介面解耦?

違規處理流程

  1. 識別違規:標記具體的類別和 import 語句
  2. 分類嚴重度:嚴重 / 中度 / 建議
  3. 提供修正方案:給出具體的重構建議
  4. 阻止提交:嚴重違規時應阻止代碼合併

範例:違規修正

修正前 (違規)

// domain/service/OrderDomainService.java
package com.example.domain.service;

import org.springframework.stereotype.Service;  // ❌
import com.example.infrastructure.repository.JpaOrderRepository;  // ❌

@Service  // ❌
public class OrderDomainService {
    private final JpaOrderRepository repository;  // ❌
}

修正後 (正確)

// domain/service/OrderDomainService.java
package com.example.domain.service;

import com.example.domain.repository.OrderRepository;  // ✅ 介面

public class OrderDomainService {
    private final OrderRepository repository;  // ✅ 依賴介面
}

// domain/repository/OrderRepository.java
package com.example.domain.repository;

public interface OrderRepository {  // ✅ 純介面
    Order findById(OrderId id);
    void save(Order order);
}

// infrastructure/persistence/repository/JpaOrderRepository.java
package com.example.infrastructure.persistence.repository;

import org.springframework.stereotype.Repository;  // ✅ 在 Infrastructure
import com.example.domain.repository.OrderRepository;

@Repository
public class JpaOrderRepository implements OrderRepository {
    // JPA 實作
}

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

enforce-contract

No summary provided by upstream source.

Repository SourceNeeds Review
General

spec-compliance-validator

No summary provided by upstream source.

Repository SourceNeeds Review
General

coding-standards

No summary provided by upstream source.

Repository SourceNeeds Review
General

saga-orchestrator

No summary provided by upstream source.

Repository SourceNeeds Review