# Nexus 项目交接文件 — Cursor 继续开发

> 生成时间: 2026-06-01（2026-06-01 晚更新：单负责人收口）
> 当前分支: main（与 origin/main 同步，含 b8af1fc 单 Agent 规则）
> 协作方式: **用户 ↔ 当前 Cursor Agent**（无虚拟部门/Skill 分派）
> 主前端: **Vue 3 + Vuetify SPA**（`frontend/` → `web/app/`）
> 生产: https://api.synaglobal.vip 已部署

---

## 零、Cursor 接管第一步

### 1. 已为你准备好的文件

| 文件 | 位置 | 作用 |
|------|------|------|
| **Cursor Rules** | `.cursorrules`（项目根目录）| 强制规则、部署流程、文件速查 — Cursor 自动读取 |
| **MCP 配置** | `C:\Users\uzuma\.cursor\mcp.json` | nexus/playwright/gitea/fetch/context7 — 已写好 |
| **项目规则** | `CLAUDE.md`（项目根目录）| 完整项目记忆、决策、实现状态、部署常遇问题 |
| **交接文件** | `docs/handoff-2026-06-01.md` | 本文件 |

### 2. Cursor 中使用步骤

1. 用 Cursor 打开 `C:\Users\uzuma\Desktop\svn\Nexus`
2. MCP 自动加载（`~/.cursor/mcp.json` 已配置好）
3. `.cursorrules` 自动生效（Cursor 自动读取项目根目录的此文件）
4. 直接开始对话

### 3. 给 Cursor Agent 的开场提示词（复制到 Chat）

```
读取 docs/handoff-2026-06-01.md 了解项目全貌，然后读取 CLAUDE.md 了解强制规则。项目 ~99% 完成，当前待续事项见交接文件第八节。用中文回复。
```

### 4. 更完整的 Agent System Prompt（如需配置 Custom Agent）

```
你是 Nexus 6.0 项目的开发助手。这是一个 2000+ 服务器运维管理平台。

技术栈:
- 后端: FastAPI 0.115.6 + Async SQLAlchemy 2.0 + Redis 5.2 + WebSocket + Telegram
- 前端: Vue 3 + Vuetify 4 + TypeScript SPA (14个页面)
- 构建工具: Vite 8，输出到 web/app/
- 部署: Gitea → SSH git pull → supervisorctl restart (后端)，Vite build → tar+scp (前端)

强制规则:
1. 所有实现必须是完美实现 — 不允许降级、妥协、留技术债
2. 安全铁律: 禁止明文密码前端、禁止静默吞错、禁止f-string拼SQL、禁止硬编码密钥
3. 文档纪律: 每次修改必须写 changelog (docs/changelog/，行数≥10)，新功能必须先有设计文档
4. 修改流程: 实现 → 验证 → 审计8步 → 部署 → 健康检查 → 浏览器验证 → changelog
5. 用中文回复
6. 部署用 SSH: ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"
7. 前端部署: cd frontend && npx vite build && cd .. && tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/ && scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz && ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
8. 健康检查: ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health" → 预期 "ok"

生产环境:
- 域名: https://api.synaglobal.vip
- SSH 别名: ssh nexus (root@47.254.123.106)
- 管理员: admin / Nexus@2026
- 数据库: MySQL nexus/Nexus@2026!@127.0.0.1:3306/nexus

详细项目文档: 项目根目录 CLAUDE.md
交接文件: docs/handoff-2026-06-01.md
```

---

## 一、项目基本信息

| 项目 | 值 |
|------|------|
| 项目名 | Nexus 6.0 |
| 功能 | 2000+ 服务器运维管理平台 |
| 仓库 | http://66.154.115.8:3000/admin/Nexus.git |
| 本地路径 | `C:\Users\uzuma\Desktop\svn\Nexus` |
| 生产域名 | https://api.synaglobal.vip |
| 生产 IP | 47.254.123.106 |
| 后端端口 | 8600 |
| 部署路径 | `/www/wwwroot/api.synaglobal.vip/` |
| 管理员凭据 | admin / Nexus@2026 |
| 数据库 | MySQL nexus/Nexus@2026!@127.0.0.1:3306/nexus |
| Gitea 部署 Token | SHA: 26fee743a9332895b55f79b2dbe2e931dc7c2fe5 |

