# Nexus 6.0 — 功能开发指南(SSOT) > **版本**: 2026-06-04 > **读者**: 接续开发工程师、AI Agent > **定位**: 后续功能开发的**主参考文档**(比 handoff 更细、比 changelog 更稳) > **关联**: [linux-dev-paths.md](linux-dev-paths.md) · [local-integration-test.md](local-integration-test.md) · [risk-acceptance-single-operator.md](risk-acceptance-single-operator.md) --- ## 目录 1. [项目概述](#1-项目概述) 2. [技术栈与仓库结构](#2-技术栈与仓库结构) 3. [启动模式与配置](#3-启动模式与配置) 4. [架构分层与请求生命周期](#4-架构分层与请求生命周期) 5. [认证、会话与安全](#5-认证会话与安全) 6. [数据模型(19 表)](#6-数据模型19-表) 7. [Redis 与实时数据流](#7-redis-与实时数据流) 8. [后台任务(Primary Worker)](#8-后台任务primary-worker) 9. [后端 API 全览](#9-后端-api-全览) 10. [核心业务模块详解](#10-核心业务模块详解) 11. [前端 SPA 架构](#11-前端-spa-架构) 12. [15 个业务页面功能说明](#12-15-个业务页面功能说明) 13. [Composables 与状态管理](#13-composables-与状态管理) 14. [WebSocket 与 WebSSH](#14-websocket-与-webssh) 15. [Agent 与子机协议](#15-agent-与子机协议) 16. [安装向导](#16-安装向导) 17. [本地开发、测试与门控](#17-本地开发测试与门控) 18. [部署与运维](#18-部署与运维) 19. [扩展开发指南](#19-扩展开发指南) 20. [不可改项与已接受风险](#20-不可改项与已接受风险) 21. [文档索引](#21-文档索引) --- ## 1. 项目概述 Nexus 是面向 **2000+ 子服务器** 的运维管理平台(中心机 + Agent 架构),核心能力: | 能力域 | 说明 | |--------|------| | **服务器资产** | CRUD、分类、Platform/Node、心跳监控、健康检查 | | **文件管理** | SSH 远程浏览/编辑/chmod/压缩,sudo 提权 | | **批量推送** | Nexus 主机 rsync → 子机,4 种 sync 模式,ZIP 上传,调度与重试 | | **脚本执行** | 脚本库 + 临时命令,SSH 并行或 Agent 长任务 | | **WebSSH** | 浏览器终端,多 Tab,命令日志 | | **告警** | CPU/内存/磁盘阈值,WebSocket + Telegram,恢复通知 | | **审计** | 全 CUD + 登录/WebSSH/推送 审计 | | **安全** | JWT + TOTP + IP 白名单 + Fernet 凭据加密 | **生产域名**: `https://api.synaglobal.vip` **后端端口**: `8600` **前端入口**: `/app/`(Vue 3 SPA,Vite 构建到 `web/app/`) --- ## 2. 技术栈与仓库结构 ### 2.1 技术栈 | 层 | 技术 | |----|------| | 后端 | Python 3.11+ · FastAPI · Async SQLAlchemy · Pydantic v2 | | 数据库 | MySQL 8.x | | 缓存/实时 | Redis 7(心跳、告警、WS 跨 worker、脚本执行状态) | | SSH | asyncssh 连接池 | | 前端 | Vue 3 · TypeScript · Vuetify 4 · Pinia · Vite | | 编辑器/终端 | Monaco Editor · xterm.js | | 进程守护 | Supervisor + Python self_monitor + Shell health_monitor | ### 2.2 目录结构 ``` Nexus/ ├── server/ # FastAPI 后端(Clean Architecture) │ ├── main.py # 入口、lifespan、中间件、路由挂载 │ ├── config.py # Pydantic Settings + DB 覆盖 │ ├── api/ # 路由层(JWT、校验、审计) │ ├── application/services/ # 业务编排 │ ├── domain/models/ # SQLAlchemy ORM(19 表) │ ├── infrastructure/ # DB/Redis/SSH/Telegram 实现 │ └── background/ # 后台循环任务 ├── frontend/ # Vue 3 SPA 源码 │ └── src/ │ ├── pages/ # 14 个页面 │ ├── components/ # 按模块分子目录 │ ├── composables/ # 业务逻辑(files/push/terminal…) │ ├── stores/ # Pinia(auth、files) │ ├── api/index.ts # HTTP 客户端 │ └── router/index.ts # Hash 路由 ├── web/app/ # 静态挂载点(index.html + assets/) │ └── install.html # 安装向导(独立静态页,非 Vue) ├── deploy/ # Supervisor、nginx、门控、部署脚本 ├── docker/ # compose 环境生成 ├── scripts/ # 本地 dev、验收、MCP ├── tests/ # pytest API 测试 └── docs/ # 设计、审计、changelog ``` ### 2.3 架构分层(禁止跨层直连) ``` frontend/pages → api/index.ts → server/api/*.py → application/services/*.py → infrastructure/* → domain/models ``` - **API 层**: 路由 + Pydantic + `Depends(get_current_admin)`,不写裸 SQL - **Service 层**: 业务编排,经 Repository 访问 DB - **Infrastructure**: SSH 池、Redis、Telegram、Fernet - **Domain**: ORM 模型,无 FastAPI 依赖 --- ## 3. 启动模式与配置 ### 3.1 两种启动模式 | 模式 | 条件 | 可用能力 | |------|------|----------| | **安装模式** | 仓库根无 `.env` | `/api/install/*`、`/app/install.html`、静态文件;其他 API **503** | | **正常模式** | 存在 `.env` 且 `SECRET_KEY` / `API_KEY` / `ENCRYPTION_KEY` / `DATABASE_URL` 齐全 | 全功能 + 后台任务 | `is_install_mode()` 在 **运行时** 检测 `.env`,安装向导写入后可立即切换(需重启 worker 加载完整 lifespan)。 ### 3.2 配置三写(安装向导 Step 3) 安装成功时**同时写入**: | 目标 | 内容 | |------|------| | `web/data/config.json` | 共享配置(API_BASE_URL、DB、API_KEY) | | `.env` | `NEXUS_*` 前缀,Python 启动必需 | | MySQL `settings` 表 | 可热覆盖的动态项(阈值、Telegram、pool 等) | **不可从 DB 覆盖**(仅 `.env`):`SECRET_KEY`、`API_KEY`、`ENCRYPTION_KEY`、`DATABASE_URL`。 ### 3.3 重要环境变量(`NEXUS_` 前缀) | 变量 | 说明 | 可 DB 覆盖 | |------|------|------------| | `NEXUS_DATABASE_URL` | `mysql+aiomysql://...` | ❌ | | `NEXUS_SECRET_KEY` | JWT HS256 | ❌ | | `NEXUS_API_KEY` | Agent 全局密钥 | ❌ | | `NEXUS_ENCRYPTION_KEY` | Fernet 凭据加密 | ❌ | | `NEXUS_REDIS_URL` | 默认 `redis://127.0.0.1:6379/0` | ✅ | | `NEXUS_API_BASE_URL` | 公网 URL(Agent curl 安装) | ✅ | | `NEXUS_CORS_ORIGINS` | 逗号分隔 | ✅ | | `NEXUS_DEPLOY_PATH` | 部署根路径 | ✅ | | `NEXUS_DB_POOL_SIZE` / `MAX_OVERFLOW` | 连接池 | ✅ | | `NEXUS_CPU/MEM/DISK_ALERT_THRESHOLD` | 告警阈值 % | ✅ | | `NEXUS_TELEGRAM_BOT_TOKEN` / `CHAT_ID` | 告警推送 | ✅ | | `NEXUS_LOGIN_ALLOWLIST_*` | 登录 IP 白名单 | ✅ | | `NEXUS_JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | 默认 60 | ✅ | | `NEXUS_TEST_ADMIN_PASSWORD` | 本地测试登录(不入 git) | — | 完整映射见 `server/config.py` 的 `DB_OVERRIDE_MAP`。 --- ## 4. 架构分层与请求生命周期 ### 4.1 HTTP 请求(普通 API) ``` Client → CORS → JwtAuthMiddleware → DbSessionMiddleware → Router → request.state.db → Service → Repo → MySQL ``` - **DbSessionMiddleware**: 每请求一个 `AsyncSession`,请求结束 close - **例外**: WebSocket、`/api/install/` 自建 session ### 4.2 Primary Worker 锁 多 worker uvicorn 时,**仅一个** worker 运行后台任务: 1. Redis `SETNX nexus:primary_worker`(TTL 30s,续期) 2. Redis 不可用时 fallback:`flock /tmp/nexus-primary.lock` 后台任务列表见 [§8](#8-后台任务primary-worker)。 ### 4.3 静态文件与 SPA - FastAPI 挂载 `web/app/` → `/app/` - Vue 使用 **Hash 路由** `#/servers`,刷新不依赖 nginx try_files - 构建: `cd frontend && npx vite build` → 输出 `web/app/index.html` + `assets/` --- ## 5. 认证、会话与安全 ### 5.1 管理端 JWT | 项目 | 说明 | |------|------| | 登录 | `POST /api/auth/login`(username + password + 可选 TOTP) | | Access Token | 响应 body,**仅存内存**(Pinia `auth.ts`) | | Refresh Token | HttpOnly Cookie `nexus_refresh`,`POST /api/auth/refresh` | | 过期 | Access 默认 60min;前端过期前 5min 主动 refresh | | 失效 | 改密/TOTP 变更 → `token_version` 递增,旧 JWT 失效 | | 防暴破 | 5 次失败 / 15min → HTTP 429 | | 会话空闲 | 8 小时(refresh 重用检测) | **JWT 中间件公开前缀**(无需 Bearer): `/api/auth/login` · `/api/auth/refresh` · `/api/auth/logout` · `/api/agent/` · `/api/install/` · `/api/settings/bing-wallpapers` · `/health` · `/ws/` · OpenAPI ### 5.2 TOTP | API | 说明 | |-----|------| | `POST /api/auth/totp/setup` | 返回 QR + secret | | `POST /api/auth/totp/enable` | 验证码确认 | | `POST /api/auth/totp/disable` | 需当前密码 + TOTP | ### 5.3 敏感操作二次验证(Re-auth) | 场景 | API | 需当前密码 | |------|-----|------------| | 查看 API Key | `POST /api/settings/api-key/reveal` | ✅ | | 查看 Telegram Token | `POST /api/settings/telegram/reveal-token` | ✅ | | 查看 Agent Key | `POST /api/servers/{id}/agent-key` | ✅ | | 生成安装命令 | `POST /api/servers/{id}/agent-install-cmd` | ✅ | | 改密 | `PUT /api/auth/password` | ✅ | ### 5.4 Agent API Key | 层级 | 行为 | |------|------| | Per-server | `servers.agent_api_key`(`nxs-*`),优先 | | 全局回退 | `NEXUS_API_KEY`(legacy,单人运维已接受) | | 未知 server_id | **拒绝**(batch 安装仍可能用 global key) | Header: `X-API-Key` 或 query(Agent 脚本约定)。 ### 5.5 凭据存储 - `Server.password` / `ssh_key_private` → Fernet(`ENCRYPTION_KEY`) - API 响应: `password_set: true`,**不返明文** - 密码预设: `encrypted_pw` 字段,前端 POST 后不入 localStorage ### 5.6 登录 IP 白名单 - `settings` + `.env`: `LOGIN_ALLOWLIST_ENABLED` - 手动 IP + 订阅 URL 解析(`ip_allowlist_refresh` 每 2h) - 登录 API 在 JWT 之前校验客户端 IP --- ## 6. 数据模型(19 表) 定义文件: `server/domain/models/__init__.py` | ORM | 表名 | 用途 | 关键字段 | |-----|------|------|----------| | `Platform` | `platforms` | 资产模板 | `name`, `category`, `default_protocols` | | `Node` | `nodes` | 资产树节点 | `parent_id`, `sort_order` | | `Server` | `servers` | 子服务器 | `domain`, `port`, SSH 凭据, `target_path`, `agent_api_key`, `is_online`, `system_info`, `files_elevation` | | `SyncLog` | `sync_logs` | 推送历史 | `status`, `sync_mode`, 字节/文件统计, `operator` | | `Admin` | `admins` | 管理员 | `password_hash`, `totp_*`, `token_version` | | `LoginAttempt` | `login_attempts` | 登录尝试 | 防暴破 | | `Setting` | `settings` | KV 配置 | `key` PK, `value` | | `PasswordPreset` | `password_presets` | SSH 密码模板 | `encrypted_pw` | | `SshKeyPreset` | `ssh_key_presets` | SSH 密钥模板 | `encrypted_private_key` | | `PushSchedule` | `push_schedules` | 定时任务 | `cron_expr`, `server_ids`, `schedule_type` push/script | | `PushRetryJob` | `push_retry_jobs` | 失败重试 | 指数退避, `max_retries=3` | | `AuditLog` | `audit_logs` | 审计(**7 天**自动清理) | `action`, `target_*`, `ip_address` | | `Script` | `scripts` | 脚本库 | `content`, `category` | | `ScriptExecution` | `script_executions` | 执行记录 | `results` JSON, `status` | | `DbCredential` | `db_credentials` | DB 凭据 | 脚本内 `$DB_*` 替换 | | `AlertLog` | `alert_logs` | 告警历史(**7 天**自动清理) | `is_recovery` | | `SshSession` | `ssh_sessions` | WebSSH 会话 | UUID `id` | | `CommandLog` | `command_logs` | 终端命令 | `command` ≤2000 字符 | | `QuickCommand` | `quick_commands` | 终端快捷命令 | `sort_order` | --- ## 7. Redis 与实时数据流 ### 7.1 Key 约定 | Key 模式 | TTL | 内容 | |----------|-----|------| | `heartbeat:{server_id}` | 600s | 最新心跳字段(HSET) | | `alerts:{server_id}` | 3600s | 活跃告警集合 | | `sync:cancel:{batch_id}` | — | 推送取消标记 | | `nexus:alerts` | Pub/Sub | 跨 worker WS 广播 | | `script:exec:{id}` | — | 脚本执行实时状态 | | `nexus:primary_worker` | 30s | Primary 锁 | ### 7.2 心跳数据流 ``` Agent(60s) → POST /api/agent/heartbeat → Redis 实时写入 → 前端 Dashboard 读 API(overlay Redis) → 每 600s heartbeat_flush → MySQL servers 历史字段 → 超阈值 → WebSocket alert + Telegram(5min 防抖) → 恢复 → recovery 通知 ``` --- ## 8. 后台任务(Primary Worker) | 模块 | 间隔 | 文件 | 职责 | |------|------|------|------| | `heartbeat_flush` | 600s | `background/heartbeat_flush.py` | Redis → MySQL 心跳持久化 | | `script_execution_flush` | 60s | `background/script_execution_flush.py` | 脚本状态 Redis → MySQL;stuck 检测 | | `self_monitor` | 30s | `background/self_monitor.py` | Redis/MySQL/WS 自检;Telegram | | `schedule_runner` | 60s | `background/schedule_runner.py` | Cron/once 调度 → 推送或脚本 | | `retry_runner` | 300s | `background/retry_runner.py` | `push_retry_jobs` SKIP LOCKED 重试 | | `ip_allowlist_refresh` | 7200s | `background/ip_allowlist_refresh.py` | 订阅 URL 更新白名单 | | `upload_staging_cleanup` | 3600s | `background/upload_staging_cleanup.py` | 清理 `/tmp/nexus_upload_*` >24h | | `alert_log_purge` | 24h | `background/alert_log_purge.py` | 清理 `alert_logs` >7d | | `audit_log_purge` | 24h | `background/audit_log_purge.py` | 清理 `audit_logs` >7d | --- ## 9. 后端 API 全览 ### 9.1 认证 `/api/auth` | 方法 | 路径 | 鉴权 | |------|------|------| | POST | `/login` | 公开 | | POST | `/refresh` | Cookie | | POST | `/logout` | 公开 | | POST | `/totp/setup|enable|disable` | JWT | | PUT | `/password` | JWT + re-auth | | POST | `/webssh-token` | JWT | | GET | `/me` | JWT | ### 9.2 Agent `/api/agent` | 方法 | 路径 | 鉴权 | |------|------|------| | POST | `/heartbeat` | X-API-Key | | POST | `/script-callback` | X-API-Key + job token | ### 9.3 服务器 `/api/servers` CRUD、stats、categories、logs、CSV import/export、batch agent install/upgrade/uninstall、**batch detect-path**(SSH 在 `/www/wwwroot` 下搜索 `crmeb` 目录写入 `target_path`)、health check、files-capability、setup-files-sudo、单台 agent 操作。 ### 9.4 同步 `/api/sync`(`sync_v2.py`,核心) | 分类 | 端点示例 | |------|----------| | 推送 | `POST /files`, `/preview`, `/cancel` | | 远程文件 | `/browse`, `/file-ops`, `/read-file`, `/write-file`, `/chmod`, `/compress`… | | 本机文件 | `/browse-local`, `/local-file-ops`, `/upload`, `/upload-zip` | | 工具 | `/validate-source-path`, `/diagnose`, `/reconcile-stale-logs` | ### 9.5 文件浏览 `/api/files` | 方法 | 路径 | 说明 | |------|------|------| | GET | `/browse?server_id=&path=` | JWT + ETag 缓存 | ### 9.6 脚本 `/api/scripts` 脚本 CRUD、`POST /exec`、executions 停止/重试/stuck、DB 凭据 CRUD。 ### 9.7 设置族 `/api/settings` + 子路由 | 路由器 | 前缀 | 内容 | |--------|------|------| | settings | `/api/settings` | 系统 KV、Telegram、IP 白名单、bing 壁纸 | | schedule | `/api/schedules` | 调度 CRUD | | preset | `/api/presets` | 密码预设 | | ssh_key_preset | `/api/ssh-key-presets` | SSH 密钥预设 | | alert_history | `/api/alert-history` | 告警列表/统计 | | audit | `/api/audit` | 审计分页 | | retry | `/api/retries` | 重试队列 | ### 9.8 其他 | 模块 | 前缀 | 说明 | |------|------|------| | assets | `/api/assets` | Platform/Node/ssh-sessions/command-logs | | terminal | `/api/terminal` | 快捷命令 CRUD | | search | `/api/search` | 全局搜索 | | install | `/api/install` | 安装向导 | | health | `/health`, `/health/detail` | 探活 | ### 9.9 WebSocket | 路径 | Token | 用途 | |------|-------|------| | `/ws/alerts` | Access JWT | 告警/恢复/系统 | | `/ws/sync` | Access JWT | 推送进度 | | `/ws/terminal/{id}` | WebSSH JWT | 终端 Koko 协议 | --- ## 10. 核心业务模块详解 ### 10.1 推送引擎 SyncEngineV2 文件: `server/application/services/sync_engine_v2.py` | 概念 | 说明 | |------|------| | 执行位置 | **Nexus 中心机** 上执行 `rsync`,SSH 到子机 | | 并发 | `asyncio.Semaphore`,默认 max 10 | | 超时 | rsync 300s + 30s grace | | 认证 | sshpass -e(密码)或临时 key 文件 0600 | | 失败 | 写 `sync_logs` + 可选 `push_retry_jobs` | | 取消 | Redis `sync:cancel:{batch_id}` | | 预览 | `rsync --dry-run --stats` | **Sync 模式**(`sync_mode`): | 模式 | rsync 参数 | 行为 | |------|------------|------| | `incremental` | `-az` | 默认增量 | | `full` | `-az --delete` | 删除目标多余文件 | | `checksum` | `-az --checksum` | 校验和 | | `overwrite` | `-az --inplace` | 原地覆盖 | **源路径安全**: `resolve_nexus_push_source_path()` 禁止 `/etc` 等系统路径;ZIP 解压至 `UPLOAD_STAGING_PREFIX` 下暂存目录。 ### 10.2 远程文件浏览 - `GET /api/files/browse` → `files_browse_service.list_remote_directory` - 远程命令: `ls -la` + `shlex.quote(path)` - ETag: 目录 mtime + 条目数,支持 `If-None-Match` → 304 - 前端: `useFilesStore` 内存缓存 + TTL **Files elevation**(`files_elevation` 字段): | 值 | 行为 | |----|------| | `off` | 不 sudo | | `auto` | 写失败时尝试 sudo | | `always_sudo` | 始终 sudo | `POST /api/servers/{id}/setup-files-sudo` 远程配置 sudoers(密码走 stdin)。 ### 10.3 脚本执行 文件: `server/application/services/script_service.py` | 模式 | 条件 | 路径 | |------|------|------| | SSH 短命令 | 超时内完成 | asyncssh 并行,Semaphore | | Agent 长任务 | 超时 > 阈值 | nohup + callback URL + Redis 状态 | - DB 凭据: 脚本内 `$DB_HOST` 等占位符替换 - 危险命令: `check_dangerous_command()` WARN 日志(不阻断) - 停止: `POST /scripts/executions/{id}/stop` ### 10.4 服务器 Agent | 操作 | API | 方式 | |------|-----|------| | 安装 | batch/single install | SSH curl agent 脚本 | | 升级 | upgrade-agent | SSH 拉取 agent.py | | 卸载 | uninstall-agent | SSH systemctl stop | | 安装命令 | agent-install-cmd | 返回 curl(**禁止**暴露 global API_KEY) | Agent 心跳 JSON 含 CPU/内存/磁盘/负载;变化 >10% 或超阈值时主动告警。 ### 10.5 告警与 Telegram - 阈值: `CPU/MEM/DISK_ALERT_THRESHOLD`(默认 80%) - 防抖: WebSocket 5min;Telegram 同类型去重 - 恢复: 指标回落 → recovery 事件 - 推送完成: `send_telegram_sync_complete` --- ## 11. 前端 SPA 架构 ### 11.1 构建与开发 | 项 | 值 | |----|-----| | 开发 | `cd frontend && npm run dev` → `http://localhost:3000/app/` | | API 代理 | Vite proxy `/api`、`/ws` → `127.0.0.1:8600` | | 构建输出 | `web/app/`(`base: '/app/'`) | | 路由 | Hash `#/path` | ### 11.2 入口链路 ``` main.ts → App.vue(侧栏/搜索)→ router-view → pages/*.vue → composables → api/index.ts → /api/* ``` ### 11.3 HTTP 客户端(`src/api/index.ts`) | 能力 | 实现 | |------|------| | Token | 内存 access JWT | | 401 | 自动 refresh 一次 | | 202 | `TotpRequiredError` | | 429 | 锁定文案 | | 304 | 文件 browse ETag | | Upload | FormData 不设 JSON Content-Type | ### 11.4 Pinia Stores | Store | 职责 | |-------|------| | `auth` | token、admin、login/logout/refresh | | `files` | selectedServer、currentPath、browse 缓存 | 其余状态在 composable 或页面 `ref` 中。 --- ## 12. 15 个业务页面功能说明 > 路由均位于 `#/` 下;除 Login 外需 JWT。 ### 12.1 DashboardPage `/` | 功能 | API/机制 | |------|----------| | 统计卡片 | `GET /servers/stats` | | 服务器分页表 | `useServerPagination` | | 告警摘要 | `GET /alert-history/?limit=5` | | 资源概览 | 拉 200 台算 CPU/内存均值 | | 分类分布 | stats.categories | | 最近审计 | `GET /audit/?limit=10` | | 实时刷新 | `useWebSocket` → 告警时 reload stats | | 快捷跳转 | 终端/文件 `?server_id=` | ### 12.2 ServersPage `/servers` | 功能 | API | |------|-----| | CRUD | `/servers/` | | **快速添加(仅 IP)** | `POST /servers/add-by-ip` — 轮询全部密码/SSH 预设;成功返回 `matched_preset` / `matched_username` | | **连接失败列表** | `GET /servers/pending` | | **失败重试 / 删除** | `POST /servers/pending/{id}/retry`、`DELETE /servers/pending/{id}` | | 批量选择 | 安装/升级/卸载 Agent、**检测目标路径**、健康检查、删除 | | **检测目标路径** | `POST /servers/batch/detect-path` — Body: `{ server_ids }`;SSH 在 `/www/wwwroot` 下搜索 `crmeb` 目录写入 `target_path`;结果弹窗逐台展示 | | **列表快捷编辑** | 目标路径列 ✏️ → `PUT /servers/{id}` `{ target_path }` | | CSV 导出 | 客户端生成(无密码列) | | CSV 导入 | `POST /servers/import` FormData | | 详情面板 | 系统信息 + `GET /servers/{id}/logs` | | 表单 | `ServerFormDialog` + `useServerFormDialog` | 详见附录 J(凭据轮询契约)。 ### 12.3 TerminalPage `/terminal` | 功能 | 说明 | |------|------| | 多 Tab | `useTerminalSessions` | | WebSSH | `POST /auth/webssh-token` → `WS /ws/terminal/{id}?token=` | | xterm | FitAddon、256 色 | | 命令栏 | shell 高亮、`sendCmd`/`sendCtrl` | | 快捷命令 | `GET /terminal/quick-commands` | | 路由入参 | `#/terminal?server_id=123` 自动开 Tab | | 清理 | `onBeforeUnmount` → `disposeAllSessions` | ### 12.4 FilesPage `/files` 薄编排页,逻辑在 composables: | 子模块 | 能力 | |--------|------| | Toolbar | 上传、刷新、上级目录 | | List | 排序、多选、双击进目录 | | Editor | Monaco,`POST /sync/read-file|write-file` | | 权限 | files-capability 检测、sudo 提示 | | 热键 | 复制/粘贴/删除(`useFilesHotkeys`) | | 跨机传输 | 工具栏/右键跳转 `#/server-transfer`(见 §12.4.1) | ### 12.4.1 ServerTransferPage `/server-transfer` | 能力 | 说明 | |------|------| | 源机浏览 | `POST /sync/browse`,多选 + 手动绝对路径 | | 直传 | `POST /sync/server-transfer`(单文件 ≤500MB) | | 打包投递 | `POST /sync/server-transfer/deliver` + 可选解压 | | 深链 | `?source=&path=&paths=` 自文件页预填 | ### 12.5 PushPage `/push` | 功能 | API/WS | |------|--------| | 源/目标路径 | 表单校验 | | ZIP 上传 | `POST /sync/upload-zip` | | 服务器网格 | 分类全选 | | 预览 | `POST /sync/preview` 并发 | | 推送 | `POST /sync/files` + `/ws/sync` 进度 | | 取消 | `POST /sync/cancel` | | 历史 | sync_logs 分页、诊断、对账 | ### 12.6 ScriptsPage `/scripts` | 功能 | API | |------|-----| | 脚本 CRUD | `GET/POST/PUT/DELETE /scripts/`(分类 ops/deploy/check/cleanup) | | Monaco 编辑 | `ScriptContentEditor` · `content` 字段 | | 库内执行 | `POST /scripts/exec`(`script_id` 或 `command` 二选一) | | 临时命令 | 页内 quick exec 面板 | | 长任务 / DB 凭据 | `long_task`、`credential_id`;`GET /scripts/exec-config` | | 提交执行 | `POST /scripts/exec` **立即返回** `running`(后台批次) | | 全局进度 | `App.vue` + `useScriptExecutionQueue`(WS `script_progress` / `script_complete`) | | 历史 | `GET /scripts/executions?script_id=` | | 停止 / 重试 / 卡住 | `POST .../stop`、`.../retry`、`.../mark-stuck` | ### 12.7 ScriptRunsPage `/script-runs` · `/script-runs/:id` | 功能 | API | |------|-----| | 执行看板列表 | `GET /scripts/executions`(状态筛选 running/completed/partial/failed) | | 单次明细 | `GET /scripts/executions/{id}` · 失败分组 · 复制清单 · 跳转终端 | | 重试 / 停止 | 同 ScriptsPage | | 入口 | 侧栏「脚本看板」;Telegram 深链 `#/script-runs/{id}` | ### 12.8 CredentialsPage `/credentials` 三 Tab:密码预设、SSH 密钥、DB 凭据;编辑时空密码表示不修改。 | Tab | API | 契约要点 | |-----|-----|----------| | 密码预设 | `GET/POST /presets/`、`PUT/DELETE /presets/{id}` | 字段 `name`、`username`(默认 `root`)、`encrypted_pw`;列表返回 `username` | | SSH 密钥 | `GET/POST /ssh-key-presets/`、`PUT/DELETE /ssh-key-presets/{id}` | 同上 `username`;私钥 `private_key` 仅创建/更新时传 | | DB 凭据 | `GET/POST /scripts/credentials`、`PUT/DELETE /scripts/credentials/{id}` | 脚本执行用 DB 连接,与 SSH 轮询无关 | `username` 供 `credential_poller` 在 `add-by-ip` / retry 时与预设密码或私钥组合尝试 SSH。 ### 12.9 SchedulesPage `/schedules` | 功能 | API / 行为 | |------|------------| | 类型 | `schedule_type`: `push`(rsync)或 `script`(ScriptService) | | 运行模式 | `run_mode`: `cron`(5 字段 cron_expr)或 `once`(fire_at) | | 推送字段 | `source_path`(必填)、`target_path`(可选,留空走各机配置)、`sync_mode` | | 脚本字段 | `script_id` 或 `script_content`、`exec_timeout`、`long_task` | | 列表 | `next_run` API 计算;`GET /schedules/` | | 立即执行 | push → `POST /sync/files`;script → `POST /scripts/exec` | | 后台 | `schedule_runner` 60s 扫描到期项 | ### 12.10 RetriesPage `/retries` 失败推送重试队列;`POST /retries/{id}/retry`。 ### 12.11 CommandsPage `/commands` | 视图 | API | 筛选 | |------|-----|------| | 命令视图 | `GET /assets/command-logs` | server_id | | 会话视图 | `GET /assets/ssh-sessions` | server_id | | 推送日志 | `GET /servers/logs` | server_id、status、sync_mode、trigger_type | ### 12.12 AlertsPage `/alerts` 告警统计 + 分页;按 type/status 过滤。 ### 12.13 AuditPage `/audit` 操作审计;action/user/date 过滤;`normalizeAuditList`。 ### 12.14 SettingsPage `/settings` 系统名/阈值/连接池、Telegram、改密、TOTP、API Key reveal、IP 白名单、终端快捷命令设置。 ### 12.15 LoginPage `/login` JWT 登录、TOTP、429 锁定、开放重定向防护(`//` 拒绝)、bing 壁纸背景。 --- ## 13. Composables 与状态管理 ### 13.1 模块索引 | 目录 | 入口 | 用途 | |------|------|------| | `composables/files/` | `useFilesPage` | 文件页总编排 | | `composables/push/` | `usePushPage` | 推送页总编排 | | `composables/terminal/` | `useTerminalSessions` | WebSSH 会话 | | `composables/servers/` | `useServerFormDialog` | 服务器表单 | | `composables/useWebSocket.ts` | — | 告警 WS | | `composables/useServerPagination.ts` | — | 分页表 | ### 13.2 新增页面 Checklist 1. `frontend/src/pages/XxxPage.vue` 2. `router/index.ts` 注册路由 3. `App.vue` 侧栏 nav 项 4. `types/api.ts` 补充类型 5. 后端 API + 审计日志 6. E2E: `frontend/e2e/full-acceptance.spec.mjs` --- ## 14. WebSocket 与 WebSSH ### 14.1 告警 WS `/ws/alerts` - 连接: `buildWebSocketUrl('/ws/alerts', { token: accessToken })` - 消息类型: alert / recovery / system / **script_progress** / **script_complete** - App.vue:`useWebSocket` + `useScriptExecutionQueue`(全局进度条与完成 Alert) - WS 断线时队列 3s 轮询直至终态 ### 14.2 推送 WS `/ws/sync` - batch_id 维度进度 - `usePushProgress` 维护 per-server 状态 ### 14.3 WebSSH - 独立 JWT: `purpose=webssh`, `server_id`, 15min - 绑定路径 server_id,防 IDOR - Koko 消息: `TERMINAL_INIT`, `DATA`, `RESIZE`, `CLOSE` - 命令日志: Enter 时写 `command_logs` **已接受风险**: JWT 走 query string(ADR-011),见 risk-acceptance 文档。 --- ## 15. Agent 与子机协议 ### 15.1 网络模型 | 方向 | 端口 | 用途 | |------|------|------| | 子机 → 中心 | 443 出站 | 心跳、script callback | | 中心 → 子机 | 22 | 推送、文件、脚本、Agent 安装 | | 子机本机 | 127.0.0.1:8601 | Agent HTTP(可选) | ### 15.2 心跳 Payload(摘要) `server_id`, `cpu`, `memory`, `disk`, `load`, `uptime`, `agent_version`, `system_info`, ... ### 15.3 脚本回调 长任务完成后 Agent `POST /api/agent/script-callback`,携带 job id 与 per-server 结果。 --- ## 16. 安装向导 | 步骤 | UI | API | |------|-----|-----| | 1 | 环境检查 | `GET /install/env-check` | | 2 | MySQL/Redis 配置 | `POST /install/init-db` | | 3 | 三写配置 | 同上(写 .env + config.json + settings) | | 4 | 创建管理员 | `POST /install/create-admin`(install_token) | | 5 | 锁定 | `POST /install/lock` | 静态页: `web/app/install.html`(Tailwind,非 Vue SPA)。 锁定后 `/install/status` → 404,防止信息泄露。 --- ## 17. 本地开发、测试与门控 ### 17.1 快速启动 ```bash # Docker MySQL + Redis docker compose up -d mysql redis # 生成 .env(若无) python3 docker/generate_env.py && python3 docker/sync_root_env.py # 启动 API bash scripts/start-dev.sh # → http://127.0.0.1:8600 # 前端 cd frontend && npm run dev # → http://localhost:3000/app/ ``` ### 17.2 验证命令 | 级别 | 命令 | |------|------| | L2b | `bash scripts/local_verify.sh` | | L2c | `.venv/bin/pytest tests/ -q` | | L3 | `bash deploy/pre_deploy_check.sh` | | L4 | `python3 scripts/run_nexus_acceptance.py --base http://127.0.0.1:8600 --with-ui` | | E2E | `cd frontend && NEXUS_E2E_BASE=http://127.0.0.1:8600 npm run test:e2e` | ### 17.3 七道门控 见 `deploy/pre_deploy_check.sh`:Changelog、Audit、Test、Ruff、Import、Bandit、Review。 --- ## 18. 部署与运维 ### 18.1 生产部署 ```bash git push origin main bash deploy/pre_deploy_check.sh bash deploy/deploy-production.sh # 或手动: ssh nexus "cd $DEPLOY && git reset --hard origin/main && supervisorctl restart nexus" # 前端: bash deploy/deploy-frontend.sh ``` ### 18.2 三层守护 | 层 | 机制 | |----|------| | 1 | Supervisor 进程重启 | | 2 | `self_monitor` 30s | | 3 | `health_monitor.sh` cron 1min → 连续失败 restart + Telegram | ### 18.3 健康检查 - `GET /health` → 纯文本 `ok` - `GET /health/detail` → JSON(需 JWT) --- ## 19. 扩展开发指南 ### 19.1 新增 REST API 1. 设计文档 `docs/design/specs/YYYY-MM-DD-*.md` 2. Service + Repository(若需) 3. `server/api/xxx.py` + `Depends(get_current_admin)` 4. `main.py` include_router 5. 审计: `AuditLog` 写入 6. `tests/test_api.py` 或专项测试 7. Changelog + 审计 8 步 ### 19.2 新增前端功能 1. 明确页面 vs 对话框 vs composable 边界 2. 类型先进 `types/api.ts` 3. 错误用 `formatApiError` + snackbar,**禁止静默吞错** 4. 敏感数据不进 localStorage 5. Playwright 抽测关键路径 ### 19.3 新增后台任务 1. 仅 primary worker 注册(`main.py` lifespan) 2. 循环内 try/except + logger,不可空 pass 3. 需可关闭(CancelledError) 4. 文档 + changelog ### 19.4 数据库变更 1. 修改 `domain/models` 2. 启动时 `init_db` 或手写迁移 SQL(生产谨慎) 3. 不可破坏 `ENCRYPTION_KEY` 下已有密文 --- ## 20. 不可改项与已接受风险 ### 20.1 不可改(架构/安全一致性) | 项 | 原因 | |----|------| | `API_KEY` | Agent 与加密回退一致 | | `SECRET_KEY` | JWT 与已有 token | | `ENCRYPTION_KEY` | 已加密凭据 | | `DATABASE_URL` | 启动绑定 | ### 20.2 已接受风险(单人运维) 见 `docs/project/risk-acceptance-single-operator.md`: - WebSocket / WebSSH JWT 在 query - Agent global API_KEY 回退 - 危险命令仅 WARN 不阻断 - dev docker-compose 默认密码 --- ## 21. 文档索引 | 文档 | 用途 | |------|------| | **本文** | 功能开发 SSOT(架构 + 模块概览) | | **[附录](nexus-functional-development-guide-appendix.md)** | API 字段表、Files/Push/Terminal 调用链、E2E/L4 对照、组件映射 | | [AI-HANDOFF-2026-06-03.md](AI-HANDOFF-2026-06-03.md) | 会话接续 | | [linux-dev-paths.md](linux-dev-paths.md) | Linux 路径 | | [local-integration-test.md](local-integration-test.md) | 本地验收 | | [script-execution.md](script-execution.md) | 脚本执行细节 | | [alert-push-policy.md](alert-push-policy.md) | 告警策略 | | [deploy.md](deploy.md) | 部署补充 | | [development-acceptance-standard.md](development-acceptance-standard.md) | L0–L5 验收 | | `docs/design/specs/` | 新功能设计 | | `docs/changelog/` | 每次变更记录 | --- ## 22. 详细参考(附录摘要) 完整查表见 **[nexus-functional-development-guide-appendix.md](nexus-functional-development-guide-appendix.md)**。 | 附录 | 内容 | |------|------| | **A** | `/api/sync` 全 21 端点 + Pydantic 字段 + WS 推送时序 | | **B** | Files 页组件树、composable 依赖图、操作→API 映射 | | **C** | Push 页 composable 与推送时序 | | **D** | Terminal / WebSSH 调用链 | | **E** | schedules/retries/audit/scripts/agent/search API 明细 | | **F** | 15 页 ↔ composable ↔ 组件对照表 | | **G** | L4 验收 + Playwright 15 用例对照 | | **H** | HTTP 错误码与前端处理 | | **I** | 扩展开发检查清单 | --- **维护约定**: 新增模块或变更 API/页面时,**同步更新本文 + 附录对应章节** + changelog(≥10 行)。