refactor(api): Phase 22 P0 leWOOOgo 模組化修復
Some checks failed
E2E Health Check / e2e-health (push) Has been cancelled

Router 層禁止直接 httpx.AsyncClient,抽取到 Service 層:

新增 Services:
- OpenClawHttpService: Error 分析/Code Review/CI 診斷
- GitHubApiService: PR Diff 取得
- HealthCheckService: HTTP/PostgreSQL/Redis 健康檢查

修改 Routers:
- sentry_webhook.py: 使用 OpenClawHttpService
- github_webhook.py: 使用 GitHubApiService + OpenClawHttpService
- health.py: 使用 HealthCheckService

遵循規範:
- Skill 09: Router 層禁止直接外部 API 呼叫
- feedback_lewooogo_modular_enforcement.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-31 16:06:35 +08:00
parent 2f02f1523a
commit 8313a3787b
6 changed files with 730 additions and 205 deletions

View File

@@ -16,13 +16,11 @@ AWOOOI API - Sentry Webhook Handler
import uuid
import httpx
import structlog
from fastapi import APIRouter, BackgroundTasks, HTTPException, Request
from pydantic import BaseModel
from src.core.circuit_breaker import get_openclaw_guard
from src.core.config import settings
from src.core.metrics import (
record_alert_chain_failure,
record_alert_chain_success,
@@ -37,6 +35,7 @@ from src.models.approval import (
)
from src.services.anomaly_counter import get_anomaly_counter
from src.services.approval_db import get_approval_service
from src.services.openclaw_http_service import get_openclaw_http_service
from src.services.sentry_service import get_sentry_service
from src.services.telegram_gateway import get_telegram_gateway
from src.utils.timezone import now_taipei_iso
@@ -287,6 +286,8 @@ async def call_openclaw_analyzer(error_context: dict) -> ErrorAnalysisResult | N
優先使用 Ollama (本地,零成本)
Fallback: Claude (高嚴重性)
Phase 22 P0 修復: 使用 OpenClawHttpService (2026-03-31)
"""
guard = get_openclaw_guard()
@@ -301,28 +302,21 @@ async def call_openclaw_analyzer(error_context: dict) -> ErrorAnalysisResult | N
# ADR-038 Layer 2: Concurrency Semaphore 排隊
async with guard.semaphore:
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(
f"{settings.OPENCLAW_URL}/api/v1/analyze/error",
json={
"error_context": error_context,
"prefer_local": True, # 優先 Ollama
}
)
# Phase 22 P0: 使用 Service 層而非直接 httpx
service = get_openclaw_http_service()
data = await service.analyze_error(
error_context=error_context,
prefer_local=True,
timeout=60.0,
)
if response.status_code == 200:
data = response.json()
guard.record_success()
return ErrorAnalysisResult(**data)
else:
logger.warning(f"OpenClaw returned {response.status_code}")
guard.record_failure()
return None
if data:
guard.record_success()
return ErrorAnalysisResult(**data)
else:
guard.record_failure()
return None
except httpx.TimeoutException:
logger.warning("OpenClaw analysis timeout")
guard.record_failure()
return None
except Exception as e:
logger.exception(f"OpenClaw call failed: {e}")
guard.record_failure()