Files
zclaw_openfang/wiki/saas.md
iven ed77095a37
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
docs(wiki): 系统性更新 — L0速览+L1模块标准化+L2功能链路映射(33条)
三层架构增强:
- L0 index.md: 用户功能清单+跨模块数据流全景图+导航树增强 (92→143行)
- L1 8个模块页标准化: 功能清单/API接口/测试链路/已知问题
  routing(252→326) chat(101→157) saas(153→230) memory(182→333)
  butler(137→179) middleware(121→159) hands-skills(218→257) pipeline(111→156)
- L1 新增2页: security.md(157行) data-model.md(180行)
- L2 feature-map.md: 33条端到端功能链路映射(408行)

维护机制: CLAUDE.md §8.3 wiki触发规则 5→9条
设计文档: docs/superpowers/specs/2026-04-21-wiki-systematic-overhaul-design.md
2026-04-21 23:48:19 +08:00

231 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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

---
title: SaaS 平台
updated: 2026-04-21
status: active
tags: [module, saas, auth, billing]
---
# SaaS 平台
> 从 [[index]] 导航。关联模块: [[routing]] [[chat]]
## 设计思想
**核心定位: SaaS 是 Tauri 桌面端的中枢,不是独立 Web 应用。**
关键决策:
1. **Token Pool** — 桌面端不持有 LLM API KeySaaS 维护共享 Key 池RPM/TPM 轮换
2. **JWT + Cookie 双通道** — Tauri 用 OS keyring 存 JWT浏览器用 HttpOnly cookie
3. **计费闭环** — 配额实时递增 → 聚合器调度 → mock 支付路由
4. **Admin V2** — 17 页管理后台,管理模型/用户/计费/知识库
## 功能清单
| 功能 | 描述 | 入口文件 | 状态 |
|------|------|----------|------|
| 用户认证 | 注册/登录/JWT刷新/登出 | auth/handlers.rs | ✅ |
| TOTP 2FA | 设置/验证/禁用 | auth/handlers.rs | ✅ |
| Token Pool | RPM/TPM 轮换 Key 分配 | relay/handlers.rs | ✅ |
| 聊天中转 | OpenAI 兼容 relay | relay/handlers.rs | ✅ |
| 计费系统 | 配额递增/订阅/支付回调 | billing/ | ✅ |
| 用户管理 | CRUD/状态/设备/token | account/ | ✅ |
| 模型管理 | Provider/模型/Key CRUD | model_config/ | ✅ |
| Agent 模板 | 模板 CRUD + 自动分配 | agent_template/ | ✅ |
| 知识库 | 分类/条目/搜索/pgvector | knowledge/ | ✅ |
| Prompt 管理 | 版本控制/回滚 | prompt/ | ✅ |
| 角色权限 | RBAC + 权限模板 | role/ | ✅ |
| 行业配置 | 行业 CRUD + 账户分配 | industry/ | ✅ |
| 定时任务 | 任务调度 CRUD | scheduled_task/ | ✅ |
| 用量统计 | Telemetry 上报/查询 | telemetry/ | ✅ |
| 配置同步 | 项 CRUD/分析/seed/sync/diff | migration/ | ✅ |
| Admin Dashboard | 系统概览 + 运营指标 | account/admin_routes | ✅ |
| Mock 支付 | 开发环境模拟支付 | billing/mock_routes | ✅ |
## 代码逻辑
### 认证流
```
用户登录 (POST /api/v1/auth/login)
→ Argon2id + OsRg 盐验证密码
→ 签发 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 + OsRg 随机盐
TOTP 加密: AES-256-GCM + 随机 Nonce
```
### Token 刷新
```
POST /api/v1/auth/refresh
→ 验证 refresh_token (单次使用)
→ 旧 refresh_token 撤销到 DB (rotation 校验)
→ 签发新 access + refresh token
```
### SaaS 模块结构(代码验证)
16 个模块目录 (`crates/zclaw-saas/src/`):
```
account/ agent_template/ auth/ billing/ industry/
knowledge/ migration/ model_config/ models/ prompt/
relay/ role/ scheduled_task/ tasks/ telemetry/ workers/
```
### SaaS API 分布
137 个 `.route()` 调用13 个路由模块 (main.rs `.merge()` 注册)。
| 模块 | 路由注册 | 说明 |
|------|----------|------|
| auth | handlers.rs | 登录/注册/刷新/2FA |
| relay | relay/ | 聊天中转/模型列表/任务 |
| billing | billing/ + callback_routes | 配额/订阅/支付 |
| knowledge | knowledge/ | 知识库 CRUD + pgvector (最大模块) |
| model_config | model_config/ | Provider + 模型管理 |
| account | account/ | 用户管理 |
| agent_template | agent_template/ | Agent 模板 |
| role | role/ | 角色 + 权限 |
| telemetry | telemetry/ | 用量统计 |
| prompt | prompt/ | Prompt 模板 |
| scheduled_task | scheduled_task/ | 定时任务 CRUD |
| industry | industry/ | 行业配置管理 (V13 新增) |
| migration | migration/ | Schema 迁移 |
### 数据表 (42 CREATE TABLE)
38 个 SQL 迁移文件 (21 up + 17 down)42 个 `CREATE TABLE` 语句。
核心表: users, agents, conversations, messages, billing_*, knowledge_*, model_configs, roles, permissions, scheduled_tasks, telemetry, agent_templates, saas_schema_version, user_profiles, trajectory_records, industries, account_industries
### Workers (7 个)
| Worker | 文件 | 职责 |
|--------|------|------|
| log_operation | workers/ | 操作日志 |
| cleanup_rate_limit | workers/ | 限流记录清理 |
| cleanup_refresh_tokens | workers/ | 刷新 token 清理 |
| record_usage | workers/ | 用量记录 |
| update_last_used | workers/ | 模型最后使用更新 |
| aggregate_usage | workers/ | 用量聚合 |
| generate_embedding | workers/ | 内容分块 (embedding deferred) |
## API 接口
~118 个唯一路由,分布在 13 个模块中详见上方「SaaS API 分布」和各模块 `mod.rs`)。
| 模块 | 路由数 | 核心端点 |
|------|--------|---------|
| auth | 9 | POST /auth/{register,login,refresh,logout} + TOTP + password |
| relay | 5 | POST /relay/chat/completions + GET /relay/models |
| billing | 12 | 订阅/用量/支付/mock/回调/invoice |
| knowledge | 24 | 分类/条目/搜索/上传/版本/分析/结构化 |
| model_config | 19 | Provider/模型/Key/模型组/用量 |
| account | 12 | CRUD/状态/token/设备/操作日志/dashboard |
| agent_template | 11 | 模板 CRUD + 创建 Agent + 分配 |
| industry | 8 | 行业 CRUD + 账户分配 |
| prompt | 6 | Prompt CRUD + 版本/回滚 |
| role | 6 | 角色/权限模板 CRUD |
| telemetry | 4 | 上报/统计/日报/审计 |
| scheduled_task | 2 | 定时任务 CRUD |
| migration | 8 | 配置项 CRUD + 分析/seed/sync/diff |
## 测试链路
| 功能 | 测试文件 | 说明 |
|------|---------|------|
| 认证 | `crates/zclaw-saas/tests/auth_test.rs` | 注册/登录/刷新/登出 |
| 认证安全 | `crates/zclaw-saas/tests/auth_security_test.rs` | 安全边界场景 |
| 账户 | `crates/zclaw-saas/tests/account_test.rs` | CRUD/token/设备 |
| 账户安全 | `crates/zclaw-saas/tests/account_security_test.rs` | 安全边界 |
| Agent 模板 | `crates/zclaw-saas/tests/agent_template_test.rs` | 模板 CRUD |
| 计费 | `crates/zclaw-saas/tests/billing_test.rs` | 计划/订阅/支付 |
| 知识库 | `crates/zclaw-saas/tests/knowledge_test.rs` | CRUD/搜索 |
| 模型配置 | `crates/zclaw-saas/tests/model_config_test.rs` | Provider/模型/Key |
| 模型配置扩展 | `crates/zclaw-saas/tests/model_config_extended_test.rs` | 扩展覆盖 |
| Prompt | `crates/zclaw-saas/tests/prompt_test.rs` | 版本管理 |
| 权限矩阵 | `crates/zclaw-saas/tests/permission_matrix_test.rs` | 角色/权限 |
| Relay | `crates/zclaw-saas/tests/relay_test.rs` | 聊天中转 |
| Relay 验证 | `crates/zclaw-saas/tests/relay_validation_test.rs` | 请求验证 |
| 角色 | `crates/zclaw-saas/tests/role_test.rs` | 角色 CRUD |
| 定时任务 | `crates/zclaw-saas/tests/scheduled_task_test.rs` | 任务 CRUD |
| Telemetry | `crates/zclaw-saas/tests/telemetry_test.rs` | 上报/查询 |
| 配置同步 | `crates/zclaw-saas/tests/migration_test.rs` | sync/diff/seed |
| Admin 启动 | `crates/zclaw-saas/tests/smoke_saas.rs` | 启动冒烟 |
| Admin V2 UI | `admin-v2/tests/pages/*.test.tsx` (17文件) | 每页独立测试 |
| 桌面端 SaaS | `tests/desktop/connectionStore.adminRouting.test.ts` | Admin 路由 |
| 桌面端集成 | `tests/desktop/integration/zclaw-api.test.ts` | API 集成 |
## 关联模块
- [[routing]] — SaaS Relay 是 Tauri 的主路径
- [[chat]] — 聊天请求经过 SaaS relay 中转
- [[memory]] — knowledge_chunks 表有 pgvector 索引
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-saas/src/main.rs` | 路由注册入口 (13个 .merge()) |
| `crates/zclaw-saas/src/auth/handlers.rs` | 认证端点 |
| `crates/zclaw-saas/src/relay/` | 聊天中转 |
| `crates/zclaw-saas/src/billing/` | 计费 |
| `crates/zclaw-saas/src/knowledge/` | 知识库 |
| `crates/zclaw-saas/src/workers/` | 7 个后台 Worker |
| `crates/zclaw-saas/migrations/` | SQL 迁移 (38 文件) |
| `admin-v2/src/pages/` | 17 页管理后台(含 Dashboard/Accounts/Billing/Industries/Knowledge/Prompts/Roles/ScheduledTasks/Config 等) |
| `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 加密密钥
## 已知问题
- ⚠️ **Admin 用量统计显示 0/0** — P2 Open。Dashboard 显示 17 requests / 6304 tokens但 Usage 页显示 0/0数据源不一致
- ⚠️ **SaaS Embedding 生成未实现** — Open。pgvector 索引就绪,`generate_embedding.rs` Worker 存在但生成逻辑未实现
- ⚠️ **AuthGuard 竞态条件** — P1-04 Deferred。并发请求时可能绕过认证
-**Dashboard 404** — BUG-H1 已修复。`/api/v1/admin/dashboard` 路由注册遗漏
-**invoice_id 未暴露** — BUG-M1 已修复
-**非 Admin 返回 404 而非 403** — BUG-M4 已修复 (admin_guard_middleware)