feat: integrate Sentry + fix CI/CD issues

Sentry Integration (補強 SignOz):
- Add @sentry/nextjs for frontend error tracking + session replay
- Add sentry-sdk[fastapi] for backend error tracking
- Create sentry.client/server/edge.config.ts
- Integrate with next.config.js + instrumentation.ts
- Add Sentry exception capture in FastAPI error handler
- Create deployment scripts for Self-Hosted @ 192.168.0.110

CI/CD Fixes:
- Fix F821 Undefined name 'Field' in incidents.py
- Add NEXT_PUBLIC_API_URL env var to CI build step
- Add build-arg to Docker build verification

E2E Test Improvements:
- Fix strict mode violations in dashboard-acceptance tests
- Add timeout increase for Phase 4 demo tests
- Make tests more resilient to UI variations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-24 15:19:52 +08:00
parent 7a76f3e628
commit 9bff46a1b0
41 changed files with 3195 additions and 153 deletions

120
scripts/qa-zero-touch.sh Executable file
View File

@@ -0,0 +1,120 @@
#!/bin/bash
# =============================================================================
# AWOOOI 終極全域自動化 QA 處決矩陣 - 正式環境版 (Prod Zero-Touch QA)
# 目標: awoooi.wooo.work & awoooi-prod Kubernetes Namespace
# =============================================================================
# 嚴格模式:任何錯誤立即終止,未定義變數報錯,管線錯誤不被掩蓋
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
# 正式環境專屬變數配置
PROD_API_URL=${PROD_API_URL:-"https://awoooi.wooo.work"}
K8S_NAMESPACE=${K8S_NAMESPACE:-"awoooi-prod"}
LOG_TAIL_LINES=50
echo -e "${CYAN}======================================================${NC}"
echo -e "${CYAN}🚀 AWOOOI 統帥部:正式環境 (PRODUCTION) QA 處決矩陣啟動...${NC}"
echo -e "${CYAN}目標端點: ${PROD_API_URL}${NC}"
echo -e "${CYAN}叢集命名空間: ${K8S_NAMESPACE}${NC}"
echo -e "${CYAN}======================================================${NC}\n"
# -----------------------------------------------------------------------------
# Phase 1: 基礎設施與 API 數據真實性自檢 (HTTPS & Prod DB)
# -----------------------------------------------------------------------------
echo -e "${YELLOW}[Phase 1] 實施正式環境基礎設施與 API 數據自檢...${NC}"
echo -n " -> 測試 Prod API 骨幹存活度與 Redis/DB 連線: "
# 使用 -k 略過本地開發可能的憑證問題,但正式環境應保持嚴格校驗,此處不加 -k
HEALTH_RESPONSE=$(curl -s -w "\n%{http_code}" "${PROD_API_URL}/api/v1/health" || echo -e "\n500")
HTTP_BODY=$(echo "$HEALTH_RESPONSE" | sed '$d')
HTTP_CODE=$(echo "$HEALTH_RESPONSE" | tail -n1)
if [ "$HTTP_CODE" -ne 200 ]; then
echo -e "${RED}FAILED (HTTP $HTTP_CODE)${NC}"
echo -e "${RED}❌ Prod API Server 未就緒或拒絕連線!${NC}"
exit 1
fi
# 檢查 API 回傳 status: "healthy" 且所有 components 都 "up"
if echo "$HTTP_BODY" | grep -q '"status":"healthy"'; then
echo -e "${GREEN}PASSED (HTTP 200 & status=healthy)${NC}"
else
echo -e "${RED}FAILED${NC}"
echo -e "${RED}❌ API 回傳 200但正式環境 JSON 數據狀態異常Raw Data: $HTTP_BODY${NC}"
exit 1
fi
# -----------------------------------------------------------------------------
# Phase 2: 全鏈路 E2E 驗證 (Playwright targeting Prod)
# -----------------------------------------------------------------------------
echo -e "\n${YELLOW}[Phase 2] 啟動 Playwright E2E 視覺憲法與邏輯測試...${NC}"
cd apps/web || { echo -e "${RED}❌ 找不到 apps/web 目錄!${NC}"; exit 1; }
echo " -> 執行依賴檢查 (pnpm install)..."
pnpm install --silent
echo " -> 執行 Playwright 測試矩陣 (指向正式環境)..."
# 注入 BASE_URL 環境變數,強迫 Playwright 打向正式環境而非 localhost
if BASE_URL="${PROD_API_URL}" pnpm exec playwright test --reporter=list,html; then
echo -e "${GREEN} ✅ Prod 前端 E2E 視覺與互動測試全數通過!${NC}"
else
echo -e "${RED} ❌ Playwright 正式環境測試遭遇失敗!${NC}"
echo -e " 🔍 請打開 apps/web/playwright-report/index.html 進行詳細視覺診斷!"
exit 1
fi
cd ../../ # 回到根目錄
# -----------------------------------------------------------------------------
# Phase 3: K8s 雙端日誌深層稽核 (Kubernetes Log Verification)
# -----------------------------------------------------------------------------
echo -e "\n${YELLOW}[Phase 3] 執行開發憲法鐵律Kubernetes Pod 雙端日誌稽核...${NC}"
has_error=0
check_k8s_logs() {
local app_label=$1
echo -n " -> 掃描 Deployment [$app_label] 歷史日誌是否有隱性崩潰: "
# 檢查該 Label 的 Pod 是否存在且 Running
POD_COUNT=$(kubectl get pods -n "$K8S_NAMESPACE" -l "app=$app_label" --field-selector=status.phase=Running --no-headers 2>/dev/null | wc -l || echo "0")
if [ "$POD_COUNT" -eq 0 ]; then
echo -e "${YELLOW}SKIPPED (No Running Pods found for app=$app_label)${NC}"
return
fi
# 使用 kubectl logs 抓取該 label 下所有 Pod 的最後 N 行日誌
LOG_ERRORS=$(kubectl logs -n "$K8S_NAMESPACE" -l "app=$app_label" --tail="$LOG_TAIL_LINES" --all-containers 2>&1 | grep -iE "error|exception|traceback|critical" || true)
if [ -n "$LOG_ERRORS" ]; then
echo -e "${RED}FAILED${NC}"
echo -e "${RED}❌ 警告!在 Prod [$app_label] 發現隱性錯誤日誌:${NC}"
echo -e "$LOG_ERRORS" | head -n 5
has_error=1
else
echo -e "${GREEN}CLEAN (無隱性異常)${NC}"
fi
}
# 檢查 K8s 中的 API 與 Worker (使用 Label Selector)
check_k8s_logs "awoooi-api"
check_k8s_logs "awoooi-worker"
if [ "$has_error" -eq 1 ]; then
echo -e "\n${RED}☠️ 正式環境深層稽核失敗!前端雖正常,但 K8s 底層日誌存在致命錯誤。請立即介入調查!${NC}"
exit 1
fi
# -----------------------------------------------------------------------------
# Phase 4: 戰果總結
# -----------------------------------------------------------------------------
echo -e "\n${CYAN}======================================================${NC}"
echo -e "${GREEN}🎉 統帥awoooi.wooo.work 正式環境全鏈路與 K8s 日誌稽核完美通關!系統堅如磐石。${NC}"
echo -e "${CYAN}======================================================${NC}"
exit 0