# 🏛️ DramaLing 架構治理指南

## 🎯 **架構治理目標**

> **核心原則**: 隨著功能增長保持架構清晰，避免技術債務積累

### **治理範圍**
- 🏗️ **架構邊界**: 服務、層次、模組邊界
- 🔗 **依賴管理**: 避免循環依賴和不當耦合
- 📏 **代碼標準**: 統一的編碼規範和模式
- 📊 **品質指標**: 可量化的架構健康度

---

## 🛡️ **架構防護措施**

### **1. 強制性架構規則**

#### **📁 目錄結構規則**
```bash
# ✅ 允許的依賴方向
Controllers → Services/Domain → Services/Infrastructure → Repositories → Data

# ❌ 禁止的依賴
Infrastructure → Domain  # 基礎設施不能依賴業務邏輯
Repositories → Services  # 數據層不能依賴服務層
Controllers → Repositories # 控制器不能直接訪問數據層
```

#### **🔧 服務命名約定**
```csharp
// ✅ 正確命名
public interface IFlashcardService    // I + 業務名 + Service
public class FlashcardService         // 業務名 + Service

// ❌ 錯誤命名
public class FlashcardManager         // 避免 Manager
public class FlashcardHelper          // 避免 Helper
public class FlashcardUtils           // 避免 Utils
```

#### **🎯 單一職責驗證**
```csharp
// ✅ 職責清晰
public interface IFlashcardService
{
    // 只處理詞卡相關業務邏輯
}

// ❌ 職責混雜
public interface IFlashcardAndUserService
{
    // 混合多個業務領域
}
```

### **2. 自動化檢查工具**

#### **依賴分析腳本**
```bash
#!/bin/bash
# architecture-check.sh

echo "🔍 檢查架構規則..."

# 檢查循環依賴
echo "檢查循環依賴..."
find . -name "*.cs" -exec grep -l "using.*Services" {} \; | \
grep -E "(Repositories|Data)" && echo "❌ 發現不當依賴" || echo "✅ 依賴方向正確"

# 檢查過大的服務
echo "檢查服務大小..."
find Services -name "*.cs" -exec wc -l {} + | \
awk '$1 > 300 {print "⚠️ " $2 " 超過300行，考慮拆分"}'

# 檢查介面覆蓋率
echo "檢查介面覆蓋率..."
SERVICE_FILES=$(find Services -name "*Service.cs" | wc -l)
INTERFACE_FILES=$(find Services -name "I*Service.cs" | wc -l)
echo "服務介面覆蓋率: $INTERFACE_FILES/$SERVICE_FILES"
```

#### **架構測試**
```csharp
// Tests/Architecture/ArchitectureTests.cs
[Test]
public void Services_Should_Not_Depend_On_Repositories()
{
    var assembly = typeof(Program).Assembly;
    var serviceTypes = assembly.GetTypes()
        .Where(t => t.Namespace?.Contains("Services") == true)
        .Where(t => !t.Namespace?.Contains("Infrastructure") == true);

    foreach (var serviceType in serviceTypes)
    {
        var dependencies = serviceType.GetConstructors()
            .SelectMany(c => c.GetParameters())
            .Select(p => p.ParameterType);

        var hasBadDependency = dependencies.Any(d =>
            d.Namespace?.Contains("Repositories") == true);

        Assert.IsFalse(hasBadDependency,
            $"Service {serviceType.Name} should not depend on Repository directly");
    }
}
```

### **3. 代碼審查清單**

#### **每次 PR 必檢項目**
```markdown
## 🔍 架構審查清單

### 服務設計
- [ ] 服務職責單一且明確
- [ ] 有對應的介面定義
- [ ] 依賴注入正確使用
- [ ] 錯誤處理一致

### 依賴關係
- [ ] 無循環依賴
- [ ] 依賴方向正確 (向上依賴)
- [ ] 無跨層直接依賴
- [ ] 介面隔離原則

### 命名規範
- [ ] 服務命名遵循約定
- [ ] 方法名表達業務意圖
- [ ] 參數和返回類型合理
- [ ] 無魔法數字或字串

### 測試覆蓋
- [ ] 新服務有對應測試
- [ ] 核心業務邏輯有測試
- [ ] 異常情況有測試
- [ ] 測試名稱清晰
```

