Split monolithic kernel_commands.rs (2185 lines) and pipeline_commands.rs (1391 lines) into focused sub-modules under kernel_commands/ and pipeline_commands/ directories. Add gateway module (commands, config, io, runtime), health_check, and 15 new TypeScript client libraries for SaaS relay, auth, admin, telemetry, and kernel sub-systems (a2a, agent, chat, hands, skills, triggers). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
259 lines
11 KiB
Markdown
259 lines
11 KiB
Markdown
# ZCLAW 系统评估报告
|
||
|
||
> **评估日期**: 2026-03-31
|
||
> **评估范围**: SaaS 后端 (Axum) + Admin V2 (React/Ant Design) + Desktop (Tauri/React/Zustand)
|
||
> **系统定位**: LLM Token 池中转管理 + 行业 Agent 模板分发
|
||
|
||
---
|
||
|
||
## 1. 总览
|
||
|
||
### 系统健康度
|
||
|
||
| 子系统 | 状态 | 端点 | 编译/类型检查 | 评估 |
|
||
|--------|------|------|-------------|------|
|
||
| SaaS 后端 | 运行中 | localhost:8080 | `cargo check` 通过 | 良好 |
|
||
| Admin V2 | 运行中 | localhost:5173 | `tsc --noEmit` 通过 | 良好 |
|
||
| Desktop | 运行中 | localhost:1420 | 计划文件零错误; 有遗留重构错误 | 基本可用 |
|
||
|
||
### 发现汇总
|
||
|
||
| 严重级别 | SaaS 后端 | Admin V2 | Desktop |
|
||
|----------|-----------|----------|---------|
|
||
| Critical | 0 | 0 | 0 |
|
||
| High | 1 | 3 | 2 |
|
||
| Medium | 5 | 8 | 7 |
|
||
| Low | 3 | 8 | 4 |
|
||
| **合计** | **9** | **19** | **13** |
|
||
|
||
---
|
||
|
||
## 2. SaaS 后端评估
|
||
|
||
### 2.1 路由覆盖
|
||
|
||
**总计 69 条路由** (5 公开 + 64 受保护)
|
||
|
||
| 模块 | 路由数 | CRUD 完整性 |
|
||
|------|--------|-------------|
|
||
| Auth | 8 | 登录/注册/刷新/登出/密码/TOTP |
|
||
| Account | 12 | CRUD + 状态管理 + Token + 日志 + Dashboard + 设备 |
|
||
| Model Config | 15 | Provider/Model/ApiKey CRUD + 用量统计 |
|
||
| Relay | 9 | 中转任务 + Key Pool 管理 |
|
||
| Config | 11 | 配置迁移/同步/差异分析 |
|
||
| Role | 10 | 角色 CRUD + 权限模板 |
|
||
| Prompt | 10 | 提示词 CRUD + 版本管理 |
|
||
| Agent Template | 7 | 模板 CRUD + /available + /full |
|
||
| Scheduler | 5 | 定时任务 CRUD |
|
||
| Telemetry | 4 | 上报 + 统计 |
|
||
|
||
### 2.2 安全评估
|
||
|
||
**正面发现:**
|
||
- 全量参数化查询 (sqlx bind),无 SQL 注入风险
|
||
- SSRF 防护: `validate_provider_url()` 拦截私网 IP、十六进制/八进制混淆
|
||
- Argon2id 密码哈希 (spawn_blocking 避免阻塞异步运行时)
|
||
- AES-256-GCM 加密 TOTP 密钥和 Provider API Key
|
||
- Refresh Token 单次使用 + DB 撤销
|
||
- TOTP 暴力破解防护: 5次/10分钟/账户
|
||
- Cookie: HttpOnly + SameSite=Strict + Secure (生产环境)
|
||
- CORS: 生产环境空白名单直接 panic 拒绝启动
|
||
- JWT 密钥: release 编译无 `ZCLAW_SAAS_JWT_SECRET` 拒绝启动
|
||
- 请求体限制: 1MB
|
||
- TCP keepalive + 短 SO_LINGER 防止 CLOSE_WAIT
|
||
|
||
**发现的问题:**
|
||
|
||
| 级别 | 问题 | 位置 |
|
||
|------|------|------|
|
||
| **High** | `X-Forwarded-For` 头信任 — 攻击者可伪造 IP 绕过限流 | `middleware.rs:138-142` |
|
||
| Medium | 内存限流不跨重启持久化,多实例部署时无效 | `middleware.rs` |
|
||
| Medium | `format!("SELECT ... FROM {}", table)` — 当前安全但模式脆弱 | `db.rs:852,858` |
|
||
| Medium | `.and_hms_opt(0,0,0).unwrap()` 多处 — 理论上安全但不防御 | `model_config/service.rs:441` |
|
||
| Medium | scheduler spawn 中 `_db` 克隆后未使用 | `scheduler.rs:46` |
|
||
| Medium | SCHEMA_VERSION=9 但仅 5 个迁移文件 — 可能混淆 | `db.rs:7` |
|
||
| Low | Demo 种子明文 API Key — 仅限 demo 场景 | `db.rs:467-471` |
|
||
| Low | `#[allow(dead_code)]` 标记的保留函数 | `auth/handlers.rs:499` |
|
||
| Low | SQL 分割器中 `.unwrap()` | `db.rs:127` |
|
||
|
||
### 2.3 新功能验证
|
||
|
||
| 功能 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| `accounts.llm_routing` 列 | ✅ | 迁移 + CRUD + 登录响应全部接入 |
|
||
| `/agent-templates/available` | ✅ | 轻量公开列表端点 |
|
||
| `/agent-templates/:id/full` | ✅ | 完整模板端点 |
|
||
| Agent 模板 9 个扩展字段 | ✅ | soul_content, scenarios, welcome_message 等 |
|
||
| Key Pool LRU 排序 | ✅ | `ORDER BY priority, total_requests ASC` |
|
||
| Key Pool 清理定时任务 | ✅ | 24h 周期清理 key_usage_window |
|
||
| 6 个行业种子模板 | ✅ | Coder/Writer/Analyst/Researcher/Translator/Medical |
|
||
|
||
---
|
||
|
||
## 3. Admin V2 前端评估
|
||
|
||
### 3.1 页面清单
|
||
|
||
**12 个页面**, 使用 React Query 管理服务端状态, Zustand 仅用于 auth store, 其余均为 `useState`。
|
||
|
||
### 3.2 类型安全
|
||
|
||
- TypeScript 严格模式启用
|
||
- `noUnusedLocals` + `noUnusedParameters` 启用
|
||
- 整个代码库仅 1 处 `any` (Providers.tsx:69)
|
||
- 可选字段正确标记
|
||
- 前后端类型基本对齐
|
||
|
||
### 3.3 发现的问题
|
||
|
||
| 级别 | 问题 | 位置 |
|
||
|------|------|------|
|
||
| **High** | 未使用的 `@ant-design/charts` 依赖增加包体积 | `package.json:13` |
|
||
| **High** | `any` 类型在 addKeyMutation | `Providers.tsx:69` |
|
||
| **High** | Token 刷新竞态 — 刷新失败时 pending 请求未 reject | `request.ts:96-99` |
|
||
| Medium | 6 个表格无搜索/筛选功能 | Accounts/Models/Providers 等 |
|
||
| Medium | 服务端分页不同步本地状态 | Accounts/Models/Providers 等 |
|
||
| Medium | Agent Template 详情 Modal 缺少扩展字段展示 | `AgentTemplates.tsx:189-210` |
|
||
| Medium | Config 内联编辑无加载指示器 | `Config.tsx:51` |
|
||
| Medium | Dashboard 统计卡片加载时布局跳动 | `Dashboard.tsx:93` |
|
||
| Medium | 网络错误未包装为 `ApiRequestError` | `request.ts:115` |
|
||
| Medium | configService 返回格式不一致 | `services/config.ts:6` |
|
||
| Medium | Key Pool 变更丢弃错误详情 | `Providers.tsx:78,88,98` |
|
||
| Low | Model 类型缺少 `created_at`/`updated_at` | `types/index.ts:65-77` |
|
||
| Low | 所有表格禁用 page size 切换 | 所有 ProTable 页面 |
|
||
| Low | Login 页面固定 480px 非响应式 | `Login.tsx:79` |
|
||
| Low | Config 点击值缺少 hover 视觉反馈 | `Config.tsx:62` |
|
||
| Low | OperationLog/PromptVersion 类型微小不匹配 | `types/index.ts` |
|
||
| Low | `@ant-design/pro-layout` 与 pro-components 冗余 | `package.json:17` |
|
||
| Low | `AgentTemplateAvailable` 类型已定义但未消费 | `types/index.ts:243-250` |
|
||
|
||
### 3.4 新功能验证
|
||
|
||
| 功能 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| Accounts LLM 路由模式列 | ✅ | Tag 组件 + valueEnum |
|
||
| Accounts 编辑 Modal 路由下拉 | ✅ | relay/local Select |
|
||
| Providers Key Pool CRUD | ✅ | 添加/启用禁用/删除全部可用 |
|
||
| Agent Template 扩展字段表单 | ✅ | emoji/personality/soul_content 等 |
|
||
| Agent Template 详情 Modal | ⚠️ | 缺少扩展字段展示 |
|
||
|
||
---
|
||
|
||
## 4. Desktop 前端评估
|
||
|
||
### 4.1 Store 架构
|
||
|
||
**14 个 Zustand Store**, 模块化拆分完成。核心协调中心为 `connectionStore`。
|
||
|
||
### 4.2 新功能验证
|
||
|
||
| 功能 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| saas-types 模板类型 | ✅ | AgentTemplateAvailable + AgentTemplateFull |
|
||
| saas-client 模板 API | ✅ | fetchAvailableTemplates + fetchTemplateFull |
|
||
| saasStore 模板状态 | ✅ | availableTemplates + fetchAvailableTemplates |
|
||
| connectionStore 路由优先级 | ✅ | admin llm_routing 覆盖 localStorage |
|
||
| agentStore.createFromTemplate | ✅ | Clone + SOUL.md 持久化 |
|
||
| Wizard Step 0 模板选择 | ✅ | Grid 布局 + 空白 Agent 选项 |
|
||
|
||
### 4.3 发现的问题
|
||
|
||
| 级别 | 问题 | 位置 |
|
||
|------|------|------|
|
||
| **High** | 模板 Grid 非响应式 — 使用 `getState()` 而非 React hook | `AgentOnboardingWizard.tsx:387` |
|
||
| **High** | adminRouting 从 localStorage 解析无验证 | `connectionStore.ts:358-372` |
|
||
| Medium | 8 处 `console.log/warn` 在生产 store 中 | `agentStore.ts`, `handStore.ts` |
|
||
| Medium | sessionStore 假设 GatewayClient 不适配 KernelClient | `sessionStore.ts:225` |
|
||
| Medium | ChatStore persist partialize 日期序列化 | `chatStore.ts:703` |
|
||
| Medium | OfflineStore 健康检查 interval 清理风险 | `offlineStore.ts:347` |
|
||
| Medium | 硬编码中文错误消息 (无 i18n) | `saasStore.ts`, `connectionStore.ts` |
|
||
| Medium | gateway-api.ts / kernel-hands.ts 有 TS 错误 | 之前重构遗留 |
|
||
| Low | gatewayStore facade 订阅所有 store 引起过多渲染 | `gatewayStore.ts:67-76` |
|
||
| Low | Store 初始化 setTimeout 时序问题 | `store/index.ts:89-92` |
|
||
| Low | deprecated `secureStorageSync` 仍导出 | `secure-storage.ts:306-330` |
|
||
| Low | SkillInfo 类型微小不匹配 | `configStore.ts:638-665` |
|
||
|
||
### 4.4 安全评估
|
||
|
||
- SaaS Token: OS keyring 存储 + 加密 localStorage fallback — 合理
|
||
- Legacy 明文 Token 清理逻辑存在
|
||
- API Key: secureStorage 存储带格式验证 + 哈希
|
||
- Master encryption key 在无 keyring 时存 localStorage — 降级方案
|
||
- authToken 始终为 null 在 Zustand state — 仅在 saasClient 内存中持有
|
||
|
||
---
|
||
|
||
## 5. 架构一致性验证
|
||
|
||
### 设计规格 vs 实现
|
||
|
||
基于 `docs/superpowers/specs/2026-03-30-saas-positioning-design.md` 逐项核对:
|
||
|
||
| 设计要求 | 实现状态 | 说明 |
|
||
|----------|----------|------|
|
||
| 账号级 LLM 路由 (relay/local) | ✅ 完成 | accounts.llm_routing 列 + CRUD + 登录响应 |
|
||
| Admin 配置路由模式 | ✅ 完成 | Accounts 页编辑 Modal 有下拉 |
|
||
| Desktop 遵守路由模式 | ✅ 完成 | connectionStore 优先级覆盖 |
|
||
| Token Pool 多 Key 轮转 | ✅ 完成 | LRU 排序 + RPM/TPM 限制 |
|
||
| Key Pool Admin 管理 | ✅ 完成 | 添加/启用禁用/删除 |
|
||
| 行业模板扩展字段 | ✅ 完成 | 9 个新字段 (soul_content 等) |
|
||
| /available 端点 | ✅ 完成 | 轻量公开列表 |
|
||
| /full 端点 | ✅ 完成 | 完整模板数据 |
|
||
| Desktop 模板消费 | ✅ 完成 | fetchAvailableTemplates + fetchTemplateFull |
|
||
| Agent 首次创建选模板 | ✅ 完成 | Wizard Step 0 Grid |
|
||
| SOUL.md 注入 | ✅ 完成 | createFromTemplate 持久化 |
|
||
| 模板不覆盖已成长 Agent | ✅ 完成 | 仅在创建时使用 |
|
||
|
||
**结论: 设计规格 12/12 项全部实现。**
|
||
|
||
---
|
||
|
||
## 6. 优先修复建议
|
||
|
||
### P0 — 立即修复 (安全/稳定性)
|
||
|
||
1. **Token 刷新竞态** (`request.ts:96-99`): 刷新失败时 reject 所有 pending 请求
|
||
2. **X-Forwarded-For 信任** (`middleware.rs:138-142`): 限制仅信任已知代理 IP
|
||
|
||
### P1 — 近期修复 (功能完整性)
|
||
|
||
3. **模板 Grid 响应式** (`AgentOnboardingWizard.tsx:387`): 使用 `useSaaSStore()` hook 替代 `getState()`
|
||
4. **Agent Template 详情 Modal** (`AgentTemplates.tsx`): 补充扩展字段展示
|
||
5. **adminRouting 解析验证** (`connectionStore.ts:358`): 对 localStorage 解析结果做类型校验
|
||
6. **清理 `@ant-design/charts` 未使用依赖**
|
||
|
||
### P2 — 中期优化 (代码质量)
|
||
|
||
7. **统一分页状态管理** — Admin 多个表格页
|
||
8. **添加表格搜索/筛选功能** — 至少 Accounts/Models/Providers
|
||
9. **修复 gateway-api.ts / kernel-hands.ts TS 错误** — 之前重构遗留
|
||
10. **替换 store 中的 console.log** — 使用 createLogger
|
||
11. **Config 页内联编辑加载指示**
|
||
|
||
### P3 — 长期改进
|
||
|
||
12. **内存限流 → Redis/PostgreSQL 持久化限流** (多实例部署准备)
|
||
13. **i18n 框架** (当前所有中文硬编码)
|
||
14. **单元测试** — Admin V2 和 Desktop 目前零测试覆盖
|
||
15. **统一 SAAS_SCHEMA_VERSION 管理** (减少迁移文件与版本号的不一致困惑)
|
||
|
||
---
|
||
|
||
## 7. 结论
|
||
|
||
**系统整体评价: 良好 (B+)**
|
||
|
||
**优势:**
|
||
- 后端安全实践优秀: 参数化查询、SSRF 防护、密钥加密、Cookie 安全
|
||
- 设计规格 100% 实现,无遗漏
|
||
- Admin V2 TypeScript 严格模式,仅 1 处 `any`
|
||
- 69 个 API 端点覆盖全面,权限控制细粒度
|
||
- Desktop Store 架构清晰,14 个 store 模块化
|
||
|
||
**短板:**
|
||
- Desktop 有遗留 TS 错误未修复 (gateway-api.ts, kernel-hands.ts)
|
||
- Admin V2 缺少搜索/筛选功能影响可用性
|
||
- Token 刷新竞态条件需立即修复
|
||
- 零测试覆盖 (Admin V2 + Desktop)
|
||
- Agent Template 详情展示不完整
|