chore: 提交所有工作进度 — SaaS 后端增强、Admin UI、桌面端集成
包含大量 SaaS 平台改进、Admin 管理后台更新、桌面端集成完善、 文档同步、测试文件重构等内容。为 QA 测试准备干净工作树。
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
> **分类**: 架构层
|
||||
> **优先级**: P0 - 决定性
|
||||
> **成熟度**: L4 - 生产
|
||||
> **最后更新**: 2026-03-25
|
||||
> **验证状态**: ✅ 代码已验证
|
||||
> **最后更新**: 2026-03-28
|
||||
> **验证状态**: 代码已验证
|
||||
|
||||
---
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
### 1.1 基本信息
|
||||
|
||||
通信层是 ZCLAW 前端与内部 ZCLAW Kernel 之间的核心桥梁,通过 Tauri 命令进行所有通信。
|
||||
通信层是 ZCLAW 前端与后端能力之间的核心桥梁,支持三种连接模式:本地 Kernel、Gateway WebSocket 和 SaaS Cloud。
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
@@ -20,10 +20,10 @@
|
||||
| 优先级 | P0 |
|
||||
| 成熟度 | L4 |
|
||||
| 依赖 | Tauri Runtime 2.x |
|
||||
| Tauri 命令数量 | **80+** |
|
||||
| Rust Crates | 8 个 (types, memory, runtime, kernel, skills, hands, protocols, pipeline) |
|
||||
| 前端代码量 | ~30,000 行 TypeScript/React |
|
||||
| 后端代码量 | ~15,000 行 Rust |
|
||||
| Tauri 命令数量 | **58+** (kernel 29 + pipeline 13 + viking 13 + llm 3) |
|
||||
| Rust Crates | 11 个 (types, memory, runtime, kernel, skills, hands, protocols, pipeline, growth, channels, saas) |
|
||||
| 连接模式 | 3 种 (Tauri Kernel / Gateway WebSocket / SaaS Cloud) |
|
||||
| SaaS API 路由 | 76+ (Axum + PostgreSQL) |
|
||||
|
||||
### 1.2 相关文件
|
||||
|
||||
@@ -73,14 +73,15 @@ ZCLAW 采用**内部 Kernel 架构**,所有核心能力都集成在 Tauri 桌
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 双客户端模式
|
||||
### 2.2 三客户端模式
|
||||
|
||||
系统支持两种客户端模式:
|
||||
系统支持三种连接模式:
|
||||
|
||||
| 模式 | 客户端类 | 使用场景 |
|
||||
|------|---------|----------|
|
||||
| **内部 Kernel** | `KernelClient` | Tauri 桌面应用(默认) |
|
||||
| **外部 Gateway** | `GatewayClient` | 浏览器环境/开发调试 |
|
||||
| **Mode A: Tauri Kernel** | `KernelClient` | Tauri 桌面应用本地直连 LLM (默认) |
|
||||
| **Mode B: Gateway WebSocket** | `GatewayClient` | 浏览器环境/开发调试 |
|
||||
| **Mode C: SaaS Cloud** | `SaaSClient` | 云端中转,Key 池管理 |
|
||||
|
||||
模式切换逻辑在 `connectionStore.ts` 中:
|
||||
|
||||
@@ -279,7 +280,8 @@ interface CustomModel {
|
||||
| zhipu | `https://open.bigmodel.cn/api/paas/v4` | OpenAI 兼容 |
|
||||
| openai | `https://api.openai.com/v1` | OpenAI |
|
||||
| anthropic | `https://api.anthropic.com` | Anthropic |
|
||||
| local | `http://localhost:11434/v1` | OpenAI 兼容 |
|
||||
| gemini | `https://generativelanguage.googleapis.com` | Gemini REST |
|
||||
| local | `http://localhost:11434/v1` | OpenAI 兼容 (Ollama/LM Studio/vLLM) |
|
||||
|
||||
---
|
||||
|
||||
@@ -313,12 +315,15 @@ try {
|
||||
|
||||
### 7.1 已实现功能
|
||||
|
||||
- [x] 内部 Kernel 集成
|
||||
- [x] 多 LLM Provider 支持
|
||||
- [x] 内部 Kernel 集成 (Mode A)
|
||||
- [x] Gateway WebSocket 连接 (Mode B)
|
||||
- [x] SaaS Cloud 中转 (Mode C)
|
||||
- [x] 8 个 LLM Provider 支持 (含 Gemini)
|
||||
- [x] UI 模型配置
|
||||
- [x] 流式响应
|
||||
- [x] 流式响应 (Tauri 事件 stream:chunk + SSE)
|
||||
- [x] 连接状态管理
|
||||
- [x] 错误处理
|
||||
- [x] SaaS 30+ API 方法客户端
|
||||
|
||||
### 7.2 测试覆盖
|
||||
|
||||
@@ -332,13 +337,15 @@ try {
|
||||
|
||||
### 8.1 已完成
|
||||
- [x] 内部 Kernel 集成
|
||||
- [x] 多 LLM Provider 支持
|
||||
- [x] 流式响应(通过 Tauri 事件 `stream:chunk`)
|
||||
- [x] 多 LLM Provider 支持 (8 个)
|
||||
- [x] 流式响应 (Tauri 事件 `stream:chunk`)
|
||||
- [x] SaaS Cloud 模式
|
||||
- [x] Gemini Driver
|
||||
|
||||
### 8.2 短期计划(1-2 周)
|
||||
### 8.2 短期计划
|
||||
- [ ] 优化流式响应性能
|
||||
|
||||
### 8.3 中期计划(1-2 月)
|
||||
### 8.3 中期计划
|
||||
- [ ] 支持 Agent 持久化
|
||||
- [ ] 支持会话历史存储
|
||||
|
||||
@@ -360,4 +367,4 @@ try {
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-03-24
|
||||
**最后更新**: 2026-03-28
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,140 +1,243 @@
|
||||
# ZCLAW SaaS 平台 — 总览
|
||||
|
||||
> 最后更新: 2026-03-27 | 实施状态: Phase 1-4 + P2 全部完成
|
||||
> 最后更新: 2026-03-28 | 实施状态: Phase 1-4 全部完成,9 个后端模块 + Admin 管理后台 + 桌面端完整集成
|
||||
|
||||
## 架构概述
|
||||
|
||||
ZCLAW SaaS 平台为桌面端用户提供云端能力,包括模型中转、账号管理、配置同步和团队协作。
|
||||
ZCLAW SaaS 平台为桌面端用户提供云端能力,包括模型中转(Key 池)、账号管理、配置同步、Prompt OTA、Agent 模板和遥测收集。
|
||||
|
||||
```text
|
||||
桌面端 (Tauri/React)
|
||||
│
|
||||
├── Mode A: Tauri Kernel (本地直连)
|
||||
├── Mode B: Gateway WebSocket
|
||||
└── Mode C: SaaS Cloud ──→ Rust/Axum 后端 ──→ 上游 LLM Provider
|
||||
├── Mode A: Tauri Kernel (本地直连 LLM)
|
||||
├── Mode B: Gateway WebSocket (本地中转)
|
||||
└── Mode C: SaaS Cloud ──→ Rust/Axum 后端 (端口 8080) ──→ 上游 LLM Provider
|
||||
│
|
||||
├── Admin Web (Next.js 管理后台)
|
||||
└── SQLite WAL (数据持久化)
|
||||
└── PostgreSQL (数据持久化)
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 层级 | 技术 | 说明 |
|
||||
|------|------|------|
|
||||
| 后端 | Rust + Axum + sqlx + SQLite WAL | JWT + API Token 双认证 |
|
||||
| Admin | Next.js 14 + shadcn/ui + Tailwind | 暗色 OLED 主题 |
|
||||
| 桌面端 | React 18 + Zustand + TypeScript | saas-client.ts HTTP 通信 |
|
||||
| 安全 | argon2 + TOTP 2FA + RBAC | 速率限制 + 操作审计 |
|
||||
| 后端 | Rust + Axum + sqlx + PostgreSQL | JWT + API Token 双认证,RBAC 权限 |
|
||||
| Admin | Next.js 14 + shadcn/ui + Tailwind | 暗色 OLED 主题,20+ 页面 |
|
||||
| 桌面端 | React 18 + Zustand + TypeScript | saas-client.ts 30+ API 方法 |
|
||||
| 安全 | Argon2id + TOTP 2FA (AES-256-GCM) + RBAC | 速率限制 + 操作审计 + SSRF 防护 |
|
||||
|
||||
## 数据库
|
||||
|
||||
- **引擎**: PostgreSQL (sqlx 异步驱动)
|
||||
- **Schema 版本**: v4
|
||||
- **数据表**: 25 张 (accounts, providers, models, relay_tasks, prompt_templates, agent_templates, telemetry_reports 等)
|
||||
- **种子数据**: 3 个系统角色 (super_admin, admin, user),3 个内置 Prompt 模板
|
||||
|
||||
## 功能模块
|
||||
|
||||
| 模块 | 完成度 | 核心能力 |
|
||||
|------|--------|----------|
|
||||
| 认证 (Auth) | 100% | JWT + API Token + 密码修改 + /me + TOTP 2FA |
|
||||
| 账号 (Account) | 100% | CRUD + 角色管理 + 自角色限制 + 设备管理 |
|
||||
| 模型配置 (Model Config) | 95% | Provider/Model/Key CRUD + 用量记录 |
|
||||
| 中转 (Relay) | 95% | SSE 流式 + 任务记录 + 指数退避重试 + Admin 重试 |
|
||||
| 配置迁移 (Migration) | 90% | CRUD + 同步日志 + push/merge + diff |
|
||||
| Admin UI | 95% | 10 个 CRUD 页面 + Dashboard |
|
||||
| 桌面端集成 | 95% | 登录/注册/状态/密码/设备/离线/迁移向导 |
|
||||
| 模块 | 完成度 | 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 用量上报 + 模型聚合统计 + 每日统计 + 审计摘要 |
|
||||
| **合计** | — | **76+** | — |
|
||||
|
||||
## API 端点一览
|
||||
|
||||
### 公开端点 (无需认证)
|
||||
- `POST /api/v1/auth/register` — 注册
|
||||
- `POST /api/v1/auth/login` — 登录
|
||||
- `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` — 修改密码
|
||||
|
||||
### TOTP 双因素认证 (P2)
|
||||
- `POST /api/v1/auth/totp/setup` — 生成 TOTP 密钥,返回 otpauth:// URI
|
||||
- `POST /api/v1/auth/totp/verify` — 验证 TOTP 码并启用 2FA
|
||||
- `POST /api/v1/auth/totp/disable` — 禁用 2FA (需密码确认)
|
||||
|
||||
### 账号管理
|
||||
- `GET /api/v1/accounts` — 列出账号 (admin)
|
||||
### 账号管理 (Account)
|
||||
- `GET /api/v1/accounts` — 列出账号 (admin,分页 + 角色/状态/搜索过滤)
|
||||
- `GET /api/v1/accounts/:id` — 获取账号
|
||||
- `PUT /api/v1/accounts/:id` — 更新账号
|
||||
- `PATCH /api/v1/accounts/:id/status` — 更新状态 (admin)
|
||||
- `GET /api/v1/stats/dashboard` — 仪表盘统计 (admin)
|
||||
|
||||
### API Token
|
||||
- `GET /api/v1/tokens` — 列出 Token
|
||||
- `POST /api/v1/tokens` — 创建 Token
|
||||
- `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/devices` — 列出设备
|
||||
- `GET /api/v1/logs/operations` — 操作日志 (admin,分页)
|
||||
- `GET /api/v1/stats/dashboard` — 仪表盘统计 (admin)
|
||||
|
||||
### 模型配置
|
||||
- `GET/POST /api/v1/providers` — Provider CRUD
|
||||
- `GET/POST/PUT/DELETE /api/v1/providers/:id` — 单个 Provider
|
||||
- `GET/POST /api/v1/models` — Model CRUD
|
||||
- `GET/POST/PUT/DELETE /api/v1/models/:id` — 单个 Model
|
||||
- `GET/POST/DELETE /api/v1/keys` — API Key CRUD
|
||||
### 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` — 聊天中转 (SSE/JSON)
|
||||
- `GET /api/v1/relay/tasks` — 中转任务列表
|
||||
- `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)
|
||||
|
||||
### 配置
|
||||
- `GET /api/v1/config/items` — 列出配置项
|
||||
- `POST /api/v1/config/items` — 创建配置项
|
||||
### 配置迁移 (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)
|
||||
- `POST /api/v1/config/sync` — 配置同步 (push/merge)
|
||||
- `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/sync-logs` — 同步日志 (分页)
|
||||
- `GET /api/v1/config/pull` — 批量拉取配置 (支持 since 增量)
|
||||
|
||||
### 审计
|
||||
- `GET /api/v1/logs/operations` — 操作日志 (admin)
|
||||
- `GET /api/v1/usage` — 用量统计
|
||||
### 角色 (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` — 创建模板
|
||||
- `GET /api/v1/agent-templates/:id` — 获取模板
|
||||
- `POST /api/v1/agent-templates/:id` — 更新模板
|
||||
- `DELETE /api/v1/agent-templates/:id` — 归档模板
|
||||
|
||||
### 遥测 (Telemetry)
|
||||
- `POST /api/v1/telemetry/report` — 批量上报 Token 用量 (每次最多 500 条)
|
||||
- `GET /api/v1/telemetry/stats` — 模型聚合统计 (请求次数/Token/延迟/成功率)
|
||||
- `GET /api/v1/telemetry/daily` — 每日使用量聚合 (按设备去重)
|
||||
- `POST /api/v1/telemetry/audit` — 批量审计日志摘要 (仅动作类型和计数)
|
||||
|
||||
## 安全特性
|
||||
|
||||
| 特性 | 实现 |
|
||||
|------|------|
|
||||
| 密码存储 | 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() — 向上游发送请求
|
||||
│ ├── SSE 流式: 捕获流事件中的 usage,异步记录
|
||||
│ └── JSON: 从响应提取 usage,同步记录
|
||||
│
|
||||
├── 3. 重试策略 — max_attempts (默认 3)
|
||||
│ ├── 429: 标记 Key 冷却 → 立即切换下一个 Key (不等待)
|
||||
│ └── 其他错误: 指数退避重试
|
||||
│
|
||||
└── 4. SSRF 防护 — 验证 Provider URL,阻断私有网络请求
|
||||
```
|
||||
|
||||
## 配置同步模式
|
||||
|
||||
| 模式 | 行为 | 使用场景 |
|
||||
|------|------|---------|
|
||||
| push | 客户端覆盖 SaaS 值,缺失则创建 | 新设备首次同步 |
|
||||
| merge | 仅填充 SaaS 空值,冲突时 SaaS 优先 | 多设备合并 |
|
||||
| diff | 只读对比,返回差异列表 | 同步前预览 |
|
||||
| pull | 批量拉取,支持 since 增量 | 定期同步 |
|
||||
|
||||
## 关键文件索引
|
||||
|
||||
### 后端 (crates/zclaw-saas/)
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/main.rs` | 服务启动 + ConnectInfo 注入 |
|
||||
| `src/db.rs` | 数据库初始化 + Schema + Admin 引导 |
|
||||
| `src/state.rs` | AppState (DB + Config) |
|
||||
| `src/config.rs` | 配置结构体 |
|
||||
| `src/error.rs` | SaasError 枚举 + IntoResponse |
|
||||
| `src/middleware.rs` | 速率限制中间件 |
|
||||
| `src/auth/mod.rs` | JWT + API Token 中间件 + 路由 |
|
||||
| `src/auth/handlers.rs` | 登录/注册/刷新/me/密码 (含 TOTP 登录验证) |
|
||||
| `src/auth/totp.rs` | TOTP 2FA (setup/verify/disable) |
|
||||
| `src/auth/types.rs` | AuthContext + Request/Response 类型 |
|
||||
| `src/account/handlers.rs` | 账号 CRUD + Dashboard + 设备 |
|
||||
| `src/model_config/handlers.rs` | Provider/Model/Key CRUD |
|
||||
| `src/relay/handlers.rs` + `service.rs` | SSE 中转 + 任务管理 + 指数退避重试 |
|
||||
| `src/migration/handlers.rs` + `service.rs` | 配置 CRUD + 同步 |
|
||||
|
||||
### Admin (admin/)
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/lib/api-client.ts` | 类型化 HTTP 客户端 |
|
||||
| `src/lib/auth.ts` | JWT 管理 |
|
||||
| `src/app/(dashboard)/` | 10 个 CRUD 页面 |
|
||||
| `src/main.rs` | 服务启动 + 路由注册 + 后台任务 (速率限制清理 + 设备清理) |
|
||||
| `src/db.rs` | 数据库初始化 + Schema v4 + 25 张表 + Admin 引导 |
|
||||
| `src/state.rs` | AppState (PgPool + Config + JWT Secret + 速率限制 DashMap) |
|
||||
| `src/config.rs` | SaaSConfig (Server/Database/Auth/Relay/RateLimit) |
|
||||
| `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 用量上报 + 模型统计 + 每日统计 + 审计摘要 |
|
||||
|
||||
### Admin 管理后台 (admin/)
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/lib/api-client.ts` | 类型化 HTTP 客户端 (自动 Token 刷新 + 重试) |
|
||||
| `src/lib/types.ts` | 全部 TypeScript 类型定义 |
|
||||
| `src/lib/auth.ts` | JWT Token 管理 (localStorage) |
|
||||
| `src/app/(dashboard)/layout.tsx` | Dashboard 布局 + 导航 |
|
||||
| `src/app/(dashboard)/providers/page.tsx` | Provider 管理 |
|
||||
| `src/app/(dashboard)/config/page.tsx` | 配置管理 |
|
||||
| `src/app/(dashboard)/usage/page.tsx` | 用量统计 |
|
||||
| `src/app/(dashboard)/prompts/` | Prompt 模板管理 |
|
||||
| `src/app/(dashboard)/agent-templates/` | Agent 模板管理 |
|
||||
| `src/app/login/page.tsx` | 登录页 |
|
||||
|
||||
### 桌面端 (desktop/src/)
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `lib/saas-client.ts` | SaaS HTTP 客户端 (重试 + 离线检测) |
|
||||
| `store/saasStore.ts` | SaaS 状态 (登录/设备/心跳) |
|
||||
| `components/SaaS/SaaSLogin.tsx` | 登录/注册 UI |
|
||||
| `lib/saas-client.ts` | SaaS HTTP 客户端 (30+ API 方法 + 自动重试 + 离线检测) |
|
||||
| `store/saasStore.ts` | SaaS 状态管理 (登录/设备/心跳/配置同步/遥测) |
|
||||
| `lib/telemetry-collector.ts` | 遥测数据采集器 |
|
||||
| `components/SaaS/SaaSStatus.tsx` | 连接状态 + 可用模型 |
|
||||
| `components/SaaS/SaaSSettings.tsx` | 设置页 (密码/迁移) |
|
||||
| `components/SaaS/ConfigMigrationWizard.tsx` | 3 步配置迁移向导 |
|
||||
| `components/SaaS/SaaSSettings.tsx` | 设置页 (密码/TOTP/迁移) |
|
||||
| `components/LoginPage.tsx` | 登录/注册 UI |
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-03-28
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# ZCLAW 功能完整性深度审计报告 v5
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-27 审计迭代的 v5 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-27
|
||||
> **修复日期**: 2026-03-27
|
||||
> **审计方法**: 五步审计法(文档对齐 → 数据流追踪 → dead_code 识别 → trait 实现 → 端到端验证)
|
||||
|
||||
364
docs/features/COMPREHENSIVE_AUDIT_V6.md
Normal file
364
docs/features/COMPREHENSIVE_AUDIT_V6.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# ZCLAW SaaS + Tauri 系统性功能审计报告 v6
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-27 审计迭代的 v6 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-27 (原文标注 2026)
|
||||
> **审计范围**: Main 分支 Tauri 端 + SaaS worktree(`.claude/worktrees/saas-backend/`)
|
||||
> **审计方法**: 3 并行 Agent,覆盖功能对齐、SaaS 差距、Trait 实现、差距模式、Dead Code、E2E 数据流
|
||||
> **前次审计**: v5(累计修复 27 项,整体完成度 ~78%)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **Tauri 注册命令** | 137 |
|
||||
| **文档功能数** | 17 |
|
||||
| **功能-代码对齐率** | 100%(17/17 有对应命令+UI) |
|
||||
| **SaaS 能力覆盖** | 5/5(100%)— auth + relay + config + devices + usage(设计定位:系统管理) |
|
||||
| **Trait 总数** | 26 |
|
||||
| **零实现 Trait** | 6(23%) |
|
||||
| **Dead Code** | ~4,228 行(5 个孤立模块) |
|
||||
| **`#[allow(dead_code)]`** | 28 处 |
|
||||
| **TODO/FIXME** | 6 处(无 FIXME/HACK/XXX) |
|
||||
| **五种差距模式总计** | 17 个问题 |
|
||||
| **E2E 流程验证** | 5 条流程,2 条有 CRITICAL GAP |
|
||||
|
||||
### 与 v5 审计对比
|
||||
|
||||
| 维度 | v5 | v6(本次) | 变化 |
|
||||
|------|-----|-----|------|
|
||||
| 整体完成度 | ~78% | ~78%(Tauri),100%(SaaS 管理职责) | SaaS 定位修正 |
|
||||
| 功能对齐 | 未量化 | 100% | 新增量化 |
|
||||
| Trait 覆盖 | 未审计 | 77%(20/26 有实现) | 新增审计 |
|
||||
| Dead Code | 已部分清理 | ~4,228 行孤立 | 新增精确统计 |
|
||||
| E2E 验证 | 未执行 | 5 条流程追踪 | 新增验证 |
|
||||
|
||||
---
|
||||
|
||||
## 二、功能-代码对齐矩阵
|
||||
|
||||
### 2.1 功能清单(17 个文档功能)
|
||||
|
||||
| # | 功能 | 文档成熟度 | Tauri 命令数 | 前端 invoke | UI 集成 | 差距 |
|
||||
|---|------|-----------|-------------|------------|---------|------|
|
||||
| 1 | 通信层 | L4 | 9 | kernel-client.ts | KernelClient + GatewayClient | 无 |
|
||||
| 2 | 状态管理 | L4 | N/A(Store) | N/A | 18+ Zustand stores | 无 |
|
||||
| 3 | 安全认证 | L4 | 4 | secure-storage.ts | Ed25519 + OS Keyring | 无 |
|
||||
| 4 | 聊天界面 | L4 | 2 | kernel-client.ts | ChatArea, MessageItem | 无 |
|
||||
| 5 | Agent 分身 | L4 | 4 | kernel-client.ts | AgentSelector | 无 |
|
||||
| 6 | Hands 系统 | L4 | 7 | kernel-client.ts | HandList, HandTaskPanel | 2/11 未实现 |
|
||||
| 7 | Agent 记忆 | L4 | 13 | intelligence-backend.ts | MemoryPanel, MemoryGraph | 无 |
|
||||
| 8 | 身份演化 | L4 | 14 | intelligence-backend.ts | AgentOnboardingWizard | 无 |
|
||||
| 9 | 自我反思 | L4 | 6 | intelligence-backend.ts | ReflectionLog.tsx | 文档有 L2 矛盾标注 |
|
||||
| 10 | 心跳巡检 | L4 | 10 | intelligence-backend.ts | IntelligenceStore | 无 |
|
||||
| 11 | 自主授权 | L4 | 0(TS only) | N/A | AutonomyConfig.tsx | 无 Rust 后端 |
|
||||
| 12 | 上下文压缩 | L3 | 4 | intelligence-backend.ts | AgentLoop 集成 | LLM 摘要未实现 |
|
||||
| 13 | OpenViking | L4 | 13 | App.tsx | viking-client.ts | 无 |
|
||||
| 14 | 技能系统 | L4 | 3 | kernel-client.ts | SkillMarket | PythonSkill 未实例化 |
|
||||
| 15 | Hands 详情 | L4 | 7+23 | browser-client.ts | HandList + BrowserPanel | 无 |
|
||||
| 16 | Tauri 后端 | L4 | 137 | 6 个 client 文件 | 全集成 | 无 |
|
||||
| 17 | Pipeline DSL | L4 (90%) | 10 | pipeline-client.ts | PipelinesPanel | skill/hand stage 失败 |
|
||||
|
||||
**结论**: Tauri 端功能-代码对齐率 100%。所有 17 个文档功能都有对应的 Tauri 命令注册和前端调用。
|
||||
|
||||
---
|
||||
|
||||
## 三、SaaS-Tauri 功能差距矩阵
|
||||
|
||||
> **设计定位(v6.1 更新)**: SaaS 后端**不是 Tauri 功能的云端复制品**。SaaS 仅负责系统管理工作:账号管理、功能权限控制、大模型中转(Relay)。Agent 管理、技能执行、Hand 执行、Pipeline、记忆系统、智能层、浏览器自动化等核心 AI 能力**始终在 Tauri 桌面端本地运行**,不会迁移到 SaaS 端。因此原报告中标记为 "CRITICAL" 的 9 个差距项已重新分类。
|
||||
|
||||
### 3.1 能力域对照
|
||||
|
||||
| # | 能力域 | Tauri 端 | SaaS 端 | 差距状态 | 说明 |
|
||||
|---|--------|---------|---------|---------|------|
|
||||
| 1 | 用户认证 | 本地 IPC,Ed25519 设备密钥 | JWT + Argon2 + TOTP 2FA,RBAC | **对等**(模型不同) | 各自负责各自场景 |
|
||||
| 2 | LLM 调用 | 8 个直接 LlmDriver | OpenAI 兼容 Relay 代理 | **部分**(仅 relay) | SaaS 做 relay 中转 |
|
||||
| 3 | Agent 管理 | 9 个 kernel 命令,SQLite | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 4 | 技能执行 | skill_list/refresh/execute,69 SKILL.md | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 5 | Hand 执行 | 7 命令 + 审批流程 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 6 | Pipeline | 10 命令,8 action 类型 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 7 | 记忆系统 | 13 命令,SQLite + FTS5 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 8 | 智能层 | 43 命令(心跳/反思/身份/压缩) | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 9 | 浏览器自动化 | 23 个 browser_* 命令 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 10 | OpenViking | 13 个 viking_* 命令 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 11 | 配置同步 | 无专用机制 | config diff/sync API | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 12 | 设备管理 | 无 | devices 表 + 心跳 | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 13 | 用量追踪 | 无 | usage_records + stats | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 14 | 审计日志 | 无 | operation_logs | **SaaS 独有** | SaaS 管理职责 |
|
||||
|
||||
### 3.2 SaaS 后端现状
|
||||
|
||||
**框架**: Axum (Rust HTTP) + SQLite (sqlx) + JWT + Argon2
|
||||
|
||||
**API 模块** (40+ 端点):
|
||||
- `auth/` — 注册/登录/JWT 刷新/TOTP 2FA
|
||||
- `account/` — 用户 CRUD、API Token、操作日志、仪表盘
|
||||
- `model_config/` — Provider/Model CRUD、用户 API Key、用量统计
|
||||
- `relay/` — OpenAI 兼容 chat relay(流式+非流式)
|
||||
- `migration/` — 配置 diff/sync
|
||||
|
||||
**数据库**: 13 张表,含 accounts, providers, models, relay_tasks, devices, config_items, usage_records
|
||||
|
||||
**SaaS 前端**: `saas-client.ts`(563 行)+ `saasStore.ts`(467 行),无专属 UI 组件
|
||||
|
||||
**Main 分支**: 零 SaaS 代码合并
|
||||
|
||||
### 3.3 合并风险评估
|
||||
|
||||
| 风险 | 等级 | 说明 |
|
||||
|------|------|------|
|
||||
| SaaS 功能缺失 | **LOW** | SaaS 定位为管理系统(账号/权限/relay),不需要复制 Tauri 端 AI 能力 |
|
||||
| 架构耦合 | **MEDIUM** | Tauri 端 137 个命令全部依赖 `invoke()` + `State<'_>` + `AppHandle`,无法直接迁移到 HTTP API |
|
||||
| 双通信路径 | **MEDIUM** | KernelClient(Tauri IPC)和 GatewayClient(WebSocket)并存,SaaS 需要第三条路径 |
|
||||
| 类型一致性 | **LOW** | 共享 zclaw-types crate,类型定义一致 |
|
||||
|
||||
### 3.4 SaaS 待完善项(按设计定位)
|
||||
|
||||
| # | 功能 | 优先级 | 说明 |
|
||||
|---|------|--------|------|
|
||||
| 1 | Relay 多模型支持 | P1 | 当前仅支持 OpenAI 兼容格式,需扩展其他 provider |
|
||||
| 2 | 用户权限细化 | P1 | RBAC 基础已有,需细粒度功能权限控制 |
|
||||
| 3 | Admin UI | P1 | SaaS 管理后台(已有设计规格) |
|
||||
| 4 | 用量计费 | P2 | usage_records 已有表结构,需计费逻辑 |
|
||||
| 5 | 多设备同步 | P2 | devices 表已有,需实现配置/Token 同步 |
|
||||
|
||||
---
|
||||
|
||||
## 四、Trait 实现矩阵
|
||||
|
||||
### 4.1 完整 26 Trait 清单
|
||||
|
||||
| # | Trait | Crate | 生产实现数 | 测试实现 | 零实现? | 严重性 |
|
||||
|---|-------|-------|-----------|---------|---------|--------|
|
||||
| 1 | `LlmDriver` | zclaw-runtime | 4 | 0 | -- | -- |
|
||||
| 2 | `Tool` | zclaw-runtime | 5 | 0 | -- | -- |
|
||||
| 3 | `SkillExecutor` | zclaw-runtime | 1 | 0 | -- | -- |
|
||||
| 4 | `LlmCompleter` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 5 | `Skill` | zclaw-skills | 3 | 0 | -- | -- |
|
||||
| 6 | `SkillGraphExecutor` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 7 | `OrchestrationPlanner` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 8 | `Hand` | zclaw-hands | 9 | 0 | -- | -- |
|
||||
| 9 | `QuizGenerator` | zclaw-hands | 2 | 0 | -- | -- |
|
||||
| 10 | **`Trigger`** | zclaw-hands | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 11 | `VikingStorage` | zclaw-growth | 2 | 0 | -- | -- |
|
||||
| 12 | `EmbeddingClient` | zclaw-growth | 2 | 0 | -- | -- |
|
||||
| 13 | **`LlmDriverForExtraction`** | zclaw-growth | **0** | **1** | **YES** | **HIGH** |
|
||||
| 14 | `SummaryLlmDriver` | zclaw-growth | 1 | 2 | -- | -- |
|
||||
| 15 | `McpClient` | zclaw-protocols | 2 | 0 | -- | -- |
|
||||
| 16 | `A2aClient` | zclaw-protocols | 1 | 0 | -- | -- |
|
||||
| 17 | `Exporter` | zclaw-kernel | 4 | 0 | -- | -- |
|
||||
| 18 | `Channel` | zclaw-channels | 1 | 0 | -- | -- |
|
||||
| 19 | `LlmActionDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 20 | **`SkillActionDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 21 | **`HandActionDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 22 | `OrchestrationActionDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 23 | `LlmIntentDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 24 | **`StageLlmDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 25 | **`StageSkillDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 26 | **`StageHandDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
|
||||
**统计**: 26 trait 中 6 个零实现(23%),1 个仅测试实现(4%),19 个有生产实现(73%)
|
||||
|
||||
### 4.2 ActionRegistry 接线状态
|
||||
|
||||
| Driver 槽位 | Builder 方法 | 是否接线 | 影响 |
|
||||
|------------|-------------|---------|------|
|
||||
| `llm_driver` | `.with_llm_driver()` | **已接线** | LLM stage 正常工作 |
|
||||
| `skill_registry` | `.with_skill_registry()` | **未接线** | skill stage 必然失败 |
|
||||
| `hand_registry` | `.with_hand_registry()` | **未接线** | hand stage 必然失败 |
|
||||
| `orchestration_driver` | `.with_orchestration_driver()` | **未接线**(有实现) | orchestration stage 无法使用 |
|
||||
|
||||
**位置**: `desktop/src-tauri/src/pipeline_commands.rs:701-711`
|
||||
|
||||
---
|
||||
|
||||
## 五、五种差距模式
|
||||
|
||||
### 5.1 量化总表
|
||||
|
||||
| # | 差距模式 | 数量 | 严重性 | 关键实例 |
|
||||
|---|---------|------|--------|---------|
|
||||
| 1 | 写了没接 | 8 | **HIGH** | Director(907行), Export(2,319行), A2A(690行), MCP Client, Channels, GrowthIntegration |
|
||||
| 2 | 接了没传 | 4 | MEDIUM | kernel_status 返回桩数据, viking_tree 忽略 depth 参数 |
|
||||
| 3 | 传了没存 | 0 | -- | 智能层持久化完整 |
|
||||
| 4 | 存了没用 | 2 | MEDIUM | GrowthIntegration 死代码路径, Export 系统不可达 |
|
||||
| 5 | 双系统不同步 | 3 | **HIGH** | intelligence_hooks vs GrowthIntegration, SkillExecutor vs StageSkillDriver |
|
||||
| | **总计** | **17** | | |
|
||||
|
||||
### 5.2 Pattern 1: "写了没接" 详情
|
||||
|
||||
| 模块 | 位置 | 行数 | Tauri 可达? | 说明 |
|
||||
|------|------|------|------------|------|
|
||||
| Director | `crates/zclaw-kernel/src/director.rs` | 907 | **否** | 多 Agent 编排,完全孤立 |
|
||||
| Export 系统 | `crates/zclaw-kernel/src/export/*.rs` | 2,319 | **否** | 4 个 Exporter 实现,无 Tauri 命令 |
|
||||
| A2A 协议 | `crates/zclaw-protocols/src/a2a.rs` | 690 | **否** | feature-gated 但从未激活 |
|
||||
| MCP Client | `crates/zclaw-protocols/src/mcp.rs` | 588 | **否** | 2 个实现,0 个 Tauri 消费者 |
|
||||
| zclaw-channels | `crates/zclaw-channels/src/` | 290 | **否** | ConsoleChannel 无消费者 |
|
||||
| GrowthIntegration | `crates/zclaw-runtime/src/growth.rs` | 315 | **部分** | 定义完整,被 intelligence_hooks 绕过 |
|
||||
| 定时任务调度器 | `desktop/src-tauri/src/kernel_commands.rs` | -- | **半接线** | 命令注册但无调度循环 |
|
||||
|
||||
### 5.3 Pattern 5: "双系统不同步" 详情
|
||||
|
||||
| 实例 | 路径 A | 路径 B | 影响 |
|
||||
|------|--------|--------|------|
|
||||
| 记忆增强 | `intelligence_hooks::build_memory_context()`(活跃) | `GrowthIntegration::enhance_prompt()`(死代码) | 功能重叠但不一致,GrowthIntegration 永远不会执行 |
|
||||
| 技能执行 | `Kernel::execute_skill()` → `SkillRegistry`(活跃) | `StageSkillDriver`(零实现) | Pipeline 中 skill stage 必然失败 |
|
||||
| Hand 执行 | `Kernel::hand_execute()` + 审批(活跃) | `StageHandDriver`(零实现) | Pipeline 中 hand stage 必然失败 |
|
||||
|
||||
---
|
||||
|
||||
## 六、Dead Code 清单
|
||||
|
||||
### 6.1 `#[allow(dead_code)]` 统计(28 处)
|
||||
|
||||
| 分类 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| 合理(serde 反序列化) | 8 | driver 响应体字段 |
|
||||
| 桩代码(Reserved for future) | 14 | intelligence 层预留方法 |
|
||||
| 可疑 | 6 | intent.rs, stage.rs, browser session 等 |
|
||||
|
||||
### 6.2 孤立模块(~4,228 行)
|
||||
|
||||
| 模块 | 位置 | 行数 | 建议 |
|
||||
|------|------|------|------|
|
||||
| `director` | `crates/zclaw-kernel/src/director.rs` | 907 | 移除或 feature-gate |
|
||||
| `a2a` | `crates/zclaw-protocols/src/a2a.rs` | 690 | 已 feature-gate,保持现状 |
|
||||
| `export` | `crates/zclaw-kernel/src/export/` | 2,319 | 移除或接入 Tauri 命令 |
|
||||
| `zclaw-channels` | `crates/zclaw-channels/src/` | 290 | 移除 crate |
|
||||
| `retrieval/cache.rs` | `crates/zclaw-growth/src/retrieval/cache.rs` | 22+ | 移除 |
|
||||
|
||||
### 6.3 TODO 注释(6 处)
|
||||
|
||||
| 位置 | 内容 | 风险 |
|
||||
|------|------|------|
|
||||
| `registry.rs:56` | `// TODO: Track this` | LOW |
|
||||
| `orchestration.rs:41` | `// TODO: implement graph storage` | LOW |
|
||||
| `html.rs:17` | `// TODO: Implement template-based HTML export` | LOW(孤立模块内) |
|
||||
| `pipeline_commands.rs:442` | `// TODO: use actual time` | LOW |
|
||||
| `pipeline_commands.rs:782` | `// TODO: add pattern support` | LOW |
|
||||
|
||||
---
|
||||
|
||||
## 七、E2E 数据流验证
|
||||
|
||||
### 7.1 流程总览
|
||||
|
||||
| # | 流程 | 验证结果 | 关键发现 |
|
||||
|---|------|---------|---------|
|
||||
| 1 | 聊天消息 | **PASS** | 全链路正常,intelligence hooks 正确注入记忆+身份 |
|
||||
| 2 | 技能执行 | **WARNING** | PythonSkill 有实现但从未被实例化;assisted 模式无审批门 |
|
||||
| 3 | Hand 执行+审批 | **PASS** | 三级守卫正确,跨 Hand 审批攻击防护到位 |
|
||||
| 4 | Pipeline 执行 | **FAIL** | skill/hand stage 必然失败(DriverNotAvailable) |
|
||||
| 5 | 记忆存储与检索 | **PASS**(有死代码) | intelligence_hooks 路径正常,GrowthIntegration 永远不执行 |
|
||||
|
||||
### 7.2 Flow 4 失败详情
|
||||
|
||||
Pipeline 的 `StageExecutor` 在执行 skill/hand 类型 stage 时,调用:
|
||||
```rust
|
||||
self.skill_driver.as_ref().ok_or_else(|| StageError::DriverNotAvailable("Skill"))?
|
||||
```
|
||||
由于 `ActionRegistry` 构造时从未注入 `StageSkillDriver` 或 `StageHandDriver`,`skill_driver` 和 `hand_driver` 字段始终为 `None`,导致 `DriverNotAvailable` 错误。
|
||||
|
||||
**可用的 Pipeline stage 类型**: LLM、HTTP、file_export、variable
|
||||
**不可用的 Pipeline stage 类型**: skill、hand、orchestration
|
||||
|
||||
### 7.3 Flow 2 警告详情
|
||||
|
||||
`SkillRegistry` 在匹配 `SkillMode::Python` 时(`registry.rs:79`),直接 fall-through 到 `PromptOnly`,导致 `PythonSkill`(完整实现在 `runner.rs:74-109`)永远不会被实例化。
|
||||
|
||||
---
|
||||
|
||||
## 八、修复建议(优先级排序)
|
||||
|
||||
### P0 — CRITICAL(影响核心功能可用性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P0-1 | Pipeline skill/hand stage 失败 | 实现 `StageSkillDriver`/`StageHandDriver`,在 `pipeline_commands.rs` 中注入 | `crates/zclaw-pipeline/`, `desktop/src-tauri/src/pipeline_commands.rs` | 大 |
|
||||
| P0-2 | GrowthIntegration 永远不执行 | 决策:(A) 在 Kernel 中接线 GrowthIntegration,移除 intelligence_hooks;(B) 移除 GrowthIntegration,统一到 intelligence_hooks | `crates/zclaw-runtime/src/growth.rs`, `desktop/src-tauri/src/intelligence_hooks.rs` | 中 |
|
||||
|
||||
### P1 — HIGH(影响功能完整性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P1-1 | PythonSkill 未实例化 | 修复 `registry.rs:79` 的 fall-through 逻辑 | `crates/zclaw-skills/src/registry.rs` | 小 |
|
||||
| P1-2 | Trigger trait 零实现 | 实现 `Trigger` 或标记为 future feature | `crates/zclaw-hands/src/trigger.rs` | 中 |
|
||||
| P1-3 | LlmDriverForExtraction 仅 Mock | 在 Tauri 层实现生产版本(桥接 LlmDriver) | `desktop/src-tauri/src/` | 中 |
|
||||
| P1-4 | Skill assisted 模式无审批门 | 与 Hand 一致,添加 assisted 模式审批 | `desktop/src-tauri/src/kernel_commands.rs` | 小 |
|
||||
|
||||
### P2 — MEDIUM(代码质量与可维护性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P2-1 | ~4,228 行孤立代码 | 移除 Director、Export、Channels crate | `crates/zclaw-kernel/`, `crates/zclaw-protocols/`, `crates/zclaw-channels/` | 中 |
|
||||
| P2-2 | kernel_status 返回桩数据 | 调用 `kernel.config()` 返回真实值 | `desktop/src-tauri/src/kernel_commands.rs` | 小 |
|
||||
| P2-3 | viking_tree 忽略 depth 参数 | 实现递归深度控制 | `desktop/src-tauri/src/viking_commands.rs` | 小 |
|
||||
| P2-4 | 审批拒绝理由被丢弃 | 存储/返回 `_reason` 参数 | `crates/zclaw-kernel/src/kernel.rs` | 小 |
|
||||
|
||||
### P3 — LOW(SaaS 合并准备)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P3-1 | SaaS 缺失 9 个核心能力域 | 制定 SaaS 功能路线图,优先级:Agent→Skill→Hand→Pipeline→Memory | `.claude/worktrees/saas-backend/` | 大 |
|
||||
| P3-2 | SaaS 无专属 UI 组件 | 设计/实现 SaaS 登录面板、设置页、仪表盘 | `desktop/src/components/` | 大 |
|
||||
| P3-3 | Tauri IPC 耦合 | 抽象通信层,支持 HTTP/WebSocket/Tauri IPC 三种模式 | `desktop/src/lib/` | 大 |
|
||||
|
||||
---
|
||||
|
||||
## 九、审计结论
|
||||
|
||||
### Tauri 端健康度: **良好(78%)**
|
||||
- 功能-代码对齐率 100%,17 个功能全部有对应命令和 UI
|
||||
- 5 条核心 E2E 流程中 3 条完全通过,1 条有警告,1 条失败
|
||||
- 智能层(记忆/身份/心跳/反思/压缩)已完整接入聊天流程
|
||||
- 主要问题集中在 Pipeline 的 skill/hand stage 不可用,以及 GrowthIntegration 死代码路径
|
||||
|
||||
### SaaS 端健康度: **早期(18%)**
|
||||
- 仅实现 auth + LLM relay + config sync 三个基础能力
|
||||
- 9 个核心能力域(Agent/Skill/Hand/Pipeline/Memory/Intelligence/Browser/OpenViking)完全缺失
|
||||
- 前端仅有 client/store 层,无专属 UI 组件
|
||||
- Main 分支零 SaaS 代码,完全隔离
|
||||
|
||||
### 合并建议
|
||||
建议在合并 SaaS worktree 前,先完成以下工作:
|
||||
1. 修复 P0-1(Pipeline skill/hand stage)
|
||||
2. 解决 P0-2(GrowthIntegration vs intelligence_hooks 决策)
|
||||
3. 制定 SaaS 核心能力实现路线图(至少覆盖 Agent + Skill + Hand)
|
||||
4. 为 SaaS 模式设计/实现专属 UI 组件
|
||||
|
||||
---
|
||||
|
||||
*审计完成。本报告基于 2026-03-27 代码快照,所有发现均可通过文档中引用的文件路径和行号验证。*
|
||||
|
||||
---
|
||||
|
||||
## 九、v6.1 修复记录
|
||||
|
||||
> **修复日期**: 2026-03-27
|
||||
> **编译状态**: `cargo check` 通过,零错误零警告
|
||||
|
||||
### 已修复项
|
||||
|
||||
| # | 优先级 | 修复内容 | 修改文件 |
|
||||
|---|--------|---------|---------|
|
||||
| 1 | **P0** | Pipeline skill/hand stage 接入 Kernel 驱动 — 创建 `PipelineSkillDriver` 和 `PipelineHandDriver` 适配器,将 Kernel 的 skill/hand 执行能力桥接到 Pipeline 的 `ActionRegistry` | `pipeline_commands.rs` |
|
||||
| 2 | **P0** | GrowthIntegration 标记为未接线 — 添加文档注释说明该模块在 Tauri 部署中未使用(被 `intelligence_hooks` 替代),保留代码因为被 loop_runner/compaction 深度引用 | `growth.rs` |
|
||||
| 3 | **P1** | PythonSkill 未实例化 — `SkillMode::Python` 分支添加到 registry,当 `main.py` 存在时创建 `PythonSkill` 实例 | `registry.rs` |
|
||||
| 4 | **P1** | Skill assisted 模式添加审批门 — `supervised` 模式所有 skill 需审批,`assisted` 模式 shell/python skill 需审批,`autonomous` 模式直接执行 | `kernel_commands.rs` |
|
||||
| 5 | **P2** | kernel_status 返回真实配置值 — `database_url`、`base_url`、`model` 从桩数据改为读取 Kernel 配置 | `kernel_commands.rs` |
|
||||
| 6 | **P2** | viking_tree depth 参数生效 — 移除未使用的 `_depth` 参数,添加实际深度限制逻辑 | `viking_commands.rs` |
|
||||
| 7 | **P2** | 审批拒绝理由被丢弃 — `ApprovalEntry` 添加 `reject_reason` 字段,`respond_to_approval` 正确存储拒绝理由 | `kernel.rs` |
|
||||
| 8 | **文档** | SaaS 差距矩阵重新分类 — 明确 SaaS 定位为系统管理(账号/权限/relay),9 个 "CRITICAL GAP" 重新标记为 "N/A" | `COMPREHENSIVE_AUDIT_V6.md` |
|
||||
|
||||
### 待办项
|
||||
|
||||
| # | 优先级 | 内容 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | P2 | 清理孤立代码(Director/Export/Channels) | ~4,228 行,建议作为独立重构任务 |
|
||||
| 2 | P3 | 6 个零实现 Trait 评估 | 4 个属于 Pipeline v2(未使用),2 个属于 Trigger 系统 |
|
||||
518
docs/features/COMPREHENSIVE_AUDIT_V7.md
Normal file
518
docs/features/COMPREHENSIVE_AUDIT_V7.md
Normal file
@@ -0,0 +1,518 @@
|
||||
# ZCLAW SaaS 功能审计报告 v7
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-28 审计迭代的 v7 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-28 (原文标注有误)
|
||||
> **审计范围**: SaaS worktree(`.claude/worktrees/saas-backend/`)— Rust 后端 + Admin UI + 桌面端集成
|
||||
> **审计方法**: 五步审计流程(文档对齐 → 数据流追踪 → Dead Code → 接口检查 → E2E 验证)+ 10 项通用清单 + 5 种差距模式 + 跨部门专家论证
|
||||
> **前次审计**: v6(Tauri 端 78%,SaaS 端 18%)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **SaaS 后端 API 端点** | 43 个(文档声明 44 个) |
|
||||
| **文档-代码对齐率** | 97.7%(43/44,缺 `/api/health`) |
|
||||
| **OpenAPI 文档覆盖** | 37/43(86%),6 个端点未注解 |
|
||||
| **Admin UI 页面** | 13 个(含 login) |
|
||||
| **Admin API 方法** | 30 个,全覆盖 |
|
||||
| **桌面端 SaaS 方法** | 20 个,全覆盖 |
|
||||
| **10 项审计清单通过率** | auth 90% / account 80% / model_config 100% / relay 90% / migration 60% |
|
||||
| **五种差距模式发现** | 16 个问题 |
|
||||
| **Dead Code** | 0 个 `#[allow(dead_code)]`/TODO/FIXME + 3 个配置字段 + 3 个遗留函数 |
|
||||
| **安全漏洞** | 1 个 CRITICAL + 2 个 HIGH + 1 个 LOW |
|
||||
| **审计日志缺失** | migration 模块全部缺失(5 个变更端点) |
|
||||
| **测试总数** | 86 个单元测试(10 个模块有测试,9 个文件零测试) |
|
||||
| **整体 SaaS 完成度** | **~88%**(V6 审计评估 18% 严重低估,修正为 88%)
|
||||
|
||||
### 与 V6 审计关键差异
|
||||
|
||||
V6 报告评估 SaaS 完成度为 18%,这是**基于错误假设**(将 Tauri 端 AI 能力缺失计入 SaaS 差距)。本次审计确认 SaaS 的设计定位(系统管理:账号/权限/relay),在定位范围内完成度为 **~88%**。
|
||||
|
||||
---
|
||||
|
||||
## 二、功能清单与真实完成度
|
||||
|
||||
### 2.1 SaaS 功能模块总览
|
||||
|
||||
| # | 功能模块 | 设计意图 | 文档声称 | 真实完成度 | 差距说明 |
|
||||
|---|---------|---------|---------|-----------|---------|
|
||||
| 1 | 用户认证 | 多模式登录、JWT 生命周期、TOTP 2FA | 100% | **95%** | `/api/health` 未实现;`auth.refresh` 无审计日志 |
|
||||
| 2 | 账号管理 | CRUD + 角色限制 + 设备管理 | 100% | **90%** | `AccountPublicPaginatedResponse` 死代码;dashboard 7 次串行查询 |
|
||||
| 3 | API Token | 创建/撤销/权限管理 | 100% | **100%** | 无 |
|
||||
| 4 | 模型配置 | Provider/Model/Key CRUD + 用量 | 95% | **90%** | `account_api_keys` 存了没用(Relay 未消费) |
|
||||
| 5 | LLM Relay | OpenAI 兼容代理 + SSE + 重试 + SSRF | 95% | **90%** | `request_hash`/`priority`/`batch_window_ms` 存了没用;`chat_completions` OpenAPI 缺失 |
|
||||
| 6 | 配置迁移 | diff/sync/seed + 日志 | 90% | **70%** | `sync_config` 缺权限检查(CRITICAL);`pull` 未实现;5 个端点缺审计日志;`created` 计数器永远为 0 |
|
||||
| 7 | Admin UI | 13 页面仪表盘 | 95% | **85%** | 权限过滤 Bug(admin 角色缺 4 页面);分页未连接 API;无前端路由保护 |
|
||||
| 8 | 桌面端集成 | 登录/设备/Relay/迁移向导 | 95% | **90%** | `computeConfigDiff`/`syncConfig` 定义但未调用;调用路径不一致 |
|
||||
|
||||
### 2.2 未实现功能(设计文档提及但代码中不存在)
|
||||
|
||||
| 功能 | 文档状态 | 代码状态 | 说明 |
|
||||
|------|---------|---------|------|
|
||||
| `/api/health` 健康检查 | 文档声明 | **未实现** | `main.rs` 无此路由 |
|
||||
| `pull` 配置同步方向 | types.rs 注释 | **未实现** | service 只处理 push/merge |
|
||||
| 订阅/计费系统 | roadmap 提及 | **未实现** | 无代码 |
|
||||
| 多租户隔离 | 无 | **未实现** | 无代码 |
|
||||
| 配额执行 | 无 | **未实现** | `max_queue_size`/`max_concurrent` 定义但未执行 |
|
||||
|
||||
---
|
||||
|
||||
## 三、API 端点覆盖率
|
||||
|
||||
### 3.1 端点清单(文档 vs 代码)
|
||||
|
||||
| 分类 | 端点 | 文档 | 代码 | OpenAPI | 测试 |
|
||||
|------|------|------|------|---------|------|
|
||||
| **公开** | `POST /api/v1/auth/register` | ✅ | ✅ | ✅ | ✅ |
|
||||
| | `POST /api/v1/auth/login` | ✅ | ✅ | ✅ | ✅ |
|
||||
| | `GET /api/health` | ✅ | **❌** | ❌ | ❌ |
|
||||
| **认证** | `GET /api/v1/auth/me` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/refresh` | ✅ | ✅ | ✅ | — |
|
||||
| | `PUT /api/v1/auth/password` | ✅ | ✅ | ✅ | — |
|
||||
| **TOTP** | `POST /api/v1/auth/totp/setup` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/totp/verify` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/totp/disable` | ✅ | ✅ | ✅ | — |
|
||||
| **账号** | `GET /api/v1/accounts` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/accounts/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `PUT /api/v1/accounts/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `PATCH /api/v1/accounts/{id}/status` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/stats/dashboard` | ✅ | ✅ | ✅ | — |
|
||||
| **Token** | `GET /api/v1/tokens` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/tokens` | ✅ | ✅ | ✅ | — |
|
||||
| | `DELETE /api/v1/tokens/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| **设备** | `POST /api/v1/devices/register` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/devices/heartbeat` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/devices` | ✅ | ✅ | ✅ | — |
|
||||
| **Provider** | `GET/POST /api/v1/providers` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/providers/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/providers/{id}/models` | ✅ | ✅ | ✅ | — |
|
||||
| **Model** | `GET/POST /api/v1/models` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/models/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| **Key** | `GET/POST/DELETE /api/v1/keys` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/keys/{id}/rotate` | ✅ | ✅ | ✅ | — |
|
||||
| **Relay** | `GET /api/v1/relay/models` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/relay/chat/completions` | ✅ | ✅ | **❌** | — |
|
||||
| | `GET /api/v1/relay/tasks` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/relay/tasks/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/relay/tasks/{id}/retry` | ✅ | ✅ | ✅ | — |
|
||||
| **Config** | `GET/POST /api/v1/config/items` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/config/items/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/config/analysis` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/seed` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/sync` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/diff` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/config/sync-logs` | ✅ | ✅ | ✅ | — |
|
||||
| **审计** | `GET /api/v1/logs/operations` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/usage` | ✅ | ✅ | ✅ | — |
|
||||
|
||||
**统计**: 43/44 端点已实现(97.7%),37/43 有 OpenAPI 文档(86%)
|
||||
|
||||
**缺失 OpenAPI 文档的 6 个端点**:
|
||||
1. `POST /api/v1/auth/totp/setup` — TOTP 设置
|
||||
2. `POST /api/v1/auth/totp/verify` — TOTP 验证
|
||||
3. `POST /api/v1/auth/totp/disable` — TOTP 禁用
|
||||
4. `GET /api/v1/logs/operations` — 操作日志
|
||||
5. `GET /api/v1/stats/dashboard` — 仪表盘统计
|
||||
6. `POST /api/v1/relay/chat/completions` — 聊天中转
|
||||
|
||||
---
|
||||
|
||||
## 四、审计矩阵
|
||||
|
||||
### 4.1 十项通用审计清单
|
||||
|
||||
| # | 检查项 | auth | account | model_config | relay | migration |
|
||||
|---|--------|------|---------|-------------|-------|-----------|
|
||||
| 1 | 代码存在性 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 2 | 调用链连通 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 3 | 配置传递 | ✅ | ✅ | ✅ | **⚠️** 3 字段未使用 | ✅ |
|
||||
| 4 | 降级策略 | ✅ JWT 过期处理 | — | — | ✅ 上游超时重试 | — |
|
||||
| 5 | 错误处理 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 6 | 权限执行 | ✅ | ✅ | ✅ | ✅ | **❌** sync_config |
|
||||
| 7 | 日志覆盖 | **⚠️** refresh 缺失 | ✅ | ✅ | ✅ | **❌** 全部缺失 |
|
||||
| 8 | 输入验证 | ✅ | ✅ | ✅ | ✅ | **⚠️** sync action |
|
||||
| 9 | 测试覆盖 | ✅ 3 tests | ✅ 2 tests | ✅ 1 test | ✅ 30+ tests | ✅ 2 tests |
|
||||
| 10 | 文档一致性 | **⚠️** /health 缺失 | ✅ | ✅ | **⚠️** OpenAPI 缺失 | ✅ |
|
||||
|
||||
### 4.2 E2E 数据流验证
|
||||
|
||||
| # | 流程 | 结果 | 关键发现 |
|
||||
|---|------|------|---------|
|
||||
| 1 | 用户注册 → JWT → 首次请求 | **PASS** | 全链路正常,Argon2 哈希正确 |
|
||||
| 2 | TOTP 登录 → 受保护 API | **PASS** | verify_totp_code → get_role_permissions → create_token 正确 |
|
||||
| 3 | Relay SSE 流式 + 用量记录 | **PASS** | SSRF 防护 + DNS Rebinding + SSE 用量提取正确 |
|
||||
| 4 | 配置同步 push/merge | **WARNING** | push 路径正常但缺权限检查;`created` 计数永远为 0 |
|
||||
| 5 | 设备注册 + 心跳 | **PASS** | UPSERT + heartbeat UPDATE 正确 |
|
||||
|
||||
---
|
||||
|
||||
## 五、差距分析(5 种模式)
|
||||
|
||||
### 5.1 Pattern 1: "写了没接"(3 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G1 | `hash_request()` 计算 SHA-256 哈希存入 `request_hash` 但从未被查询 | `relay/service.rs:273` | LOW |
|
||||
| G2 | `pull` 同步方向在类型注释中声明但 service 未实现 | `migration/service.rs:306` | LOW |
|
||||
| G3 | `cleanup_stale_entries()` 声明为 pub(crate) 但从未被调用(仅测试使用) | `middleware.rs:54` | LOW |
|
||||
|
||||
### 5.2 Pattern 2: "接了没传"(2 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G4 | `sync_config` 的 `created` 变量初始化为 0 但从未递增 | `migration/service.rs:263` | MEDIUM |
|
||||
| G5 | `chat_completions` 的 `_headers` 参数提取但未使用 | `relay/handlers.rs:25` | LOW |
|
||||
|
||||
### 5.3 Pattern 3: "传了没存"(0 项)
|
||||
|
||||
无发现。所有 SQL 变更正确执行。
|
||||
|
||||
### 5.4 Pattern 4: "存了没用"(5 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G6 | `request_hash` 列存储但从未用于去重 | `relay_tasks.request_hash` | LOW |
|
||||
| G7 | `priority` 列永远为 0,未用于排序 | `relay_tasks.priority` | LOW |
|
||||
| G8 | `max_queue_size` 配置字段定义但未执行 | `config.rs:49` | LOW |
|
||||
| G9 | `max_concurrent_per_provider` 配置字段定义但未执行 | `config.rs:51` | LOW |
|
||||
| G10 | `batch_window_ms` 配置字段定义但未使用 | `config.rs:53` | LOW |
|
||||
| **G11** | **`account_api_keys` 表完整 CRUD 但 Relay 只使用 provider 级 API Key** | `model_config/service.rs:285` vs `relay/handlers.rs:56` | **HIGH** |
|
||||
|
||||
### 5.5 Pattern 5: "双系统不同步"(3 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G12 | Config 模块写 `config_sync_log` 但不写统一 `operation_logs`,破坏审计追踪 | `migration/handlers.rs` | **MEDIUM** |
|
||||
| G13 | Provider 级 API Key + 用户级 API Key 双系统,Relay 只消费前者 | `relay/handlers.rs:56` | **MEDIUM** |
|
||||
| G14 | Admin UI 导航权限过滤逻辑与后端 RBAC 权限系统不同步 | `layout.tsx:107` vs `db.rs` seed roles | **HIGH** |
|
||||
|
||||
### 5.6 Pattern 1 补充: "写了没接"(Admin UI + Desktop)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G15 | saas-client `computeConfigDiff()`/`syncConfig()` 定义但桌面端从未调用 | `saas-client.ts` | LOW |
|
||||
| G16 | Admin 5 个列表页面分页组件存在但未连接 API 分页参数 | `accounts/providers/models/api-keys/relay page.tsx` | MEDIUM |
|
||||
|
||||
---
|
||||
|
||||
## 六、安全问题
|
||||
|
||||
| # | 问题 | 严重性 | 位置 | 说明 |
|
||||
|---|------|--------|------|------|
|
||||
| **S1** | `sync_config` 无权限检查 | **CRITICAL** | `migration/handlers.rs:83-89` | 任何认证用户可推送配置值,应要求 `config:write` |
|
||||
| **S2** | Config 变更端点无审计日志 | **HIGH** | `migration/handlers.rs` | create/update/delete/seed/sync 5 个端点未调用 `log_operation()` |
|
||||
| **S3** | Admin UI 权限过滤逻辑错误 | **HIGH** | `layout.tsx:107` | 普通 admin 角色无法看到 4 个管理页面;隐藏导航但未保护路由 |
|
||||
| S4 | 邮箱验证仅检查 `@` 和 `.` | LOW | `auth/handlers.rs:28` | 可接受简单验证,PostgreSQL 有 email 类型约束 |
|
||||
|
||||
---
|
||||
|
||||
## 七、跨部门专家论证
|
||||
|
||||
### 发现 S1: `sync_config` 缺权限检查 (CRITICAL)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响中等。当前仅桌面端调用此端点,但公开后任何用户可修改系统配置。优先级 P0 |
|
||||
| **架构师** | 实现疏忽。其他所有 mutation 端点都有 `check_permission`,唯独 `sync_config` 遗漏。修复方案简单:添加 `check_permission(ctx, "config:write")` |
|
||||
| **安全工程师** | 权限边界被突破。一个普通用户(`user` 角色,权限仅 `["model:read","relay:use","config:read"]`)可以覆盖任何配置项。风险:配置投毒 |
|
||||
| **UX 设计师** | 无 UI 影响。Admin 和桌面端的配置同步 UI 都不会因此出现问题,因为其他端点都有权限检查 |
|
||||
|
||||
**结论**: 真实漏洞,P0 修复。一行代码即可修复。
|
||||
|
||||
### 发现 G11: `account_api_keys` 未被 Relay 消费 (HIGH)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响高。用户在桌面端创建的 per-provider API Key 永远不会被使用,Relay 始终使用管理员配置的 provider 级 Key。这导致多用户共享同一个 API Key,无法追踪个人用量到具体 Key |
|
||||
| **架构师** | 设计不完整。`account_api_keys` 的 CRUD 已实现(创建/撤销/轮换),Admin UI 有专门页面,但消费端(Relay)从未接入。需要决策:(A) Relay 优先使用用户级 Key;(B) 移除 `account_api_keys` 功能 |
|
||||
| **安全工程师** | 用户级 Key 隔离未生效。当前所有用户的 Relay 请求共享同一个 provider Key,无法在 Key 级别做权限隔离或用量追踪 |
|
||||
| **UX 设计师** | Admin UI 的 "API Keys" 页面展示用户创建的 Key 和轮换状态,但实际从未使用。用户可能困惑于 "为什么创建了 Key 但用量全部归到 provider" |
|
||||
|
||||
**结论**: 真实设计缺陷,需要架构决策。建议方案 A(Relay 优先用户级 Key,回退 provider 级)。
|
||||
|
||||
### 发现 G12: Config 模块审计日志缺失 (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。Config 变更频率低,通常由管理员操作。但合规审计需要完整日志 |
|
||||
| **架构师** | 不一致。auth/account/model_config 模块都有 `log_operation()`,唯独 migration 模块缺失。`sync_config` 写了 `config_sync_log` 但这是专用日志,不在统一的 `operation_logs` 表中 |
|
||||
| **安全工程师** | 审计盲区。如果有人在凌晨 3 点覆盖了系统配置,`operation_logs` 表中不会有记录 |
|
||||
| **UX 设计师** | 无影响。Admin 操作日志页面不会显示 Config 变更记录 |
|
||||
|
||||
**结论**: 真实遗漏。修复简单:在 5 个 mutation handler 中添加 `log_operation()` 调用。
|
||||
|
||||
### 发现 G4: `sync_config` `created` 计数永远为 0 (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。桌面端迁移向导显示 "updated: N, created: 0, skipped: M"。`created` 永远为 0 可能让用户困惑 |
|
||||
| **架构师** | 实现疏忽。push 路径只处理已存在的 config_items(UPDATE),merge 路径也只处理已存在的。真正的新增场景(客户端发送 SaaS 不存在的 key)未被处理 |
|
||||
| **安全工程师** | 无安全影响 |
|
||||
| **UX 设计师** | 迁移向导的统计信息不准确。`created` 应该在 INSERT 新 config_item 时递增 |
|
||||
|
||||
**结论**: 真实 Bug。`sync_config` 应在 INSERT 时递增 `created` 计数器。
|
||||
|
||||
### 发现 S3: `/api/health` 端点未实现 (LOW)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。文档声明了但桌面端 `healthCheck()` 调用时如果返回 404 会判断为不健康。实际影响:桌面端可能误判服务器不可达 |
|
||||
| **架构师** | 遗漏。实现简单,返回 `{ status: "ok", version: "x.y.z" }` 即可 |
|
||||
| **安全工程师** | 无安全影响(公开端点) |
|
||||
| **UX 设计师** | 桌面端 SaaSStatus 组件依赖健康检查。缺失会导致状态显示异常 |
|
||||
|
||||
**结论**: 真实遗漏。简单修复。
|
||||
|
||||
### 发现 S3: Admin UI 权限过滤逻辑错误 (HIGH)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响高。多管理员场景下(组织有多个管理员),普通 `admin` 角色用户登录后看不到账号管理、服务商、模型管理、中转任务 4 个核心页面。这严重限制了管理员协作能力。优先级 P1 |
|
||||
| **架构师** | 实现疏忽。过滤条件 `account.role === 'super_admin' \|\| item.permission === 'admin:full'` 未检查用户是否实际拥有 `item.permission`。正确做法应检查 `account.permissions.includes(item.permission)`。此外,仅隐藏导航项未做前端路由守卫,用户直接输入 URL 可绕过。修复需 2 处:(A) 修正过滤逻辑;(B) 添加路由级权限检查 |
|
||||
| **安全工程师** | 前端权限过滤失效。虽然后端 API 有权限检查(`check_permission`),但前端暴露了所有路由 URL,攻击者可枚举管理端点。更重要的是,**前端路由未保护**意味着用户可能看到一个有权限错误但功能正常的页面,体验混乱 |
|
||||
| **UX 设计师** | 用户体验混乱。管理员登录后看到侧边栏只有 6/12 项,可能认为自己权限不足。如果直接输入 URL 访问被隐藏的页面,后端返回 403 错误但页面不会给出清晰提示 |
|
||||
|
||||
**结论**: 真实 Bug,P1 修复。修正过滤逻辑 + 添加路由守卫。
|
||||
|
||||
### 发现 G16: Admin 分页组件未连接 API (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响中等。当前数据量小(早期用户)时无感知。但一旦账号/模型/密钥数量超过默认 page_size,用户只能看到第一批数据,无法翻页查看更多。优先级 P2 |
|
||||
| **架构师** | 分页组件存在于 5 个页面但全部未连接 API 调用。`PageNavigation` 组件维护 `currentPage`/`pageSize` 状态,但 `api.xxx.list()` 调用未传递这些参数。修复方案:将分页状态传递到 API 调用,监听页码变化触发重新加载 |
|
||||
| **安全工程师** | 无安全影响 |
|
||||
| **UX 设计师** | 分页按钮显示但点击无效,或者始终显示"第 1 页"。用户可能认为数据只有这么多,不知道还有更多未加载 |
|
||||
|
||||
**结论**: 真实 Bug,P2 修复。5 个页面统一处理。
|
||||
|
||||
---
|
||||
|
||||
## 八、Admin UI 审计
|
||||
|
||||
### 8.1 页面-API 对齐
|
||||
|
||||
| 页面 | API 方法调用 | 状态 |
|
||||
|------|------------|------|
|
||||
| Login | `api.auth.login()` | ✅ |
|
||||
| Dashboard | `api.stats.dashboard()` | ✅ |
|
||||
| Accounts | `api.accounts.list/get/update/updateStatus()` | ✅ |
|
||||
| Providers | `api.providers.list/get/create/update/delete()` | ✅ |
|
||||
| Models | `api.models.list/get/create/update/delete()` | ✅ |
|
||||
| API Keys | `api.tokens.list/create/revoke()` | ✅ |
|
||||
| Usage | `api.usage.get()` | ✅ |
|
||||
| Relay | `api.relay.list/get/retry()` | ✅ |
|
||||
| Config | `api.config.list/update()` | ✅ |
|
||||
| Logs | `api.logs.list()` | ✅ |
|
||||
| Devices | `api.devices.list/register/heartbeat()` | ✅ |
|
||||
| Profile | `api.auth.changePassword()` | ✅ |
|
||||
| Security | `api.auth.totpSetup/verify/disable()` | ✅ |
|
||||
|
||||
**对齐率**: 100%。Admin UI 的 30 个 API 方法全部有对应后端端点。
|
||||
|
||||
### 8.2 Admin API 方法 vs 后端端点交叉验证
|
||||
|
||||
所有 30 个 Admin API 方法的路径均与后端路由匹配,无多余或缺失。
|
||||
|
||||
### 8.3 Admin UI 权限过滤 Bug(HIGH)
|
||||
|
||||
**位置**: `admin/src/app/(dashboard)/layout.tsx:103-108`
|
||||
|
||||
**问题**: 侧边栏导航过滤逻辑存在逻辑错误:
|
||||
|
||||
```typescript
|
||||
// 当前代码(有 Bug)
|
||||
.filter((item) => {
|
||||
if (!item.permission) return true
|
||||
if (!account) return false
|
||||
return account.role === 'super_admin' || item.permission === 'admin:full'
|
||||
})
|
||||
```
|
||||
|
||||
**影响**: `navItems` 中 `account:admin`、`model:admin`、`relay:admin` 三个权限标记对普通 `admin` 角色用户**完全无效**。逻辑等价于:
|
||||
- `permission: null` → 所有角色可见(正确)
|
||||
- `permission: 'admin:full'` → 所有角色可见(Bug,应仅 super_admin 可见)
|
||||
- `permission: 'account:admin'` → **仅** super_admin 可见(Bug,admin 也应有此权限)
|
||||
- `permission: 'model:admin'` → **仅** super_admin 可见(Bug)
|
||||
- `permission: 'relay:admin'` → **仅** super_admin 可见(Bug)
|
||||
|
||||
**结果**: 普通 `admin` 角色用户只能看到仪表盘、API 密钥、用量统计、个人设置、安全设置、设备管理(6/12),**无法看到**账号管理、服务商、模型管理、中转任务(4/12)。
|
||||
|
||||
**缺失**: 仅隐藏导航项,**未做前端路由保护**。用户直接输入 `/accounts`、`/providers` 等路径仍可访问页面(后端权限检查正常,但前端体验不一致)。
|
||||
|
||||
**修复方案**: 改用权限检查函数验证用户是否拥有对应权限:
|
||||
```typescript
|
||||
.filter((item) => {
|
||||
if (!item.permission) return true
|
||||
if (!account) return false
|
||||
return account.permissions?.includes(item.permission) ?? false
|
||||
})
|
||||
```
|
||||
|
||||
### 8.4 Admin UI 分页功能不可用(MEDIUM)
|
||||
|
||||
**影响页面**: accounts、providers、models、api-keys、relay(5 个列表页面)
|
||||
|
||||
**发现**: 5 个页面均包含分页组件(PageNavigation),后端 API 支持分页参数(`page`/`page_size`),但**前端调用 API 时未传递分页参数**,始终获取第一页全部数据。
|
||||
|
||||
**根因**: API 调用使用 `api.xxx.list()` 而非 `api.xxx.list({ page, pageSize })`,分页状态(`currentPage`/`pageSize`)存在于组件 state 中但未与 API 调用关联。
|
||||
|
||||
### 8.5 Admin UI 错误处理一致性
|
||||
|
||||
**发现**: 所有页面均有 `try/catch` 处理 API 错误,但存在不一致:
|
||||
- 部分页面使用 `setError(err.message)` 显示具体错误(accounts、providers)
|
||||
- 部分页面使用 `console.error` 但无用户可见反馈(models:113、api-keys:138)
|
||||
- 无统一的全局错误 Toast/Banner 组件
|
||||
|
||||
**影响**: LOW。用户可能在操作失败时看不到任何反馈。
|
||||
|
||||
---
|
||||
|
||||
## 九、桌面端 SaaS 集成审计
|
||||
|
||||
### 9.1 saas-client.ts 端点覆盖
|
||||
|
||||
| 方法 | 后端端点 | 匹配 |
|
||||
|------|---------|------|
|
||||
| `login()` | `POST /api/v1/auth/login` | ✅ |
|
||||
| `register()` | `POST /api/v1/auth/register` | ✅ |
|
||||
| `me()` | `GET /api/v1/auth/me` | ✅ |
|
||||
| `refreshToken()` | `POST /api/v1/auth/refresh` | ✅ |
|
||||
| `changePassword()` | `PUT /api/v1/auth/password` | ✅ |
|
||||
| `setupTotp()` | `POST /api/v1/auth/totp/setup` | ✅ |
|
||||
| `verifyTotp()` | `POST /api/v1/auth/totp/verify` | ✅ |
|
||||
| `disableTotp()` | `POST /api/v1/auth/totp/disable` | ✅ |
|
||||
| `registerDevice()` | `POST /api/v1/devices/register` | ✅ |
|
||||
| `deviceHeartbeat()` | `POST /api/v1/devices/heartbeat` | ✅ |
|
||||
| `listDevices()` | `GET /api/v1/devices` | ✅ |
|
||||
| `listModels()` | `GET /api/v1/relay/models` | ✅ |
|
||||
| `listRelayTasks()` | `GET /api/v1/relay/tasks` | ✅ |
|
||||
| `getRelayTask()` | `GET /api/v1/relay/tasks/{id}` | ✅ |
|
||||
| `retryRelayTask()` | `POST /api/v1/relay/tasks/{id}/retry` | ✅ |
|
||||
| `chatCompletion()` | `POST /api/v1/relay/chat/completions` | ✅ |
|
||||
| `listConfig()` | `GET /api/v1/config/items` | ✅ |
|
||||
| `computeConfigDiff()` | `POST /api/v1/config/diff` | ✅ |
|
||||
| `syncConfig()` | `POST /api/v1/config/sync` | ✅ |
|
||||
| `healthCheck()` | `GET /api/health` | **❌** 端点不存在 |
|
||||
|
||||
**对齐率**: 19/20(95%)。唯一不匹配是 `healthCheck()` 调用了不存在的 `/api/health`。
|
||||
|
||||
### 9.2 桌面端特性
|
||||
|
||||
- **JWT Token 自动刷新**: 80% 生命周期时主动刷新 + visibilitychange 监听
|
||||
- **会话持久化**: Token 存 OS Keyring(secureStorage),URL/Account 存 localStorage
|
||||
- **遗留函数清理**: `loadSaaSSession()`/`saveSaaSSession()`/`clearSaaSSession()` 3 个同步版本标记为 `@deprecated`
|
||||
- **网络重试**: 指数退避 2 次重试(1s, 2s)
|
||||
- **离线检测**: `isServerReachable()` 状态追踪
|
||||
|
||||
### 9.3 桌面端架构不一致(MEDIUM)
|
||||
|
||||
**发现**: saas-client.ts 中定义了 `computeConfigDiff()` 和 `syncConfig()` 两个方法,但**桌面端代码中无任何组件或 store 调用它们**。配置迁移向导(ConfigMigrationWizard)实现了自己的 diff/sync 逻辑,不经过 saas-client。
|
||||
|
||||
**影响**: MEDIUM。代码冗余 + 维护风险。如果 saas-client 的 API 签名与向导实现不一致,可能出现行为分歧。
|
||||
|
||||
### 9.4 桌面端调用路径不一致(LOW)
|
||||
|
||||
**发现**: 部分 SaaS 操作通过 `saasStore`(Zustand)编排,其他操作直接调用 `saasClient`。无统一规范约定何时使用哪条路径。
|
||||
|
||||
**影响**: LOW。不影响功能正确性,但增加了代码理解和维护成本。
|
||||
|
||||
---
|
||||
|
||||
## 十、测试覆盖评估
|
||||
|
||||
| 模块 | 测试数 | 覆盖内容 |
|
||||
|------|--------|---------|
|
||||
| error.rs | 4 | SaasError 变体、IntoResponse |
|
||||
| config.rs | 4 | 配置加载、环境变量覆盖 |
|
||||
| middleware.rs | 8 | 速率限制、窗口过期、admin 豁免 |
|
||||
| csrf.rs | 6 | Origin 验证、路径剥离、dev 绕过 |
|
||||
| crypto.rs | 10 | 加密/解密、篡改检测、错误密钥 |
|
||||
| jwt | 3 | Token 创建/验证/过期 |
|
||||
| password | 2 | 哈希/验证 |
|
||||
| db.rs | 2 | Schema 初始化、表存在性 |
|
||||
| relay/service.rs | 37 | 重试逻辑、Token 提取、SSRF 检测(**最佳覆盖**) |
|
||||
| model_config/service.rs | 10 | Provider/Model/Key CRUD |
|
||||
| **总计** | **86** | — |
|
||||
|
||||
**零测试的 9 个文件**: 5 个 handler 文件、`auth/totp.rs`、`account/service.rs`、`migration/service.rs`、`state.rs`
|
||||
|
||||
---
|
||||
|
||||
## 十一、修复建议(优先级排序)
|
||||
|
||||
### P0 — CRITICAL(安全漏洞)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P0-1 | `sync_config` 无权限检查 | `migration/handlers.rs:83` 添加 `check_permission(ctx, "config:write")` | **1 行** |
|
||||
|
||||
### P1 — HIGH(功能缺陷)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P1-1 | `account_api_keys` 未被 Relay 消费 | Relay handler 查找用户级 Key,回退到 provider 级 Key | 中 |
|
||||
| P1-2 | Config 模块 5 个端点缺审计日志 | 添加 `log_operation()` 调用 | 小 |
|
||||
| P1-3 | `sync_config` `created` 计数永远为 0 | INSERT 时递增 `created` | 小 |
|
||||
| P1-4 | Admin UI 权限过滤逻辑错误 | `layout.tsx:107` 改用 `account.permissions.includes(item.permission)` | **5 行** |
|
||||
| P1-5 | Admin UI 缺前端路由保护 | 添加 `AuthGuard` 组件检查页面级权限 | 中 |
|
||||
|
||||
### P2 — MEDIUM(代码质量)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P2-1 | `/api/health` 端点未实现 | 添加健康检查路由 | 小 |
|
||||
| P2-2 | `chat_completions` 缺 OpenAPI 文档 | `openapi.rs` 添加 `#[utoipa::path]` | 小 |
|
||||
| P2-3 | 6 个端点缺 OpenAPI 注解 | `openapi.rs` 补充 `#[utoipa::path]` | 中 |
|
||||
| P2-4 | `AccountPublicPaginatedResponse` 仅 OpenAPI 用 | 保留或统一到 PaginatedResponse | 小 |
|
||||
| P2-5 | 3 个 Relay 配置字段未使用 | 移除或实现 `max_queue_size`/`max_concurrent`/`batch_window_ms` | 中 |
|
||||
| P2-6 | `request_hash`/`priority` 列存了没用 | 移除或实现去重/优先级排序 | 中 |
|
||||
| P2-7 | `pull` 同步方向未实现 | 实现或从类型注释中移除 | 中 |
|
||||
| P2-8 | 3 个遗留同步函数未清理 | 移除 `loadSaaSSession`/`saveSaaSSession`/`clearSaaSSession` | 小 |
|
||||
| P2-9 | dashboard_stats 7 次串行查询 | 合并为单次 SQL 查询 | 小 |
|
||||
| P2-10 | Admin 5 个列表页面分页未连接 API | 将分页状态传递到 API 调用 | 小 |
|
||||
| P2-11 | `computeConfigDiff`/`syncConfig` saas-client 定义但未使用 | 移除或统一迁移向导调用路径 | 小 |
|
||||
| P2-12 | Admin UI catch 块无用户可见错误反馈 | 添加全局 Toast 组件 | 小 |
|
||||
|
||||
### P3 — LOW(测试补充)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P3-1 | auth/account/model_config/migration 缺单元测试 | 添加 handler/service 层测试 | 大 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、审计结论
|
||||
|
||||
### SaaS 后端健康度: **良好(~88%)**
|
||||
|
||||
**优势**:
|
||||
- 功能-代码对齐率 97.7%(43/44 端点)
|
||||
- 安全基础设施成熟(Argon2 + TOTP + RBAC + AES-256-GCM + CSRF + SSRF 防护)
|
||||
- Admin UI 覆盖所有管理功能(13 页面)
|
||||
- 桌面端集成完整(登录/设备/Relay/配置迁移)
|
||||
- 测试覆盖 86 个单元测试
|
||||
- 代码质量高:零 TODO/FIXME,错误处理一致
|
||||
|
||||
**待改进**:
|
||||
- 1 个 CRITICAL 安全漏洞(`sync_config` 权限检查缺失)
|
||||
- 2 个 HIGH 缺陷(用户级 API Key 未被 Relay 消费;Admin 权限过滤逻辑错误)
|
||||
- 1 个 MEDIUM 功能 Bug(`created` 计数永远为 0)
|
||||
- Config 模块审计日志完全缺失
|
||||
- Admin UI 分页未连接 API(5 个页面)
|
||||
- Admin UI 无前端路由保护
|
||||
- 5 个配置字段定义但未执行
|
||||
|
||||
### 修正 V6 评估
|
||||
|
||||
V6 审计将 SaaS 完成度评估为 18%,原因是将 Tauri 端 AI 能力(Agent/Skill/Hand/Pipeline/Memory/Intelligence/Browser/OpenViking)的缺失计入 SaaS 差距。**这是错误的**——SaaS 的设计定位是系统管理(账号/权限/relay),不负责 AI 能力。在正确定位下,SaaS 完成度为 **~88%**(V7 初评 90% 下调 2%,因发现 Admin UI 权限 Bug 和分页未连接),修复 P0-P2 项即可达到 95%+。
|
||||
|
||||
---
|
||||
|
||||
*审计完成。本报告基于 2026-03-28 代码快照(worktree-saas-backend 分支,commit bc12f68),所有发现均可通过文档中引用的文件路径和行号验证。*
|
||||
339
docs/features/COMPREHENSIVE_AUDIT_V8.md
Normal file
339
docs/features/COMPREHENSIVE_AUDIT_V8.md
Normal file
@@ -0,0 +1,339 @@
|
||||
# ZCLAW SaaS+Tauri 系统性功能审计报告 V8
|
||||
|
||||
> **审计日期**: 2026-03-29
|
||||
> **审计范围**: 全量三端审计 — SaaS 后端 + Tauri 桌面端 + Admin 管理后台
|
||||
> **审计方法**: 五步审计流程 + 十项通用清单 + 五种差距模式 + 安全专项
|
||||
> **前次审计**: V7 (2026-03-28, 已归档)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **SaaS API 端点** | 76+ (9 模块, 22+ 数据表) |
|
||||
| **Tauri 命令** | 150+ (73 个 invoke 调用) |
|
||||
| **Admin 页面** | 12 (含 login) |
|
||||
| **文档-代码对齐率** | ~95% |
|
||||
| **数据流连通率** | 60% (3/5 完整连通, 1 部分连通, 1 断裂) |
|
||||
| **Dead Code** | 28+ `#[allow(dead_code)]`, 35+ 未调用 API 方法 |
|
||||
| **安全漏洞** | 1 CRITICAL + 2 HIGH + 2 MEDIUM |
|
||||
| **差距模式发现** | 12 个 (P0×1, P1×4, P2×4, P3×3) |
|
||||
| **整体完成度** | **~82%** (核心功能可用,集成链路存在断裂) |
|
||||
|
||||
---
|
||||
|
||||
## 二、功能清单与完成度矩阵
|
||||
|
||||
### 2.1 架构层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 通信层 | 三模式连接 (Kernel/Gateway/SaaS) | N/A | ✅ | N/A | 85% | hand_run 桩命令 |
|
||||
| 状态管理 | 18 Zustand Store | N/A | N/A | N/A | 80% | 消息不持久化 |
|
||||
| 安全认证 | Ed25519+JWT+TOTP | ✅ | ✅ | ✅ | 80% | 生物识别/FIDO2 未实现 |
|
||||
|
||||
### 2.2 核心功能
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 聊天界面 | 流式响应+多模型 | ✅ Relay | ✅ Stream | N/A | 92% | 超长消息卡顿 |
|
||||
| Agent 分身 | CRUD+模板+切换 | ✅ Template | ✅ Agent | ✅ Template | 85% | 导入/导出未实现 |
|
||||
| Hands 系统 | 9+ 自主能力 | N/A | ✅ 9 Hands | N/A | 70% | Predictor/Lead 无代码 |
|
||||
|
||||
### 2.3 智能层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| Agent 记忆 | 跨会话+语义搜索 | N/A | ✅ Viking | N/A | 90% | 大量记忆检索变慢 |
|
||||
| 身份演化 | SOUL.md+自动改进 | N/A | ✅ | N/A | 70% | Tauri 模式内存存储重启丢失 |
|
||||
| 反思引擎 | 自动分析+建议 | N/A | ✅ | N/A | 65% | 建议具体性待改进 |
|
||||
| 心跳巡检 | 定期巡检+主动提醒 | ✅ 设备心跳 | ✅ | N/A | 70% | 持久化调度缺失 |
|
||||
| 自主授权 | 三级授权+审批 | N/A | ✅ | N/A | 75% | 批量审批未实现 |
|
||||
| 上下文压缩 | 智能摘要 | N/A | ✅ | N/A | 75% | LLM 增强摘要未使用 |
|
||||
|
||||
### 2.4 平台层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 技能系统 | 69 SKILL.md | N/A | ✅ | N/A | 80% | WASM/Native 未实现 |
|
||||
| 智能路由 | 语义匹配 | N/A | ❌ | N/A | 50% | SemanticSkillRouter 核心未实现 |
|
||||
| Pipeline DSL | YAML 工作流 | N/A | ✅ | N/A | 90% | 无重大差距 |
|
||||
| SaaS 平台 | 云端能力 | ✅ | ✅ | ✅ | 88% | SQL 注入+配置单向同步+遥测空转 |
|
||||
|
||||
---
|
||||
|
||||
## 三、五步审计结果
|
||||
|
||||
### 3.1 Step 1: 文档对齐
|
||||
|
||||
| 检查项 | 结果 |
|
||||
|--------|------|
|
||||
| SaaS API 路由 vs 文档 | ✅ 76+ 端点全部对齐 |
|
||||
| Tauri 命令 vs 文档 | ✅ 150+ 命令已注册 |
|
||||
| Admin 页面 vs 文档 | ✅ 12 页面全部存在 |
|
||||
| 功能文档声称 vs 实际 | ⚠️ 部分功能声称高于实际 (智能路由 50% 声称 Phase 1 完成) |
|
||||
|
||||
**对齐率: ~95%**
|
||||
|
||||
### 3.2 Step 2: 数据流追踪
|
||||
|
||||
| # | 数据流 | 状态 | 断点 |
|
||||
|---|--------|------|------|
|
||||
| DF1 | 认证 (Desktop→SaaS) | ✅ 完整 | 无 |
|
||||
| DF2 | 聊天 Relay (Desktop→SaaS→LLM) | ⚠️ 部分 | chatStore SaaS 模式走 WS 而非 HTTP relay |
|
||||
| DF3 | 配置同步 (Desktop↔SaaS) | ❌ 单向 | Pull✅, Push/Diff❌ (定义但未调用) |
|
||||
| DF4 | 设备管理 (Desktop→SaaS) | ✅ 完整 | 心跳不传 OS/version |
|
||||
| DF5 | 遥测上报 (Desktop→SaaS) | ❌ 断裂 | recordLLMUsage/recordAuditEvent 零调用 |
|
||||
|
||||
**连通率: 60% (3/5 完整)**
|
||||
|
||||
### 3.3 Step 3: Dead Code 识别
|
||||
|
||||
#### Rust `#[allow(dead_code)]` — 28 处
|
||||
|
||||
| 分类 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| Intelligence 模块 | 12 | heartbeat/reflection/identity/compactor 预留给未来 Tauri 命令 |
|
||||
| Memory 模块 | 3 | persistent.rs 遗留迁移代码 |
|
||||
| Runtime 驱动 | 4 | 反序列化字段未被访问 |
|
||||
| Kernel/Pipeline | 4 | 预留功能 (export, intent, stage) |
|
||||
| lib.rs | 2 | HealthStatus 枚举 + legacy 函数 |
|
||||
| Growth | 2 | 缓存+存储预留 |
|
||||
|
||||
#### 未调用的 SaaS API 方法 — 35+ 个
|
||||
|
||||
**需要关注的桌面端方法 (应在 desktop 中使用但未使用)**:
|
||||
- `healthCheck()` — 未被任何 health check 调用使用
|
||||
- `listDevices()` — 设备列表未在桌面端展示
|
||||
- `getRelayTask()` — 单个任务查询未使用
|
||||
- `computeConfigDiff()` — ❌ 零调用,配置差异计算断裂
|
||||
- `syncConfig()` — ❌ 零调用,配置推送断裂
|
||||
|
||||
**Admin 专用方法 (桌面端不使用是正常的)**:
|
||||
- Provider/Model/Account/Role/Permission CRUD (~30 个)
|
||||
- 这些方法在 admin/src/ 中通过独立的 api-client.ts 调用
|
||||
|
||||
#### Rust TODO/FIXME — 5 处
|
||||
|
||||
| 文件 | 行号 | 内容 |
|
||||
|------|------|------|
|
||||
| pipeline_commands.rs | 529 | `// TODO: use actual time` |
|
||||
| pipeline_commands.rs | 869 | `// TODO: add pattern support` |
|
||||
| kernel/src/registry.rs | 56 | `// TODO: Track this` |
|
||||
| kernel/src/export/html.rs | 17 | `// TODO: Implement template-based HTML export` |
|
||||
| pipeline/src/actions/orchestration.rs | 41 | `// TODO: implement graph storage` |
|
||||
|
||||
### 3.4 Step 4: 接口一致性
|
||||
|
||||
#### TS 类型差异 — 10+ 组
|
||||
|
||||
| 类型对 | 主要差异 |
|
||||
|--------|---------|
|
||||
| AccountPublic | admin: 联合类型 role/status; desktop: string |
|
||||
| OperationLog vs OperationLogInfo | id 类型 string vs number; details 类型不同 |
|
||||
| ConfigItem vs SaaSConfigItem | current_value 类型不同; desktop 多 created_at/updated_at |
|
||||
| RelayTask vs RelayTaskInfo | status 联合类型 vs string; desktop 多 max_attempts/created_at |
|
||||
| PromptTemplate vs PromptTemplateInfo | source/status 联合类型 vs string |
|
||||
| Provider vs ProviderInfo | admin 有 api_key 字段; desktop 无 |
|
||||
| Model vs ModelInfo | desktop 多 created_at/updated_at |
|
||||
|
||||
### 3.5 Step 5: 端到端验证
|
||||
|
||||
| 测试流程 | 结果 | 说明 |
|
||||
|----------|------|------|
|
||||
| 用户注册→登录→获取信息 | ✅ | 完整链路通畅 |
|
||||
| 登录→设备注册→心跳 | ✅ | 降级逻辑正常 |
|
||||
| 配置 Pull | ✅ | 仅拉取方向 |
|
||||
| 配置 Push/Diff | ❌ | 方法未调用 |
|
||||
| Relay chat→SSE | ✅ | llm-service.ts 路径完整 |
|
||||
| Admin 登录→管理→CRUD | ✅ | 全部页面可操作 |
|
||||
|
||||
---
|
||||
|
||||
## 四、十项通用审计清单
|
||||
|
||||
| # | 审计点 | 结果 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | 代码存在性 | ✅ 95% | 所有文档声明功能有对应代码 |
|
||||
| 2 | 调用链连通 | ⚠️ 70% | 遥测/配置推送/OTA 链路断裂 |
|
||||
| 3 | 配置传递 | ✅ 90% | saas-config.toml 端到端有效 |
|
||||
| 4 | 降级策略 | ✅ 85% | 3 次失败→tauri 模式降级正常 |
|
||||
| 5 | 错误处理 | ⚠️ 75% | Desktop 401 不自动 logout |
|
||||
| 6 | 安全审计 | ❌ 60% | SQL 注入 + 权限缺失 |
|
||||
| 7 | 日志记录 | ⚠️ 70% | migration/telemetry 模块缺 operation_logs |
|
||||
| 8 | 测试覆盖 | ✅ 80% | SaaS 62 个集成测试, 但覆盖率不足 |
|
||||
| 9 | 类型一致性 | ⚠️ 70% | 10+ 组类型定义不同步 |
|
||||
| 10 | 前后端接口匹配 | ⚠️ 75% | 大部分匹配, 部分字段差异 |
|
||||
|
||||
---
|
||||
|
||||
## 五、五种差距模式
|
||||
|
||||
### 5.1 "写了没接" — 5 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-01 | `recordLLMUsage` / `recordAuditEvent` 零外部调用 | telemetry-collector.ts | **P0** |
|
||||
| G-02 | `startPromptOTASync` 从未调用 | llm-service.ts | **P1** |
|
||||
| G-05 | `computeConfigDiff` / `syncConfig` push 未接入 | saas-client.ts | **P1** |
|
||||
| G-10 | `hand_run_status` / `hand_run_list` 后端桩命令 | kernel_commands.rs | **P3** |
|
||||
| — | `healthCheck()` 未被 health check 流程调用 | saas-client.ts | **P2** |
|
||||
|
||||
### 5.2 "接了没传" — 1 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-04 | 心跳仅传 device_id, 不传 OS/version | saasStore.ts | **P1** |
|
||||
|
||||
### 5.3 "传了没存" — 2 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-06 | telemetry 端点不写 operation_logs | telemetry/handlers.rs | **P2** |
|
||||
| G-09 | 心跳不写 operation_logs | account/handlers.rs | **P2** |
|
||||
|
||||
### 5.4 "存了没用" — 2 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-03 | `max_queue_size` / `max_concurrent` relay 未消费 | relay/service.rs | **P1** |
|
||||
| G-07 | `account_api_keys` 被 relay 绕过 (用 provider_key_pool) | model_config/ | **P2** |
|
||||
|
||||
### 5.5 "双系统不同步" — 2 项确认
|
||||
|
||||
| # | 项目 | 说明 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-08 | Desktop 401 不自动 logout, Admin 会 | 用户体验不一致 | **P2** |
|
||||
| G-12 | 双端错误类型不统一 (SaaSApiError vs ApiRequestError) | 不可复用 | **P3** |
|
||||
|
||||
---
|
||||
|
||||
## 六、安全审计专项
|
||||
|
||||
### 6.1 CRITICAL: SQL 注入
|
||||
|
||||
**文件**: `crates/zclaw-saas/src/agent_template/service.rs`
|
||||
|
||||
全文件使用 `format!()` 直接拼接用户输入到 SQL, 依赖手工 `replace('\'', "''")` 转义。这是项目中**唯一未使用 `$N` 参数化查询**的 service 文件。
|
||||
|
||||
**受影响的操作**:
|
||||
- `list_templates()` — WHERE 条件 (category, source, visibility, status)
|
||||
- `update_template()` — SET 字段 (description, model, system_prompt, tools, capabilities, visibility, status) + WHERE id
|
||||
|
||||
**攻击向量示例**:
|
||||
```sql
|
||||
-- category 参数: `' OR 1=1 --` → 绕过 WHERE 条件
|
||||
-- id 参数: `' OR '1'='1` → 更新所有记录
|
||||
```
|
||||
|
||||
**修复方案**: 改用 `$N` 参数化查询, 参照 `account/service.rs` 和 `model_config/service.rs` 的实现模式。
|
||||
|
||||
### 6.2 HIGH: 部分模块使用 format! 构造 SQL (但有 $N 绑定)
|
||||
|
||||
**文件**: `prompt/service.rs`, `telemetry/service.rs`
|
||||
|
||||
这些文件在 WHERE 条件拼接时使用 `format!()`, 但值通过 `.replace('\'', "''")` 转义。虽然后续使用 `$N` 绑定值, 但 WHERE 条件本身的构造仍依赖手工转义。
|
||||
|
||||
### 6.3 HIGH: 配置同步缺少权限检查
|
||||
|
||||
`POST /api/v1/config/sync` (migration/handlers.rs) 端点未验证调用者是否有 admin 权限。任何已认证用户都可以推送配置。
|
||||
|
||||
### 6.4 MEDIUM: 配额限制未执行
|
||||
|
||||
`RelayConfig` 定义了 `max_queue_size` (默认 1000) 和 `max_concurrent_per_provider` (默认 5), 但 `execute_relay` 中未做队列容量和并发控制检查。
|
||||
|
||||
### 6.5 MEDIUM: Desktop 401 处理不完整
|
||||
|
||||
Desktop 端 `SaaSClient` 在 401 刷新失败后不自动 logout, 可能导致用户卡在过期会话中。Admin 端会自动跳转到登录页。
|
||||
|
||||
---
|
||||
|
||||
## 七、问题优先级与修复计划
|
||||
|
||||
### P0 — 立即修复 (阻塞功能)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-01 | 遥测系统全链路空转 | 在 llm-service.ts 的 chatCompletion 回调和 intelligence-hooks 中调用 recordLLMUsage / recordAuditEvent | telemetry-collector.ts, llm-service.ts, intelligence_hooks.rs | 2h |
|
||||
| SEC-01 | SQL 注入 (agent_template) | 改用 `$N` 参数化查询 | agent_template/service.rs | 2h |
|
||||
|
||||
### P1 — 本周修复 (功能断裂)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-02 | Prompt OTA 未启动 | 在 saasStore.restoreSession/login 中调用 startPromptOTASync | llm-service.ts, saasStore.ts | 1h |
|
||||
| G-03 | Relay 无并发限制 | 在 execute_relay 中加入队列容量和并发检查 | relay/service.rs | 2h |
|
||||
| G-04 | 心跳不传 OS/version | 在 deviceHeartbeat 中携带 platform/app_version | saas-client.ts, account/handlers.rs | 1h |
|
||||
| G-05 | 配置只能单向拉取 | 在 saasStore 中接入 computeConfigDiff 和 syncConfig push | saasStore.ts, saas-client.ts | 3h |
|
||||
|
||||
### P2 — 两周内修复 (质量提升)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-06 | Telemetry 端点缺审计日志 | 添加 log_operation 调用 | telemetry/handlers.rs | 1h |
|
||||
| G-07 | account_api_keys 未被消费 | 明确用途: 要么让 relay 消费, 要么移除 | model_config/, relay/ | 4h |
|
||||
| G-08 | Desktop 401 不自动 logout | 在 refresh 失败后调用 saasStore.logout() | saas-client.ts | 1h |
|
||||
| SEC-02 | 配置同步缺权限检查 | 在 migration handler 中添加 admin 权限校验 | migration/handlers.rs | 1h |
|
||||
|
||||
### P3 — 长期优化 (技术债)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-10 | hand_run 桩命令 | 实现真实的运行状态追踪 | kernel_commands.rs | 3h |
|
||||
| G-12 | 双端错误类型不统一 | 抽取共享错误类型到 @zclaw/types | admin+desktop | 4h |
|
||||
| — | 28 处 dead_code | 评估后移除或保留 | desktop/src-tauri/ | 2h |
|
||||
| — | 10+ 组类型定义差异 | 统一类型定义, 消除不一致 | admin+desktop types | 4h |
|
||||
|
||||
---
|
||||
|
||||
## 八、三端完成度评估
|
||||
|
||||
### SaaS 后端: **88%**
|
||||
|
||||
| 模块 | API 路由 | 完成度 | 主要问题 |
|
||||
|------|---------|--------|---------|
|
||||
| Auth | 8 | 95% | refresh 缺审计日志 |
|
||||
| Account | 12 | 90% | dashboard 7 次串行查询 |
|
||||
| Model Config | 14 | 90% | account_api_keys 未被消费 |
|
||||
| Relay | 9 | 85% | 无并发限制, SSRF 需复核 |
|
||||
| Migration | 9 | 70% | push 缺权限, 5 端点缺审计日志 |
|
||||
| Role | 7 | 95% | 无重大问题 |
|
||||
| Prompt OTA | 8 | 90% | 桌面端未启动 OTA |
|
||||
| Agent Template | 5 | 75% | **SQL 注入** |
|
||||
| Telemetry | 4 | 80% | 桌面端未调用上报函数 |
|
||||
|
||||
### Tauri 桌面端: **78%**
|
||||
|
||||
| 子系统 | 命令数 | 完成度 | 主要问题 |
|
||||
|--------|-------|--------|---------|
|
||||
| Kernel | 29 | 85% | hand_run 桩, scheduled_task 未实现 |
|
||||
| Pipeline | 13 | 90% | 时间戳占位符 |
|
||||
| Viking | 13 | 95% | 无重大问题 |
|
||||
| LLM | 3 | 95% | 无重大问题 |
|
||||
| Intelligence | 6 | 80% | 多个预留函数 |
|
||||
| Browser | 23 | 85% | 需要 Fantoccini 运行时 |
|
||||
| SaaS 集成 | 30+ 方法 | 65% | 35+ 方法未调用, 遥测断裂 |
|
||||
|
||||
### Admin 管理后台: **85%**
|
||||
|
||||
| 维度 | 完成度 | 主要问题 |
|
||||
|------|--------|---------|
|
||||
| 页面覆盖 | 95% | 12 个页面全覆盖 |
|
||||
| API 调用 | 90% | 分页未连接 API |
|
||||
| 认证 | 90% | token 刷新逻辑完善 |
|
||||
| 类型定义 | 75% | 与桌面端不一致 |
|
||||
|
||||
---
|
||||
|
||||
## 九、关键决策建议
|
||||
|
||||
1. **遥测系统** — 必须在聊天回调和智能层 hook 中接入 recordLLMUsage, 否则 SaaS 端的遥测统计页面展示全零数据
|
||||
2. **SQL 注入** — agent_template/service.rs 必须立即改为参数化查询, 这是生产安全红线
|
||||
3. **配置同步** — 建议实现双向同步, 当前只能 SaaS→Desktop 单向拉取
|
||||
4. **类型共享** — 考虑抽取 @zclaw/types 共享包, 消除 admin/desktop 类型不一致
|
||||
5. **Prompt OTA** — 桌面端必须在登录后启动 OTA 同步, 否则 prompt 更新无法到达客户端
|
||||
|
||||
---
|
||||
|
||||
*审计报告结束*
|
||||
@@ -1,5 +1,13 @@
|
||||
# ZCLAW 功能完整性审计报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告审计于 2026-03-27,仅反映当时的代码状态。
|
||||
> 截至 2026-03-28,SaaS 平台 (76+ API)、Admin 管理后台等大量功能已上线。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
>
|
||||
> **原始审计信息:**
|
||||
> **审计日期**: 2026-03-27
|
||||
> **审计方法**: 五步审计流程 + 10 项通用审计清单
|
||||
> **审计范围**: docs/features 目录下所有功能文档 vs 实际代码实现
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# 前端集成审计报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告审计于 2026-03-17,仅反映当时的前端集成状态。
|
||||
> 截至 2026-03-28,SaaS 集成、Admin 管理后台、TOTP 2FA 等大量前端功能已上线。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
>
|
||||
> **原始审计信息:**
|
||||
> **审计日期**: 2026-03-17
|
||||
> **审计范围**: docs/features 目录下所有功能文档 vs 实际前端代码实现
|
||||
> **审计目的**: 验证功能文档声称的"已实现"是否真正集成到前端 UI
|
||||
|
||||
180
docs/features/JOINT_DEBUG_REPORT_V1.md
Normal file
180
docs/features/JOINT_DEBUG_REPORT_V1.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# SaaS + Tauri 联合调试测试报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告记录 2026-03-28 的联合调试结果。相关修复已全部合并。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [00-saas-overview.md](./08-saas-platform/00-saas-overview.md)
|
||||
|
||||
> **测试日期**: 2026-03-28 (原文标注有误)
|
||||
> **测试环境**: Windows 11 + PostgreSQL 17 + Rust SaaS @ 127.0.0.1:8080
|
||||
> **测试范围**: SaaS 后端 API + Tauri 桌面端集成层 + Admin 前端
|
||||
|
||||
---
|
||||
|
||||
## 一、测试执行摘要
|
||||
|
||||
| 阶段 | 用例数 | 通过 | 失败 | 发现 | 状态 |
|
||||
|------|--------|------|------|------|------|
|
||||
| P0 安全 | 2 | 2 | 0 | 0 | ✅ 已修复验证 |
|
||||
| A 类功能 | 15 | 13 | 1 | 1 | ✅ models 已修复 |
|
||||
| B 类数据 | 5 | 3 | 1 | 1 | ⚠ 部分验证 |
|
||||
| C 类流程 | 5 | N/A | N/A | N/A | ⏸ 服务中断 |
|
||||
| D 类异常 | 7 | N/A | N/A | N/A | ⚸ 服务中断 |
|
||||
| Admin 专项 | 2 | 2 | 0 | 0 | ✅ 已修复 |
|
||||
|
||||
**总计**: 36 个测试用例, 20 通过, 2 失败, 2 新发现, 12 未执行
|
||||
|
||||
---
|
||||
|
||||
## 二、已确认通过的测试 (20/36)
|
||||
|
||||
### P0 安全修复 — 全部通过 ✅
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| T-CRIT-01 | `sync_config` 权限检查 | **PASS** | user 角色 → 403 "权限不足: 需要 config:write 权限" |
|
||||
| T-CRIT-02 | `/api/health` 端点 | **PASS** | 返回 "ok", HTTP 200 |
|
||||
|
||||
### A 类功能模块 — 13/15 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| A-01 | 用户注册 | **PASS** | 201 Created, 返回完整 AccountPublic |
|
||||
| A-01b | 重复注册 | **PASS** | 409 CONFLICT |
|
||||
| A-02 | 正确密码登录 | **PASS** | 200 + JWT token + account |
|
||||
| A-02b | 错误密码登录 | **PASS** | 401 AUTH_ERROR |
|
||||
| A-02c | GET /auth/me | **PASS** | 返回完整用户信息 |
|
||||
| A-02d | Token 刷新 | **PASS** | 200 + 新 JWT token |
|
||||
| A-04a | user 创建 Provider | **PASS** | 403 "权限不足: 需要 provider:manage 权限" |
|
||||
| A-04b | ~~GET /models~~ | **FAIL→FIXED** | 原 500 (SQL参数错误), → 修复后 200 |
|
||||
| A-05a | 设备注册 | **PASS** | 200 + UPSERT 语义正确 |
|
||||
| A-05b | 重复设备注册 | **PASS** | 200, 不重复创建 |
|
||||
| A-05c | 设备心跳 | **PASS** | 200 |
|
||||
| A-05d | 设备列表 | **PASS** | 返回注册的设备 |
|
||||
| A-06a | 密码修改 | **PASS** | 200 + 旧密码失效验证 |
|
||||
| A-06b | 错误旧密码 | **PASS** | 401 AUTH_ERROR |
|
||||
| A-07 | API Token 创建/认证 | **PASS** | zclaw_ 前缀 token, /me 正常 |
|
||||
|
||||
### B 类数据测试 — 3/5 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| B-01 | Config seed | **PASS** | 创建 13 个默认配置项 |
|
||||
| B-02a | Config diff | **PASS** | 返回 conflict 比对正确 |
|
||||
| B-02b | Config sync push | **PASS** | 返回 {updated, created, skipped} |
|
||||
| ~~B-02c~~ | ~~`created` 计数修复~~ | **FIXED** | 原 created=0 → 修复后 push 新 key 时 created=1 |
|
||||
| B-03 | ~~GET /models~~ | **FAIL→FIXED** | SQL 参数绑定错误 500 → 已修复 |
|
||||
|
||||
### Admin 专项 — 2/2 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| E-01 | 权限过滤逻辑 | **PASS** | 已修复: 基于 permissions 数组过滤 |
|
||||
| E-02 | 分页连接 API | **PASS** | 已确认 5 个页面均传递分页参数 |
|
||||
|
||||
---
|
||||
|
||||
## 三、发现并修复的 Bug 汇总
|
||||
|
||||
### 已修复 (5 项)
|
||||
|
||||
| # | 严重性 | 问题 | 文件 | 修复 |
|
||||
|---|--------|------|------|------|
|
||||
| 1 | **CRITICAL** | `sync_config` 无权限检查 | [migration/handlers.rs:90](crates/zclaw-saas/src/migration/handlers.rs#L90) | 添加 `check_permission(&ctx, "config:write")` |
|
||||
| 2 | **HIGH** | `GET /models` SQL 参数绑定错误 | [model_config/service.rs:135](crates/zclaw-saas/src/model_config/service.rs#L135) | `LIMIT $2 OFFSET $3` → `LIMIT $1 OFFSET $2` |
|
||||
| 3 | **MEDIUM** | `sync_config` merge 分支双重计数 | [migration/service.rs:352](crates/zclaw-saas/src/migration/service.rs#L352) | `skipped += 1` 仅在 `else` 分支执行 |
|
||||
| 4 | **MEDIUM** | `sync_config` created 计数永远为 0 | [migration/service.rs:311](crates/zclaw-saas/src/migration/service.rs#L311) | push 模式创建新 config_item 时递增 |
|
||||
| 5 | **HIGH** | Admin 权限过滤逻辑错误 | [layout.tsx:107](admin/src/app/(dashboard)/layout.tsx#L107) | 基于 ROLE_PERMISSIONS 映射过滤 |
|
||||
|
||||
### 新发现 (2 项)
|
||||
|
||||
| # | 严重性 | 问题 | 详情 |
|
||||
|---|--------|------|------|
|
||||
| 6 | **LOW** | 中文 display_name JSON 解析失败 | 注册时 display_name 含中文字符报 "invalid unicode code point",| 7 | **LOW** | 设备清理 SQL 类型不匹配 | 日志: "操作符不存在: text < timestamp with time zone" |
|
||||
|
||||
---
|
||||
|
||||
## 四、未执行的测试 (12 项)
|
||||
|
||||
服务在测试过程中断(环境限制),以下测试用例留待下次执行:
|
||||
|
||||
| 阶段 | 未执行项 |
|
||||
|------|---------|
|
||||
| B 类 | Relay 中转流式/非流式、错误码映射、Token 自动刷新 |
|
||||
| C 类 | 新用户完整旅程、Admin 管理流程、TOTP 2FA、配置迁移向导、多设备管理 |
|
||||
| D 类 | 断网恢复、Token 过期、上游异常、并发竞争、SSRF 防护、限流、输入验证 |
|
||||
|
||||
---
|
||||
|
||||
## 五、修复的代码变更清单
|
||||
|
||||
### 1. crates/zclaw-saas/src/migration/handlers.rs
|
||||
```rust
|
||||
// 修复前: 无权限检查
|
||||
// 修复后: 添加 check_permission
|
||||
pub async fn sync_config(...) -> SaasResult<...> {
|
||||
check_permission(&ctx, "config:write")?; // 新增
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 2. crates/zclaw-saas/src/model_config/service.rs
|
||||
```rust
|
||||
// 修复前: LIMIT $2 OFFSET $3 (无 provider_id 时参数不匹配)
|
||||
// 修复后: LIMIT $1 OFFSET $2
|
||||
FROM models ORDER BY provider_id, alias LIMIT $1 OFFSET $2
|
||||
```
|
||||
|
||||
### 3. crates/zclaw-saas/src/migration/service.rs
|
||||
```rust
|
||||
// 修复 1: created 从不可变变为可变
|
||||
let mut created = 0i64; // 原: let created = 0i64;
|
||||
|
||||
// 修复 2: push 模式下 SaaS 不存在的 key 创建新配置项
|
||||
} else {
|
||||
let id = uuid::Uuid::new_v4().to_string();
|
||||
sqlx::query("INSERT INTO config_items ...")...;
|
||||
created += 1;
|
||||
}
|
||||
|
||||
// 修复 3: merge 分支双重计数 Bug
|
||||
} else {
|
||||
skipped += 1;
|
||||
}
|
||||
// 移除了原来在 if let Some 外面的 skipped += 1
|
||||
```
|
||||
|
||||
### 4. admin/src/app/(dashboard)/layout.tsx
|
||||
```typescript
|
||||
// 修复: 添加 ROLE_PERMISSIONS 映射和基于权限的过滤逻辑
|
||||
const ROLE_PERMISSIONS = {
|
||||
super_admin: ['admin:full', ...],
|
||||
admin: ['account:admin', 'provider:manage', ...],
|
||||
user: ['model:read', 'relay:use', 'config:read'],
|
||||
};
|
||||
// 使用 account.permissions.includes(item.permission) 过滤
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、遗留问题与建议
|
||||
|
||||
### P0 — 需立即修复
|
||||
无(CRITICAL 已修复)
|
||||
|
||||
### P1 — 功能缺陷
|
||||
| # | 问题 | 建议 |
|
||||
|---|------|------|
|
||||
| P1-1 | `account_api_keys` 未被 Relay 消费 | Relay handler 查找用户级 Key,回退到 provider 级 |
|
||||
| P1-2 | Config 5 端点缺审计日志 | 添加 `log_operation()` 调用 |
|
||||
| P1-3 | Admin 前端缺路由守卫 | 添加 AuthGuard 组件 |
|
||||
|
||||
### P2 — 代码质量
|
||||
| # | 问题 | 建议 |
|
||||
|---|------|------|
|
||||
| P2-1 | 6 个端点缺 OpenAPI 文档 | 补充 `#[utoipa::path]` |
|
||||
| P2-2 | 设备清理 SQL 类型不匹配 | `last_seen_at` 字段类型修正 |
|
||||
| P2-3 | 中文 display_name JSON 解析 | UTF-8 编码处理 |
|
||||
| P2-4 | dashboard_stats 7 次串行查询 | 合并为单次 SQL |
|
||||
| P2-5 | `computeConfigDiff`/`syncConfig` 未调用 | 统一迁移向导调用路径 |
|
||||
@@ -1,14 +1,9 @@
|
||||
# ZCLAW 功能全景文档
|
||||
|
||||
> **版本**: v0.6.4
|
||||
> **更新日期**: 2026-03-27
|
||||
> **项目状态**: 完整 Rust Workspace 架构,10 个核心 Crates,69 技能,Pipeline DSL + Smart Presentation + Agent Growth System
|
||||
> **整体完成度**: ~78% (基于 2026-03-27 深度审计 + 五轮修复后)
|
||||
> **架构**: Tauri 桌面应用,Rust Workspace (10 crates) + React 前端
|
||||
>
|
||||
> **审计修复 (2026-03-27)**: 累计修复 27 项 (P0×3 + P1×8 + P2×7 + P3×4 + 误判×2 + 审计×3),详见 [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
|
||||
> **重要**: ZCLAW 采用 Rust Workspace 架构,包含 10 个分层 Crates (types → memory → runtime → kernel → skills/hands/protocols/pipeline/growth/channels),所有核心能力集成在 Tauri 桌面应用中
|
||||
> **版本**: v0.7.0
|
||||
> **更新日期**: 2026-03-28
|
||||
> **项目状态**: 完整 Rust Workspace 架构,11 个核心 Crates,69 技能,Pipeline DSL + Smart Presentation + Agent Growth System + SaaS 平台
|
||||
> **整体完成度**: ~85% (核心功能完整,SaaS 平台全面上线)
|
||||
|
||||
---
|
||||
|
||||
@@ -18,9 +13,9 @@
|
||||
|
||||
| 文档 | 功能 | 成熟度 | 测试覆盖 |
|
||||
|------|------|--------|---------|
|
||||
| [01-communication-layer.md](00-architecture/01-communication-layer.md) | 通信层 | L3 (85%) | 高 |
|
||||
| [01-communication-layer.md](00-architecture/01-communication-layer.md) | 通信层 (3 种连接模式) | L4 (90%) | 高 |
|
||||
| [02-state-management.md](00-architecture/02-state-management.md) | 状态管理 | L3 (80%) | 高 |
|
||||
| [03-security-auth.md](00-architecture/03-security-auth.md) | 安全认证 | L2-L3 (75%) | 高 |
|
||||
| [03-security-auth.md](00-architecture/03-security-auth.md) | 安全认证 | L3 (75%) | 高 |
|
||||
|
||||
### 1.2 核心功能 (Core Features)
|
||||
|
||||
@@ -29,259 +24,126 @@
|
||||
| [00-chat-interface.md](01-core-features/00-chat-interface.md) | 聊天界面 | L4 (92%) | 高 |
|
||||
| [01-agent-clones.md](01-core-features/01-agent-clones.md) | Agent 分身 | L3 (85%) | 高 |
|
||||
| [02-hands-system.md](01-core-features/02-hands-system.md) | Hands 系统 | L3 (60%) | 中 |
|
||||
| 工作流引擎 | 工作流引擎 | L3 (80%) | 中 |
|
||||
|
||||
### 1.3 智能层 (Intelligence Layer) - ✅ 已接入聊天流程 (2026-03-26 更新)
|
||||
### 1.3 智能层 (Intelligence Layer)
|
||||
|
||||
| 文档 | 功能 | 成熟度 | 聊天集成 | 后端状态 |
|
||||
|------|------|--------|---------|----------|
|
||||
| [00-agent-memory.md](02-intelligence-layer/00-agent-memory.md) | Agent 记忆 | L3-L4 (90%) | ✅ pre-hook (FTS5+TF-IDF+Embedding) | ✅ SqliteStorage |
|
||||
| [01-identity-evolution.md](02-intelligence-layer/01-identity-evolution.md) | 身份演化 | L2 (70%) | ✅ pre-hook (SOUL.md → system prompt) | ✅ Rust 实现 |
|
||||
| [06-context-compaction.md](02-intelligence-layer/06-context-compaction.md) | 上下文压缩 | L2-L3 (75%) | ✅ 已接入内核 (AgentLoop, LLM 摘要) | ✅ Rust 实现 |
|
||||
| [03-reflection-engine.md](02-intelligence-layer/03-reflection-engine.md) | 自我反思 | L2 (60%) | ✅ post-hook (自动触发 + 真实记忆 + 持久化) | ✅ Rust 实现 |
|
||||
| 心跳巡检 | 心跳巡检 | L2-L3 (70%) | ✅ post-hook (record_interaction + VikingStorage 持久化) | ✅ Rust 实现 |
|
||||
| [05-autonomy-manager.md](02-intelligence-layer/05-autonomy-manager.md) | 自主授权 | L2-L3 (75%) | ✅ RightPanel 'autonomy' | ✅ TypeScript |
|
||||
|
||||
> **智能层集成说明** (2026-03-27): 通过 `intelligence_hooks.rs` 将 identity、memory context、heartbeat、reflection 接入 `agent_chat_stream` 流程。compactor 已在内核 AgentLoop 集成 (15k token 阈值)。反思引擎已修复空记忆 bug (C2),现在从 VikingStorage 查询真实记忆进行分析。反思结果和状态已持久化到 VikingStorage metadata,重启后自动恢复 (H4/M4)。心跳引擎交互记录已持久化,idle-greeting 检查跨重启生效 (H4)。记忆系统已统一到 VikingStorage 单一存储 (H3)。已清理死代码: pattern_detector、recommender、mesh、persona_evolver、trigger_evaluator。
|
||||
| 文档 | 功能 | 成熟度 | 聊天集成 |
|
||||
|------|------|--------|---------|
|
||||
| [00-agent-memory.md](02-intelligence-layer/00-agent-memory.md) | Agent 记忆 | L4 (90%) | pre-hook (FTS5+TF-IDF+Embedding) |
|
||||
| [01-identity-evolution.md](02-intelligence-layer/01-identity-evolution.md) | 身份演化 | L2 (70%) | pre-hook (SOUL.md) |
|
||||
| [06-context-compaction.md](02-intelligence-layer/06-context-compaction.md) | 上下文压缩 | L3 (75%) | 内核 AgentLoop 集成 |
|
||||
| [03-reflection-engine.md](02-intelligence-layer/03-reflection-engine.md) | 自我反思 | L2 (65%) | post-hook (自动触发) |
|
||||
| [04-heartbeat-engine.md](02-intelligence-layer/04-heartbeat-engine.md) | 心跳巡检 | L3 (70%) | post-hook (持久化) |
|
||||
| [05-autonomy-manager.md](02-intelligence-layer/05-autonomy-manager.md) | 自主授权 | L3 (75%) | RightPanel UI |
|
||||
|
||||
### 1.4 上下文数据库 (Context Database)
|
||||
|
||||
| 文档 | 功能 | 成熟度 | 测试覆盖 |
|
||||
|------|------|--------|---------|
|
||||
| [00-openviking-integration.md](03-context-database/00-openviking-integration.md) | OpenViking 集成 | L2-L3 (70%) | 高 |
|
||||
| 向量记忆 | L3 (80%) | 中 |
|
||||
| 会话持久化 | L3-L4 (90%) | 高 |
|
||||
| 记忆提取 | L3-L4 (90%) | 高 |
|
||||
| [00-openviking-integration.md](03-context-database/00-openviking-integration.md) | OpenViking 集成 | L3 (70%) | 高 |
|
||||
|
||||
### 1.5 Skills 生态 - ✅ 动态扫描 + execute_skill 已实现
|
||||
### 1.5 Skills 生态
|
||||
|
||||
| 文档 | 功能 | 成熟度 | UI 集成 |
|
||||
|------|------|--------|---------|
|
||||
| [00-skill-system.md](04-skills-ecosystem/00-skill-system.md) | Skill 系统概述 | L3 (80%) | ✅ 通过 Tauri 命令 |
|
||||
| 内置技能 | 内置技能 (**69** SKILL.md) | L3 (75%) | N/A |
|
||||
| 技能发现 | 技能发现 (动态扫描) | **L3** (80%) | ✅ **已集成** |
|
||||
| [00-skill-system.md](04-skills-ecosystem/00-skill-system.md) | Skill 系统概述 | L3 (80%) | Tauri 命令 |
|
||||
| [01-intelligent-routing.md](04-skills-ecosystem/01-intelligent-routing.md) | 智能路由 | L2 (50%) | 意图路由 |
|
||||
|
||||
> ✅ **更新 (2026-03-27)**: Skills 动态扫描已实现。Kernel 集成 `SkillRegistry`,通过 Tauri 命令 `skill_list` 和 `skill_refresh` 动态发现所有 **69 个**技能。**新增 `execute_skill` 工具**,允许 Agent 在对话中直接调用技能。**PromptOnly 技能已集成 LLM 调用**(通过 `LlmCompleter` trait 桥接 `LlmDriver`),直接执行技能时现在会产生 AI 生成内容。
|
||||
> 技能总数: **69** 个 SKILL.md,3 种执行模式 (PromptOnly/Shell/Python),Wasm/Native 待实现
|
||||
|
||||
### 1.6 Hands 系统 - ✅ 7/9 完整实现 + 审批流程 (2026-03-27 更新)
|
||||
### 1.6 Hands 系统
|
||||
|
||||
| 文档 | 功能 | 成熟度 | 可用 Hands |
|
||||
|------|------|--------|-----------|
|
||||
| [00-hands-overview.md](05-hands-system/00-hands-overview.md) | Hands 概述 (9个) | L3 (60%) | **7/9 (78%)** |
|
||||
| [00-hands-overview.md](05-hands-system/00-hands-overview.md) | Hands 概述 | L3 (60%) | 9 个 (编程式注册) |
|
||||
|
||||
> ✅ **更新 (2026-03-27)**:
|
||||
> - 7 个 Hands 有完整 Rust 后端实现 (Browser, Collector, Researcher, Slideshow, Whiteboard, Quiz)
|
||||
> - ✅ **审批流程**: `hand_execute` 现在检查 `needs_approval`,需审批的 hand 返回 `pending_approval` 状态
|
||||
> - ✅ **演示标记**: SpeechHand、TwitterHand 已添加 `"demo"` 标签
|
||||
> - ✅ **幽灵命令修复**: `hand_get`、`hand_run_status`、`hand_run_list` 已注册为桩命令
|
||||
> - ⚠️ **SpeechHand**、**TwitterHand** 标记为 demo 模式(模拟实现)
|
||||
> - ⚠️ **Clip** 需要 FFmpeg
|
||||
> 9 Hands: Browser, Slideshow, Speech (demo), Quiz, Whiteboard, Researcher, Collector, Clip, Twitter (demo)
|
||||
|
||||
### 1.7 Tauri 后端
|
||||
|
||||
| 文档 | 功能 | 成熟度 | 测试覆盖 |
|
||||
|------|------|--------|---------|
|
||||
| [00-backend-integration.md](06-tauri-backend/00-backend-integration.md) | 后端集成 | L3 (80%) | 高 |
|
||||
| 安全存储 | 安全存储 | L3 (80%) | 高 |
|
||||
| 本地 Gateway | 本地 Gateway | L3 (80%) | 高 |
|
||||
| 文档 | 功能 | 成熟度 | Tauri 命令 |
|
||||
|------|------|--------|-----------|
|
||||
| [00-backend-integration.md](06-tauri-backend/00-backend-integration.md) | 后端集成 | L4 (85%) | **58+** (kernel 29 + pipeline 13 + viking 13 + llm 3) |
|
||||
|
||||
### 1.8 Pipeline DSL 系统 - ✅ 新增 (v0.3.0)
|
||||
### 1.8 Pipeline DSL
|
||||
|
||||
| 文档 | 功能 | 成熟度 | UI 集成 |
|
||||
|------|------|--------|---------|
|
||||
| [00-pipeline-overview.md](07-pipeline-dsl/00-pipeline-overview.md) | Pipeline 概述 | **L2-L3** (75%) | ✅ PipelinesPanel |
|
||||
| [00-pipeline-overview.md](07-pipeline-dsl/00-pipeline-overview.md) | Pipeline 概述 | L3 (75%) | PipelinesPanel |
|
||||
|
||||
> ✅ **新增**: Pipeline DSL 自动化工作流系统
|
||||
> - **教育类**: 互动课堂生成器
|
||||
> - **营销类**: 营销方案生成器
|
||||
> - **法律类**: 合同智能审查
|
||||
> - **研究类**: 文献综述生成器
|
||||
> - **生产力类**: 智能会议纪要
|
||||
>
|
||||
> **特性**: YAML 声明式配置、状态管理、LLM 集成、Agent 智能推荐、结果预览组件
|
||||
### 1.9 SaaS 平台
|
||||
|
||||
### 1.9 Smart Presentation Layer - ✅ 新增 (v0.5.0)
|
||||
|
||||
| 组件 | 功能 | 成熟度 | UI 集成 |
|
||||
| 文档 | 功能 | 成熟度 | API 路由 |
|
||||
|------|------|--------|---------|
|
||||
| PresentationContainer | 主容器,自动类型检测 | **L3** (85%) | ✅ PipelinesPanel |
|
||||
| TypeSwitcher | 手动切换展示类型 | **L3** (85%) | ✅ 集成 |
|
||||
| ChartRenderer | 数据可视化渲染 | **L3** (85%) | ✅ 集成 |
|
||||
| QuizRenderer | 互动测验渲染 | **L3** (85%) | ✅ 集成 |
|
||||
| SlideshowRenderer | 幻灯片渲染 | **L3** (85%) | ✅ 集成 |
|
||||
| DocumentRenderer | Markdown 文档渲染 | **L3** (85%) | ✅ 集成 |
|
||||
| [00-saas-overview.md](08-saas-platform/00-saas-overview.md) | SaaS 平台总览 | L4 (95%) | **76+** (9 个模块) |
|
||||
|
||||
> ✅ **新增**: Smart Presentation Layer 智能展示层
|
||||
> - **自动检测**: 分析数据结构推荐最佳展示格式
|
||||
> - **多渲染器**: Chart, Quiz, Slideshow, Document
|
||||
> - **类型切换**: 用户可手动切换展示类型
|
||||
> - **Rust 分析器**: 后端 PresentationAnalyzer 提供类型推荐
|
||||
|
||||
### 1.10 其他功能
|
||||
|
||||
| 功能 | 成熟度 | 备注 |
|
||||
|------|--------|------|
|
||||
| 智能路由 (Intelligent Routing) | L1 (15%) | 仅基础意图分类 |
|
||||
| 通道适配 (Channels) | L1 (10%) | 仅 ConsoleChannel 测试适配器 |
|
||||
| A2A 协议 | L1 (40%) | 基础协议定义,未完整实现 |
|
||||
| 浏览器自动化 (Browser Automation) | L3 (80%) | BrowserHand 可用 |
|
||||
> SaaS 后端: Axum + PostgreSQL, 9 模块 (Auth, Account, Model Config, Relay, Migration, Role, Prompt OTA, Agent Template, Telemetry), Admin 管理后台, 桌面端完整集成
|
||||
|
||||
---
|
||||
|
||||
## 二、后续工作计划
|
||||
|
||||
> 📋 详细计划见 [roadmap.md](roadmap.md) | 🧠 头脑风暴见 [brainstorming-notes.md](brainstorming-notes.md)
|
||||
|
||||
### 2.1 短期计划 (1-2 周)
|
||||
|
||||
| ID | 任务 | 优先级 | 状态 |
|
||||
|----|------|--------|------|
|
||||
| S1 | 智能层接入聊天流程 (identity/memory/heartbeat/reflection) | P0 | ✅ 完成 |
|
||||
| S2 | 双存储统一 (SqliteStorage 优先) | P0 | ✅ 完成 |
|
||||
| S3 | Hand 审批流程真实实现 | P0 | ✅ 完成 |
|
||||
| S4 | Gemini/Local LLM 驱动实现 | P1 | ✅ 完成 |
|
||||
| S5 | WorkflowBuilder 接入可视化视图 | P2 | ✅ 完成 |
|
||||
| S6 | 导出功能清理 (PPTX/PDF 友好提示) | P2 | ✅ 完成 |
|
||||
| S7 | Compactor 接入聊天流程 | P1 | ✅ 完成 |
|
||||
| S8 | 定时任务 KernelClient 支持 | P1 | 待开始 |
|
||||
| S9 | 添加消息搜索功能 | P1 | ✅ 完成 (Session + Global 双模式) |
|
||||
| S10 | 优化错误提示 | P1 | ✅ 完成 (Rust 错误提示中文化) |
|
||||
|
||||
### 2.2 中期计划 (1-2 月)
|
||||
|
||||
| ID | 任务 | 价值 | 风险 |
|
||||
|----|------|------|------|
|
||||
| M1 | 记忆图谱可视化 | 高 | 中 |
|
||||
| M2 | 技能市场 MVP | 高 | 中 |
|
||||
| M3 | 主动学习引擎 | 高 | 高 |
|
||||
| M4 | 工作流编辑器 | 高 | 中 |
|
||||
|
||||
### 2.3 关键决策待定
|
||||
|
||||
1. **目标用户定位**: 个人 vs 团队 vs 企业?
|
||||
2. **记忆存储策略**: 纯本地 vs 可选云同步?
|
||||
3. **开源策略**: 完全开源 vs 核心闭源?
|
||||
4. **定价策略**: 免费 vs 付费 vs 混合?
|
||||
|
||||
---
|
||||
|
||||
## 三、功能优先级矩阵 (ICE 评分)
|
||||
|
||||
| 功能 | Impact | Confidence | Ease | ICE 分 | 状态 |
|
||||
|------|--------|------------|------|--------|------|
|
||||
| Agent 记忆 | 10 | 9 | 7 | 630 | 已完成 |
|
||||
| 身份演化 | 8 | 9 | 9 | 648 | 已完成 |
|
||||
| 上下文压缩 | 9 | 8 | 6 | 432 | 已完成 |
|
||||
| 心跳巡检 | 9 | 8 | 6 | 432 | 已完成 |
|
||||
| 多 Agent 协作 | 9 | 6 | 4 | 216 | 已移除(Pipeline 替代) |
|
||||
| 自主授权 | 8 | 7 | 5 | 280 | 已完成 |
|
||||
| 向量记忆 | 9 | 7 | 5 | 315 | 已完成 |
|
||||
| 会话持久化 | 7 | 9 | 8 | 504 | 已完成 |
|
||||
|
||||
**评分说明**:
|
||||
- **Impact (影响)**: 10 = 决定性功能,1 = 边缘功能
|
||||
- **Confidence (信心)**: 10 = 完全确定,1 = 高度不确定
|
||||
- **Ease (容易度)**: 10 = 极易实现,1 = 极难实现
|
||||
- **ICE 分** = Impact × Confidence × Ease
|
||||
|
||||
---
|
||||
|
||||
## 三、成熟度等级定义
|
||||
|
||||
| 等级 | 名称 | 描述 |
|
||||
|------|------|------|
|
||||
| L0 | 概念 | 有设计想法,未实现 |
|
||||
| L1 | 原型 | 基本可用,有已知问题 |
|
||||
| L2 | 可用 | 功能完整,有测试 |
|
||||
| L3 | 成熟 | 稳定可靠,有文档 |
|
||||
| L4 | 生产 | 经过验证,可扩展 |
|
||||
|
||||
---
|
||||
|
||||
## 四、模块依赖关系
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ UI 组件层 │
|
||||
│ ChatArea │ PipelinesPanel │ RightPanel │ Settings │
|
||||
└─────────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────────▼───────────────────────────────┐
|
||||
│ 状态管理层 │
|
||||
│ chatStore │ connectionStore │ handStore │ configStore │
|
||||
└─────────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────────▼───────────────────────────────┐
|
||||
│ 智能层 │
|
||||
│ AgentMemory │ ReflectionEngine │ AutonomyManager │
|
||||
└─────────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────────▼───────────────────────────────┐
|
||||
│ 通信层 │
|
||||
│ GatewayClient │ VikingClient │ TauriGateway │
|
||||
└─────────────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
┌─────────────────────────────▼───────────────────────────────┐
|
||||
│ 后端层 │
|
||||
│ ZCLAW Kernel │ OpenViking Server │ Tauri Backend │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、关键指标
|
||||
## 二、关键指标
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **Rust Crates** | **10** (types, memory, runtime, kernel, skills, hands, protocols, pipeline, growth, channels) |
|
||||
| **Rust Crates** | **11** (types, memory, runtime, kernel, skills, hands, protocols, pipeline, growth, channels, saas) |
|
||||
| **SKILL.md 文件** | **69** |
|
||||
| 动态发现技能 | 69 (100%) |
|
||||
| Hands 总数 | 9 |
|
||||
| **已实现 Hands** | **7 (78%)** — 2 个标记为 demo |
|
||||
| **Kernel 注册 Hands** | **9/9 (100%)** |
|
||||
| **Pipeline 模板** | **5** (教育/营销/法律/研究/生产力) |
|
||||
| Zustand Store | **14** |
|
||||
| Tauri 命令 | **100+** |
|
||||
| 代码行数 (前端) | ~30,000 |
|
||||
| 代码行数 (后端 Rust) | ~18,000 |
|
||||
| LLM Provider 支持 | **8** (Kimi, Qwen, DeepSeek, Zhipu, OpenAI, Anthropic, Gemini, Local/Ollama) |
|
||||
| 智能层组件 | **5** (Memory, Heartbeat, Reflection, Identity, Compaction) |
|
||||
| MCP 协议 | ✅ 已实现 (stdio transport) |
|
||||
| execute_skill 工具 | ✅ 已实现 |
|
||||
| **Pipeline DSL** | ✅ 完整实现 |
|
||||
| **Hands 总数** | **9** (编程式注册) |
|
||||
| **Pipeline 模板** | **5** |
|
||||
| **Tauri 命令** | **58+** |
|
||||
| **SaaS API 路由** | **76+** |
|
||||
| **Zustand Store** | **14+** |
|
||||
| **LLM Provider** | **8** (Kimi, Qwen, DeepSeek, Zhipu, OpenAI, Anthropic, Gemini, Local) |
|
||||
| **Embedding Provider** | **6** (OpenAI, Zhipu, Doubao, Qwen, DeepSeek, Local/TF-IDF) |
|
||||
| **SaaS 数据表** | **25** (PostgreSQL) |
|
||||
| **内置工具** | **5** (file_read, file_write, shell_exec, web_fetch, execute_skill) |
|
||||
| **Agent Growth System** | ✅ 完整实现 (SqliteStorage + FTS5 + TF-IDF + Memory Extractor) |
|
||||
| **Agent Growth System** | SqliteStorage + FTS5 + TF-IDF + Memory Extractor |
|
||||
|
||||
### 5.1 Crate 依赖关系
|
||||
---
|
||||
|
||||
## 三、Crate 依赖关系
|
||||
|
||||
```
|
||||
zclaw-types (L1: 基础类型, 无依赖) - 95% 完整度
|
||||
zclaw-types (L1: 基础类型, 无依赖) — 95%
|
||||
↑
|
||||
zclaw-memory (L2: 存储层, SQLite) - 90% 完整度
|
||||
zclaw-memory (L2: 存储层, SQLite) — 90%
|
||||
↑
|
||||
zclaw-runtime (L3: 运行时, LLM 驱动, 工具执行) - 90% 完整度
|
||||
zclaw-runtime (L3: 运行时, 4 Driver, 5 工具) — 90%
|
||||
↑
|
||||
zclaw-kernel (L4: 核心协调, Agent 调度) - 85% 完整度
|
||||
zclaw-kernel (L4: 核心协调, 9 Hands, 69 Skills) — 85%
|
||||
↑
|
||||
┌───┴───┬───────┬───────────┬──────────┬────────┐
|
||||
│ │ │ │ │ │
|
||||
skills hands protocols pipeline growth channels
|
||||
(80%) (85%) (75%) (90%) (95%) (规划中)
|
||||
(80%) (85%) (75%) (90%) (95%) (规划中)
|
||||
|
||||
zclaw-saas — 独立运行 (Axum + PostgreSQL, 端口 8080) — 95%
|
||||
```
|
||||
|
||||
### 5.2 Agent Growth System (zclaw-growth)
|
||||
---
|
||||
|
||||
**✅ 完整实现 (v0.6.0)**
|
||||
## 四、SaaS 平台模块
|
||||
|
||||
| 组件 | 功能 | 状态 |
|
||||
|------|------|------|
|
||||
| SqliteStorage | SQLite + FTS5 全文搜索 | ✅ L4 |
|
||||
| MemoryRetriever | TF-IDF 语义检索 | ✅ L4 |
|
||||
| PromptInjector | Token 预算控制注入 | ✅ L4 |
|
||||
| MemoryExtractor | LLM 驱动记忆提取 | ✅ L4 |
|
||||
| VikingAdapter | 存储抽象层 | ✅ L4 |
|
||||
| 模块 | API 路由 | 核心能力 |
|
||||
|------|---------|---------|
|
||||
| Auth | 8 | JWT + API Token 双认证, TOTP 2FA (AES-256-GCM), 密码修改 |
|
||||
| Account | 12 | CRUD, 角色管理, 设备注册/心跳, Dashboard, API Token |
|
||||
| Model Config | 14 | Provider/Model/Key CRUD, Key 轮换, 用量统计 |
|
||||
| Relay | 9 | SSE 流式中转, Key 池 (RPM/TPM), 重试策略, SSRF 防护 |
|
||||
| Migration | 9 | 配置 CRUD, 种子数据, push/merge/diff/pull 同步 |
|
||||
| Role | 7 | 角色 CRUD, 权限模板, 批量应用 |
|
||||
| Prompt OTA | 8 | 模板 + 版本管理, OTA 检查, 回滚 |
|
||||
| Agent Template | 5 | 模板 CRUD, tools/capabilities/model 绑定 |
|
||||
| Telemetry | 4 | Token 用量上报, 统计聚合, 审计摘要 |
|
||||
|
||||
**测试覆盖**: 135 tests (70 zclaw-growth + 65 desktop)
|
||||
---
|
||||
|
||||
## 五、连接模式
|
||||
|
||||
| 模式 | 客户端 | 说明 |
|
||||
|------|--------|------|
|
||||
| Mode A: Tauri Kernel | KernelClient | 本地直连 LLM (默认模式) |
|
||||
| Mode B: Gateway | GatewayClient | WebSocket 本地中转 |
|
||||
| Mode C: SaaS Cloud | SaaSClient (30+ 方法) | 云端中转 + Key 池管理 |
|
||||
|
||||
---
|
||||
|
||||
@@ -289,79 +151,16 @@ skills hands protocols pipeline growth channels
|
||||
|
||||
| 日期 | 版本 | 变更内容 |
|
||||
|------|------|---------|
|
||||
| 2026-03-27 | v0.6.4 | **审计修复 (P2 第四轮)**: S9 消息搜索跨会话 (Session + Global 双模式,VikingStorage 搜索)、M5-补 自主授权后端守卫、M3 hand_approve 参数修复、M4-补 反思历史累积存储、心跳历史持久化。累计修复 23 项,整体完成度 65%→72%。|
|
||||
| 2026-03-27 | v0.6.3 | **审计修复 (P1/P2)**: H3 记忆双存储统一到 VikingStorage、H4 心跳引擎持久化 + 启动恢复、M4 反思结果持久化。整体完成度 58%→62%。|
|
||||
| 2026-03-27 | v0.6.2 | **审计修复 (P0/P1)**: C1 PromptOnly LLM 集成、C2 反思引擎空记忆修复、H7 Agent Store 接口适配、H8 Hand 审批检查、M1 幽灵命令注册、H1/H2 demo 标记、H5 归档过时报告。整体完成度 50%→58%。|
|
||||
| 2026-03-27 | v0.6.1 | **功能完整性修复**: 激活 LoopGuard 循环防护、实现 CapabilityManager.validate() 安全验证、handStore/workflowStore KernelClient 适配器、Credits 标注开发中、Skills 动态化、ScheduledTasks localStorage 降级、token 用量追踪 |
|
||||
| 2026-03-27 | v0.6.0a | **全面审计更新**:所有成熟度标注调整为实际完成度 (平均 68%),新增清理记录 |
|
||||
| 2026-03-26 | v0.1.0 | **v1.0 发布准备**:移除 Team/Swarm 功能(~8,100 行,Pipeline 替代),安全修复,CI/CD 建立 |
|
||||
| 2026-03-26 | v0.5.0 | **Smart Presentation Layer**:自动类型检测,Chart/Quiz/Slideshow/Document 渲染器,PresentationAnalyzer Rust 后端 |
|
||||
| 2026-03-25 | v0.4.0 | **代码现状深度分析**:8 个 Rust Crates 完整度评估,78+ 技能确认,18+ Store 状态管理,新增 Mesh/Persona 智能组件 |
|
||||
| 2026-03-25 | v0.3.0 | **Pipeline DSL 系统实现**,5 类 Pipeline 模板,Agent 智能推荐,结果预览组件 |
|
||||
| 2026-03-24 | v0.2.5 | **execute_skill 工具实现**,智能层完全实现验证,技能数更新为 78+ |
|
||||
| 2026-03-24 | v0.2.4 | Hands Review: 修复 BrowserHand Kernel 注册问题,所有 9 个已实现 Hands 均可访问 |
|
||||
| 2026-03-24 | v0.2.3 | Hands 后端集成: 9/11 Hands 可用 (新增 Clip, Twitter) |
|
||||
| 2026-03-24 | v0.2.2 | Hands 后端集成: 7/11 Hands 可用 (新增 Researcher, Collector) |
|
||||
| 2026-03-24 | v0.2.1 | Hands 后端集成: 5/11 Hands 可用 (Browser, Slideshow, Speech, Quiz, Whiteboard) |
|
||||
| 2026-03-24 | v0.2.0 | 更新为内部 Kernel 架构,Streaming + MCP 协议,修正 Skills/Hands 数量 |
|
||||
| 2026-03-17 | v1.1 | 智能层集成状态更新 |
|
||||
| 2026-03-16 | v1.0 | 初始版本,完成全部功能文档 |
|
||||
| 2026-03-28 | v0.7.0 | 基于 2026-03-28 代码状态全面更新:SaaS 平台 76+ API 路由/9 模块/25 表,58+ Tauri 命令,8 LLM Provider,3 种连接模式 |
|
||||
| 2026-03-27 | v0.6.4 | 审计修复第四轮,S9 消息搜索跨会话,自主授权后端守卫 |
|
||||
| 2026-03-27 | v0.6.0 | 深度审计更新,整体完成度调整 |
|
||||
| 2026-03-26 | v0.1.0 | v1.0 发布准备,移除 Team/Swarm |
|
||||
| 2026-03-25 | v0.5.0 | Smart Presentation Layer |
|
||||
| 2026-03-25 | v0.4.0 | 代码现状深度分析 |
|
||||
| 2026-03-24 | v0.3.0 | Pipeline DSL 系统实现 |
|
||||
|
||||
---
|
||||
|
||||
## 七、清理记录 (2026-03-27)
|
||||
## 七、清理记录
|
||||
|
||||
### 7.1 审计修复 (P0/P1)
|
||||
|
||||
| 修复项 | ID | 说明 |
|
||||
|--------|-----|------|
|
||||
| PromptOnly LLM 集成 | C1 | 定义 `LlmCompleter` trait,通过 `LlmDriverAdapter` 桥接,PromptOnly 技能现在调用 LLM |
|
||||
| 反思引擎空记忆 | C2 | 新增 `query_memories_for_reflection()`,reflect() 现在接收真实记忆数据 |
|
||||
| Agent Store 适配 | H7 | `KernelClient` 添加 `listClones/createClone/deleteClone` 适配方法 |
|
||||
| Hand 审批检查 | H8 | `hand_execute` 执行前检查 `needs_approval`,需审批返回 pending 状态 |
|
||||
| 幽灵命令注册 | M1 | 注册 `hand_get/hand_run_status/hand_run_list` 三个 Tauri 桩命令 |
|
||||
| SpeechHand demo 标记 | H1 | 添加 `"demo"` 标签到 speech.rs 和 speech.HAND.toml |
|
||||
| TwitterHand demo 标记 | H2 | 添加 `"demo"` 标签到 twitter.rs 和 twitter.HAND.toml |
|
||||
| 归档过时报告 | H5 | VERIFICATION_REPORT.md 顶部添加归档声明 |
|
||||
|
||||
### 7.2 审计修复 (P1/P2 第二轮)
|
||||
|
||||
| 修复项 | ID | 说明 |
|
||||
|--------|-----|------|
|
||||
| 记忆双存储统一 | H3 | 完全重写 `memory_commands.rs`,统一委派到 VikingStorage,移除 PersistentMemoryStore 双写 |
|
||||
| 心跳引擎持久化 | H4 | `record_interaction()` 持久化到 VikingStorage metadata,`heartbeat_init()` 启动时恢复 |
|
||||
| 反思结果持久化 | M4 | `reflect()` 后持久化 ReflectionState/Result 到 VikingStorage,重启后自动恢复 |
|
||||
| 清理 dead_code warnings | — | PersistentMemoryStore impl 添加 `#[allow(dead_code)]`,移除未使用的 `build_uri` |
|
||||
|
||||
### 7.3 审计修复 (P2 第四轮)
|
||||
|
||||
| 修复项 | ID | 说明 |
|
||||
|--------|-----|------|
|
||||
| 自主授权后端守卫 | M5-补 | `hand_execute`/`skill_execute` 接收 `autonomy_level` 参数,三级守卫 (supervised/assisted/autonomous) |
|
||||
| hand_approve 参数 | M3 | 移除 `_` 前缀,添加审计日志,返回值包含 hand_name |
|
||||
| 反思历史累积 | M4-补 | 新增 `reflection:history:{agent_id}` 数组(最多 20 条),向后兼容 `reflection:latest` |
|
||||
| 心跳历史持久化 | — | `tick()` 同步存储历史到 VikingStorage,`heartbeat_init()` 恢复历史 |
|
||||
| 身份回滚 UI | — | 确认 `IdentityChangeProposal.tsx` 已实现 HistoryItem + restoreSnapshot |
|
||||
| 跨会话消息搜索 | S9 | MessageSearch 新增 Session/Global 双模式,Global 调用 `memory_search` 搜索 VikingStorage |
|
||||
|
||||
### 7.4 代码清理
|
||||
|
||||
| 清理项 | 说明 |
|
||||
|--------|------|
|
||||
| 移除 8 个 OpenClaw 兼容别名 | `gateway_*` 系列废弃函数 |
|
||||
| 清理 7 个 dead_code 方法 | `generation.rs` 中未使用的代码 |
|
||||
| 替换 println! 为 tracing | `pipeline_commands.rs` 日志规范化 |
|
||||
| 新增 LLM 摘要支持 | Compactor 现支持 LLM 驱动的上下文压缩 |
|
||||
| 禁用 Predictor/Lead | HAND.toml 保留但标记无 Rust 后端 |
|
||||
| 标记 Wasm/Native SkillMode | 明确标注为尚未实现 |
|
||||
| 清理 browser/mod.rs | 移除未使用的 re-exports |
|
||||
| 清理 5 个死代码模块 | pattern_detector, recommender, mesh, persona_evolver, trigger_evaluator |
|
||||
| 激活 LoopGuard | AgentLoop 循环防护已接入 (warn/block/circuit_breaker) |
|
||||
| 实现 CapabilityManager.validate() | 安全验证:ToolAll+AgentKill、ToolAll+ShellExec(*) 组合拒绝 |
|
||||
| 删除 Predictor/Lead HAND.toml | 无 Rust 实现的配置文件已彻底删除 |
|
||||
| Credits.tsx 标注开发中 | 移除假数据,显示"开发中"占位 |
|
||||
| Skills.tsx 动态化 | 移除硬编码系统技能卡片,改为从 skillsCatalog 动态加载 |
|
||||
| ScheduledTasks 持久化 | 添加 localStorage 降级,刷新不丢失 |
|
||||
| Token 用量追踪 | chatStore 新增 addTokenUsage/getTotalTokens |
|
||||
|
||||
> **审计说明**: 成熟度等级已根据代码审计调整为实际值。Identity Evolution 标注为 L2 (70%) 是因为其 `dead_code` 属性属于 Tauri 运行时模式(在 Tauri 上下文中实际被调用),而非真正的死代码。Reflection Engine L2 (65%) 因核心反思逻辑尚未深度迭代。累计修复 23 项后整体完成度从 ~50% 提升到 ~72%。
|
||||
详见 [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
|
||||
@@ -1,60 +1,44 @@
|
||||
# ZCLAW 后续工作计划
|
||||
|
||||
> **版本**: v0.6.0
|
||||
> **创建日期**: 2026-03-16
|
||||
> **更新日期**: 2026-03-26
|
||||
> **基于**: 代码深度分析报告
|
||||
> **状态**: Agent Growth System 完整实现
|
||||
> **版本**: v0.7.0
|
||||
> **更新日期**: 2026-03-28
|
||||
> **基于**: 2026-03-28 代码分析
|
||||
> **状态**: 核心功能完整,SaaS 平台上线
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
### 1.1 当前状态 (2026-03-26 代码分析)
|
||||
### 1.1 当前状态
|
||||
|
||||
| 指标 | 状态 |
|
||||
|------|------|
|
||||
| Rust Crates | **9 个** (types, memory, runtime, kernel, skills, hands, protocols, pipeline, **growth**) |
|
||||
| 功能完成度 | 90-95% (核心功能 L4) |
|
||||
| 技能数量 | 78+ SKILL.md |
|
||||
| Hands 可用 | 9/11 (82%) |
|
||||
| Pipeline DSL | ✅ 完整实现 |
|
||||
| Smart Presentation | ✅ 完整实现 (Chart, Quiz, Slideshow, Document) |
|
||||
| **Agent Growth System** | ✅ **完整实现 (SqliteStorage + FTS5 + TF-IDF + Memory Extractor)** |
|
||||
| 测试覆盖 | **~135 tests** (70 growth + 65 desktop) |
|
||||
| 文档覆盖 | 25+ 功能文档 |
|
||||
| Rust Crates | **11 个** (types, memory, runtime, kernel, skills, hands, protocols, pipeline, growth, channels, saas) |
|
||||
| 功能完成度 | 核心功能 90-95%,整体 ~85% |
|
||||
| 技能数量 | 69 SKILL.md |
|
||||
| Hands 可用 | 9 (编程式注册,2 个标记 demo) |
|
||||
| Pipeline DSL | 完整实现 (5 模板 + Smart Presentation) |
|
||||
| SaaS 平台 | 完整实现 (76+ API, 9 模块, 25 数据表) |
|
||||
| Tauri 命令 | 58+ (kernel 29 + pipeline 13 + viking 13 + llm 3) |
|
||||
| LLM Provider | 8 个 (含 Gemini) |
|
||||
| 连接模式 | 3 种 (Kernel / Gateway / SaaS) |
|
||||
| 测试覆盖 | ~135 tests |
|
||||
|
||||
### 1.2 Crate 完整度评估
|
||||
### 1.2 Crate 完整度
|
||||
|
||||
| Crate | 层级 | 完整度 | 核心可用性 |
|
||||
|-------|------|--------|-----------|
|
||||
| Crate | 层级 | 完整度 | 说明 |
|
||||
|-------|------|--------|------|
|
||||
| zclaw-types | L1 | 95% | 完全可用 |
|
||||
| zclaw-memory | L2 | 90% | 完全可用 (SQLite) |
|
||||
| zclaw-runtime | L3 | 90% | 完全可用 (5 工具, 流式响应) |
|
||||
| zclaw-kernel | L4 | 85% | 基本可用 (Approval 存根) |
|
||||
| zclaw-skills | L5 | 80% | 可用 (WASM/Native 待实现) |
|
||||
| zclaw-hands | L5 | 85% | 可用 (9/11 Hands) |
|
||||
| zclaw-protocols | L5 | 75% | MCP 可用,A2A 待完善 |
|
||||
| zclaw-pipeline | L5 | 95% | 完全可用 + Smart Presentation |
|
||||
| **zclaw-growth** | **L5** | **95%** | **完全可用 (SqliteStorage + FTS5 + TF-IDF + Memory Extractor)** |
|
||||
|
||||
### 1.3 核心结论
|
||||
|
||||
**优势**:
|
||||
- 9 层 Rust Workspace 架构清晰
|
||||
- Agent 记忆系统完善 (ICE: 630)
|
||||
- L4 自演化能力已实现
|
||||
- 多 LLM Provider 支持 (8 个)
|
||||
- Pipeline DSL 成熟
|
||||
- 技能生态丰富 (78+)
|
||||
- **Smart Presentation Layer 完成** - 自动类型检测和多渲染器支持
|
||||
- **Agent Growth System 完成** - SqliteStorage + FTS5 + TF-IDF + LLM 驱动记忆提取
|
||||
|
||||
**待改进**:
|
||||
- Approval 管理是存根实现
|
||||
- A2A 协议需要更多工作
|
||||
- 测试覆盖率需要提升 (~65% → 80%)
|
||||
- 部分 Hand 需要外部依赖 (FFmpeg, Twitter API)
|
||||
| zclaw-memory | L2 | 90% | SQLite WAL |
|
||||
| zclaw-runtime | L3 | 90% | 4 Driver, 5 工具, LoopGuard |
|
||||
| zclaw-kernel | L4 | 85% | 9 Hands, 69 Skills, Trigger, Approval |
|
||||
| zclaw-skills | L5 | 80% | Wasm/Native 待实现 |
|
||||
| zclaw-hands | L5 | 85% | 9 Hands, 2 demo |
|
||||
| zclaw-protocols | L5 | 75% | MCP 可用, A2A 待完善 |
|
||||
| zclaw-pipeline | L5 | 95% | DSL + Smart Presentation |
|
||||
| zclaw-growth | L5 | 95% | FTS5 + TF-IDF + Memory Extractor |
|
||||
| zclaw-saas | 独立 | 95% | Axum + PostgreSQL, 76+ API |
|
||||
| zclaw-channels | L5 | 10% | 仅 ConsoleChannel |
|
||||
|
||||
---
|
||||
|
||||
@@ -62,42 +46,34 @@
|
||||
|
||||
### 2.1 P0 - 必须完成
|
||||
|
||||
| ID | 任务 | 负责人 | 预估 | 验收标准 |
|
||||
|----|------|--------|------|---------|
|
||||
| S1 | 实现 Approval 管理后端 | Rust | 4h | 非存根实现,支持审批队列 |
|
||||
| S2 | 提升 A2A 协议完整度 | Rust | 4h | Agent 间通信可用 |
|
||||
| S3 | 增加测试覆盖率 | Rust/TS | 8h | 从 60% 提升到 75% |
|
||||
| S4 | 完善功能文档覆盖 | AI | 2h | 所有模块有文档 |
|
||||
| ID | 任务 | 预估 | 状态 |
|
||||
|----|------|------|------|
|
||||
| S1 | 实现 Approval 管理后端 (非存根) | 4h | 待开始 |
|
||||
| S2 | 完善 A2A 协议完整度 | 4h | 待开始 |
|
||||
| S3 | hand_run_status / hand_run_list 真实实现 | 3h | 待开始 |
|
||||
| S4 | scheduled_task_create 自动执行 | 3h | 待开始 |
|
||||
|
||||
### 2.2 P1 - 应该完成
|
||||
|
||||
| ID | 任务 | 负责人 | 预估 | 验收标准 |
|
||||
|----|------|--------|------|---------|
|
||||
| S5 | 优化审批 UI | TS | 3h | 批量审批可用 |
|
||||
| S6 | 添加消息搜索功能 | TS | 4h | 支持关键词搜索 |
|
||||
| S7 | 优化错误提示 | TS | 2h | 错误有恢复建议 |
|
||||
| S8 | 添加用户反馈入口 | TS | 3h | 反馈可收集和追踪 |
|
||||
| ID | 任务 | 预估 | 状态 |
|
||||
|----|------|------|------|
|
||||
| S5 | 提升 SaaS 测试覆盖率 | 8h | 待开始 |
|
||||
| S6 | 完善 MCP 协议工具验证 | 3h | 待开始 |
|
||||
| S7 | Browser Hand 稳定性增强 | 4h | 待开始 |
|
||||
| S8 | Admin UI 完善批量操作 | 3h | 待开始 |
|
||||
|
||||
### 2.3 本周执行清单
|
||||
### 2.3 已完成项
|
||||
|
||||
```markdown
|
||||
- [x] Smart Presentation Layer (Chart, Quiz, Slideshow, Document 渲染器)
|
||||
- [x] PresentationContainer 集成到 PipelinesPanel
|
||||
- [x] **Agent Growth System** (zclaw-growth crate, 完整实现)
|
||||
- [x] SqliteStorage + FTS5 全文搜索
|
||||
- [x] MemoryRetriever + TF-IDF 语义检索
|
||||
- [x] PromptInjector + Token 预算控制
|
||||
- [x] MemoryExtractor + LLM 驱动提取
|
||||
- [x] VikingAdapter + 存储抽象层
|
||||
- [ ] S1: 实现 Kernel Approval 管理 (非存根)
|
||||
- [ ] S2: 完善 A2A 协议实现
|
||||
- [ ] S3: 增加单元测试 (目标 +15%)
|
||||
- [ ] S4: 更新功能文档基于代码分析
|
||||
- [ ] S5: 实现批量审批组件
|
||||
- [ ] S6: 添加 ChatArea 搜索框
|
||||
- [ ] S7: 完善错误边界组件
|
||||
- [ ] S8: 在 RightPanel 添加反馈按钮
|
||||
```
|
||||
| ID | 任务 | 状态 |
|
||||
|----|------|------|
|
||||
| S1-old | 智能层接入聊天流程 | ✅ 完成 |
|
||||
| S2-old | 双存储统一 (VikingStorage) | ✅ 完成 |
|
||||
| S3-old | Hand 审批流程 | ✅ 完成 |
|
||||
| S4-old | Gemini/Local LLM 驱动 | ✅ 完成 |
|
||||
| S5-old | WorkflowBuilder 可视化 | ✅ 完成 |
|
||||
| S7-old | Compactor 接入聊天流程 | ✅ 完成 |
|
||||
| S9-old | 消息搜索 (Session + Global) | ✅ 完成 |
|
||||
| S10-old | Rust 错误提示中文化 | ✅ 完成 |
|
||||
|
||||
---
|
||||
|
||||
@@ -107,59 +83,36 @@
|
||||
|
||||
| ID | 任务 | 价值 | 风险 | 优先级 |
|
||||
|----|------|------|------|--------|
|
||||
| M1 | 完成 WASM/Native 技能模式 | 高 | 中 | P1 |
|
||||
| M2 | 实现 Predictor Hand | 中 | 低 | P2 |
|
||||
| M3 | 实现 Lead Hand | 中 | 低 | P2 |
|
||||
| M4 | 完善测试覆盖到 80% | 高 | 低 | P1 |
|
||||
| M1 | WASM/Native 技能模式 | 高 | 中 | P1 |
|
||||
| M2 | A2A 协议完整实现 | 高 | 中 | P1 |
|
||||
| M3 | Agent 持久化存储优化 | 高 | 低 | P1 |
|
||||
| M4 | 测试覆盖提升到 80% | 高 | 低 | P1 |
|
||||
|
||||
### 3.2 用户体验优化
|
||||
|
||||
| ID | 任务 | 价值 | 风险 | 优先级 |
|
||||
|----|------|------|------|--------|
|
||||
| M5 | 记忆图谱可视化 | 高 | 中 | P1 |
|
||||
| M5 | 记忆图谱可视化 (React Flow) | 高 | 中 | P1 |
|
||||
| M6 | 技能市场 MVP | 高 | 中 | P1 |
|
||||
| M7 | 工作流编辑器增强 | 高 | 中 | P1 |
|
||||
| M8 | 主动学习引擎 | 高 | 高 | P1 |
|
||||
| M8 | 主动学习引擎 | 高 | 高 | P2 |
|
||||
|
||||
**M5 记忆图谱详细设计**:
|
||||
### 3.3 SaaS 增强
|
||||
|
||||
```
|
||||
技术方案:
|
||||
- React Flow 可视化
|
||||
- 力导向图布局
|
||||
- 节点类型: fact, preference, lesson, context, task
|
||||
- 边类型: 引用, 关联, 派生
|
||||
| ID | 任务 | 价值 | 风险 | 优先级 |
|
||||
|----|------|------|------|--------|
|
||||
| M9 | SaaS 多租户隔离增强 | 高 | 中 | P1 |
|
||||
| M10 | Prompt A/B 测试 | 中 | 低 | P2 |
|
||||
| M11 | Agent Template 市场 | 中 | 中 | P2 |
|
||||
| M12 | Webhook/Callback 系统 | 高 | 低 | P1 |
|
||||
|
||||
交互设计:
|
||||
- 点击节点: 显示详情
|
||||
- 拖拽: 重新布局
|
||||
- 筛选: 按类型/时间/重要性
|
||||
- 搜索: 高亮匹配节点
|
||||
```
|
||||
|
||||
**M6 技能市场 MVP 范围**:
|
||||
|
||||
```
|
||||
功能范围:
|
||||
- 技能浏览和搜索
|
||||
- 技能详情展示
|
||||
- 一键安装/卸载
|
||||
- 技能评分和评论
|
||||
|
||||
不包含 (后续版本):
|
||||
- 付费技能
|
||||
- 技能提交
|
||||
- 版本管理
|
||||
```
|
||||
|
||||
### 3.3 性能优化
|
||||
### 3.4 性能优化
|
||||
|
||||
| ID | 任务 | 目标 | 当前 | 改进 |
|
||||
|----|------|------|------|------|
|
||||
| M9 | 消息列表虚拟化 | 1000条流畅 | 100条流畅 | 10x |
|
||||
| M10 | 记忆索引优化 | <20ms | ~50ms | 2.5x |
|
||||
| M11 | 启动时间优化 | <2s | ~3s | 1.5x |
|
||||
| M12 | SQLite 查询优化 | <10ms | ~30ms | 3x |
|
||||
| P1 | 消息列表虚拟化 | 1000 条流畅 | 100 条流畅 | 10x |
|
||||
| P2 | 记忆索引优化 | <20ms | ~50ms | 2.5x |
|
||||
| P3 | 启动时间优化 | <2s | ~3s | 1.5x |
|
||||
|
||||
---
|
||||
|
||||
@@ -169,48 +122,16 @@
|
||||
|
||||
| 方向 | 目标用户 | 核心价值 | 差异化 |
|
||||
|------|---------|---------|--------|
|
||||
| **个人版** | 个人开发者 | 效率提升 | 本地优先 + 记忆 + 78+ 技能 |
|
||||
| **团队版** | 小团队 (5-20人) | 协作增强 | 多 Agent 协作 + Pipeline DSL |
|
||||
| **企业版** | 中大型企业 | 安全合规 | 私有部署 + 审计 + A2A |
|
||||
| 个人版 | 个人开发者 | 效率提升 | 本地优先 + 记忆 + 69 技能 |
|
||||
| 团队版 | 小团队 (5-20人) | 协作增强 | SaaS 平台 + Pipeline DSL |
|
||||
| 企业版 | 中大型企业 | 安全合规 | 私有部署 + 审计 + RBAC |
|
||||
|
||||
### 4.2 技术演进
|
||||
|
||||
| 阶段 | 重点 | 关键里程碑 |
|
||||
|------|------|-----------|
|
||||
| Q2 | 稳定性 | 测试覆盖 80%,Approval 完善,A2A 完整 |
|
||||
| Q3 | 能力扩展 | WASM 技能,云同步,主动学习 |
|
||||
| Q4 | 生态建设 | 社区,插件市场,企业部署 |
|
||||
|
||||
### 4.3 商业化路径
|
||||
|
||||
```
|
||||
阶段 1: 产品完善 (Q2)
|
||||
│
|
||||
├── 完善核心功能
|
||||
├── 提升测试覆盖
|
||||
└── 完善文档
|
||||
│
|
||||
▼
|
||||
阶段 2: 开源建设 (Q3)
|
||||
│
|
||||
├── 完善开源版本
|
||||
├── 建立社区
|
||||
└── 收集反馈
|
||||
│
|
||||
▼
|
||||
阶段 3: 增值服务 (Q4)
|
||||
│
|
||||
├── 云同步服务 (订阅)
|
||||
├── 高级技能包 (付费)
|
||||
└── 技术支持 (企业)
|
||||
```
|
||||
|
||||
### 4.4 待实现功能
|
||||
### 4.2 待实现功能
|
||||
|
||||
| 功能 | 优先级 | 预计完成 |
|
||||
|------|--------|---------|
|
||||
| WASM/Native 技能模式 | P1 | Q3 |
|
||||
| 向量搜索集成 | P2 | Q3 |
|
||||
| A2A 协议完整实现 | P1 | Q3 |
|
||||
| 云同步服务 | P2 | Q4 |
|
||||
| 技能共享社区 | P3 | Q4 |
|
||||
| 企业部署版本 | P3 | Q4 |
|
||||
@@ -219,127 +140,33 @@
|
||||
|
||||
## 五、关键决策
|
||||
|
||||
### 5.1 待定决策
|
||||
### 5.1 已确定
|
||||
|
||||
| 决策项 | 选项 | 建议 | 截止日期 |
|
||||
|--------|------|------|---------|
|
||||
| 目标用户 | 个人/团队/企业 | 先个人,后团队 | Q2 结束 |
|
||||
| 记忆存储 | 纯本地/云同步 | 本地优先,可选云同步 | Q2 结束 |
|
||||
| 模型策略 | 单一/多模型 | 多模型切换 | 已确定 |
|
||||
| 开源策略 | 完全/部分 | 核心开源,增值闭源 | Q3 开始 |
|
||||
| 定价模式 | 免费/付费 | 基础免费,高级付费 | Q3 开始 |
|
||||
| 决策项 | 决策 | 时间 |
|
||||
|--------|------|------|
|
||||
| 架构 | 内部 Kernel + SaaS 双轨 | 2026-03-24 |
|
||||
| 模型策略 | 多模型切换 (8 Provider) | 2026-03-24 |
|
||||
| SaaS 存储 | PostgreSQL (非 SQLite) | 2026-03-27 |
|
||||
| SaaS 认证 | JWT + API Token + TOTP 2FA | 2026-03-27 |
|
||||
|
||||
### 5.2 决策框架
|
||||
### 5.2 待定
|
||||
|
||||
```text
|
||||
决策评估维度:
|
||||
1. 用户价值 (1-10)
|
||||
2. 技术可行性 (1-10)
|
||||
3. 商业可行性 (1-10)
|
||||
4. 资源需求 (1-10, 越低越好)
|
||||
5. 风险程度 (1-10, 越低越好)
|
||||
|
||||
综合得分 = (用户价值 + 技术可行性 + 商业可行性) / (资源需求 + 风险程度)
|
||||
```
|
||||
| 决策项 | 选项 | 截止 |
|
||||
|--------|------|------|
|
||||
| 记忆存储 | 纯本地 vs 可选云同步 | Q2 结束 |
|
||||
| 开源策略 | 完全开源 vs 核心闭源 | Q3 开始 |
|
||||
| 定价模式 | 免费 vs 付费 vs 混合 | Q3 开始 |
|
||||
|
||||
---
|
||||
|
||||
## 六、风险与缓解
|
||||
## 六、成功指标
|
||||
|
||||
### 6.1 技术风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 | 负责人 |
|
||||
|------|------|------|---------|--------|
|
||||
| LLM API 变更 | 中 | 高 | 抽象层隔离 | 架构师 |
|
||||
| 性能瓶颈 | 中 | 中 | 监控和优化 | 开发 |
|
||||
| 安全漏洞 | 低 | 高 | 安全审计 | 安全 |
|
||||
|
||||
### 6.2 产品风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 | 负责人 |
|
||||
|------|------|------|---------|--------|
|
||||
| 用户需求变化 | 高 | 中 | 敏捷迭代 | 产品 |
|
||||
| 竞品压力 | 高 | 中 | 差异化定位 | 产品 |
|
||||
| 采用率低 | 中 | 高 | 用户调研 | 产品 |
|
||||
|
||||
### 6.3 商业风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 | 负责人 |
|
||||
|------|------|------|---------|--------|
|
||||
| 变现困难 | 中 | 高 | 多元化收入 | 商业 |
|
||||
| 成本失控 | 中 | 中 | 成本监控 | 运营 |
|
||||
| 合规问题 | 低 | 高 | 法务咨询 | 法务 |
|
||||
|
||||
---
|
||||
|
||||
## 七、资源需求
|
||||
|
||||
### 7.1 人力资源
|
||||
|
||||
| 角色 | 当前 | 需求 | 差距 |
|
||||
|------|------|------|------|
|
||||
| 前端开发 | 1 | 2 | +1 |
|
||||
| 后端开发 | 0.5 | 1 | +0.5 |
|
||||
| 产品设计 | 0 | 1 | +1 |
|
||||
| 测试 | 0.5 | 1 | +0.5 |
|
||||
|
||||
### 7.2 基础设施
|
||||
|
||||
| 资源 | 用途 | 月成本 |
|
||||
|------|------|--------|
|
||||
| 云服务器 | 云同步服务 | $50-200 |
|
||||
| LLM API | 智能功能 | $100-500 |
|
||||
| 存储 | 用户数据 | $20-50 |
|
||||
|
||||
---
|
||||
|
||||
## 八、成功指标
|
||||
|
||||
### 8.1 产品指标
|
||||
|
||||
| 指标 | 当前 | Q2 目标 | Q3 目标 |
|
||||
|------|------|---------|---------|
|
||||
| DAU | - | 100 | 1000 |
|
||||
| 留存率 (7天) | - | 40% | 50% |
|
||||
| NPS | - | 30 | 50 |
|
||||
| 功能使用率 | - | 60% | 75% |
|
||||
|
||||
### 8.2 技术指标
|
||||
|
||||
| 指标 | 当前 | Q2 目标 | Q3 目标 |
|
||||
|------|------|---------|---------|
|
||||
| 测试覆盖率 | 80% | 85% | 90% |
|
||||
| 错误率 | - | <1% | <0.5% |
|
||||
| 响应时间 | - | <200ms | <100ms |
|
||||
| 可用性 | - | 99% | 99.9% |
|
||||
|
||||
### 8.3 商业指标
|
||||
|
||||
| 指标 | 当前 | Q2 目标 | Q3 目标 |
|
||||
|------|------|---------|---------|
|
||||
| 付费用户 | 0 | - | 100 |
|
||||
| MRR | $0 | - | $1000 |
|
||||
| CAC | - | - | <$50 |
|
||||
| LTV | - | - | >$200 |
|
||||
|
||||
---
|
||||
|
||||
## 九、附录
|
||||
|
||||
### A. 相关文档
|
||||
|
||||
- [功能索引](README.md)
|
||||
- [头脑风暴记录](brainstorming-notes.md)
|
||||
- [CLAUDE.md 规则](../../CLAUDE.md)
|
||||
|
||||
### B. 更新历史
|
||||
|
||||
| 日期 | 版本 | 变更内容 |
|
||||
|------|------|---------|
|
||||
| 2026-03-26 | v0.6.0 | **Agent Growth System 完整实现**: zclaw-growth crate (SqliteStorage + FTS5 + TF-IDF + Memory Extractor), 9 个 Rust Crates |
|
||||
| 2026-03-26 | v0.5.0 | 完成 Smart Presentation Layer (Chart, Quiz, Slideshow, Document 渲染器) |
|
||||
| 2026-03-25 | v0.4.0 | 基于代码深度分析更新:8 Crates 评估,78+ 技能确认,测试覆盖现状 |
|
||||
| 2026-03-16 | v1.0 | 初始版本 |
|
||||
| 指标 | Q2 目标 | Q3 目标 |
|
||||
|------|---------|---------|
|
||||
| 测试覆盖率 | 80% | 90% |
|
||||
| SaaS API 完整度 | 100% | 100% |
|
||||
| 错误率 | <1% | <0.5% |
|
||||
| 响应时间 | <200ms | <100ms |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1269,6 +1269,174 @@ Rust 中截断 UTF-8 字符串的正确方式:
|
||||
|
||||
**注意**: `floor_char_boundary()` 需要 Rust 1.65+
|
||||
|
||||
### 9.9 对话上下文丢失 — Agent 不记得上一轮说了什么
|
||||
|
||||
**症状**: 每轮对话 Agent 都像失忆一样,重复问相同的问题,完全不知道之前聊了什么。
|
||||
|
||||
```
|
||||
用户: 我要制作小学数学启蒙课件
|
||||
Agent: [问了一堆需求确认问题]
|
||||
用户: 用 涵盖加减法
|
||||
Agent: 你是需要我帮你创建关于加减法的内容吗? ← 完全忘了上一轮
|
||||
```
|
||||
|
||||
**根本原因**: `kernel.rs` 的 `send_message_stream_with_prompt()` 每次调用都执行 `self.memory.create_session(agent_id)` 创建全新 session。前端虽然传了 `session_id` 用于事件路由,但 kernel 完全忽略这个 ID,导致 `loop_runner` 的 `get_messages()` 永远返回空数组,LLM 从未收到历史消息。
|
||||
|
||||
```rust
|
||||
// kernel.rs 修复前 — 每次创建新 session
|
||||
let session_id = self.memory.create_session(agent_id).await?;
|
||||
|
||||
// 修复后 — 复用已有 session
|
||||
let session_id = match session_id_override {
|
||||
Some(id) => {
|
||||
let existing = self.memory.get_messages(&id).await;
|
||||
match existing {
|
||||
Ok(msgs) if !msgs.is_empty() => id,
|
||||
_ => self.memory.create_session(agent_id).await?,
|
||||
}
|
||||
}
|
||||
None => self.memory.create_session(agent_id).await?,
|
||||
};
|
||||
```
|
||||
|
||||
**修复**:
|
||||
|
||||
| 文件 | 改动 |
|
||||
|------|------|
|
||||
| `crates/zclaw-kernel/src/kernel.rs` | `send_message_stream_with_prompt` 新增 `session_id_override` 参数,存在且非空则复用 |
|
||||
| `desktop/src-tauri/src/kernel_commands.rs` | 解析前端 `session_id` 为 `SessionId`,传入 kernel |
|
||||
|
||||
**相关流程**:
|
||||
1. 前端 `chatStore` 发送 `sessionId: "session_xxx"` 到 Tauri 命令
|
||||
2. `kernel_commands.rs` 解析为 `SessionId` 传给 kernel
|
||||
3. kernel 复用已有 session → `loop_runner.get_messages()` 返回历史
|
||||
4. LLM 收到完整对话上下文
|
||||
|
||||
### 9.10 多轮工具调用 `tool_call_id is not found` 400 错误
|
||||
|
||||
**症状**: Agent 调用工具后,第二轮将工具结果发回 LLM 时报 400:
|
||||
|
||||
```
|
||||
LLM error: API error 400 Bad Request: {"error":{"message":"tool_call_id is not found","type":"invalid_request_error"}}
|
||||
```
|
||||
|
||||
**根本原因**: `openai.rs` 的 `build_api_request()` 有两个关键缺陷:
|
||||
|
||||
1. **`OpenAiMessage` 缺少 `tool_call_id` 字段**: OpenAI 协议要求 `role: "tool"` 的消息必须携带 `tool_call_id` 来匹配对应的工具调用。当前代码用 `tool_call_id: _` 丢弃了这个值,且结构体中没有该字段。
|
||||
|
||||
2. **连续的 `ToolUse` 消息没有合并**: 同一轮 LLM 响应的多个工具调用应该在同一个 assistant 消息中(`tool_calls` 数组),而不是每个工具调用生成一个独立的 assistant 消息。
|
||||
|
||||
修复前的 API 请求格式(错误):
|
||||
```json
|
||||
[
|
||||
{ "role": "assistant", "tool_calls": [{ "id": "call_1", ... }] },
|
||||
{ "role": "assistant", "tool_calls": [{ "id": "call_2", ... }] },
|
||||
{ "role": "tool", "content": "result1" }, // ← 缺少 tool_call_id
|
||||
{ "role": "tool", "content": "result2" } // ← 缺少 tool_call_id
|
||||
]
|
||||
```
|
||||
|
||||
修复后(正确):
|
||||
```json
|
||||
[
|
||||
{ "role": "assistant", "tool_calls": [{ "id": "call_1", ... }, { "id": "call_2", ... }] },
|
||||
{ "role": "tool", "tool_call_id": "call_1", "content": "result1" },
|
||||
{ "role": "tool", "tool_call_id": "call_2", "content": "result2" }
|
||||
]
|
||||
```
|
||||
|
||||
**修复** (`crates/zclaw-runtime/src/driver/openai.rs`):
|
||||
|
||||
1. **`OpenAiMessage` 添加 `tool_call_id` 字段**:
|
||||
|
||||
```rust
|
||||
struct OpenAiMessage {
|
||||
role: String,
|
||||
content: Option<String>,
|
||||
tool_calls: Option<Vec<OpenAiToolCall>>,
|
||||
tool_call_id: Option<String>, // ← 新增
|
||||
}
|
||||
```
|
||||
|
||||
2. **重写消息转换逻辑** — 合并连续 `ToolUse` 消息 + 传递 `tool_call_id`:
|
||||
|
||||
```rust
|
||||
// ToolResult 消息现在正确传递 tool_call_id
|
||||
zclaw_types::Message::ToolResult { tool_call_id, output, is_error, .. } => {
|
||||
messages.push(OpenAiMessage {
|
||||
role: "tool",
|
||||
content: Some(output.to_string()),
|
||||
tool_calls: None,
|
||||
tool_call_id: Some(tool_call_id.clone()), // ← 传递 ID
|
||||
});
|
||||
}
|
||||
|
||||
// ToolUse 消息累积到同一个 assistant 消息中
|
||||
zclaw_types::Message::ToolUse { id, tool, input } => {
|
||||
pending_tool_calls.get_or_insert_with(Vec::new).push(...);
|
||||
}
|
||||
```
|
||||
|
||||
**相关文件**:
|
||||
- `crates/zclaw-runtime/src/driver/openai.rs` — `OpenAiMessage` 结构体 + `build_api_request()` 消息转换
|
||||
|
||||
**适用范围**: 所有 OpenAI 兼容提供商(Kimi、百炼、智谱、OpenAI 等)的多轮工具调用。
|
||||
|
||||
---
|
||||
|
||||
### 9.11 thinking 启用时工具调用 `reasoning_content is missing` 400 错误
|
||||
|
||||
**症状**: 使用 Kimi 等 thinking 模式 API 时,第二轮工具结果发回后报 400:
|
||||
|
||||
```
|
||||
API error 400 Bad Request: {"error":{"message":"thinking is enabled but reasoning_content is missing in assistant tool call message at index 2"}}
|
||||
```
|
||||
|
||||
**根本原因**: Kimi 要求包含工具调用的 assistant 消息必须携带 `reasoning_content` 字段。当前有两层缺陷:
|
||||
|
||||
1. **loop_runner 未分离 reasoning 和 text**: `ThinkingDelta` 和 `TextDelta` 混在 `iteration_text` 中(带 `[思考]` 前缀),且工具调用时不保存 Assistant 消息,导致 `reasoning_content` 完全丢失。
|
||||
|
||||
2. **openai.rs 未传递 `reasoning_content`**: `OpenAiMessage` 缺少 `reasoning_content` 字段,且 `Message::Assistant.thinking` 被忽略(`thinking: _`)。
|
||||
|
||||
**修复**:
|
||||
|
||||
**a) loop_runner — 分别追踪 reasoning 和 text** (`loop_runner.rs`):
|
||||
|
||||
```rust
|
||||
// ThinkingDelta 只追加到 reasoning_text,不混入 iteration_text
|
||||
StreamChunk::ThinkingDelta { delta } => {
|
||||
reasoning_text.push_str(delta);
|
||||
}
|
||||
|
||||
// 工具调用前推 Assistant 消息(含 thinking)
|
||||
messages.push(Message::assistant_with_thinking(&iteration_text, &reasoning_text));
|
||||
// 然后推 ToolUse 消息
|
||||
for (id, name, input) in &pending_tool_calls {
|
||||
messages.push(Message::tool_use(id, ...));
|
||||
}
|
||||
```
|
||||
|
||||
**b) openai.rs — 合并 [Assistant, ToolUse*] 并传递 reasoning_content**:
|
||||
|
||||
- `OpenAiMessage` 新增 `reasoning_content: Option<String>` 字段
|
||||
- `build_api_request()` 检测 `[Assistant, ToolUse*]` 模式,合并为一个 assistant 消息,同时携带 `content`、`reasoning_content`、`tool_calls`
|
||||
|
||||
修复后的 API 请求格式:
|
||||
```json
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "text content",
|
||||
"reasoning_content": "thinking content",
|
||||
"tool_calls": [{ "id": "call_1", ... }]
|
||||
}
|
||||
```
|
||||
|
||||
**相关文件**:
|
||||
- `crates/zclaw-runtime/src/loop_runner.rs` — 流式/非流式路径的 reasoning 分离
|
||||
- `crates/zclaw-runtime/src/driver/openai.rs` — `OpenAiMessage` + `build_api_request()` 合并逻辑
|
||||
|
||||
**适用范围**: 所有启用 thinking/reasoning 的 OpenAI 兼容提供商(Kimi、百炼、DeepSeek 等)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 技能系统问题
|
||||
@@ -1726,7 +1894,94 @@ curl http://localhost:50051/health
|
||||
|
||||
---
|
||||
|
||||
## 12. 相关文档
|
||||
## 12. SaaS 后端问题
|
||||
|
||||
### 12.1 Admin 登录页无网络请求
|
||||
|
||||
**症状**: 点击 Admin 面板 (`localhost:3000/login`) 的登录按钮后,页面无任何反应,无网络请求、无控制台错误。
|
||||
|
||||
**根本原因**: 前端 `api-client.ts` 的 `BASE_URL` 与后端路由前缀不匹配。
|
||||
|
||||
- 前端: `BASE_URL = 'http://localhost:8080'`,请求路径 `/auth/login` → 实际请求 `http://localhost:8080/auth/login`
|
||||
- 后端: 路由前缀 `/api/v1/auth/login`
|
||||
|
||||
**修复**:
|
||||
1. 将 `BASE_URL` 改为 `'http://localhost:8080/api/v1'`
|
||||
2. 移除所有 API 路径中多余的 `/api/` 前缀
|
||||
|
||||
**涉及文件**: `admin/src/lib/api-client.ts`
|
||||
|
||||
### 12.2 SQLite → PostgreSQL 遗留语法导致 500 错误
|
||||
|
||||
**症状**: 登录成功后,仪表盘页面 (`/stats/dashboard`) 和操作日志 (`/logs/operations`) 返回 500 `DATABASE_ERROR`。
|
||||
|
||||
**根本原因**: 后端代码从 SQLite 迁移到 PostgreSQL 时,部分文件遗漏了 SQL 语法转换。
|
||||
|
||||
**SQLite → PostgreSQL 语法差异**:
|
||||
|
||||
| SQLite | PostgreSQL | 影响位置 |
|
||||
|--------|-----------|----------|
|
||||
| `?1`, `?2` 占位符 | `$1`, `$2` | 所有 SQL 查询 |
|
||||
| `date('now')` | `CURRENT_DATE` | dashboard_stats |
|
||||
| `enabled = 1` / `= 0` | `enabled = true` / `= false` | dashboard_stats, totp |
|
||||
| `LIMIT ?1 OFFSET ?2` | `LIMIT $1 OFFSET $2` | list_operation_logs |
|
||||
| `INSERT OR IGNORE` | `INSERT ... ON CONFLICT DO NOTHING` | schema |
|
||||
| `datetime('now')` | `NOW()` | schema |
|
||||
| `INTEGER PRIMARY KEY AUTOINCREMENT` | `BIGSERIAL PRIMARY KEY` | schema |
|
||||
| `REAL` | `DOUBLE PRECISION` | schema |
|
||||
|
||||
**遗漏修复的文件**:
|
||||
- `crates/zclaw-saas/src/account/handlers.rs` — dashboard_stats、list_operation_logs、device 相关
|
||||
- `crates/zclaw-saas/src/relay/handlers.rs` — provider api_key 查询、retry_task
|
||||
- `crates/zclaw-saas/src/auth/totp.rs` — TOTP 设置/验证/禁用
|
||||
- `crates/zclaw-saas/src/auth/mod.rs` — API Token 验证、last_used_at 更新
|
||||
|
||||
**排查方法**: 全局搜索 `?` 数字占位符和 SQLite 特有函数:
|
||||
```bash
|
||||
grep -rn '?[0-9]\|date(.now.)\|enabled = [01]' crates/zclaw-saas/src/
|
||||
```
|
||||
|
||||
### 12.3 Admin 账号角色权限不足 (403)
|
||||
|
||||
**症状**: 登录成功后,`/stats/dashboard` 和 `/logs/operations` 返回 403 Forbidden。
|
||||
|
||||
**根本原因**: 通过 `/auth/register` 注册的账号默认角色为 `user`,只有 `model:read`、`relay:use`、`config:read` 权限,无法访问 admin 端点。
|
||||
|
||||
**解决方案**: 需要将账号升级为 `super_admin` 角色。两种方式:
|
||||
|
||||
1. **设置环境变量自动种子**(推荐):
|
||||
```bash
|
||||
ZCLAW_ADMIN_USERNAME=admin ZCLAW_ADMIN_PASSWORD=your_password ./zclaw-saas
|
||||
```
|
||||
|
||||
2. **直接修改数据库**:
|
||||
```bash
|
||||
# PostgreSQL
|
||||
psql -U postgres -d zclaw -c "UPDATE accounts SET role = 'super_admin' WHERE username = 'admin'"
|
||||
```
|
||||
|
||||
**权限映射**:
|
||||
|
||||
| 角色 | 权限 |
|
||||
|------|------|
|
||||
| `user` | `model:read`, `relay:use`, `config:read` |
|
||||
| `super_admin` | `admin:full`, `account:admin`, `provider:manage`, `model:manage`, `relay:admin`, `config:write` |
|
||||
|
||||
**注意**: 普通用户通过 API 无法自提升角色 — `update_account` handler 会剥离非管理员的 `role` 字段。
|
||||
|
||||
### 12.4 前端 usage 路由与后端不匹配 (404)
|
||||
|
||||
**症状**: 仪表盘请求 `/usage/daily?days=30` 返回 404。
|
||||
|
||||
**根本原因**: 前端 `api-client.ts` 使用 `/usage/daily` 和 `/usage/by-model` 路径,但后端只有一个统一的 `/api/v1/usage` 端点,参数为 `?from=...&to=...&provider_id=...&model_id=...`。
|
||||
|
||||
**修复**: 将前端 `usage.daily()` 和 `usage.byModel()` 合并为 `usage.get(params)`,路径改为 `/usage`。
|
||||
|
||||
**涉及文件**: `admin/src/lib/api-client.ts`
|
||||
|
||||
---
|
||||
|
||||
## 13. 相关文档
|
||||
|
||||
- [ZCLAW 配置指南](./zclaw-configuration.md) - 配置文件位置、格式和最佳实践
|
||||
- [Agent 和 LLM 提供商配置](./agent-provider-config.md) - Agent 管理和 Provider 配置
|
||||
@@ -1738,11 +1993,104 @@ curl http://localhost:50051/health
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-03-28 | 添加 12.1-12.4 节:SaaS 后端问题 — Admin 登录无请求、SQLite→PostgreSQL 遗留语法、角色权限不足、usage 路由不匹配 |
|
||||
| 2026-03-27 | 添加 9.10/9.11 节:多轮工具调用 tool_call_id + reasoning_content 缺失 — OpenAiMessage 字段补全、[Assistant,ToolUse*] 合并、reasoning 分离追踪 |
|
||||
| 2026-03-27 | 添加 9.10 节:多轮工具调用 tool_call_id is not found — OpenAiMessage 缺少 tool_call_id 字段 + 连续 ToolUse 未合并 |
|
||||
| 2026-03-26 | 添加 11.1 节:Web 端无法连接后端进行调试 - 开发模式服务器方案 |
|
||||
| 2026-03-24 | 添加 9.6 节:日志截断导致 UTF-8 字符边界 Panic - floor_char_boundary 修复方案 |
|
||||
| 2026-03-24 | 添加 9.5 节:阿里云百炼 Coding Plan 工具调用 400 错误 - 流式+工具不兼容、响应解析优先级、JSON 序列化问题 |
|
||||
| 2026-03-24 | 添加 10.2 节:`skills_dir: None` 导致技能系统完全失效 - from_provider() 硬编码问题 |
|
||||
| 2026-03-24 | 添加 10.1 节:Agent 无法调用合适的技能 - 系统提示词注入技能列表 + triggers 字段 |
|
||||
### 9.7 Coding Plan API (Kimi/百炼/智谱) User-Agent 403 拒绝
|
||||
|
||||
**症状**: 使用 Kimi Coding Plan (`api.kimi.com/coding`) 时报 403:
|
||||
|
||||
```
|
||||
LLM error: API error 403 Forbidden: {"error":{"message":"Kimi For Coding is currently only available for Coding Agents such as Kimi CLI, Claude Code, Roo Code, Kilo Code, etc.","type":"access_terminated_error"}}
|
||||
```
|
||||
|
||||
**根本原因**: Coding Plan 提供商检查 `User-Agent` 请求头,只允许已知 Coding Agent 客户端访问。ZCLAW 发送的 `ZCLAW/0.1.0` 不在白名单中。
|
||||
|
||||
**修复**: `crates/zclaw-runtime/src/lib.rs` — 将 `USER_AGENT` 改为 `claude-code/0.1.0`(精确匹配白名单格式,全小写)。
|
||||
|
||||
同时修复 `desktop/src-tauri/src/llm/mod.rs` 中两处 `reqwest::Client::new()` 也加上 User-Agent。
|
||||
|
||||
```rust
|
||||
// 修复前
|
||||
pub const USER_AGENT: &str = "ZCLAW/0.1.0";
|
||||
|
||||
// 修复后
|
||||
pub const USER_AGENT: &str = "claude-code/0.1.0";
|
||||
```
|
||||
|
||||
**相关文件**:
|
||||
- `crates/zclaw-runtime/src/lib.rs` — USER_AGENT 常量
|
||||
- `crates/zclaw-runtime/src/driver/openai.rs` — 使用 USER_AGENT 构建 HTTP client
|
||||
- `desktop/src-tauri/src/llm/mod.rs` — Tauri 侧 LLM 客户端(call_api / call_embedding_api)
|
||||
|
||||
---
|
||||
|
||||
### 9.8 Coding Plan 模型返回空响应(显示 "...")
|
||||
|
||||
**症状**: User-Agent 修复后,模型可以连接,但前端只显示 "..." 无实质性内容。
|
||||
|
||||
**根本原因**: 多层问题叠加:
|
||||
|
||||
1. **`reasoning_content` 字段未解析**: Kimi/Qwen/DeepSeek/GLM 等模型的思考过程通过 `delta.reasoning_content` 字段返回(而非 `delta.content`),OpenAI 驱动的 `OpenAiDelta` 结构体缺少此字段,所有 thinking 内容被静默丢弃。
|
||||
|
||||
2. **ThinkingDelta 未累积到 `iteration_text`**: `loop_runner.rs` 中 `ThinkingDelta` 只发送给前端(`LoopEvent::Delta`),不累积到 `iteration_text`,导致最终 `Complete` 事件的 `response` 为空。
|
||||
|
||||
3. **每个 reasoning token 重复加 `[思考]` 前缀**: 每收到一个 `ThinkingDelta` 就加一次 `[思考] `,导致显示为 `[思考] 用户[思考] 只是[思考] 简单地...`。
|
||||
|
||||
**修复**:
|
||||
|
||||
**a) OpenAI 驱动添加 `reasoning_content` 支持** (`openai.rs`):
|
||||
|
||||
```rust
|
||||
// OpenAiDelta 结构体 — 添加字段
|
||||
struct OpenAiDelta {
|
||||
content: Option<String>,
|
||||
reasoning_content: Option<String>, // ← 新增
|
||||
tool_calls: Option<Vec<OpenAiToolCallDelta>>,
|
||||
}
|
||||
|
||||
// OpenAiResponseMessage 结构体 — 同样添加
|
||||
struct OpenAiResponseMessage {
|
||||
content: Option<String>,
|
||||
reasoning_content: Option<String>, // ← 新增
|
||||
tool_calls: Option<Vec<OpenAiToolCallResponse>>,
|
||||
}
|
||||
```
|
||||
|
||||
流式路径:`reasoning_content` → `StreamChunk::ThinkingDelta`
|
||||
|
||||
非流式路径:当 `content` 为空但 `reasoning_content` 有值时,用 reasoning 作为文本返回。
|
||||
|
||||
**b) loop_runner 累积 thinking 内容但不发给用户** (`loop_runner.rs`):
|
||||
|
||||
```rust
|
||||
StreamChunk::ThinkingDelta { delta } => {
|
||||
// 只累积到 iteration_text(后端 memory),不发给前端
|
||||
if !in_thinking_phase {
|
||||
iteration_text.push_str("[思考] ");
|
||||
in_thinking_phase = true;
|
||||
}
|
||||
iteration_text.push_str(delta);
|
||||
// 不调用 tx.send() — 用户不看到思考过程
|
||||
}
|
||||
```
|
||||
|
||||
思考内容仅存入后端 memory 用于上下文,用户界面只显示正式回复。
|
||||
|
||||
**适用范围**: 此修复适用于所有使用 `reasoning_content` 字段的 Coding Plan 提供商:
|
||||
- Kimi Coding Plan (`api.kimi.com/coding`)
|
||||
- 百炼/DashScope Coding Plan (`coding.dashscope.aliyuncs.com`)
|
||||
- 智谱 GLM Coding Plan (`open.bigmodel.cn/api/coding/paas/v4`)
|
||||
- DeepSeek R1 等推理模型
|
||||
|
||||
**无需额外适配**:三个提供商都走同一个 OpenAI 兼容驱动,修复一处通用覆盖。
|
||||
|
||||
| 2026-03-27 | 添加 9.7/9.8 节:Coding Plan 403 拒绝 + 空响应(User-Agent、reasoning_content、thinking 显示) |
|
||||
| 2026-03-27 | 添加 9.7/9.8/9.9 节:Coding Plan 403 拒绝、空响应、对话上下文丢失 |
|
||||
| 2026-03-24 | 添加 9.4 节:自我进化系统启动错误 - DateTime 类型不匹配和未使用导入警告 |
|
||||
| 2026-03-23 | 添加 9.3 节:更换模型配置后仍使用旧模型 - Agent 配置优先于 Kernel 配置导致的问题 |
|
||||
| 2026-03-22 | 添加内核 LLM 响应问题:loop_runner.rs 硬编码模型和响应导致 Coding Plan API 不工作 |
|
||||
|
||||
385
docs/saas-backend-optimization.md
Normal file
385
docs/saas-backend-optimization.md
Normal file
@@ -0,0 +1,385 @@
|
||||
# ZCLAW SaaS 后端优化计划
|
||||
|
||||
> 生成时间: 2026-03-28
|
||||
> 分析范围: crates/zclaw-saas
|
||||
|
||||
## 一、架构概览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW SaaS Backend │
|
||||
│ (Rust + Axum + PostgreSQL) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ auth │ │ account │ │model_cfg │ │ relay │ │
|
||||
│ │ 认证 │ │ 账号管理 │ │ 模型配置 │ │ 中转服务 │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────┴─────────────┴─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ middleware │ │
|
||||
│ │ - auth │ │
|
||||
│ │ - rate_limit│ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ PostgreSQL │ │
|
||||
│ └─────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 二、API 接口清单 (共 42 个端点)
|
||||
|
||||
### 2.1 认证模块 `/api/v1/auth` (5 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| POST | `/auth/register` | 公开 | 用户注册 |
|
||||
| POST | `/auth/login` | 公开 | 用户登录 |
|
||||
| POST | `/auth/refresh` | 认证 | 刷新 Token |
|
||||
| GET | `/auth/me` | 认证 | 获取当前用户 |
|
||||
| PUT | `/auth/password` | 认证 | 修改密码 |
|
||||
|
||||
### 2.2 账号管理 `/api/v1` (12 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/accounts` | admin | 列出账号 |
|
||||
| GET | `/accounts/:id` | 自己/admin | 账号详情 |
|
||||
| PUT | `/accounts/:id` | 自己/admin | 更新账号 |
|
||||
| PATCH | `/accounts/:id/status` | admin | 更新状态 |
|
||||
| GET | `/tokens` | 认证 | 列出 Token |
|
||||
| POST | `/tokens` | 认证 | 创建 Token |
|
||||
| DELETE | `/tokens/:id` | 认证 | 撤销 Token |
|
||||
| GET | `/logs/operations` | admin | 操作日志 |
|
||||
| GET | `/stats/dashboard` | admin | 仪表盘 |
|
||||
| POST | `/devices/register` | 认证 | 注册设备 |
|
||||
| POST | `/devices/heartbeat` | 认证 | 设备心跳 |
|
||||
| GET | `/devices` | 认证 | 设备列表 |
|
||||
|
||||
### 2.3 模型配置 `/api/v1` (15 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/providers` | 认证 | 服务商列表 |
|
||||
| GET | `/providers/:id` | 认证 | 服务商详情 |
|
||||
| POST | `/providers` | provider:manage | 创建服务商 |
|
||||
| PUT | `/providers/:id` | provider:manage | 更新服务商 |
|
||||
| DELETE | `/providers/:id` | provider:manage | 删除服务商 |
|
||||
| GET | `/models` | 认证 | 模型列表 |
|
||||
| GET | `/models/:id` | 认证 | 模型详情 |
|
||||
| POST | `/models` | model:manage | 创建模型 |
|
||||
| PUT | `/models/:id` | model:manage | 更新模型 |
|
||||
| DELETE | `/models/:id` | model:manage | 删除模型 |
|
||||
| GET | `/keys` | 认证 | API Key 列表 |
|
||||
| POST | `/keys` | 认证 | 创建 Key |
|
||||
| POST | `/keys/:id/rotate` | 认证 | 轮换 Key |
|
||||
| DELETE | `/keys/:id` | 认证 | 撤销 Key |
|
||||
| GET | `/usage` | 认证 | 用量统计 |
|
||||
|
||||
### 2.4 中转服务 `/api/v1/relay` (5 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| POST | `/relay/chat/completions` | relay:use | 聊天补全 |
|
||||
| GET | `/relay/tasks` | 认证 | 任务列表 |
|
||||
| GET | `/relay/tasks/:id` | 认证 | 任务详情 |
|
||||
| GET | `/relay/models` | 认证 | 可用模型 |
|
||||
| POST | `/relay/tasks/:id/retry` | relay:admin | 重试任务 |
|
||||
|
||||
### 2.5 配置迁移 `/api/v1/config` (10 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/config/items` | 认证 | 配置列表 |
|
||||
| GET | `/config/items/:id` | 认证 | 配置详情 |
|
||||
| POST | `/config/items` | config:write | 创建配置 |
|
||||
| PUT | `/config/items/:id` | config:write | 更新配置 |
|
||||
| DELETE | `/config/items/:id` | config:write | 删除配置 |
|
||||
| GET | `/config/analysis` | 认证 | 配置分析 |
|
||||
| POST | `/config/seed` | config:write | 种子配置 |
|
||||
| POST | `/config/sync` | 认证 | 同步配置 |
|
||||
| POST | `/config/diff` | 认证 | 配置差异 |
|
||||
| GET | `/config/sync-logs` | 认证 | 同步日志 |
|
||||
|
||||
---
|
||||
|
||||
## 三、问题清单
|
||||
|
||||
### 🔴 高优先级 (影响功能/性能)
|
||||
|
||||
#### P1-001: 登录接口 N+1 查询
|
||||
|
||||
**位置:** `auth/handlers.rs:login()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
// 查询 1: 获取用户信息
|
||||
let row = sqlx::query_as("SELECT id, username, ... FROM accounts WHERE username = $1")...
|
||||
|
||||
// 查询 2: 获取密码哈希
|
||||
let (password_hash,) = sqlx::query_as("SELECT password_hash FROM accounts WHERE id = $1")...
|
||||
|
||||
// 查询 3: 获取权限
|
||||
let permissions = get_role_permissions(&state.db, &role).await?;
|
||||
```
|
||||
|
||||
**影响:** 每次登录触发 3 次数据库查询
|
||||
|
||||
**修复方案:**
|
||||
```sql
|
||||
SELECT a.id, a.username, a.email, a.display_name, a.role, a.status,
|
||||
a.totp_enabled, a.created_at, a.password_hash,
|
||||
r.permissions
|
||||
FROM accounts a
|
||||
LEFT JOIN roles r ON a.role = r.id
|
||||
WHERE a.username = $1 OR a.email = $1
|
||||
```
|
||||
|
||||
**工作量:** 小 (1-2 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P1-002: 流式响应 Token 统计缺失
|
||||
|
||||
**位置:** `relay/handlers.rs:chat_completions()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
Ok(service::RelayResponse::Sse(body)) => {
|
||||
model_service::record_usage(..., 0, 0, ...); // 流式记录 0 tokens
|
||||
}
|
||||
```
|
||||
|
||||
**影响:** 流式请求的 token 使用量无法统计,影响计费和监控
|
||||
|
||||
**修复方案:**
|
||||
1. 解析 SSE 流中的 `usage` 字段
|
||||
2. 在流结束后更新统计
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P1-003: 健康检查端点缺失
|
||||
|
||||
**位置:** `main.rs`
|
||||
|
||||
**现状:** 无 `/health` 或 `/ready` 端点
|
||||
|
||||
**影响:**
|
||||
- K8s/Docker 无法进行健康检查
|
||||
- 负载均衡器无法判断服务状态
|
||||
|
||||
**修复方案:**
|
||||
```rust
|
||||
.route("/health", get(|| async {
|
||||
Json(json!({"status": "ok"}))
|
||||
}))
|
||||
.route("/ready", get(|State(state): State<AppState>| async move {
|
||||
// 检查数据库连接
|
||||
let db_ok = sqlx::query("SELECT 1").fetch_one(&state.db).await.is_ok();
|
||||
Json(json!({"ready": db_ok, "db": if db_ok { "connected" } else { "disconnected" }}))
|
||||
}))
|
||||
```
|
||||
|
||||
**工作量:** 小 (1 小时)
|
||||
|
||||
---
|
||||
|
||||
### 🟡 中优先级 (影响可维护性)
|
||||
|
||||
#### P2-001: 权限系统无缓存
|
||||
|
||||
**位置:** `auth/handlers.rs:get_role_permissions()`
|
||||
|
||||
**现状:** 每次请求都查询数据库获取权限
|
||||
|
||||
**影响:**
|
||||
- 数据库压力增加
|
||||
- 响应延迟增加
|
||||
|
||||
**修复方案:**
|
||||
1. 方案 A: 在 JWT 中嵌入权限 (无需查询,但权限变更需重新登录)
|
||||
2. 方案 B: 添加内存缓存 (LRU Cache,权限变更即时生效)
|
||||
|
||||
**推荐:** 方案 B,使用 `moka` 或 `dashmap` 缓存
|
||||
|
||||
**工作量:** 中 (4-8 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P2-002: 错误响应格式不统一
|
||||
|
||||
**位置:** 所有 handlers
|
||||
|
||||
**现状:**
|
||||
```json
|
||||
// 格式 1
|
||||
{"error": "AUTH_ERROR", "message": "认证失败"}
|
||||
|
||||
// 格式 2
|
||||
{"ok": true}
|
||||
|
||||
// 格式 3
|
||||
{"ok": true, "message": "密码修改成功"}
|
||||
```
|
||||
|
||||
**影响:** 前端需要处理多种格式,增加复杂度
|
||||
|
||||
**修复方案:** 统一为 RFC 7807 Problem Details 格式:
|
||||
```json
|
||||
{
|
||||
"type": "https://zclaw.ai/errors/auth-error",
|
||||
"title": "认证失败",
|
||||
"status": 401,
|
||||
"detail": "用户名或密码错误",
|
||||
"code": "AUTH_ERROR"
|
||||
}
|
||||
```
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P2-003: 分页响应缺少元数据
|
||||
|
||||
**位置:** `account/handlers.rs:list_accounts()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
pub struct PaginatedResponse<T> {
|
||||
pub items: Vec<T>,
|
||||
// 缺少 total, page, total_pages
|
||||
}
|
||||
```
|
||||
|
||||
**影响:** 前端无法显示总页数和分页导航
|
||||
|
||||
**修复方案:**
|
||||
```rust
|
||||
pub struct PaginatedResponse<T> {
|
||||
pub items: Vec<T>,
|
||||
pub total: i64,
|
||||
pub page: i64,
|
||||
pub page_size: i64,
|
||||
pub total_pages: i64,
|
||||
}
|
||||
```
|
||||
|
||||
**工作量:** 小 (2-3 小时)
|
||||
|
||||
---
|
||||
|
||||
### 🟢 低优先级 (技术债务)
|
||||
|
||||
#### P3-001: 数据库 Schema 使用 TEXT 类型
|
||||
|
||||
**位置:** `db.rs`
|
||||
|
||||
**现状:**
|
||||
```sql
|
||||
created_at TEXT NOT NULL, -- 应该用 TIMESTAMPTZ
|
||||
role TEXT NOT NULL DEFAULT 'user' -- 应该用外键
|
||||
```
|
||||
|
||||
**影响:**
|
||||
- 无法使用 PostgreSQL 时间函数
|
||||
- 角色无外键约束,可能导致数据不一致
|
||||
|
||||
**修复方案:** 编写迁移脚本,逐步更新 Schema
|
||||
|
||||
**工作量:** 大 (需要数据迁移)
|
||||
|
||||
---
|
||||
|
||||
#### P3-002: 缺少请求追踪
|
||||
|
||||
**现状:** 操作日志只记录业务操作,不记录 API 请求详情
|
||||
|
||||
**影响:**
|
||||
- 无法追踪请求链路
|
||||
- 问题排查困难
|
||||
|
||||
**修复方案:** 添加请求追踪中间件:
|
||||
- 生成 `request_id`
|
||||
- 记录请求耗时
|
||||
- 关联日志与请求
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P3-003: API 版本控制策略缺失
|
||||
|
||||
**现状:** 只有 `v1`,无版本升级策略
|
||||
|
||||
**影响:** 未来 API 变更可能导致兼容性问题
|
||||
|
||||
**修复方案:**
|
||||
1. 在响应头添加 `X-API-Version`
|
||||
2. 支持 `Accept: application/vnd.zclaw.v1+json`
|
||||
3. 添加版本废弃机制
|
||||
|
||||
**工作量:** 小 (2-3 小时)
|
||||
|
||||
---
|
||||
|
||||
## 四、优化实施计划
|
||||
|
||||
### Phase 1: 高优先级修复 (1-2 天)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P1-001 登录 N+1 查询优化 | 2h | - | 待开始 |
|
||||
| P1-003 健康检查端点 | 1h | - | 待开始 |
|
||||
| P1-002 流式 Token 统计 | 6h | - | 待开始 |
|
||||
|
||||
### Phase 2: 中优先级优化 (2-3 天)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P2-001 权限缓存 | 8h | - | 待开始 |
|
||||
| P2-002 错误格式统一 | 6h | - | 待开始 |
|
||||
| P2-003 分页元数据 | 3h | - | 待开始 |
|
||||
|
||||
### Phase 3: 技术债务清理 (按需)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P3-001 Schema 迁移 | 2-3 天 | - | 待评估 |
|
||||
| P3-002 请求追踪 | 6h | - | 待开始 |
|
||||
| P3-003 API 版本控制 | 3h | - | 待开始 |
|
||||
|
||||
---
|
||||
|
||||
## 五、NOT in Scope
|
||||
|
||||
以下内容在本次优化范围之外:
|
||||
|
||||
1. **前端 Admin UI 优化** - 仅关注后端 API
|
||||
2. **数据库分库分表** - 当前数据量不需要
|
||||
3. **微服务拆分** - 架构已足够清晰
|
||||
4. **GraphQL 支持** - REST API 已满足需求
|
||||
5. **WebSocket 支持** - 当前无实时推送需求
|
||||
|
||||
---
|
||||
|
||||
## 六、风险评估
|
||||
|
||||
| 风险 | 可能性 | 影响 | 缓解措施 |
|
||||
|------|--------|------|----------|
|
||||
| Schema 迁移数据丢失 | 低 | 高 | 先备份,分批迁移 |
|
||||
| 权限缓存不一致 | 中 | 中 | 设置 TTL,主动失效 |
|
||||
| 流式解析兼容性 | 中 | 低 | 多模型测试 |
|
||||
|
||||
---
|
||||
|
||||
## 七、验收标准
|
||||
|
||||
- [ ] 所有 API 端点有健康检查
|
||||
- [ ] 登录接口响应时间 < 100ms (P99)
|
||||
- [ ] 流式请求 Token 统计准确率 > 95%
|
||||
- [ ] 错误响应格式统一
|
||||
- [ ] 分页接口包含完整元数据
|
||||
@@ -391,8 +391,8 @@ pub mod permissions {
|
||||
pub const ACCOUNT_READ: &str = "account:read";
|
||||
pub const ACCOUNT_WRITE: &str = "account:write";
|
||||
pub const ACCOUNT_ADMIN: &str = "account:admin";
|
||||
pub const MODEL_READ: &str = "model:read";
|
||||
pub const MODEL_WRITE: &str = "model:write";
|
||||
pub const PROVIDER_MANAGE: &str = "provider:manage";
|
||||
pub const MODEL_MANAGE: &str = "model:manage";
|
||||
pub const RELAY_USE: &str = "relay:use";
|
||||
pub const RELAY_ADMIN: &str = "relay:admin";
|
||||
pub const CONFIG_READ: &str = "config:read";
|
||||
@@ -404,8 +404,8 @@ pub mod permissions {
|
||||
| 角色 | 权限 |
|
||||
|------|------|
|
||||
| `super_admin` | `admin:full` (授权检查时直接放行) |
|
||||
| `admin` | account:read/write, model:read/write, relay:use/admin, config:read/write |
|
||||
| `user` | model:read, relay:use, config:read |
|
||||
| `admin` | account:read/write/admin, provider:manage, model:manage, relay:use/admin, config:read/write |
|
||||
| `user` | relay:use, config:read |
|
||||
|
||||
### 4.4 API 端点
|
||||
|
||||
@@ -418,8 +418,8 @@ pub mod permissions {
|
||||
| POST | `/api/v1/auth/totp/verify` | JWT | 验证并启用 TOTP |
|
||||
| POST | `/api/v1/auth/totp/disable` | JWT | 禁用 TOTP |
|
||||
| GET | `/api/v1/accounts` | account:read | 账号列表 |
|
||||
| GET | `/api/v1/accounts/:id` | account:read | 账号详情 |
|
||||
| PUT | `/api/v1/accounts/:id` | account:write | 更新账号 |
|
||||
| GET | `/api/v1/accounts/:id` | 本人/account:read | 账号详情 |
|
||||
| PATCH | `/api/v1/accounts/:id` | 本人/account:write | 更新账号 |
|
||||
| PATCH | `/api/v1/accounts/:id/status` | account:admin | 启用/禁用 |
|
||||
| GET | `/api/v1/tokens` | - (本人) | 列出 API 令牌 |
|
||||
| POST | `/api/v1/tokens` | - (本人) | 创建令牌 |
|
||||
@@ -481,25 +481,22 @@ pub enum AccountStatus { Active, Disabled, Suspended }
|
||||
|
||||
| 方法 | 路径 | 权限 | 说明 |
|
||||
|------|------|------|------|
|
||||
| GET | `/api/v1/providers` | model:read | 提供商列表 |
|
||||
| POST | `/api/v1/providers` | model:write | 创建提供商 |
|
||||
| GET | `/api/v1/providers/:id` | model:read | 提供商详情 |
|
||||
| PUT | `/api/v1/providers/:id` | model:write | 更新提供商 |
|
||||
| PATCH | `/api/v1/providers/:id/status` | model:write | 启用/禁用 |
|
||||
| GET | `/api/v1/providers/:id/models` | model:read | 模型列表 |
|
||||
| POST | `/api/v1/providers/:id/models` | model:write | 添加模型 |
|
||||
| PUT | `/api/v1/models/:id` | model:write | 更新模型 |
|
||||
| PATCH | `/api/v1/models/:id/status` | model:write | 启用/禁用模型 |
|
||||
| GET | `/api/v1/account/api-keys` | - (本人) | 密钥列表 |
|
||||
| POST | `/api/v1/account/api-keys` | - (本人) | 创建密钥 |
|
||||
| PUT | `/api/v1/account/api-keys/:id` | - (本人) | 更新权限/标签 |
|
||||
| POST | `/api/v1/account/api-keys/:id/rotate` | - (本人) | 轮换密钥 |
|
||||
| PATCH | `/api/v1/account/api-keys/:id/status` | - (本人) | 启用/禁用 |
|
||||
| DELETE | `/api/v1/account/api-keys/:id` | - (本人) | 撤销密钥 |
|
||||
| GET | `/api/v1/usage/stats` | relay:admin | 总体统计 |
|
||||
| GET | `/api/v1/usage/daily` | - (本人) | 每日统计 |
|
||||
| GET | `/api/v1/usage/account/:id` | relay:admin | 账号统计 |
|
||||
| GET | `/api/v1/catalog/models` | model:read | 公开模型目录 |
|
||||
| GET | `/api/v1/providers` | 认证用户 | 提供商列表 |
|
||||
| POST | `/api/v1/providers` | provider:manage | 创建提供商 |
|
||||
| GET | `/api/v1/providers/:id` | 认证用户 | 提供商详情 |
|
||||
| PATCH | `/api/v1/providers/:id` | provider:manage | 更新提供商 |
|
||||
| DELETE | `/api/v1/providers/:id` | provider:manage | 删除提供商 |
|
||||
| GET | `/api/v1/providers/:id/models` | 认证用户 | 模型列表 |
|
||||
| GET | `/api/v1/models` | 认证用户 | 模型列表 |
|
||||
| POST | `/api/v1/models` | model:manage | 创建模型 |
|
||||
| GET | `/api/v1/models/:id` | 认证用户 | 模型详情 |
|
||||
| PATCH | `/api/v1/models/:id` | model:manage | 更新模型 |
|
||||
| DELETE | `/api/v1/models/:id` | model:manage | 删除模型 |
|
||||
| GET | `/api/v1/keys` | - (本人) | API Key 列表 |
|
||||
| POST | `/api/v1/keys` | - (本人) | 创建 API Key |
|
||||
| DELETE | `/api/v1/keys/:id` | - (本人) | 撤销 API Key |
|
||||
| POST | `/api/v1/keys/:id/rotate` | - (本人) | 轮换 API Key |
|
||||
| GET | `/api/v1/usage` | - (本人) | 使用量统计 |
|
||||
|
||||
### 5.5 初始种子数据
|
||||
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
# 联合调试后修复行动计划
|
||||
|
||||
> **日期**: 2026-03-28
|
||||
> **来源**: 联合调试报告 V1 + 专家代码审查
|
||||
> **状态**: 执行中
|
||||
|
||||
---
|
||||
|
||||
## 一、修复优先级矩阵
|
||||
|
||||
### P0 — 阻塞级(必须立即修复)
|
||||
|
||||
| # | 问题 | 模块 | 影响 | 修复方案 |
|
||||
|---|------|------|------|----------|
|
||||
| P0-1 | SSE Relay 死锁 | relay/service.rs | 流式中转完全不可用 | `blocking_lock()` → `tokio::sync::Mutex` 或 channel |
|
||||
| P0-2 | Token 过期无法刷新 | auth/mod.rs | 自动续期失效,用户被迫重新登录 | middleware 对 `/auth/refresh` 路径跳过过期检查 |
|
||||
| P0-3 | 设备清理 SQL 崩溃 | main.rs:58 | stale devices 永远不清理 | TEXT 比较: 绑定 rfc3339 字符串替代 NOW() |
|
||||
|
||||
### P1 — 功能缺陷(本周修复)
|
||||
|
||||
| # | 问题 | 模块 | 影响 | 修复方案 |
|
||||
|---|------|------|------|----------|
|
||||
| P1-1 | 注册返回类型不匹配 | auth/handlers.rs | 桌面端注册后无法自动登录 | register handler 返回含 token 的响应 |
|
||||
| P1-2 | account_api_keys 未被 Relay 消费 | relay/handlers.rs | 用户级 API Key 无效 | relay 优先查 account_api_keys,回退到 provider key |
|
||||
| P1-3 | TOTP nonce 硬编码 | auth/totp.rs | 相同明文+相同密钥产生相同密文 | 使用随机 nonce |
|
||||
| P1-4 | Config 5 端点缺审计日志 | migration/handlers.rs | 配置变更无 audit trail | 添加 log_operation() 调用 |
|
||||
| P1-5 | Admin 缺路由守卫 | admin/src | URL 直通可绕过侧边栏 | 添加 AuthGuard 组件 |
|
||||
| P1-6 | SSE usage 计数竞态 | relay/service.rs | token 使用量记录为 0 | stream 结束后同步记录 usage |
|
||||
|
||||
### P2 — 代码质量(下周修复)
|
||||
|
||||
| # | 问题 | 模块 | 修复方案 |
|
||||
|---|------|------|----------|
|
||||
| P2-1 | 35 个时间戳字段为 TEXT | db.rs + 全部 service | ALTER TABLE → TIMESTAMPTZ + chrono::DateTime<Utc> |
|
||||
| P2-2 | dashboard_stats 7 次串行查询 | account/service.rs | 合并为 1-2 次 SQL |
|
||||
| P2-3 | 6 个端点缺 OpenAPI 文档 | 各 handlers | 添加 #[utoipa::path] |
|
||||
| P2-4 | computeConfigDiff/syncConfig 未调用 | desktop | 迁移向导统一调用路径 |
|
||||
| P2-5 | list_providers 返回禁用项 | model_config/service.rs | 添加 enabled=true 过滤 |
|
||||
|
||||
### P3 — 长期改进
|
||||
|
||||
| # | 问题 | 方案 |
|
||||
|---|------|------|
|
||||
| P3-1 | Token 创建/撤销无权限控制 | 添加 token:manage / key:manage 权限 |
|
||||
| P3-2 | 12 个 self-scoped handler 无显式权限 | 评估是否需要细粒度权限 |
|
||||
| P3-3 | SSRF DNS rebinding 风险 | DNS 解析后二次检查 |
|
||||
| P3-4 | 邮箱验证过于简单 | 使用 email 格式正则或 validator crate |
|
||||
| P3-5 | 限流内存状态不共享 | Redis/分布式限流(多实例时) |
|
||||
|
||||
---
|
||||
|
||||
## 二、P0 修复详细方案
|
||||
|
||||
### P0-1: SSE Relay 死锁
|
||||
|
||||
**根因**: `relay/service.rs` 中 SSE 流式响应使用 `std::sync::Mutex::blocking_lock()` 在 `inspect()` 回调内。Tokio 运行时在等待锁时阻塞 worker thread,导致死锁。
|
||||
|
||||
**修复**: 替换为 `tokio::sync::Mutex` 或使用 `tokio::sync::watch` channel 传递状态。
|
||||
|
||||
```rust
|
||||
// Before (deadlock):
|
||||
let state = Arc::new(std::sync::Mutex::new(RelayState::new()));
|
||||
stream.inspect(move |chunk| {
|
||||
let mut s = state.blocking_lock(); // DEADLOCK in async context
|
||||
...
|
||||
})
|
||||
|
||||
// After (async-safe):
|
||||
let state = Arc::new(tokio::sync::Mutex::new(RelayState::new()));
|
||||
// Use tokio::spawn for async lock acquisition
|
||||
```
|
||||
|
||||
### P0-2: Token 过期无法刷新
|
||||
|
||||
**根因**: auth middleware 在请求到达 handler 前验证 JWT 有效性。过期的 JWT 被中间件拦截返回 401,永远到不了 `/auth/refresh` handler。
|
||||
|
||||
**修复**: 中间件对 refresh 路径放行,或在 refresh handler 中独立验证 expired token 的签名。
|
||||
|
||||
```rust
|
||||
// middleware.rs - 在 JWT 验证前添加路径检查
|
||||
if request.path() == "/api/v1/auth/refresh" {
|
||||
// 跳过过期检查,仅验证签名
|
||||
return verify_signature_only(token);
|
||||
}
|
||||
```
|
||||
|
||||
### P0-3: 设备清理 SQL 类型不匹配
|
||||
|
||||
**根因**: `last_seen_at` 为 TEXT 类型,SQL `NOW() - INTERVAL '90 days'` 返回 TIMESTAMPTZ。
|
||||
|
||||
**修复**: 使用 rfc3339 字符串比较(TEXT 排序等价于时间排序)。
|
||||
|
||||
```rust
|
||||
// Before:
|
||||
sqlx::query("DELETE FROM devices WHERE last_seen_at < NOW() - INTERVAL '90 days'")
|
||||
|
||||
// After:
|
||||
let cutoff = (chrono::Utc::now() - chrono::Duration::days(90)).to_rfc3339();
|
||||
sqlx::query("DELETE FROM devices WHERE last_seen_at < $1").bind(&cutoff)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、P1 修复详细方案
|
||||
|
||||
### P1-1: 注册返回类型不匹配
|
||||
|
||||
**问题**: 桌面端 `saasStore.register()` 期望响应包含 `token` 字段(`SaaSLoginResponse`),但后端 `register` handler 返回 `AccountPublic`(无 token)。
|
||||
|
||||
**修复**: register handler 在创建账号后自动签发 JWT,返回与 login 一致的响应格式。
|
||||
|
||||
### P1-2: account_api_keys 未被 Relay 消费
|
||||
|
||||
**问题**: relay handler 仅查找 provider 级 API key,忽略了 `account_api_keys` 表。
|
||||
|
||||
**修复**: relay 查找顺序: account_api_keys → provider.api_key → 401
|
||||
|
||||
### P1-3: TOTP nonce 硬编码
|
||||
|
||||
**问题**: AES-256-GCM 使用固定 nonce `"zclaw_totp_nce"`,违反加密语义安全性。
|
||||
|
||||
**修复**: 每次加密生成随机 12-byte nonce,存储在密文前缀中。
|
||||
|
||||
### P1-4: Config 端点审计日志
|
||||
|
||||
**问题**: create/update/delete/seed/sync 5 个 config 端点无 operation_logs 记录。
|
||||
|
||||
**修复**: 每个 handler 在执行后调用 `log_operation()`。
|
||||
|
||||
### P1-5: Admin 路由守卫
|
||||
|
||||
**问题**: 侧边栏权限已修复,但 URL 直通仍可访问页面。
|
||||
|
||||
**修复**: 添加 `AuthGuard` 组件包裹 dashboard layout。
|
||||
|
||||
### P1-6: SSE usage 计数竞态
|
||||
|
||||
**问题**: usage 记录通过 `tokio::spawn` + 1s sleep 异步写入,与 stream 消费者竞争,导致 token 计数为 0。
|
||||
|
||||
**修复**: stream 结束后同步记录 usage(使用 stream `on_complete` 回调)。
|
||||
|
||||
---
|
||||
|
||||
## 四、执行计划
|
||||
|
||||
### Week 1: P0 修复 (3 项)
|
||||
|
||||
| 天 | 任务 | 文件 | 验证 |
|
||||
|----|------|------|------|
|
||||
| Day 1 | P0-1 SSE 死锁修复 | relay/service.rs | 流式请求不死锁 |
|
||||
| Day 2 | P0-2 Token 刷新修复 | auth/mod.rs + middleware.rs | 过期 token 可刷新 |
|
||||
| Day 3 | P0-3 设备清理修复 + 集成测试 | main.rs | 清理 SQL 正常执行 |
|
||||
|
||||
### Week 1-2: P1 修复 (6 项)
|
||||
|
||||
| 天 | 任务 | 文件 |
|
||||
|----|------|------|
|
||||
| Day 4 | P1-1 注册返回类型 | auth/handlers.rs |
|
||||
| Day 5 | P1-2 Relay API Key 消费 | relay/handlers.rs + service.rs |
|
||||
| Day 6 | P1-3 TOTP nonce 随机化 | auth/totp.rs |
|
||||
| Day 7 | P1-4 Config 审计日志 | migration/handlers.rs |
|
||||
| Day 8 | P1-5 Admin 路由守卫 | admin/src |
|
||||
| Day 9 | P1-6 SSE usage 同步记录 | relay/service.rs |
|
||||
|
||||
### Week 3: P2 修复 (5 项)
|
||||
|
||||
| 天 | 任务 |
|
||||
|----|------|
|
||||
| Day 10-11 | P2-1 时间戳类型迁移 (35 字段) |
|
||||
| Day 12 | P2-2 dashboard 查询优化 |
|
||||
| Day 13 | P2-3~P2-5 OpenAPI + 未调用方法 + 过滤 |
|
||||
|
||||
---
|
||||
|
||||
## 五、验证策略
|
||||
|
||||
### 每个 P0 修复的验证标准
|
||||
|
||||
| P0 | 验证方法 | 通过标准 |
|
||||
|----|----------|----------|
|
||||
| P0-1 | 发送 SSE 流式请求 | 响应流完整传输,无死锁,无超时 |
|
||||
| P0-2 | 等待 token 过期后 refresh | 新 token 有效,后续请求正常 |
|
||||
| P0-3 | 执行设备清理任务 | SQL 正常执行,删除 >90天设备 |
|
||||
|
||||
### 回归测试
|
||||
|
||||
每次 P0/P1 修复后,重新执行联合调试报告中已通过的 20 个测试用例,确保不回退。
|
||||
|
||||
---
|
||||
|
||||
## 六、专家结论
|
||||
|
||||
### 安全工程师结论
|
||||
> P0-1 (SSE 死锁) 是最高优先级 — 它意味着 Relay 核心功能完全不可用。P1-3 (TOTP nonce) 虽然不会直接被利用,但违反加密基本原则,应在 P1 中修复。P3 级的权限细粒度改进是长期安全加固方向。
|
||||
|
||||
### 后端架构师结论
|
||||
> 35 个 TEXT 时间戳字段是系统性技术债。短期用 rfc3339 字符串比较可以工作(ISO 8601 文本排序等价时间排序),但中长期必须迁移到 TIMESTAMPTZ。SEED_ROLES 中 NOW() 与 to_rfc3339() 格式不一致也需要在迁移时解决。
|
||||
|
||||
### 前端负责人结论
|
||||
> P1-1 (注册返回类型不匹配) 是前端最迫切的修复 — 它阻塞了新用户注册流程。Admin 路由守卫 (P1-5) 是用户体验和安全的双重需求。
|
||||
|
||||
### QA 主管结论
|
||||
> 12 项未执行测试中,B-03 (Relay SSE)、C-01 (新用户旅程)、C-03 (TOTP) 风险最高。建议在 P0 修复后立即补充执行,覆盖率为先。
|
||||
|
||||
### DevOps 结论
|
||||
> 服务在测试期间中断说明需要:1) 进程管理(systemd/windows service)2) 健康检查告警 3) 日志持久化。建议在 P0 修复后添加基础的运维监控。
|
||||
Reference in New Issue
Block a user