---

## 📊 **架構健康度指標**

### **可量化指標**

#### **1. 服務複雜度**
```bash
# 服務行數分佈 (理想範圍)
- 小型服務: < 100 行 (70%)
- 中型服務: 100-300 行 (25%)
- 大型服務: > 300 行 (5%)
```

#### **2. 依賴深度**
```bash
# 依賴鏈長度 (理想 < 4 層)
Controller → Service → Repository → DbContext
```

#### **3. 介面覆蓋率**
```bash
# 目標: 90%+ 服務有對應介面
介面覆蓋率 = (介面數量 / 服務數量) × 100%
```

#### **4. 測試覆蓋率**
```bash
# 服務層測試覆蓋率目標
- 單元測試: 80%+
- 集成測試: 60%+
- 端到端測試: 主要業務流程 100%
```

### **定期健康檢查**

#### **每週檢查項目**
```bash
# weekly-architecture-check.sh
#!/bin/bash

echo "📊 週架構健康檢查 - $(date)"
echo "=================================="

# 1. 代碼複雜度
echo "1. 代碼複雜度分析"
find Services -name "*.cs" -exec wc -l {} + | \
awk '{total+=$1; count++} END {print "平均服務大小:", int(total/count), "行"}'

# 2. 依賴關係檢查
echo "2. 依賴關係檢查"
./scripts/check-dependencies.sh

# 3. 測試覆蓋率
echo "3. 測試覆蓋率"
dotnet test --collect:"XPlat Code Coverage" --logger:console

# 4. 性能指標
echo "4. 快取效能檢查"
curl -s http://localhost:5008/api/ai/stats | jq '.data.cacheHitRate'

echo "=================================="
```

---

## 🔧 **實用工具和腳本**

### **1. 新服務創建模板**

#### **服務生成腳本**
```bash
#!/bin/bash
# create-service.sh

SERVICE_NAME=$1
DOMAIN=$2

if [ -z "$SERVICE_NAME" ] || [ -z "$DOMAIN" ]; then
    echo "用法: ./create-service.sh FlashcardService Learning"
    exit 1
fi

# 創建介面
cat > "Services/Domain/$DOMAIN/I${SERVICE_NAME}.cs" << EOF
namespace DramaLing.Api.Services.Domain.${DOMAIN};

/// <summary>
/// ${SERVICE_NAME} 服務介面
/// </summary>
public interface I${SERVICE_NAME}
{
    // TODO: 定義業務方法
}
EOF

# 創建實作
cat > "Services/Domain/$DOMAIN/${SERVICE_NAME}.cs" << EOF
namespace DramaLing.Api.Services.Domain.${DOMAIN};

/// <summary>
/// ${SERVICE_NAME} 服務實作
/// </summary>
public class ${SERVICE_NAME} : I${SERVICE_NAME}
{
    private readonly ILogger<${SERVICE_NAME}> _logger;

    public ${SERVICE_NAME}(ILogger<${SERVICE_NAME}> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    // TODO: 實作業務方法
}
EOF

echo "✅ 服務 $SERVICE_NAME 已在 $DOMAIN 領域創建"
```

### **2. 依賴分析工具**

