Phase 13.1 CI/CD Integration: - #76 workflow_run handler for CI failure diagnosis - #77 SignOz log query (query_logs, error_logs_summary MCP) - #78 CIAutoRepairService with risk-based execution decisions Phase 13.3 Smart Routing: - #85 Intent Classifier v2.0 (rule engine + LLM fallback) - #86 Complexity Scorer (9-dimension scoring) - #87 AI Router v3.0 (routing decision matrix) - #88 Token Counter (OTEL + Langfuse integration) New files: - services/ci_auto_repair.py (risk stratification) - services/model_registry.py (centralized model config) - services/token_counter.py (677 lines) - Skill 08: Model Router Expert - Skill 09: Strangler Pattern Expert - ADR-023: Smart Routing Architecture - ADR-024: API Layer Architecture Tests: - phase11-conversational.spec.ts (E2E tests) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
ADR-024: API 分層架構 (Phase 16 絞殺者模式)
| 項目 | 內容 |
|---|---|
| 狀態 | ✅ 已採用 |
| 日期 | 2026-03-26 |
| 決策者 | 首席架構師 + 統帥 |
| Phase | Phase 16 |
背景
Phase 16 架構大掃除需要明確的 API 分層規範,以支援絞殺者模式 (Strangler Fig Pattern) 的漸進式重構。
當前問題:
- Router 層存在業務邏輯 (32 項違規)
- 配置分散在多處
- 缺乏明確的層級邊界
決策
採用 四層架構 標準:
┌─────────────────────────────────────────────────┐
│ Router Layer (api/v1/*.py) │
│ - HTTP 轉發 ONLY │
│ - 參數驗證 (Pydantic) │
│ - 權限檢查 (Depends) │
│ - ❌ 禁止: Redis/DB/外部 API 直接呼叫 │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Service Layer (services/*.py) │
│ - 業務邏輯 │
│ - 外部 API 封裝 │
│ - 快取策略 │
│ - ✅ 可呼叫: Repository, 其他 Service │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Repository Layer (repositories/*.py) │
│ - 資料存取抽象 │
│ - SQL/ORM 操作 │
│ - Redis 快取 │
│ - ✅ 可呼叫: Model, Redis, PostgreSQL │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Model Layer (models/*.py) │
│ - Pydantic Schema │
│ - SQLAlchemy ORM │
│ - 純資料結構,無邏輯 │
└─────────────────────────────────────────────────┘
Router 層禁止清單
# ❌ 禁止在 Router 層做的事
# 1. 直接 Redis 存取
from src.core.redis_client import get_redis # ❌
# 2. 直接 DB Session
from src.db.base import get_session # ❌
# 3. 直接外部 API 呼叫
async with httpx.AsyncClient() as client: # ❌
response = await client.get(external_url)
# 4. 內嵌 Lua 腳本
LUA_SCRIPT = """...""" # ❌
# 5. 複雜業務邏輯 (>10 行)
if condition1 and condition2: # ❌
# 複雜處理...
Router 層允許清單
# ✅ Router 層可以做的事
# 1. 參數驗證
@router.get("/items/{item_id}")
async def get_item(
item_id: str = Path(...),
limit: int = Query(default=10, ge=1, le=100),
) -> ItemResponse:
# 2. 權限檢查
async def get_item(
current_user: User = Depends(get_current_user),
):
# 3. 呼叫 Service
service = get_item_service()
result = await service.get_item(item_id)
# 4. 回傳轉換 (簡單)
return ItemResponse.from_orm(result)
絞殺者模式四階段
Phase 1: Identify (識別)
├── 標記現有違規代碼
├── 建立 Service 介面
└── 不改變行為
Phase 2: Deprecate (標記棄用)
├── 新代碼使用 Service
├── 舊代碼加 @deprecated
└── 監控舊路徑使用量
Phase 3: Migrate (遷移)
├── 逐步遷移到 Service
├── 每次遷移有測試覆蓋
└── 回滾計畫就緒
Phase 4: Remove (移除)
├── 確認無流量
├── 移除舊代碼
└── 更新文檔
與 leWOOOgo 積木化的關係
leWOOOgo 六大積木 API 四層對應
─────────────────────────────────────
BRAIN (決策) → Service Layer
ACTION (執行) → Service + Repository
SENSE (感知) → Repository Layer
MEMORY (記憶) → Repository Layer
OUTPUT (輸出) → Service Layer
SAFETY (安全) → Router (Depends) + Service
回滾策略
# 功能開關 (core/config.py)
USE_NEW_LAYER: bool = Field(
default=False,
description="True=新分層, False=舊版內嵌",
)
# 回滾指令
kubectl set env deployment/awoooi-api USE_NEW_LAYER=false
後果
正面
- 清晰的層級邊界
- 可測試性提升 (每層獨立測試)
- 漸進式遷移,低風險
負面
- 短期開發成本增加
- 需要團隊學習新規範
相關文件
- ADR-005: BFF Architecture
- ADR-003: leWOOOgo Module Architecture
feedback_strangler_fig_pattern.mdreference_phase16_architecture.md