# Phase 2 深审 — Wave P2-3（WebSocket / Dashboard 告警链）

**日期**: 2026-06-04  
**范围**: 后端 WS 双通道 + 前端告警客户端 + Dashboard 刷新  
**标准**: `standards/line-walk-audit-standard-v2.md` 8 步

## 登记

| # | 文件 | 语言 | 行数 N | Read 范围 |
|---|------|------|--------|-----------|
| 1 | `server/api/websocket.py` | Python | 552 | 1–552 全文 |
| 2 | `frontend/src/composables/useWebSocket.ts` | TS | 178 | 1–178 全文 |
| 3 | `frontend/src/pages/DashboardPage.vue` | Vue | 415 | 1–415 全文 |
| 4 | `frontend/src/App.vue` | Vue | — | 247–260（WS 生命周期） |
| 5 | `server/api/settings.py` | Python | — | 759–828（alert-history GET） |

## 入口表

| 通道 | 路径 | 鉴权 |
|------|------|------|
| WS | `/ws/alerts?token=` | `_verify_ws_token` |
| WS | `/ws/sync?token=` | 同上 |
| HTTP | GET `/api/alert-history/` | JWT |
| HTTP | GET `/api/servers/stats` | JWT（Dashboard） |

## Closure 表

| H | 文件:行号 | 判定 | 理由 |
|---|-----------|------|------|
| H-WS-Auth | websocket.py:304-311,340-347 | SAFE | 无 token → 4001；无效 → 4401 |
| H-WS-Token | websocket.py:366-410 | SAFE | tv/updated_at 与 HTTP JWT 一致 |
| H-WS-ADR011 | websocket.py:9,296 | RISK | query JWT；单人运维已接受 |
| H-WS-Limit | websocket.py:49-52 | SAFE | MAX_CONNECTIONS=500 |
| H-WS-Heartbeat | websocket.py:139-165 | SAFE | 30s ping / 60s zombie |
| H-WS-Channel | websocket.py:246-249,531-551 | SAFE | alerts 与 sync 分 channel/manager |
| H-WS-Dedup | websocket.py:416-437 | SAFE | Telegram 5min 冷却；WS 仍实时 |
| H-WS-Recovery | websocket.py:512-513 | SAFE | recovery 清 cooldown |
| H-Frontend-Token | useWebSocket.ts:61 | RISK | URL query token；同 ADR-011 |
| H-Frontend-Auth | useWebSocket.ts:114-116 | SAFE | 4001/4401 → forceLogout |
| H-Frontend-XSS | useWebSocket.ts:99-102 | SAFE | snackbar 文本插值，无 v-html |
| H-Frontend-Singleton | useWebSocket.ts:17-18 | SAFE | 模块级单例；App 统一 connect |
| H-Dashboard-Refresh | DashboardPage.vue:393-397 | SAFE | WS alert → reload stats/alerts |
| H-Dashboard-API | DashboardPage.vue:302-337 | SAFE | http JWT 拉 stats/alert-history |
| H-App-Lifecycle | App.vue:257-259 | SAFE | login connect / logout disconnect |
| H-Alert-API | settings.py:768-828 | SAFE | alert-history JWT + 参数化 filter |

**len(H)=16, Closure=16**

## FINDING

无 P0/P1 新 FINDING。

## DoD

- [x] len(H) == Closure
- [x] websocket 全文 Read
- [x] 端到端链：Agent→broadcast_alert→Redis→WS→Dashboard refresh

## 验证

`bash scripts/local_verify.sh` — 全绿
