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

415 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
```python
# 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)
```python
# 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_id``userId` |
| **變更回應結構** | 升版 | 陣列 → 分頁物件 |
| **變更認證方式** | 升版 | 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
```
### 請求/回應欄位
```json
// ✅ 正確: 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"
}
```
---
## 回應格式
### 成功回應
```json
// 單一資源
{
"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"
}
}
```
### 錯誤回應
```json
{
"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` | 服務暫時不可用 |
---
## 安全規範
### 認證
```http
Authorization: Bearer <jwt_token>
```
### 必要 Headers
```http
Content-Type: application/json
Accept: application/json
X-Request-ID: <uuid> #
X-Source: awoooi # (Kali Scanner )
```
### 敏感資料處理
```python
# ❌ 禁止: 回應中包含密碼、Token
{
"user": {
"password": "hashed_value", # 禁止
"apiKey": "sk-xxx" # 禁止
}
}
# ✅ 正確: 脫敏處理
{
"user": {
"hasPassword": true,
"apiKeyPrefix": "sk-***xxx"
}
}
```
### 日誌脫敏
```python
# 自動脫敏欄位
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
```markdown
## 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。*