---

## 二、技术栈

### 后端 (server/)
- **FastAPI** 0.115.6 + **uvicorn** 0.34.0
- **SQLAlchemy** 2.0.49 (Async) + **aiomysql** 0.2.0
- **Redis** 5.2.1 (心跳/缓存/告警去重)
- **asyncssh** 2.17.0 (WebSSH 连接池)
- **PyJWT** 2.10.1 + **bcrypt** 4.2.1 (认证)
- **cryptography** 44.0.0 (Fernet 凭据加密)
- Clean Architecture 4层: api/ → application/ → domain/ → infrastructure/

### 前端 (frontend/)
- **Vue 3** ^3.5.30 + **Vuetify 4** ^4.0.2 + **TypeScript** ~5.9.3
- **Vite** ^8.0.0 + **Pinia** ^3.0.4
- **xterm.js** ^6.0.0 (WebSSH 终端)
- **Monaco Editor** ^0.55.1 (代码编辑器)
- 14个页面组件，Hash History 路由
- 构建输出到 `web/app/` (后端 StaticFiles 挂载点)

### 旧前端 (web/app/) — 仍存在但不维护
- Tailwind CSS v4 + Alpine.js，12 个 HTML 页面
- 新 SPA 构建后覆盖 web/app/index.html 和 assets/

---

## 三、MCP 服务器配置

### Cursor MCP 配置（已写入 `~/.cursor/mcp.json`）

```json
{
  "mcpServers": {
    "nexus": {
      "command": "ssh",
      "args": ["-o", "StrictHostKeyChecking=no", "-i", "C:/Users/uzuma/.ssh/id_rsa_nexus", "root@47.254.123.106", "cd /www/wwwroot/api.synaglobal.vip && NEXUS_DEPLOY_DIR=/www/wwwroot/api.synaglobal.vip python3 mcp/Nexus_server.py"]
    },
    "playwright": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@playwright/mcp@latest"]
    },
    "gitea": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "gitea-mcp"],
      "env": {
        "GITEA_ACCESS_TOKEN": "4dfc8e2edeaf86bc9c485779652e2eb67a8604dc",
        "GITEA_HOST": "http://66.154.115.8:3000"
      }
    },
    "fetch": {
      "command": "uvx",
      "args": ["mcp-server-fetch"]
    },
    "context7": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@upstash/context7-mcp"]
    }
  }
}
```

### Claude Code MCP 配置（参考）

**全局配置位置**: `C:\Users\uzuma\.claude.json` → `mcpServers`

| MCP 名称 | 类型 | 命令 | 用途 |
|----------|------|------|------|
| Nexus Remote MCP | SSH | `ssh -o StrictHostKeyChecking=no -i /c/Users/uzuma/.ssh/id_rsa_mcp root@47.254.123.106 python3 /www/wwwroot/api.synaglobal.vip/mcp/nexus_server.py` | 后端操作(API/DB/部署/日志) |
| gitea | npx | `gitea-mcp` | Gitea 仓库操作 |
| github | npx | `@modelcontextprotocol/server-github` | GitHub 操作 |
| playwright | npx | `@playwright/mcp@latest` | 浏览器自动化 |
| context7 | npx | `@upstash/context7-mcp` | 库文档查询 |
| megamemory | 本地 | `megamemory` | 项目知识图谱 |
| memory | npx | `@modelcontextprotocol/server-memory` | 内存存储 |
| fetch | uvx | `mcp-server-fetch` | URL 获取 |

**项目级 MCP** (`~/.claude.json` → projects → Nexus → mcpServers):
```json
{
  "nexus": {
    "type": "stdio",
    "command": "ssh",
    "args": ["-o", "StrictHostKeyChecking=no", "-i", "C:/Users/uzuma/.ssh/id_rsa_nexus", "root@47.254.123.106", "cd /www/wwwroot/api.synaglobal.vip && NEXUS_DEPLOY_DIR=/www/wwwroot/api.synaglobal.vip python3 mcp/Nexus_server.py"]
  }
}
```

