459 lines
16 KiB
Markdown
459 lines
16 KiB
Markdown
|
|
# Nexus 6.0 — 功能开发指南 · 附录(详细参考)
|
|||
|
|
|
|||
|
|
> **主文档**: [nexus-functional-development-guide.md](nexus-functional-development-guide.md)
|
|||
|
|
> **版本**: 2026-06-04
|
|||
|
|
> **用途**: API 请求体、前端调用链、E2E/L4 对照、组件映射 — 接续开发时查表用
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 A — `/api/sync` 端点与 Pydantic 模型
|
|||
|
|
|
|||
|
|
定义: `server/api/schemas.py` · 路由: `server/api/sync_v2.py` · 前缀: `/api/sync`
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | 请求模型 | 说明 |
|
|||
|
|
|------|------|----------|------|
|
|||
|
|
| POST | `/files` | `SyncFiles` | 批量 rsync 推送 |
|
|||
|
|
| POST | `/preview` | `SyncPreview` | dry-run 预览(单台代表服务器) |
|
|||
|
|
| POST | `/file-ops` | `FileOperation` | 远程 delete/rename/mkdir |
|
|||
|
|
| POST | `/file-clipboard` | `FileClipboardApply` | 远程 copy/move 批量粘贴 |
|
|||
|
|
| POST | `/browse` | `SyncBrowse` | 远程目录列表(POST 兼容路径) |
|
|||
|
|
| POST | `/browse-local` | `SyncBrowseLocal` | Nexus 本机 staging 目录浏览 |
|
|||
|
|
| POST | `/local-file-ops` | `LocalFileOperation` | staging 内 delete/rename |
|
|||
|
|
| POST | `/local-file-preview` | `LocalFilePreview` | staging 文件预览 |
|
|||
|
|
| POST | `/cancel` | `SyncCancel` | 按 batch_id 取消推送 |
|
|||
|
|
| POST | `/reconcile-stale-logs` | `ReconcileStaleLogs` | 将 stuck `running` 日志标失败 |
|
|||
|
|
| POST | `/validate-source-path` | `ValidateSourcePath` | 校验本机源目录 |
|
|||
|
|
| POST | `/diagnose` | `SyncDiagnose` | 单台推送失败诊断 |
|
|||
|
|
| POST | `/file-diff` | `FileSyncDiff` | 本地 vs 远程单文件 diff |
|
|||
|
|
| POST | `/upload` | multipart | 上传到 staging |
|
|||
|
|
| POST | `/upload-zip` | multipart | ZIP 解压到 staging |
|
|||
|
|
| POST | `/verify` | `SyncVerify` | 推送后 md5 校验 |
|
|||
|
|
| POST | `/download` | `FileDownload` | 远程文件下载流 |
|
|||
|
|
| POST | `/read-file` | `FileRead` | 读远程文本(≤5MB) |
|
|||
|
|
| POST | `/write-file` | `FileWrite` | 写远程文本 + 可选 etag 乐观锁 |
|
|||
|
|
| POST | `/chmod` | `FileChmod` | chmod/chown |
|
|||
|
|
| POST | `/compress` | `FileCompress` | tar.gz/zip 压缩 |
|
|||
|
|
| POST | `/decompress` | `FileDecompress` | 解压到绝对路径 |
|
|||
|
|
|
|||
|
|
### A.1 核心模型字段
|
|||
|
|
|
|||
|
|
**SyncFiles**(推送)
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认 | 约束 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| `server_ids` | `int[]` | — | min 1 |
|
|||
|
|
| `source_path` | `str` | — | Nexus 本机绝对路径,禁系统敏感路径 |
|
|||
|
|
| `target_path` | `str?` | null | 远程绝对路径;空则用各服务器 `target_path` |
|
|||
|
|
| `sync_mode` | `str` | `incremental` | `incremental\|full\|overwrite\|checksum` |
|
|||
|
|
| `batch_size` | `int` | 50 | 1–200 |
|
|||
|
|
| `concurrency` | `int` | 10 | 1–50 |
|
|||
|
|
| `batch_id` | `str?` | null | 12 位 hex;须先连 `/ws/sync` 再 POST |
|
|||
|
|
|
|||
|
|
**SyncPreview**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `server_id` | 代表服务器(单台 dry-run) |
|
|||
|
|
| `verbose` | true 时返回文件列表(≤200 行) |
|
|||
|
|
| 其余 | 同 SyncFiles 的 path/mode |
|
|||
|
|
|
|||
|
|
**FileOperation**
|
|||
|
|
|
|||
|
|
| operation | 必填 | 远程命令 |
|
|||
|
|
|-----------|------|----------|
|
|||
|
|
| `delete` | `path` | `rm -rf` |
|
|||
|
|
| `rename` | `path`, `new_path` | `mv` |
|
|||
|
|
| `mkdir` | `path` | `mkdir -p` |
|
|||
|
|
|
|||
|
|
**FileClipboardApply**
|
|||
|
|
|
|||
|
|
| 字段 | 约束 |
|
|||
|
|
|------|------|
|
|||
|
|
| `mode` | `copy` → `cp -r`;`move` → `mv -t` |
|
|||
|
|
| `sources` | 1–50 条远程绝对路径 |
|
|||
|
|
| `dest_dir` | 目标目录绝对路径 |
|
|||
|
|
|
|||
|
|
**FileRead / FileWrite**
|
|||
|
|
|
|||
|
|
| 字段 | FileRead | FileWrite |
|
|||
|
|
|------|----------|-----------|
|
|||
|
|
| `max_size` | 默认 1MB,max 5MB | — |
|
|||
|
|
| `content` | — | max 5MB |
|
|||
|
|
| `etag` | — | 乐观锁,冲突 409 |
|
|||
|
|
|
|||
|
|
**FileChmod**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `mode` | 3–4 位八进制 `^[0-7]{3,4}$` |
|
|||
|
|
| `owner` / `group` | 可选;group 须同时有 owner |
|
|||
|
|
| `recursive` | 目录递归 |
|
|||
|
|
|
|||
|
|
### A.2 推送 WS 协议(`/ws/sync`)
|
|||
|
|
|
|||
|
|
1. 前端生成 `batch_id`(12 hex)
|
|||
|
|
2. **先** `WebSocket` 连接 `/ws/sync?token=&batch_id=`
|
|||
|
|
3. **再** `POST /api/sync/files` 带相同 `batch_id`
|
|||
|
|
4. 消息: per-server 状态(pending/running/success/failed/cancelled)、进度百分比、错误摘要
|
|||
|
|
5. 取消: `POST /api/sync/cancel` `{ batch_id }`
|
|||
|
|
|
|||
|
|
### A.3 文件浏览双通道
|
|||
|
|
|
|||
|
|
| 通道 | 方法 | 优势 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| REST | `GET /api/files/browse?server_id=&path=` | ETag + 304,前端首选 |
|
|||
|
|
| Sync 兼容 | `POST /api/sync/browse` | 旧网关/部署回退 |
|
|||
|
|
|
|||
|
|
前端 `useFilesBrowse.fetchBrowseListing` 先 GET,失败再 POST。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 B — 文件页(Files)调用链
|
|||
|
|
|
|||
|
|
### B.1 组件树
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
FilesPage.vue
|
|||
|
|
├── FilesToolbar.vue # 服务器选择、刷新、上传、新建
|
|||
|
|
├── FilesPermissionAlert.vue # files-capability / sudo 提示
|
|||
|
|
├── FilesStatusBar.vue # 条目统计、SSH 用户
|
|||
|
|
├── FilesBreadcrumb.vue # 路径面包屑
|
|||
|
|
├── FilesList.vue # v-data-table + 行操作
|
|||
|
|
├── FilesDialogs.vue # 删除/重命名/chmod/压缩等对话框
|
|||
|
|
└── FileEditorWorkbench.vue # Monaco 编辑 + 预览
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`provideFilesPage(page)` → 子组件通过 `injectFilesPage()` 取上下文(`filesPageContext.ts`)。
|
|||
|
|
|
|||
|
|
### B.2 Composable 依赖图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
useFilesPage
|
|||
|
|
├── useFilesStore (Pinia) # selectedServer, currentPath, files, cache
|
|||
|
|
├── useFilesSelection # selectedFiles 多选
|
|||
|
|
├── useFilesBrowse(fileFilter) # browse(), ETag, preload Monaco
|
|||
|
|
│ └── GET /api/files/browse | POST /api/sync/browse
|
|||
|
|
├── useFilesPermissions # files-capability, setup-files-sudo
|
|||
|
|
│ └── GET /api/servers/{id}/files-capability
|
|||
|
|
│ └── POST /api/servers/{id}/setup-files-sudo
|
|||
|
|
├── useFilesNavigation # 面包屑、goUp、openEntry、?server_id=
|
|||
|
|
├── useFilesEditor # read/write/preview
|
|||
|
|
│ └── POST /api/sync/read-file | write-file
|
|||
|
|
├── useFilesActions # CRUD、clipboard、upload、compress
|
|||
|
|
│ └── POST /api/sync/file-ops | file-clipboard | upload | chmod | compress…
|
|||
|
|
├── useFilesClipboard # 跨目录 copy/cut/paste 状态
|
|||
|
|
└── useFilesHotkeys # Ctrl+C/V、Delete、F5 刷新
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### B.3 关键 API 映射(用户操作 → 端点)
|
|||
|
|
|
|||
|
|
| 用户操作 | Composable | API |
|
|||
|
|
|----------|------------|-----|
|
|||
|
|
| 选服务器/进目录 | `useFilesBrowse.browse` | `GET /files/browse` |
|
|||
|
|
| 保存编辑器 | `useFilesEditor.save` | `POST /sync/write-file` |
|
|||
|
|
| 删除/重命名/新建目录 | `useFilesActions` | `POST /sync/file-ops` |
|
|||
|
|
| 复制/剪切/粘贴 | `useFilesActions` + clipboard | `POST /sync/file-clipboard` |
|
|||
|
|
| 上传 | `useFilesActions.doUpload` | `POST /sync/upload` |
|
|||
|
|
| chmod | `useFilesActions.doChmod` | `POST /sync/chmod` |
|
|||
|
|
| 压缩/解压 | `useFilesActions` | `POST /sync/compress` / `decompress` |
|
|||
|
|
| 下载 | `useFilesActions.downloadFile` | `POST /sync/download` |
|
|||
|
|
| 配置 sudo | `useFilesPermissions.setupFilesSudo` | `POST /servers/{id}/setup-files-sudo` |
|
|||
|
|
| 打开终端 | `useFilesNavigation.openInTerminal` | 路由 `#/terminal?server_id=` |
|
|||
|
|
|
|||
|
|
### B.4 Store 缓存策略(`stores/files.ts`)
|
|||
|
|
|
|||
|
|
- Key: `{serverId}:{path}`
|
|||
|
|
- 存 ETag + entries + fetchedAt
|
|||
|
|
- `invalidateAfterMutation` 在写操作后清除当前目录及父目录缓存
|
|||
|
|
- `pageReady`: 首次 browse 完成后为 true(避免空态闪烁)
|
|||
|
|
|
|||
|
|
### B.5 路由 Query 参数
|
|||
|
|
|
|||
|
|
| 参数 | 行为 |
|
|||
|
|
|------|------|
|
|||
|
|
| `?server_id=123` | `useFilesNavigation` 自动选中并 browse |
|
|||
|
|
| `?path=/var/www` | 初始路径(须与 server_id 同用) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 C — 推送页(Push)调用链
|
|||
|
|
|
|||
|
|
### C.1 Composable 依赖图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
usePushPage
|
|||
|
|
├── usePushForm # source_path, target_path, sync_mode, batch 参数
|
|||
|
|
├── usePushServers # 服务器列表、分类、全选、在线过滤
|
|||
|
|
├── usePushLogs # sync_logs 历史分页
|
|||
|
|
├── usePushProgress # WS + doPush + cancel
|
|||
|
|
│ └── WS /ws/sync
|
|||
|
|
│ └── POST /api/sync/files, /cancel
|
|||
|
|
└── usePushPreview # 预览对话框、confirmAndPush
|
|||
|
|
└── POST /api/sync/preview (并发代表服务器)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### C.2 推送流程(时序)
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant UI as PushPage
|
|||
|
|
participant WS as /ws/sync
|
|||
|
|
participant API as /api/sync/files
|
|||
|
|
participant Eng as SyncEngineV2
|
|||
|
|
|
|||
|
|
UI->>UI: generate batch_id (12 hex)
|
|||
|
|
UI->>WS: connect(token, batch_id)
|
|||
|
|
UI->>API: POST /files {batch_id, server_ids, ...}
|
|||
|
|
Eng->>WS: per-server progress
|
|||
|
|
WS->>UI: update pushStatus
|
|||
|
|
Eng->>Eng: rsync over SSH (semaphore)
|
|||
|
|
UI->>API: POST /cancel (optional)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### C.3 相关端点(Push 页间接使用)
|
|||
|
|
|
|||
|
|
| 功能 | API |
|
|||
|
|
|------|-----|
|
|||
|
|
| 校验源路径 | `POST /sync/validate-source-path` |
|
|||
|
|
| ZIP 源 | `POST /sync/upload-zip` |
|
|||
|
|
| 失败诊断 | `POST /sync/diagnose` |
|
|||
|
|
| 对账 stuck 日志 | `POST /sync/reconcile-stale-logs` |
|
|||
|
|
| 推送后校验 | `POST /sync/verify` |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 D — 终端页(Terminal)调用链
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
TerminalPage.vue
|
|||
|
|
├── TerminalToolbar.vue
|
|||
|
|
├── TerminalTabBar.vue
|
|||
|
|
├── TerminalServerPicker.vue
|
|||
|
|
├── TerminalArea.vue # xterm 实例
|
|||
|
|
├── TerminalCmdBar.vue # 命令输入 + 高亮
|
|||
|
|
└── TerminalQuickBar.vue # 快捷命令
|
|||
|
|
|
|||
|
|
useTerminalSessions
|
|||
|
|
├── POST /api/auth/webssh-token { server_id }
|
|||
|
|
├── WebSocket /ws/terminal/{session_uuid}?token=
|
|||
|
|
├── Koko: TERMINAL_INIT, DATA, RESIZE, CLOSE
|
|||
|
|
└── onBeforeUnmount → disposeAllSessions
|
|||
|
|
|
|||
|
|
useTerminalQuickCommands → GET/POST /api/terminal/quick-commands
|
|||
|
|
useTerminalSettings → localStorage 主题/字体(非敏感)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**WebSSH JWT**: `purpose=webssh`, 绑定 `server_id`, 15min;路径 param `id` 须与 token 内 server_id 一致。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 E — 其余 API 模块明细
|
|||
|
|
|
|||
|
|
### E.1 调度 `/api/schedules`(`settings.py` 内)
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| GET | `/` | 列表 |
|
|||
|
|
| POST | `/` | 创建(cron + server_ids + source/target + sync_mode 或 script_id) |
|
|||
|
|
| PUT | `/{id}` | 更新 |
|
|||
|
|
| DELETE | `/{id}` | 删除 |
|
|||
|
|
|
|||
|
|
后台 `schedule_runner` 每分钟扫描 `enabled=1` 且 cron 到期项 → 调 SyncEngine 或 ScriptService。
|
|||
|
|
|
|||
|
|
### E.2 重试 `/api/retries`
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| GET | `/` | 待重试队列 |
|
|||
|
|
| POST | `/{id}/retry` | 手动触发 |
|
|||
|
|
| DELETE | `/{id}` | 移出队列 |
|
|||
|
|
|
|||
|
|
`retry_runner` 每 5min,`SELECT … FOR UPDATE SKIP LOCKED`,指数退避,max 3 次。
|
|||
|
|
|
|||
|
|
### E.3 审计 `/api/audit`
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | Query |
|
|||
|
|
|------|------|-------|
|
|||
|
|
| GET | `/` | `page`, `page_size`, `action`, `username`, `date_from`, `date_to` |
|
|||
|
|
|
|||
|
|
### E.4 告警 `/api/alert-history`
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| GET | `/` | 分页列表 |
|
|||
|
|
| GET | `/stats` | 汇总统计 |
|
|||
|
|
|
|||
|
|
### E.5 预设
|
|||
|
|
|
|||
|
|
| 前缀 | 用途 |
|
|||
|
|
|------|------|
|
|||
|
|
| `/api/presets` | 密码预设 CRUD |
|
|||
|
|
| `/api/ssh-key-presets` | SSH 密钥预设 CRUD |
|
|||
|
|
| `/api/scripts/credentials` | DB 凭据(脚本 `$DB_*`) |
|
|||
|
|
|
|||
|
|
### E.6 脚本 `/api/scripts`
|
|||
|
|
|
|||
|
|
| 方法 | 路径 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| POST | `/exec` | `{ script_id?, command?, server_ids, timeout }` |
|
|||
|
|
| GET | `/executions` | 分页执行记录 |
|
|||
|
|
| POST | `/executions/{id}/stop` | SIGTERM/SIGKILL |
|
|||
|
|
| POST | `/executions/{id}/retry` | 重新执行 |
|
|||
|
|
| GET | `/exec-config` | 超时阈值等前端展示用 |
|
|||
|
|
|
|||
|
|
### E.7 Agent `/api/agent`
|
|||
|
|
|
|||
|
|
**Heartbeat body(摘要)**
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"server_id": 1,
|
|||
|
|
"cpu": 12.5,
|
|||
|
|
"memory": 45.0,
|
|||
|
|
"disk": 60.0,
|
|||
|
|
"load": [0.1, 0.2, 0.15],
|
|||
|
|
"agent_version": "6.0.x",
|
|||
|
|
"system_info": { "hostname": "...", "os": "..." }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Script callback**: Agent 长任务完成后 POST,更新 Redis + MySQL execution。
|
|||
|
|
|
|||
|
|
### E.8 搜索 `/api/search`
|
|||
|
|
|
|||
|
|
`GET /?q=` — 并行查 servers、scripts、db_credentials、schedules(limit 各 10)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 F — 前端页面 ↔ 组件 ↔ Composable 映射
|
|||
|
|
|
|||
|
|
| 页面 | 主要 Composable | 关键子组件 |
|
|||
|
|
|------|-----------------|------------|
|
|||
|
|
| DashboardPage | `useWebSocket`, `useServerPagination` | StatCardsRow |
|
|||
|
|
| ServersPage | `useServerFormDialog`, `useServerPagination` | ServerFormDialog |
|
|||
|
|
| TerminalPage | `useTerminalSessions`, `useTerminalCmdBar` | TerminalArea, TerminalTabBar |
|
|||
|
|
| FilesPage | `useFilesPage` | FilesToolbar, FilesList, FileEditorWorkbench |
|
|||
|
|
| PushPage | `usePushPage` | PushToolbar, PushServerGrid, PushProgressList |
|
|||
|
|
| ScriptsPage | 页内逻辑 + Monaco | ScriptEditorDialog |
|
|||
|
|
| CredentialsPage | 三 Tab CRUD | — |
|
|||
|
|
| SchedulesPage | cron 表单 | ScheduleFormDialog |
|
|||
|
|
| RetriesPage | 列表 + retry | — |
|
|||
|
|
| CommandsPage | 双视图切换 | — |
|
|||
|
|
| AlertsPage | 过滤 + 分页 | — |
|
|||
|
|
| AuditPage | `normalizeAuditList` | — |
|
|||
|
|
| SettingsPage | TOTP/API Key/IP 白名单 | TerminalQuickCommandsSettings |
|
|||
|
|
| LoginPage | `useAuthStore.login` | — |
|
|||
|
|
|
|||
|
|
### F.1 全局布局(`App.vue`)
|
|||
|
|
|
|||
|
|
- 侧栏 14 项导航(v-list)
|
|||
|
|
- 顶栏:全局搜索 → `GET /api/search`
|
|||
|
|
- 用户菜单:主题切换、退出
|
|||
|
|
- `useWebSocket` 告警 toast + Dashboard 刷新触发
|
|||
|
|
|
|||
|
|
### F.2 类型定义
|
|||
|
|
|
|||
|
|
所有 API 响应类型优先维护在 `frontend/src/types/api.ts`;新增字段先改类型再改 composable。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 G — 验收与 E2E 对照
|
|||
|
|
|
|||
|
|
### G.1 L4 统一入口
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python3 scripts/run_nexus_acceptance.py --base http://127.0.0.1:8600 --with-ui
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
阶段:
|
|||
|
|
|
|||
|
|
| Phase | 内容 |
|
|||
|
|
|-------|------|
|
|||
|
|
| API | `tests/test_api.py` + `tests/test_api_extended.py` |
|
|||
|
|
| UI | `frontend/e2e/full-acceptance.spec.mjs`(15 用例) |
|
|||
|
|
| Unit | `--with-unit` 时跑路径/权限单测 |
|
|||
|
|
|
|||
|
|
功能 rollup 映射: `tests/acceptance_catalog.py` → `FEATURES[]`。
|
|||
|
|
|
|||
|
|
### G.2 Playwright 用例 ↔ 页面
|
|||
|
|
|
|||
|
|
| 用例 ID | 路由 | 验证点 |
|
|||
|
|
|---------|------|--------|
|
|||
|
|
| 01 | `#/` | 登录 + Dashboard 卡片 |
|
|||
|
|
| 02 | `#/servers` | 添加对话框、批量选择 |
|
|||
|
|
| 03 | `#/` | 全局搜索输入 |
|
|||
|
|
| 04 | `#/terminal` | 终端页可见 |
|
|||
|
|
| 05 | `#/files` | 文件页可见 |
|
|||
|
|
| 06 | `#/push` | 预览按钮(不真推送) |
|
|||
|
|
| 07 | `#/scripts` | 新建脚本对话框 |
|
|||
|
|
| 08 | `#/credentials` | 三 Tab 切换 |
|
|||
|
|
| 09 | `#/schedules` | 新建调度对话框 |
|
|||
|
|
| 10 | `#/retries` | 重试列表 |
|
|||
|
|
| 11 | `#/commands` | 命令/会话视图 |
|
|||
|
|
| 12 | `#/alerts` | 告警页 |
|
|||
|
|
| 13 | `#/audit` | 审计页 |
|
|||
|
|
| 14 | `#/settings` | 设置区块 |
|
|||
|
|
| 15 | `#/` | 主题切换 + 登出 |
|
|||
|
|
|
|||
|
|
**环境变量**
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
NEXUS_E2E_BASE=http://127.0.0.1:8600
|
|||
|
|
NEXUS_E2E_USER=admin
|
|||
|
|
NEXUS_E2E_PASSWORD=*** # 必填;测试账号勿开 TOTP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### G.3 API 测试环境
|
|||
|
|
|
|||
|
|
与 E2E 共用 `.env` 中 `NEXUS_TEST_ADMIN_PASSWORD`(`seed_local_admin.py` 写入)。
|
|||
|
|
|
|||
|
|
### G.4 本地验证脚本
|
|||
|
|
|
|||
|
|
`bash scripts/local_verify.sh` — ruff、import、pytest 子集、前端 typecheck(若可用)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 H — 错误码与前端处理约定
|
|||
|
|
|
|||
|
|
| HTTP | 场景 | 前端处理 |
|
|||
|
|
|------|------|----------|
|
|||
|
|
| 401 | JWT 过期 | `fetchAuthed` 自动 refresh 一次 |
|
|||
|
|
| 202 | 需 TOTP | `TotpRequiredError` → 显示 TOTP 输入 |
|
|||
|
|
| 304 | Browse ETag 命中 | 用缓存 entries |
|
|||
|
|
| 409 | write-file etag 冲突 | 提示合并/覆盖 |
|
|||
|
|
| 429 | 登录锁定 | Login 页显示剩余时间 |
|
|||
|
|
| 503 | 安装模式 | 引导 `/app/install.html` |
|
|||
|
|
|
|||
|
|
统一错误文案: `formatApiError(err)` + `$snackbar`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录 I — 新增功能检查清单(扩展)
|
|||
|
|
|
|||
|
|
### 新 Sync 相关端点
|
|||
|
|
|
|||
|
|
- [ ] `schemas.py` Pydantic + path validator
|
|||
|
|
- [ ] `sync_v2.py` 路由 + `_audit_sync`
|
|||
|
|
- [ ] `tests/test_api.py` 或 `test_sync_*.py`
|
|||
|
|
- [ ] 前端 `http.post('/sync/...')` + types
|
|||
|
|
- [ ] 更新附录 A + 主文档 §10
|
|||
|
|
- [ ] changelog ≥10 行
|
|||
|
|
|
|||
|
|
### 新 Files 操作
|
|||
|
|
|
|||
|
|
- [ ] `useFilesActions` 方法 + `FilesDialogs` UI
|
|||
|
|
- [ ] 热键(若适用)注册到 `useFilesHotkeys`
|
|||
|
|
- [ ] browse 缓存 invalidate
|
|||
|
|
- [ ] E2E 05 或专项用例
|
|||
|
|
|
|||
|
|
### 新页面(第 15 页)
|
|||
|
|
|
|||
|
|
- [ ] `pages/XxxPage.vue`
|
|||
|
|
- [ ] `router/index.ts` + `App.vue` nav
|
|||
|
|
- [ ] `acceptance_catalog.py` + Playwright 用例
|
|||
|
|
- [ ] `run_nexus_acceptance` 报告可 rollup
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**维护**: 改 API/composable 时同步更新对应附录章节。
|