Files
awoooi/docs/api/API_DEVELOPMENT_SOP.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

11 KiB
Raw Permalink Blame History

AWOOOI API 開發 SOP

版本: v1.0 建立日期: 2026-03-20 負責人: CTO 狀態: Phase 0 草稿


概述

此文件定義 AWOOOI 所有 API 端點的開發標準流程,確保 Contract-First 原則與 CI 強制檢查能夠有效執行。


API 開發流程

1. 設計階段 (Design)

┌─────────────────────────────────────────────────────────────┐
│ Step 1: OpenAPI 定義                                        │
├─────────────────────────────────────────────────────────────┤
│ 位置: docs/api/openapi.yaml                                 │
│ 工具: Stoplight Studio / VS Code OpenAPI Editor             │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ Step 2: 端點文檔 (Markdown)                                  │
├─────────────────────────────────────────────────────────────┤
│ 位置: docs/api/endpoints/{module}/{endpoint}.md             │
│ 內容: 用途說明、請求範例、回應範例、錯誤碼                    │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ Step 3: PR Review + Approval                                │
├─────────────────────────────────────────────────────────────┤
│ 審核者: CTO / CISO (安全相關 API)                            │
│ 檢查項: 命名規範、版本策略、錯誤處理、安全考量                 │
└─────────────────────────────────────────────────────────────┘

2. 實作階段 (Implementation)

# apps/api/app/routers/{module}.py

from fastapi import APIRouter, Depends, HTTPException, status
from app.schemas.{module} import {RequestModel}, {ResponseModel}
from app.services.{module} import {ServiceClass}
from app.core.deps import get_current_user, rate_limit
from app.core.cache import cache_response

router = APIRouter(prefix="/v1/{module}", tags=["{module}"])

@router.get(
    "/{endpoint}",
    response_model={ResponseModel},
    summary="端點摘要",
    description="詳細說明",
    responses={
        200: {"description": "成功"},
        400: {"description": "請求格式錯誤"},
        401: {"description": "未授權"},
        403: {"description": "權限不足"},
        404: {"description": "資源不存在"},
        429: {"description": "請求過於頻繁"},
        500: {"description": "伺服器錯誤"},
    }
)
@cache_response(ttl=60)  # 快取策略
@rate_limit(requests=100, window=60)  # 限流策略
async def endpoint_name(
    request: {RequestModel},
    current_user: User = Depends(get_current_user),
    service: {ServiceClass} = Depends()
):
    """
    端點實作邏輯
    """
    pass

3. 測試階段 (Testing)

# apps/api/tests/test_{module}.py

import pytest
from httpx import AsyncClient
from app.main import app

class Test{Module}API:
    """
    測試命名規範: test_{method}_{endpoint}_{scenario}
    """

    @pytest.mark.asyncio
    async def test_get_endpoint_success(self, client: AsyncClient, auth_headers: dict):
        response = await client.get("/v1/{module}/{endpoint}", headers=auth_headers)
        assert response.status_code == 200
        assert "data" in response.json()

    @pytest.mark.asyncio
    async def test_get_endpoint_unauthorized(self, client: AsyncClient):
        response = await client.get("/v1/{module}/{endpoint}")
        assert response.status_code == 401

    @pytest.mark.asyncio
    async def test_get_endpoint_not_found(self, client: AsyncClient, auth_headers: dict):
        response = await client.get("/v1/{module}/nonexistent", headers=auth_headers)
        assert response.status_code == 404

API 版本策略

URL 版本控制

https://api.awoooi.wooo.work/v1/...  # 目前版本
https://api.awoooi.wooo.work/v2/...  # 未來版本 (重大變更時)

版本升級規則

變更類型 版本影響 範例
新增端點 不變 新增 GET /v1/metrics/custom
新增可選欄位 不變 Response 新增 metadata 欄位
移除/重命名欄位 升版 user_iduserId
變更回應結構 升版 陣列 → 分頁物件
變更認證方式 升版 Bearer → OAuth2

棄用流程

  1. 通知 (v1.x): 在回應 Header 加入 Deprecation: true + Sunset: 2026-06-01
  2. 文檔標記: OpenAPI 加入 deprecated: true
  3. 過渡期: 至少 3 個月
  4. 移除: 完全移除舊端點

命名規範

URL 路徑

# ✅ 正確
GET    /v1/hosts                    # 列表
GET    /v1/hosts/{id}               # 單一資源
POST   /v1/hosts                    # 建立
PUT    /v1/hosts/{id}               # 完整更新
PATCH  /v1/hosts/{id}               # 部分更新
DELETE /v1/hosts/{id}               # 刪除

# ✅ 子資源
GET    /v1/hosts/{id}/metrics       # 主機的指標
POST   /v1/hosts/{id}/actions/scan  # 動作 (非 CRUD)

# ❌ 錯誤
GET    /v1/getHosts                 # 動詞命名
GET    /v1/host_list                # 底線 + 複數不一致
POST   /v1/hosts/create             # 冗餘動詞

查詢參數

