Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
问题: 旧 wiki 按文档类型组织(architecture/data-flows/file-map), 修复 Butler Router 需要读 4 个文件才能拼凑全貌。 且 SaaS Relay 主路径 vs 本地降级的优先级描述不准确。 重构为模块化结构,每个模块页自包含: - 设计思想: 为什么这样设计 - 代码逻辑: 数据流 + 关键代码 - 关联模块: 依赖关系 新增模块页: - routing.md: 客户端路由 (明确 SaaS Relay 是主路径,不是本地模式) - chat.md: 聊天系统 (3种实现 + Token Pool 中转机制) - butler.md: 管家模式 (路由/冷启动/痛点/双模式UI) - memory.md: 记忆管道 (提取→FTS5→检索→注入) - saas.md: SaaS平台 (认证/Token池/计费/Admin) - middleware.md: 中间件链 (14层 + 优先级) - hands-skills.md: Hands(9) + Skills(75) - pipeline.md: Pipeline DSL 删除旧文件: architecture.md, data-flows.md, module-status.md, file-map.md (内容已分布到对应模块页中) 添加 .gitignore 排除 Obsidian 工作区状态文件
4.2 KiB
4.2 KiB
title, updated, status, tags
| title | updated | status | tags | ||||
|---|---|---|---|---|---|---|---|
| SaaS 平台 | 2026-04-11 | active |
|
SaaS 平台
设计思想
核心定位: SaaS 是 Tauri 桌面端的中枢,不是独立 Web 应用。
关键决策:
- Token Pool — 桌面端不持有 LLM API Key,SaaS 维护共享 Key 池,RPM/TPM 轮换
- JWT + Cookie 双通道 — Tauri 用 OS keyring 存 JWT,浏览器用 HttpOnly cookie
- 计费闭环 — 配额实时递增 → 聚合器调度 → mock 支付路由
- Admin V2 — 15 页管理后台,管理模型/用户/计费/知识库
代码逻辑
认证流
用户登录 (POST /api/v1/auth/login)
→ Argon2id + OsRng 盐验证密码
→ 签发 JWT (Claims: user_id, role, pwv)
→ set_auth_cookies():
zclaw_access_token (path:/api, 2h TTL, HttpOnly)
zclaw_refresh_token (path:/api/v1/auth, 7d TTL, HttpOnly)
Secure: dev=false, prod=true | SameSite=Strict
前端存储:
→ Tauri: OS keyring → saasStore.token
→ 浏览器: HttpOnly Cookie (JS 不可读)
→ localStorage: saasUrl + account 信息 (非敏感)
Token 池 + 限流
SaaS Relay 收到 LLM 请求 (POST /api/v1/relay/chat/completions)
→ 验证 JWT → 提取 user_id
→ 从 Token Pool 选择可用 Key (RPM/TPM 轮换)
→ 转发请求到真实 LLM API
→ 记录 usage (record_usage worker)
→ 返回响应
限流规则:
→ /api/auth/login: 5次/分钟/IP (防暴力) + 持久化到 PostgreSQL
→ /api/auth/register: 3次/小时/IP (防刷注册)
→ 公共端点: 20次/分钟/IP
密码安全
JWT password_version (pwv):
→ JWT Claims 含 pwv 字段
→ 每次验证 JWT 时比对 Claims.pwv vs DB.pwv
→ 修改密码 → DB.pwv 递增 → 所有旧 JWT 自动失效
密码存储: Argon2id + OsRng 随机盐
TOTP 加密: AES-256-GCM + 随机 Nonce
Token 刷新
POST /api/v1/auth/refresh
→ 验证 refresh_token (单次使用)
→ 旧 refresh_token 撤销到 DB (rotation 校验)
→ 签发新 access + refresh token
SaaS API 分布
12 个路由模块,140 端点:
| 模块 | 端点数 | 说明 |
|---|---|---|
| auth | ~10 | 登录/注册/刷新/2FA |
| relay | ~5 | 聊天中转/模型列表/任务 |
| billing | 10 | 配额/订阅/支付 |
| knowledge | 23 | 知识库 CRUD + pgvector |
| model_config | ~8 | Provider + 模型管理 |
| account | ~8 | 用户管理 |
| agent_template | ~8 | Agent 模板 |
| role | 11 | 角色 + 权限 |
| telemetry | ~5 | 用量统计 |
| prompt | ~5 | Prompt 模板 |
| scheduled_task | 5 | 定时任务 CRUD |
| migration | ~2 | Schema 迁移 |
数据表 (34 个)
核心: users, agents, conversations, messages, billing_, knowledge_, model_configs, roles, permissions, scheduled_tasks, telemetry, agent_templates, saas_schema_version
Workers (7 个)
| Worker | 职责 |
|---|---|
| log_operation | 操作日志 |
| cleanup_rate_limit | 限流记录清理 |
| cleanup_refresh_tokens | 刷新 token 清理 |
| record_usage | 用量记录 |
| update_last_used | 模型最后使用更新 |
| aggregate_usage | 用量聚合 |
| generate_embedding | 内容分块 (Phase 2 embedding deferred) |
关联模块
- routing — SaaS Relay 是 Tauri 的主路径
- chat — 聊天请求经过 SaaS relay 中转
- memory — knowledge_chunks 表有 pgvector 索引
关键文件
| 文件 | 职责 |
|---|---|
crates/zclaw-saas/src/auth/handlers.rs |
认证端点 |
crates/zclaw-saas/src/relay/ |
聊天中转 |
crates/zclaw-saas/src/billing/ |
计费 |
crates/zclaw-saas/src/knowledge/ |
知识库 (23 API) |
crates/zclaw-saas/src/workers/ |
7 个后台 Worker |
crates/zclaw-saas/migrations/ |
SQL 迁移 (34 表) |
admin-v2/src/pages/ |
15 页管理后台 |
desktop/src/lib/saas-client.ts |
前端 SaaS API 客户端 |
desktop/src/store/saasStore.ts |
SaaS 认证状态 |
安全
完整审计: docs/features/SECURITY_PENETRATION_TEST_V1.md
- CORS 白名单 (生产缺失拒绝启动)
- Cookie Secure (dev=false, prod=true)
- JWT 签名密钥 >= 32 字符 (release fallback 拒绝启动)
- 独立 TOTP 加密密钥