Files
awoooi/docs/adr/ADR-005-bff-architecture.md
OG T 7478dc0254 feat(phase6-9): Complete modular architecture and Agent Teams
Phase 6.4 - Modular Architecture:
- Add lewooogo-brain adapters for LLM providers
- Add lewooogo-data dual memory (Redis + PostgreSQL)
- Implement consensus engine for multi-agent decisions
- Add incident memory service for historical context

Phase 9 - Agent Teams (Claude Agent SDK):
- Add base agent class with Claude Sonnet 4 integration
- Implement action planner, blast radius, and security agents
- Add agent API endpoints and proposal workflow
- Integrate ADR-009 OpenClaw Agent Teams architecture

DevOps & CI/CD:
- Add GitHub Actions CI/CD workflows (ci.yaml, cd.yaml)
- Add pre-commit hooks and secrets baseline
- Add docker-compose for local development
- Update Kubernetes network policies

Frontend Improvements:
- Add auto-healing error boundary component
- Update i18n messages for agent features
- Enhance dual-state incident card with execution feedback

Documentation:
- Add 7 ADRs covering MCP, design system, architecture decisions
- Update ARCHITECTURE_MEMORY.md with modular design
- Add GLOBAL_RULES.md and SOUL.md for project identity

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 18:40:36 +08:00

6.3 KiB

ADR-005: 導入 BFF (Backend-For-Frontend) API 閘道模式

狀態: Accepted 日期: 2026-03-19 決策者: CTO + CIO

背景

AWOOOI 的底層是由 leWOOOgo Engine 驅動的微服務/Plugin 架構。如果讓 Next.js 前端直接呼叫:

  • 多個分散的 Plugin API
  • Ollama / Claude API
  • PostgreSQL / Redis
  • K8s API

會導致:

  1. 前端邏輯過於肥大
  2. 極高的資安外洩風險
  3. 難以實施統一的身分驗證與權限控制

決策

強制實施 BFF (Backend-For-Frontend) 架構

┌─────────────────────────────────────────────────────────────────┐
│                        AWOOOI 架構                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────┐         ┌─────────────────┐                       │
│   │ Next.js │ ──────→ │  FastAPI BFF    │                       │
│   │ 前端    │ HTTPS   │  Gateway        │                       │
│   └─────────┘         └────────┬────────┘                       │
│                                │                                │
│            ┌───────────────────┼───────────────────┐            │
│            ↓                   ↓                   ↓            │
│   ┌─────────────┐     ┌─────────────┐     ┌─────────────┐       │
│   │ leWOOOgo    │     │ ClawBot     │     │ PostgreSQL  │       │
│   │ Plugins     │     │ (Ollama)    │     │ Redis       │       │
│   └─────────────┘     └─────────────┘     └─────────────┘       │
│                                                                 │
│   ════════════════════════════════════════════════════════════  │
│                    DMZ (前端無法直達)                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

核心規則

規則 說明
單一入口 前端只能打 https://api.awoooi.wooo.work/v1/*
禁止直連 前端禁止直連 PostgreSQL、Redis、K8s、Ollama
身分驗證 所有請求經 BFF JWT 驗證
資料脫敏 Privacy Shield 在 BFF 層攔截機敏資料

BFF 層職責

# apps/api/src/routes/agent.py

from fastapi import APIRouter, Depends
from src.auth import require_auth
from src.privacy import PrivacyShield
from src.services import clawbot_client, approval_service

router = APIRouter(prefix="/agent", tags=["Agent"])

@router.post("/chat")
async def chat_with_agent(
    request: ChatRequest,
    user: User = Depends(require_auth),  # 1. 身分驗證
):
    # 2. 資料脫敏
    sanitized = PrivacyShield.sanitize(request.message)

    # 3. 聚合多個後端服務
    response = await clawbot_client.chat(sanitized, user_id=user.id)

    # 4. 判斷是否需要 Approval
    if response.requires_action:
        approval = await approval_service.create(
            action=response.suggested_action,
            user_id=user.id,
        )
        response.approval_id = approval.id

    return response

禁止事項

// ❌ 禁止:前端直連資料庫
const client = new Client({ connectionString: 'postgresql://...' })

// ❌ 禁止:前端直接呼叫 Ollama
const response = await fetch('http://192.168.0.188:11434/api/generate')

// ❌ 禁止:前端直接操作 K8s
const k8s = new KubeConfig()

// ✅ 正確:透過 BFF API
const response = await fetch('https://api.awoooi.wooo.work/v1/agent/chat', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${token}` },
  body: JSON.stringify({ message: '...' }),
})

理由

1. Zero Trust 網路隔離

元件 網路可達性
Next.js (前端) Public Internet
FastAPI BFF DMZ (僅接受前端)
PostgreSQL Internal Only
Redis Internal Only
Ollama Internal Only
K8s API Internal Only

2. 統一關注點

關注點 處理位置
身分驗證 BFF Middleware
權限檢查 BFF Dependency
請求限流 BFF / Nginx
資料脫敏 BFF Privacy Shield
審計日誌 BFF Logger

3. 資料聚合

# 一個 API 呼叫 = 多個後端服務聚合
@router.get("/dashboard")
async def get_dashboard(user: User = Depends(require_auth)):
    # 平行取得多個資料源
    agent_status, pending_approvals, recent_alerts = await asyncio.gather(
        clawbot_client.get_status(),
        approval_service.list_pending(user.id),
        alert_service.list_recent(limit=10),
    )

    return DashboardResponse(
        agent=agent_status,
        approvals=pending_approvals,
        alerts=recent_alerts,
    )

後果

優點

  • Zero Trust 真正的網路隔離
  • 前端精簡 只負責渲染 UI
  • 統一治理 所有安全策略集中管理
  • 可觀測性 單一入口易於監控

缺點

  • 開發成本 新功能需在 BFF 層多寫一層
  • 延遲增加 多一層網路跳躍 (~1-5ms)

風險

風險 緩解措施
BFF 成為瓶頸 水平擴展 + Redis 快取
開發速度下降 OpenAPI 自動生成 Client SDK

參考

  • BFF Pattern
  • api-contract.yaml (BFF 對外契約)
  • ADR-001: MCP Protocol (內部服務整合)