# AI 觀測台 UI Governance

> Scope: `/observability/*` pages using `ewoooc_base.html` and `.momo-observability-mode`.

## 目標

AI 觀測台是「AI 中樞控制室」，不是 Bootstrap 報表頁。任何新增或修改都必須維持：暖色焦糖系、Noto Sans TC、點陣方格、卡片化資料面、可降級空狀態。

## 必守規範

- 使用 `static/css/observability-system.css` 的 token 與 utility class。
- 標題使用 `--obs-title-size`，KPI 數字使用 `--obs-value-size`。
- 圖表容器使用 `.obs-chart-frame`、`.obs-chart-frame-tall`、`.obs-chart-frame-slim`。
- 頁面資料缺表或 migration 未完成時，顯示安全空狀態，不得把 SQL exception 顯示給使用者。
- 側欄必須維持暖深咖啡背景，第二/三層文字要有足夠對比。
- 表格必須有暖色表頭、row hover、長文字換行保護。
- 手機與中螢幕要能自動從多欄收成單欄。

## 禁止事項

- 不要在 template 裡新增 Times / Georgia / serif 作為主標題字型。
- 不要新增紫色系、純黑 sidebar、純白卡片 hover。
- 不要把整頁做成寬表格；資料密集內容優先用卡片、矩陣、可橫向 overflow 的表格。
- 不要硬寫超大 `font-size: clamp(...)`；先調 token。
- 不要新增 `style="height:..."` 圖表容器；使用 chart frame class。
- 不要用 `查詢失敗: ProgrammingError...` 顯示給使用者。

## 新頁 checklist

1. Template 設定正確 `active_page`，讓 `observability-system.css` 載入。
2. Hero 有清楚頁面任務，不做簡報封面式大字。
3. 第一屏有 3 到 6 個可行動 KPI，不堆原始資料。
4. 主資料區先呈現結論，再給明細。
5. 空資料、缺表、外部服務未接入都要是可讀狀態。
6. 10 頁巡檢不得出現 `Traceback`、`UndefinedError`、`ProgrammingError`、`relation "`、`查詢失敗:`。

## 驗收指令

### 1. Repo 靜態 UI guard

先跑本地 guard，避免把已知 UI/UX 回歸重新帶進 repo：

```bash
scripts/check_observability_suite.sh
```

若只想跑靜態檢查：

```bash
python3 scripts/check_observability_ui.py
```

如果修改了 `static/css/observability-system.css`，先同步 Flask 實際服務用的 mirror：

```bash
python3 scripts/sync_observability_css.py
python3 scripts/sync_observability_css.py --check
```

或透過既有 quick review 選單執行第 8 項完整 QA 套件、第 6 項靜態 UI guard、第 9 項 CSS mirror sync：

```bash
./scripts/quick_review.sh
```

非互動模式可直接用於部署腳本或 CI：

```bash
./scripts/quick_review.sh --sync-observability-css
./scripts/quick_review.sh --check-observability-css
./scripts/quick_review.sh --observability-qa
```

指定不同環境時：

```bash
./scripts/quick_review.sh --observability-smoke --base-url https://mo.wooo.work
./scripts/quick_review.sh --observability-qa --base-url https://mo.wooo.work
./scripts/quick_review.sh --observability-qa --skip-production
```

Guard 會檢查：

- 觀測台頁面契約集中在 `scripts/observability_contract.py`，新增/改名頁面先改這裡。
- Times / Georgia 等非規範標題字型。
- SQL/Jinja exception 文案外露。
- 圖表 `style="height:..."` 與靜態 `style="width:..."`。
- 過大標題 clamp 與純白 hover/card surface。
- 觀測台 CSS 必要 token / utility class 是否仍存在。
- 側欄是否維持 `AI 中樞 → AI 觀測台 → 分組頁面` 的收納結構。
- 側欄是否維持暖深咖啡背景與第二/三層足夠對比。
- Topbar 是否仍載入觀測台 CSS 與健康 indicator。
- 10 個觀測頁的 `active_page`、側欄 URL、側欄 label、`momo-observability-mode` 掛載清單是否一一對齊。
- 10 個側欄 URL 是否都在 `routes/admin_observability_routes.py` 有對應 Flask route。
- `static/css/observability-system.css` 與實際 Flask static 服務用的 `web/static/css/observability-system.css` 必須一致。
- CD deploy gate 的正反案例 self-test 是否通過。

### 2. Production 10 頁 HTTP 巡檢

建議使用 repo 內建腳本：

```bash
python3 scripts/check_observability_pages.py
```

或透過 quick review 選單執行第 7 項。

此巡檢不只檢查 HTTP 200，也會檢查：

- `/health` 必須回 200 且包含 healthy marker。
- 不得出現 framework / database exception 文案。
- 每頁必須包含自己的核心標題與內容 marker。
- 每頁必須載入 `momo-observability-mode`、`observability-system.css` 與 topbar AI 觀測台 indicator。
- `/static/css/observability-system.css` 必須能線上 200 載入，且包含核心觀測台 token/class。
- HTML 不能小到像空殼頁或錯誤 fallback。

```bash
python3 - <<'PY'
import urllib.request
pages=[('/observability/overview','總覽'),('/observability/agent_orchestration','Agent'),('/observability/business_intel','商業'),('/observability/host_health','主機'),('/observability/ai_calls','AI 呼叫'),('/observability/budget','預算'),('/observability/promotion_review','晉升'),('/observability/rag_queries','RAG'),('/observability/quality_trend','品質'),('/observability/ppt_audit_history','PPT')]
needles=['Traceback','UndefinedError','ProgrammingError','Internal Server Error','relation "','查詢失敗:']
for path,label in pages:
    with urllib.request.urlopen('https://mo.wooo.work'+path,timeout=12) as r:
        html=r.read().decode('utf-8','ignore')
        found=[n for n in needles if n in html]
        print(f'{label}: HTTP {r.status}, issues={found or "none"}')
PY
```
