Files
zclaw_openfang/docs/audit-2026-03-31-system-assessment.md
iven f79560a911 refactor(desktop): split kernel_commands/pipeline_commands into modules, add SaaS client libs and gateway modules
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>
2026-03-31 11:12:47 +08:00

259 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 详情展示不完整