Update audit tracker, roadmap, architecture docs, add admin-v2 Roles page + Billing tests, sync CLAUDE.md, Cargo.toml, docker-compose.yml, add deep-research / frontend-design / chart-visualization skills Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
ZCLAW 上线前双轨并行改进设计
日期: 2026-03-31 阶段: 上线前准备 策略: 功能+质量并行 基于: 三维系统分析 + 代码审查验证(已排除已完成项)
1. 背景与动机
ZCLAW 系统经过多轮迭代(Sprint 1-8 完成,10 个 Batch 完成),核心功能完成度达 87-95%。系统当前处于 B+ 健康度,存在 41 个已知问题(0 Critical, 6 High, 20 Medium, 15 Low)。
已完成的关键项(经代码审查确认):
- Token 刷新竞态: 已修复 (request.ts
onTokenRefreshFailed) - Dockerfile: 已存在 (多阶段构建, rust:1.85-bookworm)
- saas-env.example: 已存在
- 生产部署指南: 已存在 (docs/deployment/saas-production.md, 430 行)
- /api/health: 已在公开路由组
- Agent Template 详情: 已展示所有扩展字段
- AgentOnboardingWizard: 已使用 React hook 模式
实际剩余上线阻塞项:
- 反向代理场景下限流失效(ConnectInfo 返回代理 IP 而非客户端 IP)
- 前端测试覆盖率 0-15%,回归风险极高
- 调度任务执行器为 STUB,违反"不展示假数据"原则
- Desktop 废弃代码 + TS 遗留错误
目标: 在上线前完成所有阻塞项,同时推进 1-2 个高价值功能以提升产品竞争力。
2. 系统分析摘要
2.1 规模
| 组件 | 规模 |
|---|---|
| Rust Crates | 10 个 (types/memory/runtime/kernel/skills/hands/protocols/pipeline/growth/saas) |
| SaaS API | 93 个端点 (5 公开 + 88 受保护) |
| Tauri Commands | 106 个 |
| Zustand Store | 14 个 (desktop) + 2 个 (admin-v2) |
| 技能 | 71 个 SKILL.md |
| Hands | 9 个已启用 (7 完整 + 2 demo) + 2 个已禁用 (Predictor/Lead) |
| 数据库 | PostgreSQL, Schema v11, 25+ 表 |
2.2 实际系统性挑战(经验证)
- 测试覆盖率缺口 — Admin V2 0%, Desktop ~15%, Rust 34%
- 类型安全裂缝 — Desktop 50+
as any, Mixin 模式无编译时保障 - 反向代理限流失效 — ConnectInfo 返回代理 IP,需 trusted_proxies 配置
- 功能完整度断层 — 调度任务 STUB, Quiz 占位符, 5 个 404 API
- 废弃代码残留 — gatewayStore.ts 废弃未清理, TS 遗留错误
2.3 关键洞察
- 技能系统是隐藏的宝石: 71 个 SKILL.md 是差异化资产,应优先展示
- 测试是最大风险: 0-15% 的覆盖率意味着任何改动都可能回归
- 部署基本就绪: Dockerfile + 部署指南已存在,需验证而非创建
- STUB 是隐性技术债: 违反 CLAUDE.md "不允许展示假数据" 原则
3. 设计:双轨并行方案
3.1 轨道 1 — 质量轨道 (Quality Track)
必须在上线前全部完成,阻塞发布。
Q1. 安全加固 (~2h)
Q1.1 反向代理场景限流修复 (唯一实际安全项)
- 文件:
crates/zclaw-saas/src/middleware.rs:133-140 - 问题: 代码正确地不信任 X-Forwarded-For(使用 ConnectInfo),但当部署在 Nginx 反向代理后,ConnectInfo 返回的是代理 IP(如 127.0.0.1),导致所有客户端共享同一 IP 限流桶,限流失效
- 方案:
- 在
saas-config.toml添加trusted_proxies = ["127.0.0.1", "::1"]配置 - 当请求来自可信代理 IP 时,解析
X-Forwarded-For头获取真实客户端 IP - 非可信来源继续使用 ConnectInfo(保持当前安全行为)
- 在
- 验证: 单元测试验证:可信代理 + 有效头 → 使用头中 IP;可信代理 + 无头 → 使用代理 IP;非可信来源 → 忽略头
Q1.2 adminRouting 解析验证
- 文件:
desktop/src/store/connectionStore.ts:358-372 - 问题: 从 localStorage 读取
adminRouting时无类型校验,第 376 行 catch 块静默吞错误 - 方案: 添加 Zod schema 验证解析结果,无效值 fallback 到默认模式
- 验证: 测试各种非法输入(null, undefined, 畸形 JSON)
Q2. 部署验证 (~2h)
部署基础设施已存在,此任务为验证和完善。
验证项:
docker compose up端到端测试(PostgreSQL + SaaS 启动 → 健康检查通过)- Nginx 配置引用的
deploy/nginx.conf是否存在 - saas-env.example 环境变量是否与实际代码一致
- 生产部署指南步骤是否可执行
完善项(如验证中发现缺失):
- 补充 deploy/nginx.conf(如果不存在)
- 更新 saas-env.example 中的遗漏项
Q3. 测试基础 (~10h)
Q3.1 Admin V2 测试基础设施 (~2h)
- 安装:
vitest,@testing-library/react,@testing-library/jest-dom,msw - 配置:
admin-v2/vitest.config.ts+ setup 文件 - MSW handlers 模拟 SaaS API 响应
Q3.2 Admin V2 核心测试 (~4h)
request.ts: 已有 Token 刷新修复的回归测试、网络错误包装、401 自动重定向authStore: 登录/登出/Token 刷新状态管理- 核心页面冒烟测试: Accounts, Providers, AgentTemplates 渲染验证
Q3.3 Desktop 关键 Store 测试 (~4h)
connectionStore: 三种连接模式切换逻辑chatStore: 消息发送/接收/流式响应saasStore: 认证流程 + 心跳降级
Q4. 功能补全 (~6h)
Q4.1 调度任务执行器真实实现 (~4h)
- 文件:
crates/zclaw-saas/src/scheduler.rs:132,166 - 方案: 在 scheduler loop 中实际触发任务执行:
- Agent/Hand/Workflow 类型任务通过内部 HTTP 调用触发(而非外部 API)
- 记录执行结果到 scheduled_tasks 表
- 支持失败重试 (指数退避, 最多 3 次)
- 验证: 集成测试验证任务创建 → 执行 → 结果记录全流程
Q4.2 Admin V2 表格搜索/筛选 (~2h)
- 方案: 使用 ProTable 内置搜索能力,为 Accounts/Models/Providers/ApiKeys/Prompts 表格添加搜索栏
- 范围: 至少覆盖 Accounts 和 Models 两个最常用的表格
Q5. 代码清理 (~4h)
Q5.1 废弃 gatewayStore.ts 清理 (~2h)
- 文件:
desktop/src/store/gatewayStore.ts(358 行) - 方案:
- 审查所有 gatewayStore 导入(agentStore, configStore, handStore, workflowStore, sessionStore 等可能引用)
- 验证 facade 模式是否被组件间接使用
- 移除整个文件,更新所有引用改用 connectionStore
- 运行全量测试验证无回归
- 风险: facade 模式可能被组件间接依赖,需要充分验证
Q5.2 TS 遗留错误修复 (~1h)
- 文件:
desktop/src/lib/gateway-api.ts,desktop/src/lib/kernel-hands.ts - 方案: 修复之前重构引入的类型错误
Q5.3 未使用依赖清理 (~1h)
- 文件:
admin-v2/package.json - 方案: 移除
@ant-design/charts未使用依赖
质量轨道实际总计: ~24h
3.2 轨道 2 — 功能轨道 (Feature Track)
不阻塞上线,但提升产品竞争力。可与质量轨道并行。
F1. 技能市场 UI (~16h)
目标: 展示 71 个 SKILL.md 技能,让用户浏览和发现可用能力
组件设计:
SkillMarket.tsx— 主页面,网格布局展示技能卡片SkillCard.tsx— 单个技能卡片 (名称、描述、标签、激活状态)SkillDetail.tsx— 技能详情弹窗 (完整 SKILL.md 渲染 + 使用示例)SkillSearch.tsx— 搜索栏 + 分类筛选
数据流:
- 从 Kernel IPC
skill_list命令获取技能完整列表 - 搜索方案: 客户端过滤(71 个技能规模小,前端过滤足够高效)
- 名称/描述模糊匹配 (Fuse.js 或手写 filter)
- 按分类标签筛选
- 无需后端搜索命令
- 激活/停用通过现有
skill_activate命令
分类方案(基于 SKILL.md metadata):
- 开发与工程 / 商业与营销 / 研究与内容 / 运营 / 专业技能
依赖: 需确认 skill_list 返回的数据结构包含分类信息
F2. 上下文压缩 + 记忆系统 (~12h)
上下文压缩 Kernel 集成:
- 将 zclaw-growth 的 Compactor 接入 Kernel 中间件链
- 触发条件: 上下文长度超过模型窗口的 80%
- 压缩策略: 保留最近 N 条完整消息 + 早期消息生成摘要
- 用户可见性: 压缩后在聊天界面显示"上下文已压缩"系统消息
- 存储: 摘要作为系统消息存储,原始消息保留但标记为已压缩
记忆系统升级:
- 向量化检索优化 (FTS5 → 混合 FTS5 + Embedding)
- MemoryMiddleware 30s 防抖实现
- 记忆提取后自动关联到 Agent Soul
F3. Quiz Hand 真实化 (~6h)
当前问题: Quiz Hand 使用占位符生成器,生成假数据
方案:
- 替换为 LLM 驱动的真实题目生成
- 使用 Pipeline 模板系统 (已有基础设施)
- 支持多题型: 选择题、填空题、问答题
- 难度自适应: 基于用户表现动态调整
功能轨道总计: ~34h
4. 时间线
Week 1-2: 质量轨道冲刺 (Q1-Q3) — 阻塞上线
├── Q1: 安全加固 (2h)
├── Q2: 部署验证 (2h)
└── Q3: 测试基础 (10h)
┃ 可并行 ──→ F1: 技能市场 UI (16h)
Week 3-4: 质量收尾 + 功能启动
├── Q4: 功能补全 (6h)
├── Q5: 代码清理 (4h)
├── F2: 上下文压缩 + 记忆 (12h)
└── F3: Quiz Hand 真实化 (6h)
Week 5+: 功能深化
├── Semantic Router 成熟化 (8h)
├── Pipeline 编辑器增强 (12h)
└── i18n 框架 (12h)
=== 上线 Gate ===
质量轨道 Q1-Q5 全部完成 = 可发布
5. 成功标准
上线 Gate (必须全部通过)
docker compose up可成功启动 SaaS 后端(验证现有基础设施)- 反向代理场景下限流正确区分不同客户端 IP
- Admin V2 测试套件 >10 个测试且全部通过
- Desktop 关键 Store 测试 >5 个且全部通过
- 调度任务可创建并可执行(非 STUB)
tsc --noEmit和cargo check零错误- gatewayStore.ts 已完全移除
质量指标 (目标)
- Admin V2 测试覆盖率 >30%(后续迭代提升至 80%)
- Desktop 关键 Store 测试覆盖率 >40%
- TypeScript 严格模式
any数量 Desktop <10 处 - Rust 测试覆盖率 >40%
6. 风险与缓解
| 风险 | 概率 | 影响 | 缓解 |
|---|---|---|---|
| 调度任务执行器集成复杂度超预期 | 中 | 高 | 先实现最简单的 HTTP 触发,后续迭代增加重试 |
| 测试编写发现更多 bug | 高 | 中 | 这是好事,发现的 bug 加入修复列表 |
| gatewayStore 移除导致间接依赖断裂 | 中 | 高 | 先审查所有导入,添加弃用警告阶段 |
| 技能市场 skill_list 返回数据不包含分类 | 中 | 低 | 前端基于 SKILL.md 路径或关键词自动分类 |
7. 不包含的内容
以下功能明确不在此设计范围内:
- Predictor/Lead Hand 实现(需产品定义)
- 插件系统(需安全沙盒设计)
- 多用户协作(需架构设计)
- Token Pool 计费系统(需商业化设计)
- 实时配置推送 WebSocket(当前拉取模式足够)
- Redis 持久化限流(单实例部署暂不需要)