---

## 四、SSH 配置

**`~/.ssh/config`**:
```
Host nexus
  HostName 47.254.123.106
  User root
  IdentityFile C:/Users/uzuma/.ssh/id_rsa_nexus
  StrictHostKeyChecking no
```

**密钥文件**:
- `C:\Users\uzuma\.ssh\id_rsa_nexus` — 生产服务器 SSH
- `C:\Users\uzuma\.ssh\id_rsa_mcp` — MCP 远程连接

---

## 五、部署流程

### 后端部署
```bash
# 1. Push 到 Gitea
git push origin main

# 2. 服务器拉取 + 重启
ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"

# 3. 健康检查
ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health"
# 预期: ok
```

### 前端部署
```bash
# 一键脚本
bash deploy/deploy-frontend.sh

# 或手动:
cd frontend && npx vite build && cd ..
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz
ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
```

### 本地开发
```bash
cd frontend && npm run dev   # http://localhost:3000/app/
```

Vite proxy 配置: `/api` → `https://api.synaglobal.vip`, `/ws` → `wss://api.synaglobal.vip`

### 部署常遇问题

| 问题 | 解决 |
|------|------|
| `/app/` 返回 404 | AppAuthMiddleware 拦截 — 确认 `/app/` 和 `/app/index.html` 在 `_APP_PUBLIC_PATHS` 中 |
| `/app/` 返回旧 HTML (Tailwind/Alpine) | `git reset --hard` 恢复了旧文件 — 需要重新 tar+scp 前端构建产物 |
| MCP deploy → git pull 失败 `could not read Username` | 服务器 remote URL 没配 token，用 `git remote set-url` |
| Gate 2 Audit BLOCKED | 创建 `docs/audit/YYYY-MM-DD-topic.md`，含 Step3+Closure+DoD |
| Gate 3 Test BLOCKED (401) | 服务器 .env 中 `NEXUS_TEST_ADMIN_PASSWORD` 与数据库不一致 |
| Gate 6 Security BLOCKED (bandit HIGH) | md5 → sha256 等，参看 bandit 报告修复 |
| Gate 7 Review BLOCKED | 审计文件缺少实际改动文件清单 |

---

## 六、7道门控 (deploy/pre_deploy_check.sh)

| # | 门 | 检查内容 |
|---|----|---------|
| 1 | Changelog门 | 文件存在且行数≥10 |
| 2 | Audit门 | 文件存在且含 Step3+Closure+DoD |
| 3 | Test门 | test_api.py 必须存在且通过 |
| 4 | Lint门 | `ruff check server/` 零错误 |
| 5 | Import门 | `import server.main` 成功 |
| 6 | Security门 | `bandit` 无 HIGH/MEDIUM |
| 7 | Review门 | 审计文件包含实际改动文件清单 |

MCP deploy 工具自动执行门控，任何一门不过返回 🚫 DEPLOY BLOCKED

---

## 七、最近完成的工作

### 2026-06-01: 全站 bug 审查修复 (14项)

**前端修复 (9项):**

| 级别 | Bug | 修复 |
|------|-----|------|
| **P0** | App.vue `http` 未导入 → 全局搜索崩溃 | 添加 `import { api, http }` |
| **P1** | TOTP 登录流程断裂 | 导入 `TotpRequiredError`，catch 中优先检查 |
| **P1** | ServersPage 编辑服务器 domain 被端口污染 | `form.address = item.domain` |
| **P1** | PushPage `Set[0]` 无效 → preview 发 undefined | `values().next().value` |
| **P1** | SettingsPage API 字符串未转数字 | 正则检测 + `Number()` |
| P2 | api/index.ts `getList` 重复定义 | 删除第二个 |
| P2 | LoginPage 锁定倒计时不更新 | `ref(Date.now())` + watch + 定时器 |
| P2 | TerminalPage 路径验证过严 | 白名单排除控制字符+引号 |
| P2 | useWebSocket CONNECTING 状态连接泄漏 | 关闭旧连接再建新的 |

**后端修复 (5项):**

