5.2 KiB
5.2 KiB
审计 — 监测槽开关 / 8h·24h / 暂停占槽 / 探针中文错误
日期:2026-06-11
Changelog:
docs/changelog/2026-06-11-watch-slot-monitoring-toggle.mddocs/changelog/2026-06-11-watch-probe-parse-error-fix.md
范围(未提交工作区,+799 / −124 行)
| 层级 | 文件 |
|---|---|
| 模型/迁移 | server/domain/models/__init__.py(monitoring_enabled、ttl_hours) |
server/infrastructure/database/migrations.py |
|
| Repository | server/infrastructure/database/watch_repo.py |
| Service | server/application/services/watch_service.py |
| API | server/api/watch.py(PATCH monitoring / ttl) |
| 探针 | server/background/watch_probe_runner.py |
server/infrastructure/ssh/remote_probe.py |
|
| 工具 | server/utils/watch_metrics.py |
server/utils/watch_state.py(新增 Redis 清理) |
|
server/utils/watch_probe_errors.py(新增 中文错误) |
|
| 前端 | frontend/src/composables/useWatchPins.ts |
frontend/src/components/watch/WatchSlotCard.vue |
|
frontend/src/components/watch/WatchSlotRow.vue |
|
frontend/src/components/watch/WatchProbeRecordsTable.vue |
|
frontend/src/utils/watchFormat.ts |
|
frontend/src/api/index.ts(http.patch) |
|
| 测试 | tests/test_watch_pins.py |
tests/test_watch_metrics.py |
|
tests/test_watch_probe_errors.py(新增) |
功能摘要
- 实时监测开关:
monitoring_enabled;关则停 5s 探针,槽位保留 - 8h / 24h:
ttl_hours+PATCH /pins/{slot}/ttl;默认 8h,显式切 24h - 暂停永久占槽:
monitoring_enabled=false时不参与 TTL 过期删除 - 时长到期:自动暂停(等同关开关),结束 session,不删 pin
- 恢复 Agent 60s:无活跃监测时清理
watch:live/proc/last;Agent 心跳逻辑未改 - parse_error 修复:Agent 有 CPU/内存时 SSH 失败不拖垮整轮;SSH 脚本加固
- 错误中文:后端写入 + 前端
formatProbeError兼容历史英文
Step 3 规则扫描
| H | 规则 | 结论 |
|---|---|---|
| H1 | 鉴权 / IDOR | PASS — 新 PATCH 均 get_current_admin;repo 带 admin_id |
| H2 | 无静默吞错 | PASS — 探针失败仍落库;Redis 清理失败会抛错(生产有 Redis) |
| H3 | 无新密钥 | PASS |
| H4 | CUD 审计 | PASS — watch_pin_pause / watch_pin_resume / watch_pin_ttl / remove |
| H5 | 输入边界 | PASS — Literal[8,24]、slot_index 0–3 |
| H6 | 迁移 | PASS — ALTER + duplicate column 容错 |
| H7 | 产品风险 | RISK 接受 — 4 槽均可永久暂停占用,需手动 X 释放(用户明确要求) |
逐模块走读
后端
| 模块 | 结论 | 备注 |
|---|---|---|
watch_repo._pin_still_occupied |
PASS | 暂停不占 TTL;开启监测才看过期 |
expire_due_pins |
PASS | 改为暂停 + end session,不 delete pin |
set_monitoring_enabled + _ensure_open_session |
PASS | TTL 到期后再开自动新 session |
_restore_idle_agent_watch |
PASS | 全局无监测才清 Redis |
replace_slot |
PASS | 保留槽位原 ttl_hours(审查项已修) |
probe_server_metrics |
PASS | Agent 基础指标优先;SSH 仅补 IO |
watch_probe_error_zh |
PASS | 与前端映射一致 |
前端
| 模块 | 结论 | 备注 |
|---|---|---|
WatchSlotCard |
PASS | 开关 + 8h/24h + 暂停态 UI |
tickCountdown |
PASS | 归零 refreshPins,不再误置 empty |
formatProbeError |
PASS | 状态/错误/来源中文化 |
WatchProbeRecordsTable |
PASS | 筛选器与列中文 |
审计中发现并修复
| 项 | 严重度 | 处理 |
|---|---|---|
mock_watch_redis 未 patch watch_state.get_redis |
P1 | 已修:remove_slot / set_slot_monitoring 单测 2 失败 → 19 passed |
遗留建议(非阻塞)
| 项 | 说明 |
|---|---|
| 设计文档 | 开关/暂停语义变更较大,建议补 docs/design/specs/ 短文(当前仅 changelog) |
| HTTP 集成测试 | PATCH monitoring/ttl 的 404/422 路径未覆盖 |
| TTL 到期审计 | 后台 expire_due_pins 无 audit_log(可接受,session.end_reason=expired 可查) |
| PATCH 404 语义 | 「槽位无效」与「槽位为空」均 404,与 POST 422 不一致 |
Closure
| H | 判定 | 依据 |
|---|---|---|
| H1–H6 | PASS | 鉴权、审计、迁移、探针落库均符合铁律 |
| H7 | RISK 接受 | 用户要求暂停永久占槽 |
DoD
.venv/bin/pytest tests/test_watch_metrics.py tests/test_watch_pins.py tests/test_watch_probe_errors.py— 19 passedcd frontend && npm run type-check- 审计修复:test fixture patch
watch_state.get_redis bash scripts/local_verify.sh/ 门控 7 道(部署前)- 生产浏览器:开关暂停、24h 切换、到期自动暂停、中文错误展示
验证命令
.venv/bin/pytest tests/test_watch_metrics.py tests/test_watch_pins.py tests/test_watch_probe_errors.py -q
cd frontend && npm run type-check
bash deploy/pre_deploy_check.sh
合并建议
Approve with notes — 功能完整、测试绿、安全与审计达标;部署前跑门控 + 浏览器终验。遗留 HTTP 集成测试与设计文档可跟进 PR。