# 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. [14 个业务页面功能说明](#12-14-个业务页面功能说明)
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` | 审计 | `action`, `target_*`, `ip_address` |
| `Script` | `scripts` | 脚本库 | `content`, `category` |
| `ScriptExecution` | `script_executions` | 执行记录 | `results` JSON, `status` |
| `DbCredential` | `db_credentials` | DB 凭据 | 脚本内 `$DB_*` 替换 |
| `AlertLog` | `alert_logs` | 告警历史 | `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 |

---

## 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、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. 14 个业务页面功能说明

> 路由均位于 `#/` 下；除 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/` |
| 批量选择 | 安装/升级/卸载 Agent、健康检查、删除 |
| CSV 导出 | 客户端生成（无密码列） |
| CSV 导入 | `POST /servers/import` FormData |
| 详情面板 | 系统信息 + `GET /servers/{id}/logs` |
| 表单 | `ServerFormDialog` + `useServerFormDialog` |

### 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`） |

### 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 | `/scripts/` |
| Monaco 编辑 | content 字段 |
| 执行 | `POST /scripts/exec` + 轮询 executions |
| 临时命令 | quick exec 面板 |
| 停止 | `POST /scripts/executions/{id}/stop` |

### 12.7 CredentialsPage `/credentials`

三 Tab：密码预设、SSH 密钥、DB 凭据；编辑时空密码表示不修改。

### 12.8 SchedulesPage `/schedules`

Cron 调度推送；`runNow` → `POST /sync/files`；cron 前端正则校验。

### 12.9 RetriesPage `/retries`

失败推送重试队列；`POST /retries/{id}/retry`。

### 12.10 CommandsPage `/commands`

命令视图 / 会话视图；`GET /assets/command-logs|ssh-sessions`。

### 12.11 AlertsPage `/alerts`

告警统计 + 分页；按 type/status 过滤。

### 12.12 AuditPage `/audit`

操作审计；action/user/date 过滤；`normalizeAuditList`。

### 12.13 SettingsPage `/settings`

系统名/阈值/连接池、Telegram、改密、TOTP、API Key reveal、IP 白名单、终端快捷命令设置。

### 12.14 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  
- App.vue 或 Dashboard 订阅  

### 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** | 14 页 ↔ composable ↔ 组件对照表 |
| **G** | L4 验收 + Playwright 15 用例对照 |
| **H** | HTTP 错误码与前端处理 |
| **I** | 扩展开发检查清单 |

---

**维护约定**: 新增模块或变更 API/页面时，**同步更新本文 + 附录对应章节** + changelog（≥10 行）。