| 级别 | Bug | 修复 |
|------|-----|------|
| **P1** | websocket.py `redis.keys()` O(N) 阻塞 | `scan_iter()` 非阻塞迭代 |
| **P1** | auth_service.py TTL 每次刷新都重置 | 仅 `ttl < 0` 时设置 expire |
| **P1** | servers.py 批量操作并发 session commit | `asyncio.Lock()` 序列化 |
| P2 | settings.py `asyncio.get_event_loop()` 弃用 | `get_running_loop()` |
| P2 | settings.py `datetime.utcfromtimestamp()` 弃用 | `fromtimestamp(tz=utc)` |

### 2026-05-31: TerminalPage 全面迭代 + 登录页调整

1. **登录页居中** — flexbox 居中，删除 Logo
2. **TerminalPage 25项修复** — Ctrl+L清屏、命令历史恢复、per-session重连/ping/uptime、指数退避等
3. **快捷命令 MySQL 持久化** — quick_commands 表 + CRUD API + 内置命令 seed
4. **Shell 语法高亮** — 命令输入栏 sudo→红、关键字→蓝、管道→黄、字符串→绿、flag→紫

### 项目整体进度 — ~99% 完成

14 页面全部完成部署。所有 P0/P1/P2 功能已实现。

---

## 八、待续事项（2026-06-01 更新）

### 已修复（见 `docs/changelog/2026-06-01-bug-remediation.md`）

| 原优先级 | 问题 | 状态 |
|----------|------|------|
| P1 | ServersPage 批量 Agent 操作 | ✅ `normalizeServerIds` + 生产 SPA 已部署 |
| P1 | script-callback 无 API Key | ✅ `X-API-Key` 校验 |
| P1 | Access Token 30 天 | ✅ 60min + HttpOnly refresh |
| P2 | 未知 IP 心跳 422 刷屏 | ✅ 丢弃 + debug 日志 |
| P2 | Admin 废弃 JWT 列 | ✅ 迁移 DROP |
| P3 | agent on_event 弃用 | ✅ lifespan |

### 仍待办 / 抽测

| 优先级 | 问题 | 文件 | 说明 |
|--------|------|------|------|
| P2 | 422 调试 handler 是否保留 | server/main.py | 若日志已稳定可改为仅 4xx 结构化响应 |
| P2 | 壁纸旧端点缓存 | LoginPage.vue | 强刷 `/app/` 或清站点数据 |
| UX | 终端命令栏高亮对齐 | TerminalPage.vue | 多分辨率抽测 |
| **验收** | 告警 Telegram + WS 端到端 | — | 未触发；见 `docs/reports/2026-06-01-browser-verification.md` |
| **验收** | WebSSH 连接 | terminal | ✅ 2026-06-01 `server_id=8` 已连接；resize/长会话待抽测 |
| **验收** | SPA 主要页面 | — | ✅ 仪表盘/服务器/告警/推送 |
| **验收** | 批量选择条 UI | ServersPage.vue | ✅ 2026-06-01 Vuetify4 `v-model` 修复 |
| **验收** | Sync 推送 2 台试跑 | push | 未执行正式推送（防误操作） |
| **验收** | 三层守护 kill 测试 | deploy/ | 维护窗口；cron 已确认存在 |
| **运维** | 生产 pytest | tests/test_api.py | 服务器无 pytest 模块时用 WSL/CI 25/25 为准 |

---

## 九、关键文件速查

