# ADR-071: 告警通知四類型架構 + KM 三段資料閉環

**狀態**: Accepted  
**日期**: 2026-04-11 (台北時間)  
**作者**: Claude Sonnet 4.6 + 首席架構師審查  
**關聯**: ADR-070（MCP 閉環）、ADR-068（飛輪冷啟動）

---

## 問題

AWOOOI Telegram 通知系統存在以下問題：

1. 所有告警統一用同一種卡片格式，資訊密度過高或過低
2. `incidents` 表缺少 metrics_before / metrics_after / k8s_state_after 欄位，無法做效果驗證
3. KM 知識沉澱缺少「執行前情境」，Playbook 無法學習「什麼情況下採用這個動作」
4. Drift 告警（Config 漂移）與一般服務告警混用同一卡片，語意不清

---

## 決定

### 四種通知類型

| Type | 名稱 | 觸發條件 | 特徵 |
|------|------|---------|------|
| TYPE-1 | 純資訊 | 非嚴重告警（Info/heartbeat）| 無按鈕，文字摘要 |
| TYPE-2 | 指標快照 | metrics_before 有數據 | 顯示 CPU/Mem/Disk 快照 |
| TYPE-3 | 人工審核 | needs_approval=True | Y/n 審核按鈕 |
| TYPE-4 | 自動修復結果 | auto_execute 完成 | 顯示執行結果 + metrics delta |
| TYPE-4D | Drift 告警 | alert_category=config_drift | Diff 截斷顯示 |

### 七種 alert_category 動態按鈕（TYPE-3 審核卡片）

```
service_down / high_resource / config_drift /
security_event / performance / data_issue / unknown
```

### DB Schema 變更（Migration: phase30_alert_types.sql）

新增欄位至 `incidents` 表：
```sql
alert_category      VARCHAR(50)
needs_approval      BOOLEAN DEFAULT false
metrics_before      JSONB
metrics_after       JSONB
k8s_state_after     TEXT
resolution_time_sec INTEGER
notification_type   VARCHAR(20)
signal_source       VARCHAR(50)
```

新增 Enum：`AlertCategory`, `NotificationType`

### KM 三段資料格式（km_conversion_service.py）

```markdown
## 效果驗證
- 指標變化: CPU 85%→12% | Mem 90%→45% | 重啟 3→0
- 恢復耗時: 47秒
- K8s 狀態: 2/2 Running
```

---

## 實作記錄

| 子任務 | Commit | 說明 |
|--------|--------|------|
| A — DB Migration | 325b385 | incidents 8 欄位 + 5 PgEnum，Production 已執行 |
| B — classify_notification() | 325b385 | 五型分類器 |
| C — send_info_notification() | 325b385 | TYPE-1 純資訊卡片 |
| D — 狀態機守衛 | 325b385 | `_check_incident_state_guard()` RESOLVED 防誤點 |
| E — _build_inline_keyboard() | 325b385 | 7 種 alert_category 動態按鈕 |
| F — send_drift_card() | 325b385 | TYPE-4D Drift Diff 截斷 |
| G — km_conversion_service | 325b385 | Incident→KM 自動轉換 |
| H — handle_manual_fix_done() | 325b385 | TYPE-4 手動修復 Bot 對話閉環 |
| I — metrics_before 閉環 | 1ec1965 | `_fetch_metrics_snapshot()` + DB 寫入 |
| J — KM delta 格式 | 1ec1965 | `_build_content()` 精簡 delta + k8s_state_after |

---

## 後果

### 正面
- 告警卡片語意清晰，操作員看一眼就知道需要做什麼
- KM 三段資料完整，飛輪可學習「在什麼情況下這個修復有效」
- Drift 告警獨立類型，避免和服務告警混淆

### 風險
- alert_category 分類依賴 LLM 判斷 → `unknown` fallback 保底
- metrics_before 在 execute 前抓取，若 execute 很快可能抓到 post-action 數據 → 可接受（誤差小）