#### **依賴關係可視化**
```python
# dependency-analyzer.py
import os
import re
from graphviz import Digraph

def analyze_dependencies():
    """分析服務依賴關係並生成視覺化圖表"""

    dependencies = {}

    # 掃描所有 C# 文件
    for root, dirs, files in os.walk("Services"):
        for file in files:
            if file.endswith(".cs"):
                with open(os.path.join(root, file), 'r') as f:
                    content = f.read()

                # 提取依賴關係
                service_name = file.replace(".cs", "")
                deps = re.findall(r'private readonly I(\w+Service)', content)
                dependencies[service_name] = deps

    # 生成依賴圖
    dot = Digraph(comment='Service Dependencies')

    for service, deps in dependencies.items():
        dot.node(service)
        for dep in deps:
            dot.edge(service, dep)

    dot.render('architecture/service-dependencies', format='png')
    print("✅ 依賴關係圖已生成: architecture/service-dependencies.png")

if __name__ == "__main__":
    analyze_dependencies()
```

### **3. 代碼品質守衛**

#### **Git Pre-commit Hook**
```bash
#!/bin/bash
# .git/hooks/pre-commit

echo "🔍 執行架構檢查..."

# 檢查是否有 TODO 標記
if git diff --cached --name-only | xargs grep -l "TODO.*:" > /dev/null; then
    echo "⚠️ 發現 TODO 標記，請確認是否應該完成"
    git diff --cached --name-only | xargs grep -n "TODO.*:"
fi

# 檢查服務大小
LARGE_FILES=$(git diff --cached --name-only | grep "Service\.cs$" | xargs wc -l | awk '$1 > 300 {print $2}')
if [ ! -z "$LARGE_FILES" ]; then
    echo "❌ 以下服務文件過大 (>300行)，請考慮拆分:"
    echo "$LARGE_FILES"
    exit 1
fi

# 檢查命名規範
INVALID_NAMES=$(git diff --cached --name-only | grep -E "(Helper|Utils|Manager)\.cs$")
if [ ! -z "$INVALID_NAMES" ]; then
    echo "❌ 發現不符規範的命名:"
    echo "$INVALID_NAMES"
    echo "建議使用 Service 後綴"
    exit 1
fi

echo "✅ 架構檢查通過"
```

---

## 📚 **架構決策記錄 (ADR)**

### **ADR 模板**
```markdown
# ADR-001: 採用三層快取架構

## 狀態
已接受 (2025-09-23)

## 背景
需要降低 AI API 調用成本，提升響應速度

## 決策
採用三層快取架構：Memory → Distributed → Database

## 後果
- ✅ 大幅提升性能 (57,200倍)
- ✅ 降低運營成本 (67%)
- ⚠️ 增加系統複雜度
- ⚠️ 快取一致性需要管理

## 替代方案
1. 單層快取 - 性能提升有限
2. 只用分散式快取 - 需要額外基礎設施
```

### **重要決策記錄**
1. **ADR-001**: 三層快取架構
2. **ADR-002**: Repository Pattern 採用
3. **ADR-003**: 領域驅動服務設計
4. **ADR-004**: AI 提供商抽象層

---

## 🚦 **架構演進策略**

### **Phase 1: 穩定基礎 (當前)**
- ✅ 核心架構模式確立
- ✅ 服務邊界定義
- ✅ 快取系統整合
- 🔄 測試框架建立

### **Phase 2: 品質提升 (1-2週)**
```
目標:
- 80%+ 服務有介面
- 80%+ 測試覆蓋率
- 架構檢查自動化
- 依賴關係可視化
```

### **Phase 3: 監控和治理 (1個月)**
```
目標:
- 實時架構監控
- 技術債務追蹤
- 自動化品質閥門
- 性能基準監控
```

### **Phase 4: 微服務準備 (3個月)**
```
目標:
- 服務邊界驗證
- 通訊協定定義
- 數據一致性策略
- 部署自動化
```

---

## 🎯 **具體執行方案**

### **📅 每日實踐**

#### **開發者清單**
```markdown
開發新功能前：
- [ ] 確定功能屬於哪個領域 (Learning/Analysis/User)
- [ ] 檢查是否需要新服務或擴展現有服務
- [ ] 設計介面定義 (先介面後實作)
- [ ] 確認依賴關係符合架構原則

提交代碼前：
- [ ] 運行架構檢查腳本
- [ ] 確保新代碼有對應測試
- [ ] 檢查方法複雜度 (< 20行為佳)
- [ ] 驗證命名規範
```