| 用途 | 文件路径 |
|------|----------|
| 后端入口 | server/main.py |
| 路由注册 | server/main.py 行525-560 |
| 数据模型 | server/domain/models/__init__.py |
| JWT 认证 | server/api/auth_jwt.py |
| 登录API | server/api/auth.py |
| WebSSH | server/api/webssh.py |
| 终端 WS | server/api/websocket.py |
| 设置 CRUD | server/api/settings.py |
| 服务器 CRUD | server/api/servers.py |
| 快捷命令 CRUD | server/api/terminal.py |
| Agent 心跳 | server/api/agent.py |
| 同步引擎 | server/application/services/sync_engine_v2.py |
| 认证服务 | server/application/services/auth_service.py |
| 前端入口 | frontend/src/main.ts |
| 路由 | frontend/src/router/index.ts |
| API 客户端 | frontend/src/api/index.ts |
| Auth Store | frontend/src/stores/auth.ts |
| 登录页 | frontend/src/pages/LoginPage.vue |
| 终端页 | frontend/src/pages/TerminalPage.vue |
| WebSocket composable | frontend/src/composables/useWebSocket.ts |
| Vite 配置 | frontend/vite.config.mts |
| 部署脚本 | deploy/deploy-frontend.sh |
| 门控脚本 | deploy/pre_deploy_check.sh |
| Supervisor | deploy/nexus.conf |
| Nginx | deploy/nginx_https.conf |
| DB 备份 | deploy/db_backup.sh |
| 健康检查 | deploy/health_monitor.sh |
| 项目规则 | CLAUDE.md (非常详尽，279行) |
| Cursor 规则 | .cursorrules (项目根目录) |

---

## 十、Megamemory 知识图谱

**统计**: 34 nodes, 23 edges, 11 removed

使用 `megamemory:understand` 查询项目上下文，`megamemory:list_roots` 查看所有根节点。

核心概念: nexus(总览), clean-architecture-4, db-tables-14, jwt-totp, webssh, terminal-11, sync, install-wizard, 3(3层守护), websocket, telegram, redis, security, settings, vuetify-spa, pushpage, ide, v2(文件管理器), pipeline-7(7道门控), push-cancel, reveal-with-password, nexus-theme, ruff-2026-05-30, appauthmiddleware-fix-chain, browser-tool-preference, session-2026-05-30-progress, agent, servers-list, child-server-operation-rules

---

## 十一、规则文件位置

| 文件 | 路径 | 说明 |
|------|------|------|
| **Cursor 规则** | `.cursorrules`（项目根目录）| 已创建，Cursor 自动读取 |
| **Cursor MCP** | `C:\Users\uzuma\.cursor\mcp.json` | 已创建，Cursor 自动读取 |
| 全局规则 (Claude) | `C:\Users\uzuma\.claude\CLAUDE.md` | 完美实现原则、安全铁律、文档纪律、执行顺序 |
| 项目规则 (Claude) | `C:\Users\uzuma\Desktop\svn\Nexus\CLAUDE.md` | 项目概述、目录结构、已确认决策、实现状态、部署流程 |
| 项目 Memory (Claude) | `C:\Users\uzuma\.claude\projects\C--Users-uzuma-Desktop-svn-Nexus\memory\MEMORY.md` | 语言偏好(中文)、浏览器偏好(Playwright)、SSH配置、部署流程、Vuetify进度 |

---

## 十二、开发流程提醒

```
需求确认 → 设计文档 → 技术文档 → 实现 → 测试验证 → changelog →（必要时）更新 CLAUDE.md
```

**强制文件修改流程（不可跳步）**:
```
实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog
```

**进度条**（每次改代码必须输出）:
```
□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog
```

审计8步：登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD

---

## 十三、数据流

```
Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史)
告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机
恢复: 之前告警的指标恢复正常 → 自动推送恢复通知
Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s)
Redis告警key: alerts:{server_id} (SET, TTL=3600s)
```

---

## 十四、已确认的关键决策

| 不可改项 | 原因 |
|---------|------|
| API_KEY | 加密一致性 + 子服务器认证 |
| SECRET_KEY | 加密回退密钥 |
| DATABASE_URL | 启动必需 |
| ENCRYPTION_KEY | 凭据加密 |

| 可改项 | 说明 |
|--------|------|
| system_name/title | 前端显示 |
| pool_size/overflow | 安装向导自动推荐 |
| redis_url | Redis 连接 |
| 告警阈值 | 默认 80% |
| Telegram 配置 | 告警推送 |

---

## 十五、用户审查清单

验证 AI 是否偷懒：
1. 看 `deploy/gate_log.jsonl` — 每次门控都有记录，没有记录 = 没过门控
2. 看审计文件 — 必须有 Closure 表（每个H的判定+依据）、Step 3 规则扫描、DoD
3. 看进度条 — ☑必须在□前面，否则跳步
4. 看 changelog — 行数≥10，不能是空壳
