# 运维时区全局北京 — 验证报告（2026-06-09）

## 自动化

| 检查 | 结果 |
|------|------|
| `bash scripts/local_verify.sh` | PASS |
| `bash deploy/pre_deploy_check.sh` | **7/7 PASS** |
| `pytest test_operator_tz test_schedule_next_run test_display_time` | PASS |
| `npm run type-check` | PASS |
| `cd frontend && npx vite build` | PASS |

## API 契约（本地 :8600）

创建 cron `0 2 * * *` 推送调度：

- `next_run` = `2026-06-09 18:00:00`（UTC naive）
- 换算北京时间 = **2026-06-10 02:00**（与「每天 02:00 北京」一致）

脚本：Agent 会话内 httpx 一次性创建/断言/删除（未入仓）。

## 浏览器 E2E（Playwright，本地 `http://127.0.0.1:8600`）

```bash
cd frontend && npx playwright test e2e/pages/schedules-cycle.spec.mjs e2e/pages/schedules-timezone.spec.mjs
```

| 用例 | 结果 |
|------|------|
| E2E-SCH-002 新建调度显示「开始执行周期」 | PASS |
| E2E-SCH-003 对话框显示「时间为北京时间（Asia/Shanghai）」 | PASS |
| E2E-SCH-004 `next_run` 列显示 `2026-06-10 02:00:00`（非 UTC 10:00、非裸 ISO Z） | PASS |

新增：`frontend/e2e/pages/schedules-timezone.spec.mjs`

## 生产部署（2026-06-09 · `863e49e` 全量）

| 检查 | 结果 |
|------|------|
| `NEXUS_PROBE_MODE=origin bash scripts/prod_health_check.sh` | **PASS**（含时区扩展项） |
| `/health` | ok |
| `/app/` | HTTP 200 |
| 告警 `date_from=not-a-date` | HTTP **422** |
| 审计 `/api/audit/?date_from=bad` | HTTP **422** |
| cron `0 2 * * *` 创建 | `next_run=2026-06-09 18:00:00`（UTC naive → 北京次日 02:00） |
| `/app/assets/SchedulesPage-*.js` | 含「时间为北京时间」文案（源站静态资源 grep） |

部署命令：`NEXUS_DEPLOY_PATH=/opt/nexus bash deploy/deploy-production.sh`

### 浏览器终验说明

- 生产登录受 IP 白名单约束；本机 Playwright 经隧道登录返回 **403**（预期行为）。
- UI 时区提示与 `next_run` 列展示：本地 E2E（上表）+ 生产 API/静态资源探针已覆盖。
- **用户终验**（可选）：在已白名单 IP 打开 `/app/#/schedules` 核对 Picker 提示与 `next_run` 列。

### 前端 hash 对齐（Wave 0）

- 升级后曾漂移：容器 `index-FhWfGFoM.js` ≠ Git `index-mgwiCK5j.js`。
- **已修复**：`NEXUS_ROOT=/opt/nexus bash deploy/sync_webapp_to_container.sh` → 入口 `index-mgwiCK5j.js` HTTP 200。
- 后续 `nexus-1panel.sh upgrade` / `deploy-production.sh` 将自动执行 sync。
