feat(api): Phase D-G P0 修正 - Learning Repository 積木化

新增:
- ILearningRepository Protocol (interfaces.py)
- LearningRepository (Redis 持久化層)
- Learning API 端點 (/api/v1/learning/*)
- LearningService.get_recommended_fix() 方法
- LearningService.get_learning_summary() 方法

修正:
- Service 不直接依賴 Redis Client (透過 Repository)
- 符合 leWOOOgo 積木化原則
- 首席架構師審查: 74/100 → 92/100

更新:
- ADR-030: 新增 Phase D-G P0 修正章節
- Skill 02: v1.9 → v2.0
- Runner 修復: 序列建構解決 _runner_file_commands 衝突

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-29 11:03:51 +08:00
parent d15fb7d9f4
commit 50c055b547
11 changed files with 1033 additions and 13 deletions

View File

@@ -317,16 +317,18 @@ jobs:
--from-literal=CLAUDE_API_KEY="${{ secrets.CLAUDE_API_KEY }}" \
--from-literal=NVIDIA_API_KEY="${{ secrets.NVIDIA_API_KEY }}" \
--from-literal=WEBHOOK_HMAC_SECRET="${{ secrets.WEBHOOK_HMAC_SECRET }}" \
--from-literal=SENTRY_DSN="${{ secrets.SENTRY_DSN }}"
--from-literal=SENTRY_DSN="${{ secrets.SENTRY_DSN }}" \
--from-literal=SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"
else
echo "🔄 更新 awoooi-secrets..."
# 使用 patch 更新,確保關鍵配置永遠是最新的
# 2026-03-29 ogt: ADR-036 新增 NVIDIA_API_KEY
# 2026-03-29 ogt: ADR-036 新增 NVIDIA_API_KEY, ADR-037 新增 SENTRY_AUTH_TOKEN
kubectl patch secret awoooi-secrets -n awoooi-prod --type='merge' -p="{
\"stringData\": {
\"OPENCLAW_TG_BOT_TOKEN\": \"${{ secrets.OPENCLAW_TG_BOT_TOKEN }}\",
\"OPENCLAW_TG_CHAT_ID\": \"${{ secrets.OPENCLAW_TG_CHAT_ID }}\",
\"NVIDIA_API_KEY\": \"${{ secrets.NVIDIA_API_KEY }}\"
\"NVIDIA_API_KEY\": \"${{ secrets.NVIDIA_API_KEY }}\",
\"SENTRY_AUTH_TOKEN\": \"${{ secrets.SENTRY_AUTH_TOKEN }}\"
}
}"
fi
@@ -384,6 +386,68 @@ jobs:
# 使用 Python httpx (容器沒有 curl但有 httpx)
kubectl exec -n awoooi-prod $API_POD -c api -- python -c "import httpx; r=httpx.get('http://localhost:8000/api/v1/health', timeout=5); print(r.status_code)" || echo "Health check failed but deployment succeeded"
# =======================================================================
# ADR-037 Wave B.2: Alert Chain Smoke Test
# 2026-03-29: 告警鏈路端到端驗證 (Wave A.6 腳本整合)
# =======================================================================
- name: "Alert Chain Smoke Test (ADR-037)"
run: |
echo "🔍 執行告警鏈路 Smoke Test..."
API_POD=$(kubectl get pods -n awoooi-prod -l app=awoooi-api -o jsonpath='{.items[0].metadata.name}')
# 測試各 Webhook Endpoint
kubectl exec -n awoooi-prod $API_POD -c api -- python -c "
import httpx
import sys
BASE = 'http://localhost:8000'
TIMEOUT = 30
results = []
# 1. Health
try:
r = httpx.get(f'{BASE}/api/v1/health', timeout=TIMEOUT)
results.append(('health', r.status_code == 200))
except Exception as e:
results.append(('health', False))
print(f'Health: {e}')
# 2. Alertmanager Webhook
try:
r = httpx.post(f'{BASE}/api/v1/webhooks/alertmanager', json={
'version': '4', 'status': 'firing',
'alerts': [{'status': 'firing', 'labels': {'alertname': 'E2E_CD_TEST', 'severity': 'info'}}]
}, timeout=TIMEOUT)
results.append(('alertmanager', r.status_code == 200))
except Exception as e:
results.append(('alertmanager', False))
print(f'Alertmanager: {e}')
# 3. SignOz Webhook Health
try:
r = httpx.get(f'{BASE}/api/v1/webhooks/signoz/health', timeout=TIMEOUT)
results.append(('signoz', r.status_code == 200))
except Exception as e:
results.append(('signoz', False))
print(f'SignOz: {e}')
# Summary
passed = sum(1 for _, ok in results if ok)
total = len(results)
print(f'Smoke Test: {passed}/{total} passed')
for name, ok in results:
print(f' {\"✅\" if ok else \"❌\"} {name}')
sys.exit(0 if passed == total else 1)
" || {
echo "⚠️ Smoke Test 部分失敗,但不阻擋部署"
# 發送告警
curl -sf -X POST "https://api.telegram.org/bot${{ secrets.OPENCLAW_TG_BOT_TOKEN }}/sendMessage" \
-d chat_id="${{ secrets.OPENCLAW_TG_CHAT_ID }}" \
-d text="⚠️ *AWOOOI Alert Chain Smoke Test 部分失敗*%0A%0A部署已完成但部分 Webhook 可能有問題。%0A%0A🔗 ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
-d parse_mode="Markdown" || true
}
# =======================================================================
# ADR-035: Telegram 告警鏈路 E2E 驗證
# 2026-03-29 Claude Code: 部署後必須驗證 Telegram 發送成功