# 2026-05-29 推送页面迭代 Round 2 — 设计文档

## 背景与目标

推送页面 Round 1 已完成 5 项功能（WS 实时进度、分组选择、历史增强、文件操作、推送校验）。用户在实际使用中发现 5 项体验/功能缺陷：

1. **推送失败需手动切页重试** — 失败后需跳到"重试队列"页面，操作割裂
2. **无法识别服务器在线状态** — 选中离线服务器推送必然超时失败，浪费等待时间
3. **推送完成无即时通知** — 批量推送耗时长，用户离开页面后无法得知结果
4. **文件管理器无法预览内容** — 不确定推送的是否是正确文件，需下载验证
5. **同步模式含义不明确** — "增量/全量/校验和"对非运维用户不直观

## 方案对比

### F1 失败自动重试

| 方案 | 优点 | 缺点 |
|------|------|------|
| A: 行内重试按钮 | 不离开页面，体验流畅 | 需要从推送结果中获取 retry_job_id |
| B: 自动重试无需按钮 | 全自动 | 可能对临时性错误造成无意义重试 |
| C: 弹窗显示失败列表+批量重试 | 可选择重试哪些 | 交互重 |

**选定方案 A** — 推送失败的行内"🔄 重试"按钮，利用现有 `PushRetryJob` + `/api/retries/` 体系

### F2 在线状态标识

| 方案 | 优点 | 缺点 |
|------|------|------|
| A: 选项文字前加🟢/🔴 | 直观，零交互成本 | 无 |
| B: hover 显示状态详情 | 信息更多 | 需额外交互 |

**选定方案 A** — 最简方案，API 已返回 `is_online` 字段

### F3 Telegram 通知

| 方案 | 优点 | 缺点 |
|------|------|------|
| A: 推送完成后发一条汇总通知 | 信息集中，不扰 | 延迟感知差 |
| B: 逐台通知 | 实时 | 消息太多 |
| C: 完成时汇总 + 部分失败时额外通知 | 覆盖全面 | 两条消息 |

**选定方案 A** — 推送完成后发一条汇总 Telegram 消息，含成功/失败数、失败服务器名、耗时

### F4 文件内容预览

| 方案 | 优点 | 缺点 |
|------|------|------|
| A: 点击文件名弹模态框预览 | 体验流畅 | 需新增后端端点 |
| B: 新 tab 打开 | 简单 | 跳离上下文 |

**选定方案 A** — 新增 `/api/sync/local-file-preview` 端点，前端模态框预览

### F5 同步模式说明

| 方案 | 优点 | 缺点 |
|------|------|------|
| A: radio 下方固定说明文字 | 简单直观 | 占空间 |
| B: hover tooltip | 不占空间 | 可能被忽略 |
| C: 模式旁❓图标hover显示 | 平衡 | 交互多一步 |

**选定方案 A** — radio 组下方增加动态说明文字，切换模式时更新

## 选定方案及理由

所有 5 项均选方案 A（最简方案），理由：
- 利用现有基础设施（重试体系、Telegram 模块、Redis heartbeat）
- 改动范围最小，风险最低
- 用户需求明确，无需复杂设计

## 接口/数据模型

### F1: 新增 WS 字段
- `broadcast_sync_progress()` 增加可选参数 `retry_job_id: int = None`
- WS 消息 `{type: "sync_progress", ..., retry_job_id: 123}` (失败时有值)

### F3: 新增 Telegram 函数
- `send_telegram_sync_complete(completed, failed, total, source_path, operator, failed_servers, duration_seconds)`

### F4: 新增 API 端点
- `POST /api/sync/local-file-preview` — `{path: str}` → `{name, size, content_base64, truncated, encoding_hint}`
- 新增 Schema: `LocalFilePreview`

## 安全与性能约束

- F1: 重试按钮调已有 `/api/retries/{id}/retry`，已有 JWT 认证 + 审计
- F3: Telegram 消息经 `sanitize_external_message()` 脱敏
- F4: 文件预览限制：仅 `/tmp/nexus_upload_*` 目录 + 最多 4KB + realpath 校验
- F4: 预览端点需 JWT 认证 + 审计日志

## 验收标准

1. F5: 切换同步模式 → 下方说明文字正确更新
2. F2: 服务器列表在线🟢/离线🔴标识正确
3. F1: 推送失败 → 行内出现重试按钮 → 点击可重试
4. F3: 推送完成 → Telegram 收到通知含详情
5. F4: 点击文件名 → 弹出预览框
