Some checks failed
CI / Rust Check (push) Has been cancelled
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- README.md: SKILL 76→75, Tauri 命令 175→171, SaaS API 58→131, Workers 5→7, 数据表 25→34, Admin 11→13 页面 - 00-saas-overview.md: Agent Template 新增 5 个端点文档、种子数据表、端到端数据流图 - roadmap.md: 同步最新数字 - fix(saasStore): toTopRequired → totpRequired 拼写修复
329 lines
17 KiB
Markdown
329 lines
17 KiB
Markdown
# ZCLAW SaaS 平台 — 总览
|
||
|
||
> 最后更新: 2026-04-01 | 实施状态: Phase 1-4 全部完成 + 架构重构完成,10 个后端模块 + Worker + Scheduler + Admin V2 (Vite + Ant Design Pro) + 桌面端完整集成
|
||
|
||
## 架构概述
|
||
|
||
ZCLAW SaaS 平台为桌面端用户提供云端能力,包括模型中转(Key 池)、账号管理、配置同步、Prompt OTA、Agent 模板和遥测收集。
|
||
|
||
```text
|
||
桌面端 (Tauri/React)
|
||
│
|
||
├── Mode A: Tauri Kernel (本地直连 LLM)
|
||
├── Mode B: Gateway WebSocket (本地中转)
|
||
└── Mode C: SaaS Cloud ──→ Rust/Axum 后端 (端口 8080) ──→ 上游 LLM Provider
|
||
│
|
||
├── Admin V2 (Ant Design Pro 纯 SPA)
|
||
└── PostgreSQL (数据持久化)
|
||
```
|
||
|
||
## 技术栈
|
||
|
||
| 层级 | 技术 | 说明 |
|
||
|------|------|------|
|
||
| 后端 | Rust + Axum + sqlx + PostgreSQL | JWT + API Token 双认证,RBAC 权限 |
|
||
| Admin V2 | Vite 6 + React 19 + antd v5 + ProComponents | 纯 SPA(替代 Next.js,消除 SSR/hydration 问题) |
|
||
| 桌面端 | React 18 + Zustand + TypeScript | saas-client.ts 30+ API 方法 |
|
||
| 安全 | Argon2id + TOTP 2FA (AES-256-GCM) + RBAC | 速率限制 + 操作审计 + SSRF 防护 |
|
||
|
||
## 数据库
|
||
|
||
- **引擎**: PostgreSQL (sqlx 异步驱动)
|
||
- **Schema 版本**: v6 (TIMESTAMPTZ 时间戳类型)
|
||
- **数据表**: 25 张 (accounts, providers, models, relay_tasks, prompt_templates, agent_templates, telemetry_reports 等)
|
||
- **种子数据**: 3 个系统角色 (super_admin, admin, user),3 个内置 Prompt 模板
|
||
- **迁移系统**: 声明式 SQL 文件 (`crates/zclaw-saas/migrations/`),按文件名排序执行
|
||
- **连接池**: 50 max / 5 min 连接,10s 获取超时,300s 空闲超时,1800s 最大生命周期
|
||
|
||
## 功能模块
|
||
|
||
| 模块 | 完成度 | API 路由数 | 核心能力 |
|
||
|------|--------|-----------|----------|
|
||
| 认证 (Auth) | 100% | 8 | JWT + API Token 双认证、注册/登录、密码修改、/me、TOTP 2FA (AES-256-GCM 加密) |
|
||
| 账号 (Account) | 100% | 12 | CRUD + 角色管理 + 角色提升防护 + 设备注册/心跳 + 操作日志 + Dashboard 统计 |
|
||
| 模型配置 (Model Config) | 100% | 14 | Provider/Model/Key CRUD + Key 轮换 + 用量统计 (按天/按模型聚合) |
|
||
| 中转 (Relay) | 100% | 9 | SSE 流式 + JSON 响应 + Key 池管理 + RPM/TPM 限制 + 指数退避重试 + SSRF 防护 |
|
||
| 配置迁移 (Migration) | 100% | 9 | 配置 CRUD + 分析 + 种子数据 (21 项默认) + push/merge 同步 + diff 对比 + 增量拉取 |
|
||
| 角色 (Role) | 100% | 7 | Role CRUD + 系统角色保护 + 权限模板 + 批量应用 |
|
||
| Prompt OTA | 100% | 8 | 模板 + 版本管理 + OTA 批量检查 + 版本回滚 + 不可变版本历史 |
|
||
| Agent 模板 | 100% | 5 | 模板 CRUD + tools/capabilities/model 绑定 + 可见性控制 |
|
||
| 遥测 (Telemetry) | 100% | 4 | 批量 Token 用量上报 + 模型聚合统计 + 每日统计 + 审计摘要 |
|
||
| 定时任务 (Scheduled Task) | 100% | 2 | 用户定时任务 CRUD (创建/列表/更新/删除),30s 轮询执行 |
|
||
| **Worker 系统** | 100% | — | 5 个 Worker (log_operation, cleanup_rate_limit, cleanup_refresh_tokens, record_usage, update_last_used),mpsc 异步调度,自动重试 |
|
||
| **声明式 Scheduler** | 100% | — | TOML 配置定时任务,灵活间隔 (30s/5m/1h/1d),run_on_start,内置 DB 清理 |
|
||
| **合计** | — | **58** | — |
|
||
|
||
## API 端点一览
|
||
|
||
### 公开端点 (无需认证)
|
||
- `POST /api/v1/auth/register` — 注册
|
||
- `POST /api/v1/auth/login` — 登录 (支持 TOTP 验证)
|
||
- `GET /api/health` — 健康检查
|
||
|
||
### 认证 (Auth)
|
||
- `GET /api/v1/auth/me` — 当前用户信息
|
||
- `POST /api/v1/auth/refresh` — 刷新 Token
|
||
- `PUT /api/v1/auth/password` — 修改密码
|
||
- `POST /api/v1/auth/totp/setup` — 生成 TOTP 密钥,返回 otpauth:// URI
|
||
- `POST /api/v1/auth/totp/verify` — 验证 TOTP 码并启用 2FA
|
||
- `POST /api/v1/auth/totp/disable` — 禁用 2FA (需密码确认)
|
||
|
||
### 账号管理 (Account)
|
||
- `GET /api/v1/accounts` — 列出账号 (admin,分页 + 角色/状态/搜索过滤)
|
||
- `GET /api/v1/accounts/:id` — 获取账号
|
||
- `PATCH /api/v1/accounts/:id` — 更新账号 (自更新有限字段,admin 可设置角色)
|
||
- `PATCH /api/v1/accounts/:id/status` — 更新状态 (admin: active/disabled/suspended)
|
||
- `GET /api/v1/tokens` — 列出 API Token
|
||
- `POST /api/v1/tokens` — 创建 API Token (权限限制为创建者子集)
|
||
- `DELETE /api/v1/tokens/:id` — 撤销 Token
|
||
- `GET /api/v1/devices` — 列出当前用户设备
|
||
- `POST /api/v1/devices/register` — 注册/更新设备 (UPSERT)
|
||
- `POST /api/v1/devices/heartbeat` — 设备心跳
|
||
- `GET /api/v1/logs/operations` — 操作日志 (admin,分页)
|
||
- `GET /api/v1/stats/dashboard` — 仪表盘统计 (admin)
|
||
|
||
### Provider / Model / Key 管理
|
||
- `GET/POST /api/v1/providers` — Provider 列表/创建
|
||
- `GET/PATCH/DELETE /api/v1/providers/:id` — 单个 Provider
|
||
- `GET /api/v1/providers/:id/models` — Provider 下的模型列表
|
||
- `GET/POST /api/v1/models` — Model 列表/创建
|
||
- `GET/PATCH/DELETE /api/v1/models/:id` — 单个 Model
|
||
- `GET/POST /api/v1/keys` — 账号 API Key 列表/创建
|
||
- `POST /api/v1/keys/:id/rotate` — 轮换 API Key
|
||
- `DELETE /api/v1/keys/:id` — 撤销 API Key
|
||
- `GET /api/v1/usage` — 用量统计 (按日期/模型/Provider 过滤)
|
||
|
||
### 中转 (Relay)
|
||
- `GET /api/v1/relay/models` — 可用中转模型
|
||
- `POST /api/v1/relay/chat/completions` — OpenAI 兼容聊天中转 (SSE/JSON)
|
||
- `GET /api/v1/relay/tasks` — 中转任务列表 (分页 + 状态过滤)
|
||
- `GET /api/v1/relay/tasks/:id` — 获取单个任务
|
||
- `POST /api/v1/relay/tasks/:id/retry` — 重试失败任务 (admin)
|
||
- `GET /api/v1/providers/:provider_id/keys` — Provider Key 池列表 (admin)
|
||
- `POST /api/v1/providers/:provider_id/keys` — 添加 Key 到池 (admin)
|
||
- `PUT /api/v1/providers/:provider_id/keys/:key_id/toggle` — 切换 Key 启停 (admin)
|
||
- `DELETE /api/v1/providers/:provider_id/keys/:key_id` — 删除池中 Key (admin)
|
||
|
||
### 配置迁移 (Migration)
|
||
- `GET /api/v1/config/items` — 列出配置项 (分页 + 分类/来源过滤)
|
||
- `GET /api/v1/config/items/:id` — 获取配置项
|
||
- `POST /api/v1/config/items` — 创建配置项 (admin)
|
||
- `PUT /api/v1/config/items/:id` — 更新配置项 (admin)
|
||
- `DELETE /api/v1/config/items/:id` — 删除配置项 (admin)
|
||
- `GET /api/v1/config/analysis` — 配置分析 (分类摘要 + 全部项)
|
||
- `POST /api/v1/config/seed` — 种子配置 (admin,21 项默认含 11 项安全策略)
|
||
- `POST /api/v1/config/sync` — 配置同步 (push/merge 模式)
|
||
- `POST /api/v1/config/diff` — 配置差异对比 (只读)
|
||
- `GET /api/v1/config/sync-logs` — 同步日志 (分页)
|
||
- `GET /api/v1/config/pull` — 批量拉取配置 (支持 since 增量)
|
||
|
||
### 角色 (Role)
|
||
- `GET /api/v1/roles` — 列出角色
|
||
- `GET/POST /api/v1/roles/:id` — 角色 CRUD (系统角色不可修改/删除)
|
||
- `PUT/DELETE /api/v1/roles/:id` — 更新/删除角色 (admin)
|
||
- `GET /api/v1/permission-templates` — 权限模板列表
|
||
- `POST /api/v1/permission-templates` — 创建模板 (admin)
|
||
- `POST /api/v1/permission-templates/:id/apply` — 批量应用模板到账号
|
||
|
||
### Prompt OTA
|
||
- `POST /api/v1/prompts/check` — OTA 批量检查更新 (设备上报版本,返回差量)
|
||
- `GET /api/v1/prompts` — 列出模板 (分页 + 分类/来源/状态过滤)
|
||
- `POST /api/v1/prompts` — 创建模板 + 初始 v1
|
||
- `GET /api/v1/prompts/:name` — 按名称获取模板
|
||
- `PUT /api/v1/prompts/:name` — 更新模板元数据
|
||
- `DELETE /api/v1/prompts/:name` — 归档模板
|
||
- `GET /api/v1/prompts/:name/versions` — 版本历史
|
||
- `GET /api/v1/prompts/:name/versions/:version` — 获取特定版本
|
||
- `POST /api/v1/prompts/:name/versions` — 发布新版本 (自动递增)
|
||
- `POST /api/v1/prompts/:name/rollback/:version` — 回滚到指定版本
|
||
|
||
### Agent 模板
|
||
- `GET /api/v1/agent-templates` — 列出模板 (分页 + 分类/来源/可见性过滤)
|
||
- `POST /api/v1/agent-templates` — 创建模板 (输入验证: name 非空+长度限制, temperature 0.0-1.0, max_tokens 0-65535)
|
||
- `GET /api/v1/agent-templates/:id` — 获取模板 (含全部 25 列)
|
||
- `GET /api/v1/agent-templates/available` — 列出公开可用模板 (轻量级, 仅核心字段)
|
||
- `POST /api/v1/agent-templates/:id` — 更新模板
|
||
- `DELETE /api/v1/agent-templates/:id` — 归档模板
|
||
- `POST /api/v1/agent-templates/:id/create-agent` — 从模板创建 Agent 配置 (tools 合并, model fallback)
|
||
- `POST /api/v1/accounts/me/assign-template` — 分配行业模板到当前账户
|
||
- `GET /api/v1/accounts/me/assigned-template` — 获取已分配的行业模板
|
||
- `DELETE /api/v1/accounts/me/assigned-template` — 取消行业模板分配
|
||
|
||
#### 行业模板种子数据
|
||
|
||
6 个内置行业模板 (source='builtin'):
|
||
|
||
| 模板 | 模型 | 工具 | 温度 |
|
||
|------|------|------|------|
|
||
| Code Assistant | gpt-4o | file_read, file_write, shell_exec | 0.3 |
|
||
| Content Writer | claude-sonnet-4-20250514 | web_fetch, file_write | 0.7 |
|
||
| Data Analyst | gemini-2.5-pro | shell_exec, file_read | 0.2 |
|
||
| Research Agent | deepseek-chat | web_fetch, file_read | 0.5 |
|
||
| Translator | gpt-4o | (none) | 0.3 |
|
||
| Medical Assistant | claude-sonnet-4-20250514 | web_fetch, file_read | 0.2 |
|
||
|
||
#### 端到端数据流
|
||
|
||
```text
|
||
用户选择模板 → assignTemplate(templateId)
|
||
→ 后端: accounts.assigned_template_id = templateId
|
||
→ 前端 createFromTemplate(template)
|
||
→ Step 1: saasClient.createAgentFromTemplate(templateId) — 后端合并 tools+capabilities
|
||
→ Step 2: client.createClone(merged config)
|
||
→ Step 3: identity.updateFile('soul', soul_content)
|
||
→ Step 4: identity.updateFile('system', system_prompt)
|
||
→ Step 5: updateClone(temperature, maxTokens, tools, source_template_id, welcomeMessage, quickCommands)
|
||
→ Step 6: loadClones() 刷新 store
|
||
→ ChatArea: FirstConversationPrompt
|
||
→ clone.welcomeMessage || generateWelcomeMessage()
|
||
→ clone.quickCommands || 硬编码 QUICK_ACTIONS
|
||
```
|
||
|
||
### 遥测 (Telemetry)
|
||
- `POST /api/v1/telemetry/report` — 批量上报 Token 用量 (每次最多 500 条)
|
||
- `GET /api/v1/telemetry/stats` — 模型聚合统计 (请求次数/Token/延迟/成功率)
|
||
- `GET /api/v1/telemetry/daily` — 每日使用量聚合 (按设备去重)
|
||
- `POST /api/v1/telemetry/audit` — 批量审计日志摘要 (仅动作类型和计数)
|
||
|
||
### 定时任务 (Scheduled Task)
|
||
- `POST /api/scheduler/tasks` — 创建定时任务 (支持 cron/interval 两种调度模式)
|
||
- `GET /api/scheduler/tasks` — 列出当前用户的定时任务
|
||
- `PATCH /api/scheduler/tasks/:id` — 更新定时任务 (名称/调度/启用状态)
|
||
- `DELETE /api/scheduler/tasks/:id` — 删除定时任务
|
||
|
||
## 安全特性
|
||
|
||
| 特性 | 实现 |
|
||
|------|------|
|
||
| 密码存储 | Argon2id + 随机盐 |
|
||
| TOTP 2FA | AES-256-GCM 加密密钥 + 兼容旧版明文格式 |
|
||
| JWT | RS256/HS256,支持过期 Token 刷新 |
|
||
| API Token | `zclaw_` 前缀,SHA-256 哈希存储 |
|
||
| RBAC | 三级系统角色 + 自定义角色 + 权限模板 |
|
||
| 角色提升防护 | 自更新时禁止修改 role 字段 |
|
||
| 速率限制 | 滑动窗口 per-account (可配置 RPM) |
|
||
| SSRF 防护 | 私有 IP/回环/元数据端点/十六进制 IP/DNS 解析检查 |
|
||
| Key 池安全 | RPM/TPM 限制 + 429 自动冷却 + Retry-After 支持 |
|
||
| 审计日志 | 所有写操作记录,500 错误不暴露内部细节 |
|
||
|
||
## 中转 (Relay) 核心流程
|
||
|
||
```text
|
||
客户端请求 → Auth 中间件 → Relay Handler
|
||
│
|
||
├── 1. select_best_key() — 选择最优 Key (非冷却 + 未超 RPM/TPM + 优先级)
|
||
│ └── Key 池耗尽 → 回退到 Provider 级单 Key
|
||
│
|
||
├── 2. execute_relay() — 向上游发送请求
|
||
│ ├── User-Agent: claude-code/1.0 — Coding Plan API 兼容
|
||
│ ├── SSE 流式: 捕获流事件中的 usage,异步记录
|
||
│ └── JSON: 从响应提取 usage,同步记录
|
||
│
|
||
├── 3. 重试策略 — max_attempts (默认 3)
|
||
│ ├── 429: 标记 Key 冷却 → 立即切换下一个 Key (不等待)
|
||
│ └── 其他错误: 指数退避重试
|
||
│
|
||
└── 4. SSRF 防护 — 验证 Provider URL,阻断私有网络请求
|
||
```
|
||
|
||
## 桌面端 LLM 路由模式 (llm_routing)
|
||
|
||
账户级别 `llm_routing` 设置控制桌面端如何调用 LLM:
|
||
|
||
| 模式 | 行为 | 适用场景 |
|
||
|------|------|---------|
|
||
| `relay` | 桌面端通过 SaaS relay + Key Pool 调用 LLM | 共享 Key 池,无需本地 API Key |
|
||
| `local` | 桌面端直连本地 kernel,需要本地 API Key | 私有部署,本地模型 |
|
||
|
||
**路由优先级**: Admin 配置的 `llm_routing` 覆盖桌面端 localStorage 中的 `connectionMode`。登录时 SaaS 后端返回的 `account.llm_routing` 写入 localStorage,`connectionStore.connect()` 读取并强制切换。
|
||
|
||
**数据流**:
|
||
```text
|
||
llm_routing=relay:
|
||
Desktop → connectionStore (llm_routing=relay) → KernelClient
|
||
→ baseUrl = saasUrl/api/v1/relay → kernel 追加 /chat/completions
|
||
→ apiKey = SaaS JWT token → Bearer 认证
|
||
→ Key Pool 选择最优 Key → 上游 Provider
|
||
|
||
llm_routing=local:
|
||
Desktop → connectionStore (llm_routing=local) → KernelClient
|
||
→ 本地配置的 apiKey + baseUrl → 直连 Provider
|
||
```
|
||
|
||
## 配置同步模式
|
||
|
||
| 模式 | 行为 | 使用场景 |
|
||
|------|------|---------|
|
||
| push | 客户端覆盖 SaaS 值,缺失则创建 | 新设备首次同步 |
|
||
| merge | 仅填充 SaaS 空值,冲突时 SaaS 优先 | 多设备合并 |
|
||
| diff | 只读对比,返回差异列表 | 同步前预览 |
|
||
| pull | 批量拉取,支持 since 增量 | 定期同步 |
|
||
|
||
## 关键文件索引
|
||
|
||
### 后端 (crates/zclaw-saas/)
|
||
|
||
| 文件 | 职责 |
|
||
|------|------|
|
||
| `src/main.rs` | 服务启动 + 路由注册 + 后台任务 (速率限制清理 + 设备清理) |
|
||
| `src/db.rs` | 数据库初始化 + Schema v6 + TIMESTAMPTZ 迁移 + 25 张表 + Admin 引导 |
|
||
| `src/state.rs` | AppState (PgPool + Config + JWT Secret + 速率限制 DashMap + WorkerDispatcher) |
|
||
| `src/config.rs` | SaaSConfig (Server/Database/Auth/Relay/RateLimit/Scheduler),多环境配置加载 |
|
||
| `src/error.rs` | SaasError 16 种变体 + HTTP 状态码映射 |
|
||
| `src/middleware.rs` | Request-ID + API-Version + 速率限制中间件 |
|
||
| `src/common.rs` | PaginatedResponse<T> + 分页工具函数 |
|
||
| `src/auth/` | JWT + API Token 双认证 + TOTP 2FA + 密码管理 |
|
||
| `src/account/` | 账号 CRUD + 设备管理 + Dashboard + API Token |
|
||
| `src/model_config/` | Provider/Model/AccountKey CRUD + 用量统计 |
|
||
| `src/relay/` | SSE/JSON 中转 + Key 池 + 重试 + SSRF 防护 |
|
||
| `src/relay/key_pool.rs` | Key 池选择算法 + RPM/TPM 跟踪 + 冷却管理 |
|
||
| `src/migration/` | 配置 CRUD + 同步 (push/merge) + diff + 增量 pull |
|
||
| `src/role/` | 角色 CRUD + 权限模板 + 批量应用 |
|
||
| `src/prompt/` | Prompt 模板 + 版本管理 + OTA 检查 + 回滚 |
|
||
| `src/agent_template/` | Agent 模板 CRUD + 可见性控制 |
|
||
| `src/telemetry/` | Token 用量上报 + 模型统计 + 每日统计 + 审计摘要 |
|
||
| `src/scheduled_task/` | 用户定时任务 CRUD (创建/列表/更新/删除) + 30s 轮询执行 |
|
||
| `src/workers/` | Worker 系统 (5 Worker: log_operation, cleanup_rate_limit, cleanup_refresh_tokens, record_usage, update_last_used) |
|
||
| `src/scheduler.rs` | 声明式 Scheduler (TOML 定时任务配置 + DB 清理任务) |
|
||
| `migrations/` | SQL 迁移文件 (Schema v6, TIMESTAMPTZ) |
|
||
|
||
### Admin 管理后台 (admin-v2/)
|
||
|
||
> **迁移说明**: 原有 `admin/`(Next.js 14)因 SSR/hydration 与 SWR 的根本冲突导致后端连接池耗尽,
|
||
> 已用 `admin-v2/`(Vite + React + Ant Design Pro 纯 SPA)完全替代。
|
||
> 详见 [故障排查 13 节](../../knowledge-base/troubleshooting.md)
|
||
|
||
| 文件 | 职责 |
|
||
|------|------|
|
||
| `src/services/request.ts` | Axios 实例 + JWT 拦截器 + 401 自动刷新 |
|
||
| `src/services/auth.ts` | 认证 API (login/refresh/me) |
|
||
| `src/stores/authStore.ts` | Zustand: token + account + permissions |
|
||
| `src/types/index.ts` | 全部 TypeScript 类型定义 |
|
||
| `src/layouts/AdminLayout.tsx` | ProLayout 侧边栏 + 用户信息 |
|
||
| `src/pages/Dashboard.tsx` | 仪表盘 (统计卡片 + 趋势图 + 操作日志) |
|
||
| `src/pages/Accounts.tsx` | 账号管理 (CRUD + 角色筛选) |
|
||
| `src/pages/Providers.tsx` | 服务商管理 + Key Pool 子表 |
|
||
| `src/pages/Models.tsx` | 模型管理 |
|
||
| `src/pages/ApiKeys.tsx` | API 密钥管理 |
|
||
| `src/pages/Usage.tsx` | 用量统计 (时间范围 + Tab 切换) |
|
||
| `src/pages/Relay.tsx` | 中转任务管理 |
|
||
| `src/pages/Config.tsx` | 系统配置 (分类 Tab) |
|
||
| `src/pages/Prompts.tsx` | 提示词管理 (版本历史 + 回滚) |
|
||
| `src/pages/Logs.tsx` | 操作日志 |
|
||
| `src/pages/AgentTemplates.tsx` | Agent 模板管理 |
|
||
|
||
### 桌面端 (desktop/src/)
|
||
|
||
| 文件 | 职责 |
|
||
|------|------|
|
||
| `lib/saas-client.ts` | SaaS HTTP 客户端 (30+ API 方法 + 自动重试 + 离线检测) |
|
||
| `store/saasStore.ts` | SaaS 状态管理 (登录/设备/心跳/配置同步/遥测) |
|
||
| `lib/telemetry-collector.ts` | 遥测数据采集器 |
|
||
| `components/SaaS/SaaSStatus.tsx` | 连接状态 + 可用模型 |
|
||
| `components/SaaS/SaaSSettings.tsx` | 设置页 (密码/TOTP/迁移) |
|
||
| `components/LoginPage.tsx` | 登录/注册 UI |
|
||
|
||
---
|
||
|
||
**最后更新**: 2026-04-01
|