- ADR-037 監控增強架構 - MONITORING_MASTER_PLAN 主計畫 - MASTER_EXECUTION_SCHEDULE 執行排程 - Phase D/E/Worker HPA Runbooks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
14 KiB
RunBook: 前端 UI/UX 核心痛點徹底解決方案
類型: 架構設計 + 實施 RunBook
優先級: 🔴 P0 (核心競爭力)
建立: 2026-03-29 12:38 (台北)
建立者: Antigravity
核心命題: 讓 AWOOOI 的前端「讓人看一眼就驚艷,用一次就上癮」
一、Claude Code 前端弱點診斷
1.1 五大結構性弱點
| 弱點 | 後果 | 解法 |
|---|---|---|
| 視覺感知盲區 | 代碼語法正確,但視覺效果差 | Playwright 截圖 + 統帥視覺主控 |
| CSS 語境失憶 | 改 A 壞 B,不知道全局 CSS 影響 | Storybook 隔離組件 + TypeCheck |
| 動畫設計無感 | 150ms 快閃 vs 300ms 遲滯無法感知 | 在 Storybook Story 中定義動畫標準 |
| 設計意圖推斷不足 | Nothing.tech 審美需要視覺參照 | 每個組件附帶規格截圖 |
| Safari 兼容性盲點 | backdrop-blur 在 Safari 有 bug |
Playwright multi-browser E2E |
1.2 技術債現況(截至 2026-03-29)
i18n 違規:40+ 處(TECHNICAL_DEBT_PHASE2.md)
shadcn/ui 殘留:已部分廢除,但需全面確認
GenUI Registry:只有基礎 5 張卡片,缺少監控類
Knowledge Base:頁面空白,無後端
Omni-Terminal:外殼完整,SSE 事件類型未完全對接
二、九大行動詳細實施計畫
🔴 行動 1: i18n 閃電清零(工時:4h)
策略:一次性掃描→批量修復,非逐一處理
# Step 1.1: 自動掃描所有硬編碼字串
cd /Users/ogt/awoooi/apps/web
# 掃描 TSX 中的英文硬編碼(排除技術識別符)
grep -rn '"[A-Z][A-Z]' src/ --include="*.tsx" --include="*.ts" | \
grep -v "//.*\"" | \
grep -v "className=" | \
grep -v "href=" | \
grep -v "id=" | \
grep -v "import " > /tmp/en_violations.txt
# 掃描中文硬編碼
grep -rn "\"[^\x00-\x7F]" src/ --include="*.tsx" | \
grep -v "//.*\"" > /tmp/zh_violations.txt
echo "英文違規:$(wc -l < /tmp/en_violations.txt) 處"
echo "中文違規:$(wc -l < /tmp/zh_violations.txt) 處"
已知 P0 違規快速修復清單(根據 TECHNICAL_DEBT_PHASE2.md):
// ❌ agent/data-pincer.tsx:50-78(需修復)
// 現在:
const statuses = {
standby: 'STANDBY',
analyzing: 'ANALYZING',
executing: 'EXECUTING',
awaiting: 'AWAITING APPROVAL',
error: 'ERROR'
}
// ✅ 修復後:
const statuses = {
standby: t('status.standby'),
analyzing: t('status.analyzing'),
executing: t('status.executing'),
awaiting: t('status.awaitingApproval'),
error: t('status.error')
}
// ❌ status-orb.tsx:16-31
// 現在:
const STATUS_TEXT = {
idle: 'Idle',
thinking: 'Thinking',
executing: 'Executing',
awaiting: 'Awaiting Approval'
}
// ✅ 修復後:
const STATUS_TEXT = {
idle: t('status.idle'),
thinking: t('status.thinking'),
executing: t('status.executing'),
awaiting: t('status.awaitingApproval')
}
需要同步更新的字典檔:
// apps/web/messages/zh-TW.json(追加)
{
"status": {
"idle": "待機",
"thinking": "分析中",
"executing": "執行中",
"awaitingApproval": "等待核准",
"error": "錯誤",
"standby": "待機",
"analyzing": "分析中"
}
}
// apps/web/messages/en.json(追加)
{
"status": {
"idle": "Idle",
"thinking": "Thinking",
"executing": "Executing",
"awaitingApproval": "Awaiting Approval",
"error": "Error",
"standby": "Standby",
"analyzing": "Analyzing"
}
}
驗收指令(必須通過):
cd apps/web
# 確認無中文硬編碼
if grep -rn '"[^\x00-\x7F]' src/ --include="*.tsx" | grep -v "//"; then
echo "❌ 仍有中文硬編碼!"
exit 1
else
echo "✅ 中文硬編碼清零"
fi
# TypeScript 編譯驗證(workflow 硬規則)
pnpm exec tsc --noEmit
🔴 行動 2: Storybook 組件庫建立(工時:8h)
這是解決 AI 視覺感知盲區的根本方案。
# Step 2.1: 安裝 Storybook
cd apps/web
pnpm add -D storybook@latest @storybook/nextjs @storybook/addon-essentials \
@storybook/addon-interactions @storybook/test
npx storybook@latest init --builder webpack5
# Step 2.2: 配置 Nothing.tech 主題
必須上架的 10 個核心組件 Story:
| 組件 | Nothing.tech 規格 | Story 狀態 |
|---|---|---|
GlassCard |
bg-white/70 backdrop-blur-[20px] border border-black/[0.06] |
Loading / Content / Error |
StatusOrb |
燈號 + animate-ping(critical 時) |
idle / thinking / executing / critical |
ApprovalCard |
1.0 ConversationalView 風格 | LOW / MEDIUM / HIGH / CRITICAL |
OmniTerminal |
VT323 字體 + 綠色游標閃爍 | empty / thinking / streaming / error |
HostCard |
CPU/Memory 橫條 + 脈搏點 | healthy / warning / critical |
MetricsCard |
數字大字 + 趨勢箭頭 | up / down / stable |
SystemHealthCard |
燈號矩陣 5x5 | all-healthy / some-warning / critical |
FinOpsCard |
成本分解 + 可省金額 | monthly / quarterly |
SLOCard |
達成率 + 趨勢 | healthy / at-risk / breached |
AnomalyFrequencyCard |
頻率統計 + 升級建議 | normal / repeat / escalate |
Storybook Story 範例(GlassCard):
// apps/web/src/components/ui/glass-card.stories.ts
import type { Meta, StoryObj } from '@storybook/react';
import { GlassCard } from './glass-card';
const meta: Meta<typeof GlassCard> = {
title: 'AWOOOI/UI/GlassCard',
component: GlassCard,
parameters: {
// Nothing.tech 白底背景
backgrounds: {
default: 'nothing-white',
values: [{ name: 'nothing-white', value: '#F5F5F0' }],
},
// 規格文件截圖
docs: {
description: {
component: `
Nothing.tech 白玻璃卡片。固定規格:
- bg: bg-white/70
- blur: backdrop-blur-[20px]
- border: border border-black/[0.06]
- radius: rounded-xl
`,
},
},
},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof GlassCard>;
export const Default: Story = {
args: { children: '玻璃卡片內容' }
};
export const WithCriticalBorder: Story = {
args: {
children: '緊急狀態',
className: 'border-status-critical border-2'
}
};
🔴 行動 3: AI 視覺審查 SOP(工時:2h 建立,後續 0 工時)
建立標準作業程序,讓 AI 自主截圖並等待統帥審核:
## AI 前端修改 SOP(強制執行)
### 修改前
1. 查閱 Storybook 對應組件的規格 Story
2. 確認 Nothing.tech 視覺 Token(詳見 tailwind.config.ts)
### 修改中
3. 修改代碼
4. 執行 `pnpm exec tsc --noEmit`(語法驗證)
### 修改後(🆕 新增強制步驟)
5. 啟動 Dev Server:`pnpm dev`
6. 執行截圖腳本:
```bash
cd apps/web
pnpm exec playwright screenshot \
--browser chromium \
http://localhost:3000 \
docs/screenshots/$(date +%Y%m%d-%H%M)/homepage.png
- 截圖存至
docs/screenshots/{date}/{component}.png - 在 LOGBOOK 記錄:「已截圖,視覺存檔 docs/screenshots/xxx/yyy.png」
- 等待統帥視覺審批後方可 commit
---
### 🟠 行動 4: Omni-Terminal 後端全接通(工時:8h)
根據 `ADR-031` 和 `AWOOOI_AGENTIC_WORKSPACE_ROADMAP.md` 的神經連接藍圖:
#### 4.1 三大 SSE 事件類型定義
```python
# apps/api/src/api/v1/terminal.py
# 擴充現有 SSE 端點
class SSEEventType(str, Enum):
THOUGHT = "thought" # Agent 思考流
TOOL_CALL = "tool_call" # 工具調用(含微動畫觸發信號)
TOOL_RESULT = "tool_result" # 工具結果
RENDER_UI = "render_ui" # 動態渲染 GenUI 組件
STREAM_END = "stream_end" # 思考流結束
# 範例事件:
async def stream_terminal_response(command: str):
# 1. 思考流
yield f"event: thought\ndata: {json.dumps({'text': '[Investigator] 分析指令...'})}\n\n"
# 2. 工具調用(觸發前端 CSS 動畫)
yield f"event: tool_call\ndata: {json.dumps({'tool': 'kubectl_get', 'args': {'resource': 'pod', 'namespace': 'awoooi-prod'}})}\n\n"
# 3. 工具結果
yield f"event: tool_result\ndata: {json.dumps({'pods': [...]})}\n\n"
# 4. 渲染 GenUI 卡片(前端動態載入組件)
yield f"event: render_ui\ndata: {json.dumps({'component': 'SystemHealthCard', 'props': {...}})}\n\n"
# 5. 結束
yield f"event: stream_end\ndata: {json.dumps({'success': True})}\n\n"
4.2 前端 SSE 事件處理器(關鍵)
// apps/web/src/hooks/useTerminalSSE.ts
// 修改現有 SSE hook,增加 tool_call 動畫觸發
const useTerminalSSE = (commandId: string) => {
const [state, setState] = useTerminalStore();
useEffect(() => {
const es = new EventSource(`/api/v1/terminal/stream/${commandId}`);
// 思考流
es.addEventListener('thought', (e) => {
const data = JSON.parse(e.data);
setState(s => ({ ...s, thoughts: [...s.thoughts, data.text] }));
});
// 工具調用 → 觸發微動畫
es.addEventListener('tool_call', (e) => {
const data = JSON.parse(e.data);
setState(s => ({
...s,
activeToolCall: data.tool, // UI 顯示「正在執行 kubectl_get...」
isAnimating: true
}));
});
// GenUI 動態渲染(核心功能!)
es.addEventListener('render_ui', (e) => {
const { component, props } = JSON.parse(e.data);
setState(s => ({
...s,
renderedCards: [...s.renderedCards, { component, props }]
}));
});
es.addEventListener('stream_end', () => {
setState(s => ({ ...s, isStreaming: false, isAnimating: false }));
es.close();
});
return () => es.close();
}, [commandId]);
};
🟠 行動 5: GenUI Registry 擴充(工時:8h)
新增 5 張監控類 GenUI 卡片(詳細規格見 MONITORING_ARCHITECTURE_DEEP_DIVE.md):
// apps/web/src/components/genui/registry.ts
export const GENUI_COMPONENTS = {
// 現有:
'MetricsCard': () => import('./cards/MetricsCard'),
'K8sPodCard': () => import('./cards/K8sPodCard'),
// 🆕 監控類(Wave M-3):
'SystemHealthCard': () => import('./monitoring/SystemHealthCard'),
'ServiceDetailCard': () => import('./monitoring/ServiceDetailCard'),
'FinOpsCard': () => import('./monitoring/FinOpsCard'),
'SLODashboardCard': () => import('./monitoring/SLODashboardCard'),
'AlertChainStatusCard': () => import('./monitoring/AlertChainStatusCard'),
'AnomalyFrequencyCard': () => import('./monitoring/AnomalyFrequencyCard'),
'MTTRCard': () => import('./monitoring/MTTRCard'),
}
三、前端改善路線圖時間表
📅 本週(立即):
[4h] i18n 閃電清零(一次性全修)
[2h] AI 視覺審查 SOP 建立(.awoooi-agent-rules.md 追加)
📅 Week 2-3:
[8h] Storybook 10 個核心組件 Story
[8h] Omni-Terminal 後端全接通(三種 SSE 事件)
📅 Week 4-5:
[8h] 監控 GenUI 卡片擴充(7 張新卡片)
[8h] Nexus 頁面 AI 自治率 UI 組件
📅 Month 2:
[16h] Knowledge Base 後端 + 前端完整建設
[8h] Visual Regression Testing CI 整合
📅 Month 3(Phase 4 視覺靈魂注入):
[?h] 品牌 3D 資產 + Q 版 OpenClaw
[?h] 全站微動畫升級(150ms 快閃標準)
[?h] Nothing.tech 認證級別的設計審計
四、強制驗收標準
每次前端 PR 合併前,必須通過以下全部驗收:
# 1. TypeScript 無錯誤(前端美學 Workflow 硬規則)
cd apps/web && pnpm exec tsc --noEmit
# 2. i18n 無硬編碼(CI 攔截)
[ -z "$(grep -rn '"[^\x00-\x7F]' src/ --include='*.tsx')" ] || exit 1
# 3. Storybook 可正常 build(確保組件獨立可用)
pnpm storybook build
# 4. E2E Smoke 測試通過
pnpm exec playwright test --grep @smoke
# 5. 截圖存檔(AI 執行,統帥視覺審批)
pnpm exec playwright screenshot http://localhost:3000 docs/screenshots/pr-{NUMBER}/homepage.png
# 6. Build 成功(生產環境兼容)
pnpm run build
⚠️ 架構安全補丁(2026-03-29 更新,行動 1 開始前必讀)
來源:
ARCHITECTURAL_RISK_WAR_GAME.md深度沙盤推演,代碼確認級別
補丁:Feature Freeze 前必須建立 release/v1.x 穩定分支
問題:行動 1(i18n 閃電清零)需要全域替換 src/ 底下數千行代碼,main 分支會進入持續 3-5 天的「混沌狀態」。若此期間生產爆發 P0 Bug(如簽核按鈕失效),無法切出乾淨的 Hotfix 分支,導致修復與重構互相衝突。
🔴 行動 1 開始前,必須先建立
release/v1.x穩定分支!
必須在行動 1 之前執行
# Step 0(行動 1 前置):建立穩定基準分支
git checkout main
git pull origin main
git checkout -b release/v1.x
git push origin release/v1.x
# 在 GitHub 設定 release/v1.x 為 Protected Branch
# Settings → Branches → Add branch protection rule → release/v1.x
# ✅ Require pull request reviews (1 approver)
# ✅ Do not allow bypassing the above settings
正確的行動順序
Step 0:建立 release/v1.x(🆕 前置步驟,必須先做)
Step 1:宣佈 Frontend Feature Freeze(禁止非 i18n PR 合併前端代碼)
Step 2:i18n 閃電清零(在 fix/i18n-zero-violation 分支進行)
Step 3:PR 合併到 main → 解除 Frontend Freeze
Step 4:ESLint i18n Plugin 切換為 error 模式
Step 5:繼續行動 2-9(Storybook、Terminal 等)
Freeze 期間 P0 Hotfix 緊急流程
# 情境:簽核按鈕在生產失效,i18n 清零正在進行中
# 1. 從穩定基準切出 hotfix(不影響 i18n 重構)
git checkout release/v1.x
git checkout -b hotfix/fix-approval-button
# 2. 最小化修復(只改 Bug,不動其他代碼)
# ... 修復代碼 ...
git add . && git commit -m "fix: approval button not responding on mobile"
# 3. PR 到 release/v1.x → CD 直接部署 release 分支
git push origin hotfix/fix-approval-button
# → PR 合併到 release/v1.x
# → 觸發 CD 部署(CD 配置需支援 release/* 分支)
# 4. Cherry-pick 到 main(不中斷 i18n 重構)
git checkout main
git cherry-pick <hotfix-commit-hash>
# 若有衝突:手動解決後繼續
Hotfix 觸發條件(須加入 HARD_RULES.md)
P0 Hotfix 判定標準(任一條件符合即觸發):
□ 統帥無法使用核心功能(簽核按鈕、登入、Telegram 通知)
□ Sentry P0 Error 每分鐘 > 10 次
□ 服務 availability < 99%(監控頁面顯示)
□ OpenClaw 決策鏈完全中斷超過 5 分鐘