#### **代碼審查要點**
```markdown
審查重點：
- 🎯 **業務邏輯位置**: 是否在正確的服務層？
- 🔗 **依賴方向**: 是否符合分層架構？
- 🧪 **可測試性**: 是否容易寫測試？
- 📏 **複雜度**: 方法是否過於複雜？
- 🏷️ **命名**: 是否表達清晰的業務意圖？
```

### **📊 品質看板**

#### **架構健康度儀表板**
```
🏗️ 架構健康度: 85% ↗️

📦 服務數量: 12 個
🎯 介面覆蓋率: 89% (目標: 90%)
🧪 測試覆蓋率: 73% (目標: 80%)
🔗 依賴違規: 0 個
📏 平均服務大小: 156 行 (良好)

⚠️ 需要關注:
- FlashcardController 過於複雜 (建議重構)
- AudioService 缺少單元測試
```

### **🚨 警報系統**

#### **架構違規警報**
```csharp
// 架構守衛：在 CI/CD 中執行
public class ArchitectureGuard
{
    [Test]
    public void Architecture_Should_Follow_Rules()
    {
        var violations = new List<string>();

        // 檢查服務大小
        CheckServiceSize(violations);

        // 檢查依賴方向
        CheckDependencyDirection(violations);

        // 檢查命名規範
        CheckNamingConvention(violations);

        if (violations.Any())
        {
            Assert.Fail("架構違規:\n" + string.Join("\n", violations));
        }
    }
}
```

---

## 🛠️ **重構安全指南**

### **安全重構步驟**
1. **📋 評估影響**: 列出受影響的組件
2. **🧪 增加測試**: 確保重構前有足夠測試覆蓋
3. **🔄 小步重構**: 每次只改變一個小部分
4. **✅ 驗證功能**: 每步都驗證功能正常
5. **📊 監控指標**: 確保性能沒有退化

### **重構檢查清單**
```markdown
重構前：
- [ ] 當前功能是否有測試覆蓋？
- [ ] 重構範圍是否定義清楚？
- [ ] 是否有回滾計劃？

重構中：
- [ ] 每個小步驟都能編譯通過？
- [ ] 測試是否持續通過？
- [ ] API 介面是否保持兼容？

重構後：
- [ ] 功能是否完全正常？
- [ ] 性能是否符合預期？
- [ ] 文檔是否更新？
```

---

## 📖 **最佳實踐總結**

### **🎯 核心原則**
1. **依賴倒置**: 依賴抽象，不依賴具體
2. **單一職責**: 每個服務只做一件事
3. **介面隔離**: 介面精簡，不強迫依賴不需要的方法
4. **開放封閉**: 對擴展開放，對修改封閉

### **🚀 實踐建議**
1. **先介面後實作**: 設計 API 時優先考慮介面
2. **小步快跑**: 頻繁提交小的改進，避免大重構
3. **測試先行**: 新功能先寫測試，後寫實作
4. **持續監控**: 定期檢查架構健康度

### **⚠️ 常見陷阱**
1. **過度抽象**: 不要為了抽象而抽象
2. **功能漏出**: 業務邏輯洩漏到控制器或基礎設施層
3. **依賴混亂**: 服務間循環依賴
4. **測試缺失**: 重構時沒有足夠的測試保護

---

## 🎓 **團隊執行指南**

### **新成員指導**
1. 📖 閱讀架構文檔
2. 🏗️ 理解分層原則
3. 🧪 學習測試模式
4. 🔧 熟悉開發工具

### **日常維護**
1. **每日**: 代碼審查關注架構原則
2. **每週**: 運行架構健康檢查
3. **每月**: 評估技術債務和重構需求
4. **每季**: 架構演進規劃和調整

---

**記住**: 好的架構不是一蹴而就的，需要持續的關注和維護。這套治理體系將幫助您在功能增長的同時保持代碼品質！