# 分頁
?page=1&limit=20

# 排序
?sort=created_at&order=desc

# 篩選
?status=active&host_id=h-001

# 搜尋
?q=keyword

# 時間範圍
?start_time=2026-03-01T00:00:00Z&end_time=2026-03-20T23:59:59Z

請求/回應欄位

// ✅ 正確: camelCase (JSON 標準)
{
  "hostId": "h-001",
  "hostName": "web-server-01",
  "createdAt": "2026-03-20T10:00:00Z",
  "isActive": true
}

// ❌ 錯誤: snake_case (Python 內部使用)
{
  "host_id": "h-001",
  "host_name": "web-server-01"
}

回應格式

成功回應

// 單一資源
{
  "data": {
    "id": "h-001",
    "name": "web-server-01",
    "status": "healthy"
  },
  "meta": {
    "requestId": "req-abc123",
    "timestamp": "2026-03-20T10:00:00Z"
  }
}

// 列表 (分頁)
{
  "data": [
    {"id": "h-001", "name": "web-server-01"},
    {"id": "h-002", "name": "web-server-02"}
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  },
  "meta": {
    "requestId": "req-abc123",
    "timestamp": "2026-03-20T10:00:00Z"
  }
}

錯誤回應

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "請求參數驗證失敗",
    "details": [
      {
        "field": "email",
        "message": "必須為有效的電子郵件格式"
      }
    ]
  },
  "meta": {
    "requestId": "req-abc123",
    "timestamp": "2026-03-20T10:00:00Z"
  }
}

錯誤碼對照表

HTTP Status Error Code 說明
400 VALIDATION_ERROR 請求參數驗證失敗
400 INVALID_FORMAT 請求格式錯誤
401 UNAUTHORIZED 未提供認證資訊
401 TOKEN_EXPIRED Token 已過期
403 FORBIDDEN 權限不足
404 NOT_FOUND 資源不存在
409 CONFLICT 資源衝突
422 UNPROCESSABLE_ENTITY 語意錯誤
429 RATE_LIMITED 請求過於頻繁
500 INTERNAL_ERROR 伺服器內部錯誤
503 SERVICE_UNAVAILABLE 服務暫時不可用

安全規範

認證

Authorization: Bearer <jwt_token>

必要 Headers

Content-Type: application/json
Accept: application/json
X-Request-ID: <uuid>  # 用於追蹤
X-Source: awoooi      # 識別來源 (Kali Scanner 需要)

敏感資料處理

# ❌ 禁止: 回應中包含密碼、Token
{
  "user": {
    "password": "hashed_value",  # 禁止
    "apiKey": "sk-xxx"           # 禁止
  }
}

# ✅ 正確: 脫敏處理
{
  "user": {
    "hasPassword": true,
    "apiKeyPrefix": "sk-***xxx"
  }
}

日誌脫敏

# 自動脫敏欄位
SENSITIVE_FIELDS = [
    "password", "token", "api_key", "secret",
    "authorization", "cookie", "credit_card"
]

# 日誌輸出
# ✅ {"user": "admin", "password": "[REDACTED]"}
# ❌ {"user": "admin", "password": "actual_password"}

快取策略

TTL 分層

資料類型 TTL 說明
靜態配置 1 小時 系統設定、選單
聚合數據 5 分鐘 Dashboard 統計
即時數據 30 秒 主機狀態、指標
無快取 0 審計日誌、敏感操作

快取 Key 規範

awoooi:{version}:{module}:{resource}:{id}:{params_hash}

# 範例
awoooi:v1:hosts:list:abc123
awoooi:v1:hosts:detail:h-001
awoooi:v1:metrics:dashboard:user-001:7d

CI 檢查項目

自動化檢查

檢查項 工具 失敗處理
OpenAPI Schema 驗證 spectral 阻擋合併
OpenAPI ↔ 程式碼一致性 openapi-diff 阻擋合併
端點文檔存在性 自訂腳本 阻擋合併
測試覆蓋率 > 80% pytest-cov 阻擋合併
安全掃描 bandit 警告

PR Checklist

## API 變更 Checklist

- [ ] OpenAPI 規格已更新 (`docs/api/openapi.yaml`)
- [ ] 端點文檔已更新 (`docs/api/endpoints/...`)
- [ ] 單元測試已撰寫 (覆蓋率 > 80%)
- [ ] 錯誤處理已實作
- [ ] 快取策略已定義
- [ ] 限流規則已設定
- [ ] 日誌已加入 (不含敏感資料)
- [ ] CISO 已審核 (安全相關 API)

文檔工具

內部開發

  • Swagger UI: http://localhost:8000/docs
  • 用途: 開發階段測試、除錯

對外文檔

  • Scalar: https://api.awoooi.wooo.work/scalar
  • 風格: Nothing.tech 純白主題
  • 用途: 外部開發者文檔

變更記錄

日期 版本 變更 作者
2026-03-20 v1.0 初版建立 CTO

此文件由 CTO 維護API 開發者必須遵守此 SOP。