diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 00000000..eee9a99d --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"412c1507-44d4-4702-bb80-f37e97b804a7","pid":5408,"acquiredAt":1774326092203} \ No newline at end of file diff --git a/.claude/settings.json b/.claude/settings.json index 69b88af3..063101fb 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -370,7 +370,44 @@ "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.110 'echo \"\"=== 日誌行數 ===\"\" && wc -l /tmp/sentry-install.log && echo \"\"\"\" && echo \"\"=== 最近 20 行 ===\"\" && tail -20 /tmp/sentry-install.log')", "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.110 'echo \"\"=== 日誌行數 ===\"\" && wc -l /tmp/sentry-install.log && echo \"\"\"\" && echo \"\"=== 關鍵階段 ===\"\" && grep -E \"\"^▶|✓|Error|Creating|Starting|Building|DONE\"\" /tmp/sentry-install.log | tail -30')", "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.110 'echo \"\"=== 日誌行數 ===\"\" && wc -l /tmp/sentry-install.log && echo \"\"\"\" && echo \"\"=== 最近關鍵階段 ===\"\" && grep -E \"\"^▶|✓|Error|Creating|Starting|DONE|Completed|success\"\" /tmp/sentry-install.log | tail -25')", - "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.110 'grep -E \"\"^▶|✓|Error|Completed|success|fail\"\" /tmp/sentry-install.log | tail -15')" + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.110 'grep -E \"\"^▶|✓|Error|Completed|success|fail\"\" /tmp/sentry-install.log | tail -15')", + "Bash(redis-cli -h 192.168.0.188 -p 6380 KEYS incident:*)", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"cat /home/ollama/momo-pro/monitoring/alertmanager.yml 2>/dev/null || cat /etc/alertmanager/alertmanager.yml 2>/dev/null || echo ''Config not found''\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"docker logs clawbot --tail 30 2>&1\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"docker logs clawbot --tail 20 2>&1 | grep -iE ''telegram|send|alert|incident|error''\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"cat /home/ollama/clawbot-v5/.env | grep -E ''TELEGRAM|TG_'' | head -5\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"cat /home/ollama/clawbot-v5/.env | grep -E ''REDIS|POSTGRES|DATABASE'' | head -5\")", + "Bash(ssh ollama@192.168.0.188 'curl -s \"\"http://localhost:9093/api/v2/alerts?active=true\"\" | python3 -c \"\"import sys,json; alerts=json.load\\(sys.stdin\\); print\\(f\\\\\"\"Active alerts: {len\\(alerts\\)}\\\\\"\"\\)\"\"')", + "Bash(ssh ollama@192.168.0.188 'curl -s \"\"http://localhost:9093/api/v2/alerts\"\" | python3 -c \"\"import sys,json; alerts=json.load\\(sys.stdin\\); print\\(f\\\\\"\"Total alerts: {len\\(alerts\\)}\\\\\"\"\\); [print\\(a[\\\\\"\"labels\\\\\"\"][\\\\\"\"alertname\\\\\"\"]\\) for a in alerts[:5]]\"\"')", + "Bash(ssh ollama@192.168.0.188 'redis-cli -p 6380 -n 0 GET incident:INC-20260324-36AF55 | python3 -c \"\"import sys,json; d=json.load\\(sys.stdin\\); print\\(f\\\\\"\"Status: {d.get\\(\\\\\"\"status\\\\\"\"\\)}\\\\\"\"\\); print\\(f\\\\\"\"message_id: {d.get\\(\\\\\"\"message_id\\\\\"\", \\\\\"\"NONE\\\\\"\"\\)}\\\\\"\"\\); print\\(f\\\\\"\"chat_id: {d.get\\(\\\\\"\"chat_id\\\\\"\", \\\\\"\"NONE\\\\\"\"\\)}\\\\\"\"\\)\"\"')", + "Bash(ssh ollama@192.168.0.188 'redis-cli -p 6380 -n 0 GET incident:INC-20260324-36AF55 | python3 -c \"\"import sys,json; d=json.load\\(sys.stdin\\); print\\(f\\\\\"\"status: {d.get\\('status'\\)}\\\\\"\"\\); print\\(f\\\\\"\"message_id: {d.get\\('message_id'\\)}\\\\\"\"\\); print\\(f\\\\\"\"created_at: {d.get\\('created_at'\\)}\\\\\"\"\\)\"\"')", + "Bash(redis-cli -h 192.168.0.188 -p 6380 -n 0 KEYS *approval*)", + "Bash(redis-cli -h 192.168.0.188 -p 6380 -n 0 KEYS *incident*)", + "Bash(redis-cli -h 192.168.0.188 -p 6380 -n 0 KEYS *pending*)", + "Bash(redis-cli -h 192.168.0.188 -p 6380 -n 0 KEYS *)", + "Bash(KUBECONFIG=/Users/ogt/awoooi/k3s-prod.yaml kubectl get pods -n awoooi-prod -o wide)", + "Bash(KUBECONFIG=/Users/ogt/awoooi/k3s-prod.yaml kubectl get deployment awoooi-api -n awoooi-prod -o jsonpath='{.spec.template.spec.containers[0].image}')", + "Bash(kubectl --kubeconfig=/Users/ogt/awoooi/k3s-prod.yaml get deployment awoooi-api -n awoooi-prod -o jsonpath='{.spec.template.spec.containers[0].image}')", + "Bash(python3 -c \":*)", + "Bash(/tmp/awoooi-tg-secret.yaml:*)", + "Bash(KUBECONFIG=/Users/ogt/awoooi/k3s-prod.yaml kubectl apply -f /tmp/awoooi-tg-secret.yaml)", + "Bash(for pod:*)", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no wooo@192.168.0.188 \"curl -fsSL https://ollama.com/install.sh | sh\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password wooo@192.168.0.188 \"echo connected && ollama --version\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no -o PreferredAuthentications=password ollama@192.168.0.188 \"curl -fsSL https://ollama.com/install.sh | sh\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S curl -fsSL https://ollama.com/install.sh | sudo -S sh\")", + "Bash(sshpass -p '0936223270' ssh -o StrictHostKeyChecking=no ollama@192.168.0.188 \"ollama --version\")", + "Bash(__NEW_LINE_95e9df111552805b__ echo:*)", + "Bash(sshpass -p '0936223270' scp /Users/ogt/awoooi/k8s/nginx/awoooi-prod.conf ollama@192.168.0.188:/tmp/awoooi-prod.conf)", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S cp /tmp/awoooi-prod.conf /etc/nginx/conf.d/awoooi-prod.conf && echo ''0936223270'' | sudo -S nginx -t 2>&1\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S ls -la /etc/nginx/ssl/ 2>/dev/null || echo ''No ssl dir''; echo ''0936223270'' | sudo -S ls -la /etc/nginx/conf.d/ 2>/dev/null | head -10\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S grep -r ''ssl_certificate'' /etc/nginx/ 2>/dev/null | head -5\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S grep -A 20 ''server_name awoooi'' /etc/nginx/sites-enabled/all-sites.conf 2>/dev/null | head -30\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S ls -la /etc/nginx/sites-enabled/ 2>/dev/null\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S cat /etc/nginx/sites-available/awoooi.wooo.work.conf 2>/dev/null\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S rm /etc/nginx/conf.d/awoooi-prod.conf && echo ''0936223270'' | sudo -S nginx -t 2>&1\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S nginx -s reload 2>&1\")", + "Bash(sshpass -p '0936223270' ssh ollama@192.168.0.188 \"echo ''0936223270'' | sudo -S systemctl reload nginx 2>&1\")" ], "deny": [ "Bash(rm -rf *)", diff --git a/.claude/worktrees/reverent-gauss b/.claude/worktrees/reverent-gauss new file mode 160000 index 00000000..9f353343 --- /dev/null +++ b/.claude/worktrees/reverent-gauss @@ -0,0 +1 @@ +Subproject commit 9f353343c9baa2bc61e1534bd9f9214edf45b7ab diff --git a/Gemini_Generated_Image_sxbfrvsxbfrvsxbf (2).png b/Gemini_Generated_Image_sxbfrvsxbfrvsxbf (2).png new file mode 100644 index 00000000..5f5159de Binary files /dev/null and b/Gemini_Generated_Image_sxbfrvsxbfrvsxbf (2).png differ diff --git a/Gemini_Generated_Image_sxbfrvsxbfrvsxbf.png b/Gemini_Generated_Image_sxbfrvsxbfrvsxbf.png new file mode 100644 index 00000000..3515049b Binary files /dev/null and b/Gemini_Generated_Image_sxbfrvsxbfrvsxbf.png differ diff --git a/apps/api/src/api/v1/incidents.py b/apps/api/src/api/v1/incidents.py index dfd2aa52..f5416f12 100644 --- a/apps/api/src/api/v1/incidents.py +++ b/apps/api/src/api/v1/incidents.py @@ -622,3 +622,153 @@ async def debug_resolve_incident(incident_id: str) -> dict[str, Any]: "updates": {"redis": redis_updated, "db": db_updated}, "error": error_msg, } + + +# ============================================================================= +# POST /api/v1/incidents/sync-from-approvals - 補建 Incidents +# ============================================================================= + +class SyncResult(BaseModel): + """同步結果""" + synced: int + skipped: int + errors: list[str] + details: list[dict[str, Any]] + + +@router.post( + "/sync-from-approvals", + response_model=SyncResult, + summary="從現有 Approvals 補建 Incidents", + description=""" + 修復歷史數據:為沒有對應 Incident 的 Approvals 補建。 + + 用途: + - 修復 b645981 之前創建的 Approvals(無 Incident) + - 確保「活躍事件」與「待簽核」數量一致 + """, +) +async def sync_incidents_from_approvals() -> SyncResult: + """ + 掃描所有 pending Approvals,為缺少 Incident 的補建 + """ + from uuid import UUID + + from src.models.incident import Signal + from src.services.approval_db import get_approval_service + + redis_client = get_redis() + approval_service = get_approval_service() + + synced = 0 + skipped = 0 + errors: list[str] = [] + details: list[dict[str, Any]] = [] + + # 取得所有 pending approvals + pending_approvals = await approval_service.get_pending_approvals() + + for approval in pending_approvals: + approval_id = str(approval.id) + + # 檢查是否已有 Incident 關聯此 Approval + has_incident = False + cursor = 0 + while True: + cursor, keys = await redis_client.scan( + cursor=cursor, + match="incident:INC-*", + count=100, + ) + for key in keys: + try: + data = await redis_client.get(key) + if data: + incident = Incident.model_validate_json(data) + if UUID(approval_id) in incident.proposal_ids: + has_incident = True + break + except Exception: + pass + if has_incident or cursor == 0: + break + + if has_incident: + skipped += 1 + continue + + # 補建 Incident + try: + # 映射 risk_level -> severity + risk_map = { + "critical": Severity.P0, + "high": Severity.P1, + "medium": Severity.P2, + "low": Severity.P3, + } + severity = risk_map.get(approval.risk_level.value.lower(), Severity.P2) + + # 解析 action 取得資源名稱 + action_parts = approval.action.split("|") + resource_name = action_parts[0].strip() if action_parts else "unknown" + + signal = Signal( + alert_name="sync_from_approval", + severity=severity, + source="backfill", + fired_at=approval.created_at, + labels={"approval_id": approval_id}, + annotations={"description": approval.description or ""}, + ) + + incident = Incident( + status=IncidentStatus.INVESTIGATING, + severity=severity, + signals=[signal], + affected_services=[resource_name], + proposal_ids=[UUID(approval_id)], + created_at=approval.created_at, + updated_at=datetime.now(UTC), + ) + + key = f"incident:{incident.incident_id}" + await redis_client.set( + key, + incident.model_dump_json(), + ex=604800, # 7 days + ) + + synced += 1 + details.append({ + "approval_id": approval_id, + "incident_id": incident.incident_id, + "severity": severity.value, + }) + + logger.info( + "incident_synced_from_approval", + approval_id=approval_id, + incident_id=incident.incident_id, + ) + + except Exception as e: + errors.append(f"{approval_id}: {str(e)}") + logger.error( + "incident_sync_error", + approval_id=approval_id, + error=str(e), + ) + + logger.info( + "sync_from_approvals_completed", + synced=synced, + skipped=skipped, + errors=len(errors), + ) + + return SyncResult( + synced=synced, + skipped=skipped, + errors=errors, + details=details, + ) diff --git a/apps/api/src/api/v1/sentry_webhook.py b/apps/api/src/api/v1/sentry_webhook.py new file mode 100644 index 00000000..71ca74ca --- /dev/null +++ b/apps/api/src/api/v1/sentry_webhook.py @@ -0,0 +1,247 @@ +""" +AWOOOI API - Sentry Webhook Handler +==================================== +接收 Sentry Issue Alert,轉發給 OpenClaw 進行 AI 分析 + +整合流程: +1. Sentry Alert → AWOOOI API Webhook +2. 組裝錯誤上下文 +3. 呼叫 OpenClaw Error Analyzer Agent +4. 結果回寫 Sentry Issue Comment +""" + +import logging +from typing import Any +from datetime import datetime + +from fastapi import APIRouter, Request, HTTPException, BackgroundTasks +from pydantic import BaseModel +import httpx + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/webhooks/sentry", tags=["Sentry Webhook"]) + +# OpenClaw 配置 +OPENCLAW_URL = "http://192.168.0.188:8088" +SENTRY_API_URL = "http://192.168.0.110:9000" + + +class SentryIssuePayload(BaseModel): + """Sentry Issue Alert Payload (簡化版)""" + action: str # created, resolved, etc. + data: dict + actor: dict | None = None + + +class ErrorAnalysisResult(BaseModel): + """錯誤分析結果""" + root_cause: str + impact: str + fix_suggestion: str + prevention: str + confidence: float + analyzed_by: str # ollama, claude + + +@router.post("/error") +async def handle_sentry_error( + request: Request, + background_tasks: BackgroundTasks +): + """ + Sentry Issue Webhook Handler + + 觸發條件: + - Issue 新建 (action=created) + - Level: error 或 fatal + + 處理流程: + 1. 解析 Sentry payload + 2. 組裝錯誤上下文 + 3. 背景執行 OpenClaw 分析 + 4. 回寫 Sentry Comment + """ + try: + payload = await request.json() + logger.info(f"Received Sentry webhook: action={payload.get('action')}") + + # 只處理新建的 issue + if payload.get("action") != "triggered": + return {"status": "ignored", "reason": "action is not triggered"} + + # 提取錯誤資訊 + issue_data = payload.get("data", {}).get("issue", {}) + event_data = payload.get("data", {}).get("event", {}) + + error_context = { + "issue_id": issue_data.get("id"), + "title": issue_data.get("title"), + "culprit": issue_data.get("culprit"), + "level": issue_data.get("level"), + "first_seen": issue_data.get("firstSeen"), + "count": issue_data.get("count"), + "project": issue_data.get("project", {}).get("slug"), + + # 事件詳情 + "message": event_data.get("message"), + "platform": event_data.get("platform"), + "tags": event_data.get("tags", []), + + # Stack trace (最後5個 frame) + "stacktrace": _extract_stacktrace(event_data), + } + + # 判斷是否需要 AI 分析 + level = issue_data.get("level", "error") + if level not in ["error", "fatal"]: + return {"status": "ignored", "reason": f"level {level} does not require analysis"} + + # 背景執行分析 + background_tasks.add_task( + analyze_and_comment, + error_context=error_context, + issue_id=issue_data.get("id"), + project_slug=issue_data.get("project", {}).get("slug"), + ) + + return { + "status": "accepted", + "issue_id": error_context["issue_id"], + "message": "Analysis scheduled" + } + + except Exception as e: + logger.exception("Sentry webhook processing failed") + raise HTTPException(status_code=500, detail=str(e)) + + +def _extract_stacktrace(event_data: dict) -> list[dict]: + """提取 Stack Trace (最後5個 frame)""" + try: + exception = event_data.get("exception", {}) + values = exception.get("values", []) + if not values: + return [] + + stacktrace = values[0].get("stacktrace", {}) + frames = stacktrace.get("frames", []) + + # 取最後5個 frame,只保留關鍵資訊 + return [ + { + "filename": f.get("filename"), + "function": f.get("function"), + "lineno": f.get("lineno"), + "context_line": f.get("context_line"), + } + for f in frames[-5:] + ] + except Exception: + return [] + + +async def analyze_and_comment( + error_context: dict, + issue_id: str, + project_slug: str +): + """ + 背景任務:分析錯誤並回寫 Sentry Comment + """ + try: + logger.info(f"Starting AI analysis for issue {issue_id}") + + # 呼叫 OpenClaw 分析 + analysis = await call_openclaw_analyzer(error_context) + + if analysis: + # 回寫 Sentry Comment + await post_sentry_comment( + project_slug=project_slug, + issue_id=issue_id, + analysis=analysis + ) + logger.info(f"Analysis completed for issue {issue_id}") + else: + logger.warning(f"Analysis returned empty for issue {issue_id}") + + except Exception as e: + logger.exception(f"Analysis failed for issue {issue_id}: {e}") + + +async def call_openclaw_analyzer(error_context: dict) -> ErrorAnalysisResult | None: + """ + 呼叫 OpenClaw Error Analyzer Agent + + 優先使用 Ollama (本地,零成本) + Fallback: Claude (高嚴重性) + """ + try: + async with httpx.AsyncClient(timeout=60.0) as client: + response = await client.post( + f"{OPENCLAW_URL}/api/v1/analyze/error", + json={ + "error_context": error_context, + "prefer_local": True, # 優先 Ollama + } + ) + + if response.status_code == 200: + data = response.json() + return ErrorAnalysisResult(**data) + else: + logger.warning(f"OpenClaw returned {response.status_code}") + return None + + except httpx.TimeoutException: + logger.warning("OpenClaw analysis timeout, trying fallback prompt") + # TODO: 直接呼叫 Ollama/Claude 作為 fallback + return None + except Exception as e: + logger.exception(f"OpenClaw call failed: {e}") + return None + + +async def post_sentry_comment( + project_slug: str, + issue_id: str, + analysis: ErrorAnalysisResult +): + """ + 回寫分析結果到 Sentry Issue Comment + + API: POST /api/0/issues/{issue_id}/comments/ + """ + comment_text = f"""## AI 錯誤分析 (by {analysis.analyzed_by}) + +**根本原因 (Root Cause)** +{analysis.root_cause} + +**影響範圍 (Impact)** +{analysis.impact} + +**建議修復 (Fix Suggestion)** +{analysis.fix_suggestion} + +**預防措施 (Prevention)** +{analysis.prevention} + +--- +*分析信心度: {analysis.confidence:.0%} | 分析時間: {datetime.now().isoformat()}* +""" + + try: + # TODO: 需要 Sentry API Token + # 目前先 log 出來 + logger.info(f"Would post comment to issue {issue_id}:\n{comment_text}") + + # async with httpx.AsyncClient() as client: + # response = await client.post( + # f"{SENTRY_API_URL}/api/0/issues/{issue_id}/comments/", + # headers={"Authorization": f"Bearer {SENTRY_API_TOKEN}"}, + # json={"text": comment_text} + # ) + + except Exception as e: + logger.exception(f"Failed to post Sentry comment: {e}") diff --git a/apps/web/playwright-report/data/0278a752e4d81bb2e4d865f8342a2663980f2f63.webm b/apps/web/playwright-report/data/0278a752e4d81bb2e4d865f8342a2663980f2f63.webm new file mode 100644 index 00000000..0748af9d Binary files /dev/null and b/apps/web/playwright-report/data/0278a752e4d81bb2e4d865f8342a2663980f2f63.webm differ diff --git a/apps/web/playwright-report/data/038be691f38e58a3cb2702f6432fc6a7732d05b2.png b/apps/web/playwright-report/data/038be691f38e58a3cb2702f6432fc6a7732d05b2.png new file mode 100644 index 00000000..eb6e3194 Binary files /dev/null and b/apps/web/playwright-report/data/038be691f38e58a3cb2702f6432fc6a7732d05b2.png differ diff --git a/apps/web/playwright-report/data/0ab6357444921c4fdafc23abfbe061d03057f17a.png b/apps/web/playwright-report/data/0ab6357444921c4fdafc23abfbe061d03057f17a.png new file mode 100644 index 00000000..b985c925 Binary files /dev/null and b/apps/web/playwright-report/data/0ab6357444921c4fdafc23abfbe061d03057f17a.png differ diff --git a/apps/web/playwright-report/data/12811b164edd9553309bb7706999888a4e4a2820.webm b/apps/web/playwright-report/data/12811b164edd9553309bb7706999888a4e4a2820.webm new file mode 100644 index 00000000..e00c923a Binary files /dev/null and b/apps/web/playwright-report/data/12811b164edd9553309bb7706999888a4e4a2820.webm differ diff --git a/apps/web/playwright-report/data/136d69dffadad984b563bbe9be717f34281757ad.png b/apps/web/playwright-report/data/136d69dffadad984b563bbe9be717f34281757ad.png new file mode 100644 index 00000000..cba0b936 Binary files /dev/null and b/apps/web/playwright-report/data/136d69dffadad984b563bbe9be717f34281757ad.png differ diff --git a/apps/web/playwright-report/data/145d1ce92578bb4bb9925dbe08f9c4cbe8a3eb9a.webm b/apps/web/playwright-report/data/145d1ce92578bb4bb9925dbe08f9c4cbe8a3eb9a.webm new file mode 100644 index 00000000..591b8682 Binary files /dev/null and b/apps/web/playwright-report/data/145d1ce92578bb4bb9925dbe08f9c4cbe8a3eb9a.webm differ diff --git a/apps/web/playwright-report/data/17b6a81e39d16d9a7165b0e92f03eeee12791cdd.webm b/apps/web/playwright-report/data/17b6a81e39d16d9a7165b0e92f03eeee12791cdd.webm new file mode 100644 index 00000000..c833a83d Binary files /dev/null and b/apps/web/playwright-report/data/17b6a81e39d16d9a7165b0e92f03eeee12791cdd.webm differ diff --git a/apps/web/playwright-report/data/25672f8d97a6d022a4da2af15e623ef65b5f9f5b.png b/apps/web/playwright-report/data/25672f8d97a6d022a4da2af15e623ef65b5f9f5b.png new file mode 100644 index 00000000..ab3967e1 Binary files /dev/null and b/apps/web/playwright-report/data/25672f8d97a6d022a4da2af15e623ef65b5f9f5b.png differ diff --git a/apps/web/playwright-report/data/25d4a7c7b1c73066faa0727a6cb6d72afda5f61e.webm b/apps/web/playwright-report/data/25d4a7c7b1c73066faa0727a6cb6d72afda5f61e.webm new file mode 100644 index 00000000..d7467d98 Binary files /dev/null and b/apps/web/playwright-report/data/25d4a7c7b1c73066faa0727a6cb6d72afda5f61e.webm differ diff --git a/apps/web/playwright-report/data/2961415fc8bbebe710b8d02430d0ef7a709078f4.png b/apps/web/playwright-report/data/2961415fc8bbebe710b8d02430d0ef7a709078f4.png new file mode 100644 index 00000000..7e26ace0 Binary files /dev/null and b/apps/web/playwright-report/data/2961415fc8bbebe710b8d02430d0ef7a709078f4.png differ diff --git a/apps/web/playwright-report/data/357fd986bdcc32fe3ed900a085100e401a1b0252.webm b/apps/web/playwright-report/data/357fd986bdcc32fe3ed900a085100e401a1b0252.webm new file mode 100644 index 00000000..6a755310 Binary files /dev/null and b/apps/web/playwright-report/data/357fd986bdcc32fe3ed900a085100e401a1b0252.webm differ diff --git a/apps/web/playwright-report/data/3a0cbb6219e70e7856e03ad6955a34c7cde00d97.webm b/apps/web/playwright-report/data/3a0cbb6219e70e7856e03ad6955a34c7cde00d97.webm new file mode 100644 index 00000000..2760baea Binary files /dev/null and b/apps/web/playwright-report/data/3a0cbb6219e70e7856e03ad6955a34c7cde00d97.webm differ diff --git a/apps/web/playwright-report/data/43d51cbc086d97d684b5eab42e86d4d60e2bb9cd.png b/apps/web/playwright-report/data/43d51cbc086d97d684b5eab42e86d4d60e2bb9cd.png new file mode 100644 index 00000000..43035a74 Binary files /dev/null and b/apps/web/playwright-report/data/43d51cbc086d97d684b5eab42e86d4d60e2bb9cd.png differ diff --git a/apps/web/playwright-report/data/4e49d731edd6cbad58f00175d83ee216d0e3998d.webm b/apps/web/playwright-report/data/4e49d731edd6cbad58f00175d83ee216d0e3998d.webm new file mode 100644 index 00000000..7d6e4663 Binary files /dev/null and b/apps/web/playwright-report/data/4e49d731edd6cbad58f00175d83ee216d0e3998d.webm differ diff --git a/apps/web/playwright-report/data/516b57fbef8c19f7d2eb5d653146f086c7d644dc.webm b/apps/web/playwright-report/data/516b57fbef8c19f7d2eb5d653146f086c7d644dc.webm new file mode 100644 index 00000000..41fd4977 Binary files /dev/null and b/apps/web/playwright-report/data/516b57fbef8c19f7d2eb5d653146f086c7d644dc.webm differ diff --git a/apps/web/playwright-report/data/516e26842435367830955a1e765c91378131aac7.webm b/apps/web/playwright-report/data/516e26842435367830955a1e765c91378131aac7.webm new file mode 100644 index 00000000..50a1cdc1 Binary files /dev/null and b/apps/web/playwright-report/data/516e26842435367830955a1e765c91378131aac7.webm differ diff --git a/apps/web/playwright-report/data/5366c5ca31d96a3b2b0b89113adb5ee240d4d12a.webm b/apps/web/playwright-report/data/5366c5ca31d96a3b2b0b89113adb5ee240d4d12a.webm new file mode 100644 index 00000000..babf66b7 Binary files /dev/null and b/apps/web/playwright-report/data/5366c5ca31d96a3b2b0b89113adb5ee240d4d12a.webm differ diff --git a/apps/web/playwright-report/data/5fc3b60ac7d7c39e513df45e4488f03daca48b38.webm b/apps/web/playwright-report/data/5fc3b60ac7d7c39e513df45e4488f03daca48b38.webm new file mode 100644 index 00000000..e7acab28 Binary files /dev/null and b/apps/web/playwright-report/data/5fc3b60ac7d7c39e513df45e4488f03daca48b38.webm differ diff --git a/apps/web/playwright-report/data/67cc08c03597b1550dc9a7baaa888c9e1271869c.png b/apps/web/playwright-report/data/67cc08c03597b1550dc9a7baaa888c9e1271869c.png new file mode 100644 index 00000000..6347102e Binary files /dev/null and b/apps/web/playwright-report/data/67cc08c03597b1550dc9a7baaa888c9e1271869c.png differ diff --git a/apps/web/playwright-report/data/7ad96703d03f24c2386692cae54ba21c9eecf56d.png b/apps/web/playwright-report/data/7ad96703d03f24c2386692cae54ba21c9eecf56d.png new file mode 100644 index 00000000..7fb76b60 Binary files /dev/null and b/apps/web/playwright-report/data/7ad96703d03f24c2386692cae54ba21c9eecf56d.png differ diff --git a/apps/web/playwright-report/data/7c85ae1d9e38cc5df90ff15037ed91e2b8e80e7e.webm b/apps/web/playwright-report/data/7c85ae1d9e38cc5df90ff15037ed91e2b8e80e7e.webm new file mode 100644 index 00000000..2ce1ecc7 Binary files /dev/null and b/apps/web/playwright-report/data/7c85ae1d9e38cc5df90ff15037ed91e2b8e80e7e.webm differ diff --git a/apps/web/playwright-report/data/845d87b3102993fabce170c250aa167af5444e22.webm b/apps/web/playwright-report/data/845d87b3102993fabce170c250aa167af5444e22.webm new file mode 100644 index 00000000..17183aa4 Binary files /dev/null and b/apps/web/playwright-report/data/845d87b3102993fabce170c250aa167af5444e22.webm differ diff --git a/apps/web/playwright-report/data/8b28ba28a5a7a881f3e60c9c202310a48ad0452e.webm b/apps/web/playwright-report/data/8b28ba28a5a7a881f3e60c9c202310a48ad0452e.webm new file mode 100644 index 00000000..afc64aad Binary files /dev/null and b/apps/web/playwright-report/data/8b28ba28a5a7a881f3e60c9c202310a48ad0452e.webm differ diff --git a/apps/web/playwright-report/data/8c826519ff8657d0c01cdb118746fcdd76ccf254.png b/apps/web/playwright-report/data/8c826519ff8657d0c01cdb118746fcdd76ccf254.png new file mode 100644 index 00000000..bb002b46 Binary files /dev/null and b/apps/web/playwright-report/data/8c826519ff8657d0c01cdb118746fcdd76ccf254.png differ diff --git a/apps/web/playwright-report/data/97ff76a3a1cd9466bcc9a14bf990b126ecbacc02.png b/apps/web/playwright-report/data/97ff76a3a1cd9466bcc9a14bf990b126ecbacc02.png new file mode 100644 index 00000000..15961131 Binary files /dev/null and b/apps/web/playwright-report/data/97ff76a3a1cd9466bcc9a14bf990b126ecbacc02.png differ diff --git a/apps/web/playwright-report/data/998e5c81518b2f62abcf1bc5ef81c2c8ff3ab582.webm b/apps/web/playwright-report/data/998e5c81518b2f62abcf1bc5ef81c2c8ff3ab582.webm new file mode 100644 index 00000000..ed1e18db Binary files /dev/null and b/apps/web/playwright-report/data/998e5c81518b2f62abcf1bc5ef81c2c8ff3ab582.webm differ diff --git a/apps/web/playwright-report/data/9cc0b679da726f8bf3030dea4cebe84947f55014.png b/apps/web/playwright-report/data/9cc0b679da726f8bf3030dea4cebe84947f55014.png new file mode 100644 index 00000000..d72f1bad Binary files /dev/null and b/apps/web/playwright-report/data/9cc0b679da726f8bf3030dea4cebe84947f55014.png differ diff --git a/apps/web/playwright-report/data/9f4baf7290d7a05d1f21107b4e9389e7724daa19.webm b/apps/web/playwright-report/data/9f4baf7290d7a05d1f21107b4e9389e7724daa19.webm new file mode 100644 index 00000000..348ce571 Binary files /dev/null and b/apps/web/playwright-report/data/9f4baf7290d7a05d1f21107b4e9389e7724daa19.webm differ diff --git a/apps/web/playwright-report/data/a1993b883b38a80934775e357269ab6577b8b6fb.png b/apps/web/playwright-report/data/a1993b883b38a80934775e357269ab6577b8b6fb.png new file mode 100644 index 00000000..bef5ddad Binary files /dev/null and b/apps/web/playwright-report/data/a1993b883b38a80934775e357269ab6577b8b6fb.png differ diff --git a/apps/web/playwright-report/data/aff45a35b472100e10a8db1bcd79d9fa7aeb3188.png b/apps/web/playwright-report/data/aff45a35b472100e10a8db1bcd79d9fa7aeb3188.png new file mode 100644 index 00000000..067df910 Binary files /dev/null and b/apps/web/playwright-report/data/aff45a35b472100e10a8db1bcd79d9fa7aeb3188.png differ diff --git a/apps/web/playwright-report/data/b1aec01b5660a4d85b10dba0bb4c593abec2e169.webm b/apps/web/playwright-report/data/b1aec01b5660a4d85b10dba0bb4c593abec2e169.webm new file mode 100644 index 00000000..4e239bd9 Binary files /dev/null and b/apps/web/playwright-report/data/b1aec01b5660a4d85b10dba0bb4c593abec2e169.webm differ diff --git a/apps/web/playwright-report/data/b74bfad9aebbc8a76918908e3b1c4c5e6713bfa6.png b/apps/web/playwright-report/data/b74bfad9aebbc8a76918908e3b1c4c5e6713bfa6.png new file mode 100644 index 00000000..4a8c5351 Binary files /dev/null and b/apps/web/playwright-report/data/b74bfad9aebbc8a76918908e3b1c4c5e6713bfa6.png differ diff --git a/apps/web/playwright-report/data/bbdcb161ad33657ae50733eba844f232efa4d4f7.png b/apps/web/playwright-report/data/bbdcb161ad33657ae50733eba844f232efa4d4f7.png new file mode 100644 index 00000000..5d7d0bb7 Binary files /dev/null and b/apps/web/playwright-report/data/bbdcb161ad33657ae50733eba844f232efa4d4f7.png differ diff --git a/apps/web/playwright-report/data/c48e7a4dbcf2289d90ff0614a195732e97d154bd.webm b/apps/web/playwright-report/data/c48e7a4dbcf2289d90ff0614a195732e97d154bd.webm new file mode 100644 index 00000000..6536b578 Binary files /dev/null and b/apps/web/playwright-report/data/c48e7a4dbcf2289d90ff0614a195732e97d154bd.webm differ diff --git a/apps/web/playwright-report/data/dc4685864a8de2c4ce23ff5bad13b1e49c4a88f2.png b/apps/web/playwright-report/data/dc4685864a8de2c4ce23ff5bad13b1e49c4a88f2.png new file mode 100644 index 00000000..f0cef069 Binary files /dev/null and b/apps/web/playwright-report/data/dc4685864a8de2c4ce23ff5bad13b1e49c4a88f2.png differ diff --git a/apps/web/playwright-report/data/dd1d700c5bbba415f4459b1fd7e85f81fa25071f.png b/apps/web/playwright-report/data/dd1d700c5bbba415f4459b1fd7e85f81fa25071f.png new file mode 100644 index 00000000..968a8251 Binary files /dev/null and b/apps/web/playwright-report/data/dd1d700c5bbba415f4459b1fd7e85f81fa25071f.png differ diff --git a/apps/web/playwright-report/data/efaf06b749353a3ea3b11ae60c7ef9a0db7e64ef.png b/apps/web/playwright-report/data/efaf06b749353a3ea3b11ae60c7ef9a0db7e64ef.png new file mode 100644 index 00000000..c27a9c8b Binary files /dev/null and b/apps/web/playwright-report/data/efaf06b749353a3ea3b11ae60c7ef9a0db7e64ef.png differ diff --git a/apps/web/playwright-report/data/f3111f8da1f11251d3e81d0b8798a32a05308884.webm b/apps/web/playwright-report/data/f3111f8da1f11251d3e81d0b8798a32a05308884.webm new file mode 100644 index 00000000..6b47d193 Binary files /dev/null and b/apps/web/playwright-report/data/f3111f8da1f11251d3e81d0b8798a32a05308884.webm differ diff --git a/apps/web/playwright-report/data/ff47a4d142785ef6a7191d7488ef2805a4078a9f.png b/apps/web/playwright-report/data/ff47a4d142785ef6a7191d7488ef2805a4078a9f.png new file mode 100644 index 00000000..77d3c6f5 Binary files /dev/null and b/apps/web/playwright-report/data/ff47a4d142785ef6a7191d7488ef2805a4078a9f.png differ diff --git a/apps/web/test-results/html-report/index.html b/apps/web/playwright-report/index.html similarity index 93% rename from apps/web/test-results/html-report/index.html rename to apps/web/playwright-report/index.html index ee336ec1..45f3cbaa 100644 --- a/apps/web/test-results/html-report/index.html +++ b/apps/web/playwright-report/index.html @@ -82,4 +82,4 @@ Error generating stack: `+a.message+`
- \ No newline at end of file + \ No newline at end of file diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/test-finished-1.png deleted file mode 100644 index 89d50b2f..00000000 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/test-finished-1.png and /dev/null differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/video.webm deleted file mode 100644 index 126490bf..00000000 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航---行動日誌連結可點擊-chromium/video.webm and /dev/null differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/test-finished-1.png new file mode 100644 index 00000000..5d7d0bb7 Binary files /dev/null and b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/video.webm new file mode 100644 index 00000000..e7acab28 Binary files /dev/null and b/apps/web/test-results/action-log-Action-Log-頁面測試-側邊欄導航或直接頁面存取-chromium/video.webm differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/test-finished-1.png index c580cfdc..15961131 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/test-finished-1.png and b/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/video.webm index 09176a0a..50a1cdc1 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/video.webm and b/apps/web/test-results/action-log-Action-Log-頁面測試-繁體中文頁面---基本元素驗證-chromium/video.webm differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/test-finished-1.png index 9aa1c17b..43035a74 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/test-finished-1.png and b/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/video.webm index 7187c353..afc64aad 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/video.webm and b/apps/web/test-results/action-log-Action-Log-頁面測試-英文頁面---基本元素驗證-chromium/video.webm differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/test-finished-1.png index 72a78e62..15961131 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/test-finished-1.png and b/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/video.webm index 2703a880..4e239bd9 100644 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/video.webm and b/apps/web/test-results/action-log-Action-Log-頁面測試-資料狀態顯示---顯示空狀態、表格或錯誤訊息-chromium/video.webm differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/test-finished-1.png deleted file mode 100644 index f4b76ab3..00000000 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/test-finished-1.png and /dev/null differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/video.webm deleted file mode 100644 index 64f9e71f..00000000 Binary files a/apps/web/test-results/action-log-Action-Log-頁面測試-重新整理按鈕存在且可點擊-chromium/video.webm and /dev/null differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/test-finished-1.png b/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/test-finished-1.png new file mode 100644 index 00000000..bef5ddad Binary files /dev/null and b/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/video.webm b/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/video.webm new file mode 100644 index 00000000..2760baea Binary files /dev/null and b/apps/web/test-results/action-log-Action-Log-頁面測試-頁面載入與互動元素-chromium/video.webm differ diff --git a/apps/web/test-results/approval-card-check.png b/apps/web/test-results/approval-card-check.png new file mode 100644 index 00000000..0707eb39 Binary files /dev/null and b/apps/web/test-results/approval-card-check.png differ diff --git a/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/test-finished-1.png b/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/test-finished-1.png new file mode 100644 index 00000000..7e26ace0 Binary files /dev/null and b/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/video.webm b/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/video.webm new file mode 100644 index 00000000..c833a83d Binary files /dev/null and b/apps/web/test-results/approval-card-verify-ApprovalCard-即時驗證-待簽核卡片應顯示在右側-AI-面板-chromium/video.webm differ diff --git a/apps/web/test-results/cpo102-fullpage-zh-TW.png b/apps/web/test-results/cpo102-fullpage-zh-TW.png new file mode 100644 index 00000000..743fe62e Binary files /dev/null and b/apps/web/test-results/cpo102-fullpage-zh-TW.png differ diff --git a/apps/web/test-results/cpo102-hitl-section-zh-TW.png b/apps/web/test-results/cpo102-hitl-section-zh-TW.png new file mode 100644 index 00000000..1baff6e0 Binary files /dev/null and b/apps/web/test-results/cpo102-hitl-section-zh-TW.png differ diff --git a/apps/web/test-results/cpo102-status-section-zh-TW.png b/apps/web/test-results/cpo102-status-section-zh-TW.png new file mode 100644 index 00000000..f430ab66 Binary files /dev/null and b/apps/web/test-results/cpo102-status-section-zh-TW.png differ diff --git a/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/test-finished-1.png b/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/test-finished-1.png new file mode 100644 index 00000000..067df910 Binary files /dev/null and b/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/video.webm b/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/video.webm new file mode 100644 index 00000000..41fd4977 Binary files /dev/null and b/apps/web/test-results/cpo102-visual-CPO-102-Layo-d3c7e--Full-Command-Center-Layout-chromium/video.webm differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/test-finished-1.png b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/test-finished-1.png new file mode 100644 index 00000000..d72f1bad Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/video.webm b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/video.webm new file mode 100644 index 00000000..7d6e4663 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-HITL-區域存在-chromium/video.webm differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/test-finished-1.png b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/test-finished-1.png new file mode 100644 index 00000000..f0cef069 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/video.webm b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/video.webm new file mode 100644 index 00000000..6536b578 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-主機卡片或主要內容顯示-chromium/video.webm differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/test-finished-1.png b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/test-finished-1.png new file mode 100644 index 00000000..ab3967e1 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/video.webm b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/video.webm new file mode 100644 index 00000000..17183aa4 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-完整頁面截圖---雙語對照-chromium/video.webm differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/test-finished-1.png b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/test-finished-1.png new file mode 100644 index 00000000..b985c925 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/video.webm b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/video.webm new file mode 100644 index 00000000..ed1e18db Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-繁體中文頁面驗證---基本結構-chromium/video.webm differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/test-finished-1.png b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/test-finished-1.png new file mode 100644 index 00000000..7fb76b60 Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/video.webm b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/video.webm new file mode 100644 index 00000000..e00c923a Binary files /dev/null and b/apps/web/test-results/dashboard-acceptance-Dashboard-視覺驗收-語系切換器功能---繁中轉英文-chromium/video.webm differ diff --git a/apps/web/test-results/debug-error-capture-console-errors-chromium/test-finished-1.png b/apps/web/test-results/debug-error-capture-console-errors-chromium/test-finished-1.png new file mode 100644 index 00000000..bb002b46 Binary files /dev/null and b/apps/web/test-results/debug-error-capture-console-errors-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/debug-error-capture-console-errors-chromium/video.webm b/apps/web/test-results/debug-error-capture-console-errors-chromium/video.webm new file mode 100644 index 00000000..babf66b7 Binary files /dev/null and b/apps/web/test-results/debug-error-capture-console-errors-chromium/video.webm differ diff --git a/apps/web/test-results/debug-error.png b/apps/web/test-results/debug-error.png new file mode 100644 index 00000000..0789b924 Binary files /dev/null and b/apps/web/test-results/debug-error.png differ diff --git a/apps/web/test-results/html-report/data/25e4bbe7bcf55268dcb418a7d8a8222e8b5c5cc8.png b/apps/web/test-results/html-report/data/25e4bbe7bcf55268dcb418a7d8a8222e8b5c5cc8.png deleted file mode 100644 index 72a78e62..00000000 Binary files a/apps/web/test-results/html-report/data/25e4bbe7bcf55268dcb418a7d8a8222e8b5c5cc8.png and /dev/null differ diff --git a/apps/web/test-results/html-report/data/5f543dae85fd8d29cb080c93ea6ca2a83985c722.png b/apps/web/test-results/html-report/data/5f543dae85fd8d29cb080c93ea6ca2a83985c722.png deleted file mode 100644 index c580cfdc..00000000 Binary files a/apps/web/test-results/html-report/data/5f543dae85fd8d29cb080c93ea6ca2a83985c722.png and /dev/null differ diff --git a/apps/web/test-results/html-report/data/a3b1dbcda1f19948f36e51dafe1b35f1c8e7153a.webm b/apps/web/test-results/html-report/data/a3b1dbcda1f19948f36e51dafe1b35f1c8e7153a.webm deleted file mode 100644 index 126490bf..00000000 Binary files a/apps/web/test-results/html-report/data/a3b1dbcda1f19948f36e51dafe1b35f1c8e7153a.webm and /dev/null differ diff --git a/apps/web/test-results/html-report/data/affc192081e4c115e7310cba3de63f4cd39c8989.png b/apps/web/test-results/html-report/data/affc192081e4c115e7310cba3de63f4cd39c8989.png deleted file mode 100644 index 89d50b2f..00000000 Binary files a/apps/web/test-results/html-report/data/affc192081e4c115e7310cba3de63f4cd39c8989.png and /dev/null differ diff --git a/apps/web/test-results/html-report/data/c4247c42a4ca5e18cf5fde3ae30c4605789d48fb.png b/apps/web/test-results/html-report/data/c4247c42a4ca5e18cf5fde3ae30c4605789d48fb.png deleted file mode 100644 index 9aa1c17b..00000000 Binary files a/apps/web/test-results/html-report/data/c4247c42a4ca5e18cf5fde3ae30c4605789d48fb.png and /dev/null differ diff --git a/apps/web/test-results/html-report/data/dad8009ed4d2feea187177f9481b39ffcce87343.webm b/apps/web/test-results/html-report/data/dad8009ed4d2feea187177f9481b39ffcce87343.webm deleted file mode 100644 index 2703a880..00000000 Binary files a/apps/web/test-results/html-report/data/dad8009ed4d2feea187177f9481b39ffcce87343.webm and /dev/null differ diff --git a/apps/web/test-results/html-report/data/e48501e7c8324642d64c6e1db897e5bd015299f9.webm b/apps/web/test-results/html-report/data/e48501e7c8324642d64c6e1db897e5bd015299f9.webm deleted file mode 100644 index 09176a0a..00000000 Binary files a/apps/web/test-results/html-report/data/e48501e7c8324642d64c6e1db897e5bd015299f9.webm and /dev/null differ diff --git a/apps/web/test-results/html-report/data/f74f01d01e579a62905349732cf82cf061ae3f21.png b/apps/web/test-results/html-report/data/f74f01d01e579a62905349732cf82cf061ae3f21.png deleted file mode 100644 index f4b76ab3..00000000 Binary files a/apps/web/test-results/html-report/data/f74f01d01e579a62905349732cf82cf061ae3f21.png and /dev/null differ diff --git a/apps/web/test-results/html-report/data/f7c5e0df584be638819fe8ea3b73909369497fa7.webm b/apps/web/test-results/html-report/data/f7c5e0df584be638819fe8ea3b73909369497fa7.webm deleted file mode 100644 index 7187c353..00000000 Binary files a/apps/web/test-results/html-report/data/f7c5e0df584be638819fe8ea3b73909369497fa7.webm and /dev/null differ diff --git a/apps/web/test-results/html-report/data/f8a5a9ed1f99dfc64084167b46f5fa8bc5a3f43a.webm b/apps/web/test-results/html-report/data/f8a5a9ed1f99dfc64084167b46f5fa8bc5a3f43a.webm deleted file mode 100644 index 64f9e71f..00000000 Binary files a/apps/web/test-results/html-report/data/f8a5a9ed1f99dfc64084167b46f5fa8bc5a3f43a.webm and /dev/null differ diff --git a/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/test-finished-1.png b/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/test-finished-1.png new file mode 100644 index 00000000..c27a9c8b Binary files /dev/null and b/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/video.webm b/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/video.webm new file mode 100644 index 00000000..0748af9d Binary files /dev/null and b/apps/web/test-results/multisig-security-Multi-Si-87922-ull-Multi-Sig-Security-Flow-chromium/video.webm differ diff --git a/apps/web/test-results/phase3-hitl-section-final.png b/apps/web/test-results/phase3-hitl-section-final.png new file mode 100644 index 00000000..f99ceb48 Binary files /dev/null and b/apps/web/test-results/phase3-hitl-section-final.png differ diff --git a/apps/web/test-results/phase3-rbac-permission-badge.png b/apps/web/test-results/phase3-rbac-permission-badge.png new file mode 100644 index 00000000..6b536ea6 Binary files /dev/null and b/apps/web/test-results/phase3-rbac-permission-badge.png differ diff --git a/apps/web/test-results/phase3-user-role-display.png b/apps/web/test-results/phase3-user-role-display.png new file mode 100644 index 00000000..323a862f Binary files /dev/null and b/apps/web/test-results/phase3-user-role-display.png differ diff --git a/apps/web/test-results/phase4-01-initial.png b/apps/web/test-results/phase4-01-initial.png new file mode 100644 index 00000000..04f275f9 Binary files /dev/null and b/apps/web/test-results/phase4-01-initial.png differ diff --git a/apps/web/test-results/phase4-02-ai-decision.png b/apps/web/test-results/phase4-02-ai-decision.png new file mode 100644 index 00000000..38ef8c5a Binary files /dev/null and b/apps/web/test-results/phase4-02-ai-decision.png differ diff --git a/apps/web/test-results/phase4-03-approval-cards.png b/apps/web/test-results/phase4-03-approval-cards.png new file mode 100644 index 00000000..a3311896 Binary files /dev/null and b/apps/web/test-results/phase4-03-approval-cards.png differ diff --git a/apps/web/test-results/phase4-04-access-denied.png b/apps/web/test-results/phase4-04-access-denied.png new file mode 100644 index 00000000..2b9c5c20 Binary files /dev/null and b/apps/web/test-results/phase4-04-access-denied.png differ diff --git a/apps/web/test-results/phase4-05-cto-role.png b/apps/web/test-results/phase4-05-cto-role.png new file mode 100644 index 00000000..5f2bce7a Binary files /dev/null and b/apps/web/test-results/phase4-05-cto-role.png differ diff --git a/apps/web/test-results/phase4-06-cto-signed.png b/apps/web/test-results/phase4-06-cto-signed.png new file mode 100644 index 00000000..22ff02c4 Binary files /dev/null and b/apps/web/test-results/phase4-06-cto-signed.png differ diff --git a/apps/web/test-results/phase4-07-final.png b/apps/web/test-results/phase4-07-final.png new file mode 100644 index 00000000..2b9f4527 Binary files /dev/null and b/apps/web/test-results/phase4-07-final.png differ diff --git a/apps/web/test-results/phase4-alpha-01-initial.png b/apps/web/test-results/phase4-alpha-01-initial.png new file mode 100644 index 00000000..e3494ed3 Binary files /dev/null and b/apps/web/test-results/phase4-alpha-01-initial.png differ diff --git a/apps/web/test-results/phase4-alpha-02-ai-analysis.png b/apps/web/test-results/phase4-alpha-02-ai-analysis.png new file mode 100644 index 00000000..d410b8ee Binary files /dev/null and b/apps/web/test-results/phase4-alpha-02-ai-analysis.png differ diff --git a/apps/web/test-results/phase4-alpha-03-access-denied.png b/apps/web/test-results/phase4-alpha-03-access-denied.png new file mode 100644 index 00000000..3c278633 Binary files /dev/null and b/apps/web/test-results/phase4-alpha-03-access-denied.png differ diff --git a/apps/web/test-results/phase4-alpha-04-cto-role.png b/apps/web/test-results/phase4-alpha-04-cto-role.png new file mode 100644 index 00000000..eb2da795 Binary files /dev/null and b/apps/web/test-results/phase4-alpha-04-cto-role.png differ diff --git a/apps/web/test-results/phase4-alpha-05-cto-signed.png b/apps/web/test-results/phase4-alpha-05-cto-signed.png new file mode 100644 index 00000000..abc2d3c4 Binary files /dev/null and b/apps/web/test-results/phase4-alpha-05-cto-signed.png differ diff --git a/apps/web/test-results/phase4-alpha-final.png b/apps/web/test-results/phase4-alpha-final.png new file mode 100644 index 00000000..547a6783 Binary files /dev/null and b/apps/web/test-results/phase4-alpha-final.png differ diff --git a/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/test-finished-1.png b/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/test-finished-1.png new file mode 100644 index 00000000..968a8251 Binary files /dev/null and b/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/video.webm b/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/video.webm new file mode 100644 index 00000000..2ce1ecc7 Binary files /dev/null and b/apps/web/test-results/phase4-final-demo-Phase-4-Alpha-Demo---Full-Flow-chromium/video.webm differ diff --git a/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/test-finished-1.png b/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/test-finished-1.png new file mode 100644 index 00000000..6347102e Binary files /dev/null and b/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/video.webm b/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/video.webm new file mode 100644 index 00000000..6a755310 Binary files /dev/null and b/apps/web/test-results/phase4-timeline-Phase-4-Full-Action-Timeline-Demo-Flow-chromium/video.webm differ diff --git a/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/test-finished-1.png b/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/test-finished-1.png new file mode 100644 index 00000000..cba0b936 Binary files /dev/null and b/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/video.webm b/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/video.webm new file mode 100644 index 00000000..6b47d193 Binary files /dev/null and b/apps/web/test-results/rbac-screenshot-Screenshot-RBAC-permission-UI-chromium/video.webm differ diff --git a/apps/web/test-results/screenshots/01-zh-TW-initial.png b/apps/web/test-results/screenshots/01-zh-TW-initial.png new file mode 100644 index 00000000..56f6ce6b Binary files /dev/null and b/apps/web/test-results/screenshots/01-zh-TW-initial.png differ diff --git a/apps/web/test-results/screenshots/02-zh-TW-dashboard-title.png b/apps/web/test-results/screenshots/02-zh-TW-dashboard-title.png new file mode 100644 index 00000000..9007d788 Binary files /dev/null and b/apps/web/test-results/screenshots/02-zh-TW-dashboard-title.png differ diff --git a/apps/web/test-results/screenshots/03-before-locale-switch.png b/apps/web/test-results/screenshots/03-before-locale-switch.png new file mode 100644 index 00000000..968bc2cb Binary files /dev/null and b/apps/web/test-results/screenshots/03-before-locale-switch.png differ diff --git a/apps/web/test-results/screenshots/04-after-locale-switch-en.png b/apps/web/test-results/screenshots/04-after-locale-switch-en.png new file mode 100644 index 00000000..3163f396 Binary files /dev/null and b/apps/web/test-results/screenshots/04-after-locale-switch-en.png differ diff --git a/apps/web/test-results/screenshots/05-host-cards.png b/apps/web/test-results/screenshots/05-host-cards.png new file mode 100644 index 00000000..603e89af Binary files /dev/null and b/apps/web/test-results/screenshots/05-host-cards.png differ diff --git a/apps/web/test-results/screenshots/06-approval-cards.png b/apps/web/test-results/screenshots/06-approval-cards.png new file mode 100644 index 00000000..97b848d0 Binary files /dev/null and b/apps/web/test-results/screenshots/06-approval-cards.png differ diff --git a/apps/web/test-results/screenshots/06-hitl-section.png b/apps/web/test-results/screenshots/06-hitl-section.png new file mode 100644 index 00000000..1f924be7 Binary files /dev/null and b/apps/web/test-results/screenshots/06-hitl-section.png differ diff --git a/apps/web/test-results/screenshots/07-final-zh-TW-fullpage.png b/apps/web/test-results/screenshots/07-final-zh-TW-fullpage.png new file mode 100644 index 00000000..d52a8150 Binary files /dev/null and b/apps/web/test-results/screenshots/07-final-zh-TW-fullpage.png differ diff --git a/apps/web/test-results/screenshots/08-final-en-fullpage.png b/apps/web/test-results/screenshots/08-final-en-fullpage.png new file mode 100644 index 00000000..a2057717 Binary files /dev/null and b/apps/web/test-results/screenshots/08-final-en-fullpage.png differ diff --git a/apps/web/test-results/screenshots/action-log-01-zh-TW-initial.png b/apps/web/test-results/screenshots/action-log-01-zh-TW-initial.png index a0ce548a..15961131 100644 Binary files a/apps/web/test-results/screenshots/action-log-01-zh-TW-initial.png and b/apps/web/test-results/screenshots/action-log-01-zh-TW-initial.png differ diff --git a/apps/web/test-results/screenshots/action-log-02-page-structure.png b/apps/web/test-results/screenshots/action-log-02-page-structure.png index e81622d6..15961131 100644 Binary files a/apps/web/test-results/screenshots/action-log-02-page-structure.png and b/apps/web/test-results/screenshots/action-log-02-page-structure.png differ diff --git a/apps/web/test-results/screenshots/action-log-03-en-initial.png b/apps/web/test-results/screenshots/action-log-03-en-initial.png index b708f682..8bd97c84 100644 Binary files a/apps/web/test-results/screenshots/action-log-03-en-initial.png and b/apps/web/test-results/screenshots/action-log-03-en-initial.png differ diff --git a/apps/web/test-results/screenshots/action-log-04-data-state.png b/apps/web/test-results/screenshots/action-log-04-data-state.png index b92e1188..15961131 100644 Binary files a/apps/web/test-results/screenshots/action-log-04-data-state.png and b/apps/web/test-results/screenshots/action-log-04-data-state.png differ diff --git a/apps/web/test-results/screenshots/action-log-05-before-nav.png b/apps/web/test-results/screenshots/action-log-05-before-nav.png deleted file mode 100644 index cb8c7747..00000000 Binary files a/apps/web/test-results/screenshots/action-log-05-before-nav.png and /dev/null differ diff --git a/apps/web/test-results/screenshots/action-log-06-after-nav.png b/apps/web/test-results/screenshots/action-log-06-after-nav.png deleted file mode 100644 index bdba7b2a..00000000 Binary files a/apps/web/test-results/screenshots/action-log-06-after-nav.png and /dev/null differ diff --git a/apps/web/test-results/screenshots/action-log-06-page-state.png b/apps/web/test-results/screenshots/action-log-06-page-state.png new file mode 100644 index 00000000..ff5d7b60 Binary files /dev/null and b/apps/web/test-results/screenshots/action-log-06-page-state.png differ diff --git a/apps/web/test-results/screenshots/action-log-07-before-refresh.png b/apps/web/test-results/screenshots/action-log-07-before-refresh.png deleted file mode 100644 index f2ecf34c..00000000 Binary files a/apps/web/test-results/screenshots/action-log-07-before-refresh.png and /dev/null differ diff --git a/apps/web/test-results/screenshots/action-log-07-initial-state.png b/apps/web/test-results/screenshots/action-log-07-initial-state.png new file mode 100644 index 00000000..15961131 Binary files /dev/null and b/apps/web/test-results/screenshots/action-log-07-initial-state.png differ diff --git a/apps/web/test-results/screenshots/action-log-08-after-refresh.png b/apps/web/test-results/screenshots/action-log-08-after-refresh.png index 92954724..bef5ddad 100644 Binary files a/apps/web/test-results/screenshots/action-log-08-after-refresh.png and b/apps/web/test-results/screenshots/action-log-08-after-refresh.png differ diff --git a/apps/web/test-results/screenshots/multisig-01-initial.png b/apps/web/test-results/screenshots/multisig-01-initial.png new file mode 100644 index 00000000..382b606b Binary files /dev/null and b/apps/web/test-results/screenshots/multisig-01-initial.png differ diff --git a/apps/web/test-results/screenshots/multisig-02-first-sign.png b/apps/web/test-results/screenshots/multisig-02-first-sign.png new file mode 100644 index 00000000..d07e11ed Binary files /dev/null and b/apps/web/test-results/screenshots/multisig-02-first-sign.png differ diff --git a/apps/web/test-results/screenshots/multisig-03-duplicate-rejected.png b/apps/web/test-results/screenshots/multisig-03-duplicate-rejected.png new file mode 100644 index 00000000..5293bda0 Binary files /dev/null and b/apps/web/test-results/screenshots/multisig-03-duplicate-rejected.png differ diff --git a/apps/web/test-results/screenshots/multisig-04-approved.png b/apps/web/test-results/screenshots/multisig-04-approved.png new file mode 100644 index 00000000..6a049e60 Binary files /dev/null and b/apps/web/test-results/screenshots/multisig-04-approved.png differ diff --git a/apps/web/test-results/visual-armor-approvals.png b/apps/web/test-results/visual-armor-approvals.png new file mode 100644 index 00000000..1f81c9de Binary files /dev/null and b/apps/web/test-results/visual-armor-approvals.png differ diff --git a/apps/web/test-results/visual-armor-dashboard.png b/apps/web/test-results/visual-armor-dashboard.png new file mode 100644 index 00000000..d80e4573 Binary files /dev/null and b/apps/web/test-results/visual-armor-dashboard.png differ diff --git a/apps/web/test-results/visual-armor-full.png b/apps/web/test-results/visual-armor-full.png new file mode 100644 index 00000000..5758e145 Binary files /dev/null and b/apps/web/test-results/visual-armor-full.png differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/test-finished-1.png b/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/test-finished-1.png new file mode 100644 index 00000000..eb6e3194 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/video.webm b/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/video.webm new file mode 100644 index 00000000..d7467d98 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-4fd99-oval-cards-with-Border-Beam-chromium/video.webm differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/test-finished-1.png b/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/test-finished-1.png new file mode 100644 index 00000000..77d3c6f5 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/video.webm b/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/video.webm new file mode 100644 index 00000000..591b8682 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-5a0f3-nClaw-panel-with-Brain-icon-chromium/video.webm differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/test-finished-1.png b/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/test-finished-1.png new file mode 100644 index 00000000..4a8c5351 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/test-finished-1.png differ diff --git a/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/video.webm b/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/video.webm new file mode 100644 index 00000000..348ce571 Binary files /dev/null and b/apps/web/test-results/visual-armor-upgrade-Visua-8ff78-board-with-Magic-UI-effects-chromium/video.webm differ diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index cd8dfa08..2af04838 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -5,15 +5,15 @@ --- -## 📍 當前狀態 (2026-03-24 16:15) +## 📍 當前狀態 (2026-03-24 23:50) | 項目 | 狀態 | |------|------| -| **當前 Phase** | **Phase 10 Sentry + OTEL CI/CD 整合** | +| **當前 Phase** | **Phase 10 Sentry + OTEL + UX 修復** | | **Day** | Day 6 | -| **下一步** | CD #23479188207 (OTEL) 構建中 → Sentry Tunnel (#45) → SignOz 驗證 (#46c) | -| **重大發現** | 🔴 **Sentry DSN 內網 IP 觸發區域網路權限對話框** (已暫時停用) | -| **CI/CD** | ✅ OTEL 環境變數已加入 (cd7d63e),Pre-flight Check 通過 | +| **下一步** | CD 3837827 排隊 → mock_fallback 診斷 | +| **重大修復** | ✅ Incident-Approval 同步 + ApprovalCard UX + CI 優化 (20min→3min) | +| **CI/CD** | ✅ Docker Verify PR-only (77c6bf3) + 友善部署通知 (2bb7643) | ### 🧠 認知覺醒計畫 Phase 6 施工順序 (C-Suite 2026-03-23 統帥方案) @@ -41,6 +41,17 @@ | 時間 | 事件 | 負責人 | |------|------|--------| +| 2026-03-24 23:50 | **🎨 ApprovalCard UX 優化 (3837827)**: 標題與 kubectl 命令分離 + AI 標籤清理 | Claude Code | +| 2026-03-24 23:45 | **🔧 Incident-Approval 同步 (b645981)**: Alertmanager webhook 同時創建 Incident + Approval (活躍事件修復) | Claude Code | +| 2026-03-24 23:40 | **📱 CD 通知格式改善 (2bb7643)**: 友善部署通知 (版本/時間/作者/SHA) | Claude Code | +| 2026-03-24 23:35 | **⚡ CI 優化 (77c6bf3)**: Docker Verify 只在 PR 執行 (20-30min → ~3min) | Claude Code | +| 2026-03-24 23:30 | **🔧 NetworkPolicy DNS/HTTPS 修復**: K8s Pod Telegram 連線修復 (kubectl patch) | Claude Code | +| 2026-03-24 23:25 | **🔑 Telegram K8s Secret 配置**: OPENCLAW_TG_BOT_TOKEN + CHAT_ID + WHITELIST 注入 | Claude Code | +| 2026-03-24 17:55 | **🔧 NetworkPolicy Sentry Egress (d08290b)**: 新增 192.168.0.110:9000 (Sentry) + :5000 (Harbor) 出口白名單 (#38) | Claude Code | +| 2026-03-24 17:50 | **📦 Workflow 整合 (490cd54)**: 停用 deploy-prod.yml.disabled,僅保留 cd.yaml v2.0 (避免重複部署/selector 衝突) | Claude Code | +| 2026-03-24 17:30 | **🌐 i18n 語言策略**: UI 繁中 + 技術英文,建立 feedback_i18n_language_strategy.md + 更新 Skill 01 | Claude Code | +| 2026-03-24 17:20 | **🔧 i18n 翻譯修復**: 補齊 agent/metrics/incident 命名空間 (zh-TW.json + en.json) | Claude Code | +| 2026-03-24 16:45 | **🔧 Health Check 修復 (ab240c6)**: kubectl exec 加入 -c api 容器名稱 + 增加 sleep 15s | Claude Code | | 2026-03-24 16:25 | **✅ Sentry Tunnel 完成 (b20987e)**: /api/sentry-tunnel API Route + sentry.client.config.ts 使用 tunnel + 重新啟用 NEXT_PUBLIC_SENTRY_DSN | Claude Code | | 2026-03-24 16:10 | **📊 OTEL CI/CD 監控 (cd7d63e)**: CI/CD workflows 加入 OTEL exporter → SignOz (192.168.0.121:4318) | Claude Code | | 2026-03-24 16:05 | **🔧 API import 修復 (75c991d)**: 修正 ruff I001 lint 錯誤 (import 排序) | Claude Code |