docs(wiki): Phase D完成 — 6模块页重构(routing/chat/butler/hands-skills/pipeline/data-model)
- routing.md: 移除Store/lib列表+5节模板 (330→131行) - chat.md: 添加集成契约+不变量 (180→134行) - butler.md: 移除重复→引用memory/hands-skills (215→150行) - hands-skills.md: 5节模板+契约+不变量 (281→170行) - pipeline.md: 添加契约+重组 (157→154行) - data-model.md: 添加契约+双库架构图 (181→153行) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 数据模型
|
||||
updated: 2026-04-21
|
||||
updated: 2026-04-22
|
||||
status: active
|
||||
tags: [module, database, schema]
|
||||
---
|
||||
@@ -9,82 +9,78 @@ tags: [module, database, schema]
|
||||
|
||||
> 从 [[index]] 导航。关联模块: [[saas]] [[memory]]
|
||||
|
||||
## 设计思想
|
||||
## 1. 设计决策
|
||||
|
||||
**双存储架构: PostgreSQL (SaaS 多租户) + SQLite (本地单用户)**
|
||||
**WHY 双存储架构**: PostgreSQL 适合 SaaS 多租户场景 — 42 表支持用户隔离、计费、审计、知识库。SQLite 适合桌面端单用户 — 零配置、嵌入式、本地记忆无需网络。两者完全隔离,通过 SaaS relay + 配置同步桥接。
|
||||
|
||||
- PostgreSQL: SaaS 后端,42 表,42 CREATE TABLE,支持多用户/多 Agent/计费/知识库
|
||||
- SQLite: 本地桌面端,记忆存储 + 会话持久化 + FTS5 全文索引
|
||||
- 两者通过 SaaS relay + 配置同步实现数据桥接
|
||||
**WHY 42 PostgreSQL 表**: 按领域划分为认证(5)、Provider(6)、计费(5)、知识库(7)、其他(19) 五大域,每个域内部高内聚,域间通过外键约束保证引用完整性。
|
||||
|
||||
## 功能清单
|
||||
**WHY FTS5 (SQLite 全文搜索)**: 本地记忆搜索需支持中文。FTS5 的 trigram 分词器原生支持 CJK 字符,无需外部依赖。配合 TF-IDF 权重排序,兼顾搜索精度和零配置部署。
|
||||
|
||||
| 功能 | 描述 | 存储层 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 用户管理 | 账户 CRUD + 角色权限 | PostgreSQL | ✅ |
|
||||
| 认证数据 | JWT + 密码 + TOTP | PostgreSQL | ✅ |
|
||||
| 计费系统 | 订阅/支付/发票/配额 | PostgreSQL | ✅ |
|
||||
| 知识库 | 分类/条目/向量/结构化 | PostgreSQL | ✅ |
|
||||
| 模型管理 | Provider/模型/Key 池 | PostgreSQL | ✅ |
|
||||
| Agent 配置 | 模板/分配/行业 | PostgreSQL | ✅ |
|
||||
| 本地会话 | 会话/消息持久化 | SQLite | ✅ |
|
||||
| 本地记忆 | 记忆 CRUD + FTS5 搜索 | SQLite | ✅ |
|
||||
| 用户画像 | 结构化偏好/兴趣 | SQLite | ✅ |
|
||||
| 轨迹记录 | 工具调用链 + 压缩摘要 | SQLite | ✅ |
|
||||
**WHY 迁移系统**: SaaS 用 SQL 文件迁移 (21 up + 17 down),本地 SQLite 用 schema.rs 程序化迁移。两种策略分别匹配各自部署场景 — PG 需要运维可控的 SQL 脚本,SQLite 需要应用内自动迁移。
|
||||
|
||||
## 代码逻辑
|
||||
**WHY pgvector (deferred)**: knowledge_chunks 表已创建 pgvector 索引,为将来 embedding 语义搜索预留。当前记忆搜索走 FTS5 + TF-IDF,足够满足中文场景。embedding 激活需要 LLM embedding API 调用,尚未排期。
|
||||
|
||||
### PostgreSQL (SaaS) — 42 表
|
||||
## 2. 关键文件 + 数据流
|
||||
|
||||
**迁移文件**: `crates/zclaw-saas/migrations/` (21 up + 17 down)
|
||||
### 核心文件
|
||||
|
||||
#### 认证与账户域 (5 表)
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `crates/zclaw-saas/migrations/` | 21 up SQL 迁移 (42 CREATE TABLE) |
|
||||
| `crates/zclaw-saas/src/models/` | PostgreSQL 数据模型 struct 定义 |
|
||||
| `crates/zclaw-memory/src/schema.rs` | SQLite schema 定义 + 程序化迁移 |
|
||||
| `crates/zclaw-memory/src/store.rs` | SQLite 会话/消息存储 (20 tests) |
|
||||
| `crates/zclaw-memory/src/user_profile_store.rs` | 用户画像存储 (20 tests) |
|
||||
| `crates/zclaw-memory/src/trajectory_store.rs` | 轨迹存储 (9 tests) |
|
||||
| `crates/zclaw-growth/src/storage/sqlite.rs` | FTS5 + TF-IDF 记忆存储 (6 tests) |
|
||||
| `docker-compose.yml` | PostgreSQL 容器配置 |
|
||||
|
||||
| 表 | 说明 | 关键关系 |
|
||||
|----|------|---------|
|
||||
| `accounts` | 用户账户 (邮箱/密码/pwv/角色) | → api_tokens, operation_logs, subscriptions |
|
||||
| `api_tokens` | API 访问令牌 | FK → accounts |
|
||||
| `roles` | 角色定义 | — |
|
||||
| `permission_templates` | 权限模板 | — |
|
||||
| `refresh_tokens` | JWT 刷新令牌 (单次使用) | FK → accounts |
|
||||
### 双库架构
|
||||
|
||||
#### Provider 与模型域 (6 表)
|
||||
```
|
||||
PostgreSQL (SaaS, 42 表) SQLite (本地, 2 库)
|
||||
┌─────────────────────────┐ ┌──────────────────────────┐
|
||||
│ 认证: accounts/tokens │ │ data.db: │
|
||||
│ Provider: keys/models │ │ agents, sessions, │
|
||||
│ 计费: plans/invoices │ │ messages, kv_store, │
|
||||
│ 知识库: items/chunks │ │ facts, user_profiles, │
|
||||
│ 配置/日志/Webhook │ │ trajectory_events, │
|
||||
│ 行业: industries │ │ hand_runs │
|
||||
└─────────────────────────┘ ├──────────────────────────┤
|
||||
↑ SaaS API │ memories.db: │
|
||||
│ relay_tasks │ memories (FTS5), │
|
||||
│ usage_records │ metadata │
|
||||
└──────────────────────────┘
|
||||
↑ 本地 API
|
||||
```
|
||||
|
||||
| 表 | 说明 | 关键关系 |
|
||||
|----|------|---------|
|
||||
| `providers` | LLM Provider 配置 | → models, provider_keys |
|
||||
| `models` | 模型定义 (白名单) | FK → providers |
|
||||
| `provider_keys` | 加密 API Key 池 | FK → providers, accounts |
|
||||
| `key_usage_window` | Key RPM/TPM 滑动窗口 | — |
|
||||
| `model_groups` | 模型组 (故障转移) | → model_group_members |
|
||||
| `model_group_members` | 组成员 | FK → model_groups, providers |
|
||||
### 集成契约
|
||||
|
||||
#### 计费域 (5 表)
|
||||
| 方向 | 接口 | 说明 |
|
||||
|------|------|------|
|
||||
| Called by ← saas | PostgreSQL 连接池 (sqlx) | 所有 SaaS API 端点通过连接池访问,Pool 大小可配置 |
|
||||
| Called by ← memory | SQLite/FTS5 连接 (rusqlite) | 记忆提取/检索/注入 通过 zclaw-memory + zclaw-growth |
|
||||
| Provides → growth | TF-IDF + FTS5 索引 | zclaw-growth 调用 FTS5 全文搜索 + TF-IDF 语义评分 |
|
||||
| Called by ← kernel | schema.rs 程序化迁移 | 桌面端启动时自动执行 SQLite 迁移,版本由 schema_version 表跟踪 |
|
||||
| Provides → butler | user_profiles + facts | 管家模式读取用户画像和提取事实进行上下文注入 |
|
||||
|
||||
| 表 | 说明 | 关键关系 |
|
||||
|----|------|---------|
|
||||
| `billing_plans` | 计费计划目录 | → subscriptions |
|
||||
| `billing_subscriptions` | 用户订阅 | FK → accounts, billing_plans |
|
||||
| `billing_invoices` | 发票 | FK → accounts, subscriptions, plans |
|
||||
| `billing_payments` | 支付记录 | FK → billing_invoices, accounts |
|
||||
| `billing_usage_quotas` | 用量配额 | FK → accounts, billing_plans |
|
||||
## 3. 代码逻辑
|
||||
|
||||
#### 知识库域 (7 表)
|
||||
### PostgreSQL 域划分 (42 表)
|
||||
|
||||
| 表 | 说明 | 关键关系 |
|
||||
|----|------|---------|
|
||||
| `knowledge_categories` | 分类 (自引用 parent_id) | → knowledge_items |
|
||||
| `knowledge_items` | 知识条目 | FK → categories, accounts |
|
||||
| `knowledge_chunks` | 向量分块 (pgvector) | FK → knowledge_items |
|
||||
| `knowledge_versions` | 版本历史 | FK → items, chunks, accounts |
|
||||
| `knowledge_usage` | 使用统计 | FK → knowledge_items |
|
||||
| `structured_sources` | 结构化数据源 | FK → accounts |
|
||||
| `structured_rows` | 结构化行数据 | FK → structured_sources |
|
||||
**认证域 (5 表)**: `accounts` (邮箱/密码/pwv/角色) → `api_tokens`, `refresh_tokens` (JWT 单次使用), `roles`, `permission_templates`
|
||||
|
||||
#### 其他域 (19 表)
|
||||
**Provider 域 (6 表)**: `providers` → `models` (白名单), `provider_keys` (加密 API Key 池), `key_usage_window` (RPM/TPM 滑动窗口), `model_groups` → `model_group_members` (故障转移组)
|
||||
|
||||
| 域 | 表 | 说明 |
|
||||
|----|----|------|
|
||||
**计费域 (5 表)**: `billing_plans` → `billing_subscriptions` (用户订阅) → `billing_invoices` → `billing_payments`, `billing_usage_quotas` (实时递增配额)
|
||||
|
||||
**知识库域 (7 表)**: `knowledge_categories` (自引用树) → `knowledge_items` → `knowledge_chunks` (pgvector 向量), `knowledge_versions`, `knowledge_usage`, `structured_sources` → `structured_rows`
|
||||
|
||||
**其他域 (19 表)**:
|
||||
|
||||
| 子域 | 表 | 说明 |
|
||||
|------|-----|------|
|
||||
| API & Relay | `account_api_keys`, `usage_records`, `relay_tasks` | API Key/用量/异步任务 |
|
||||
| 配置 | `config_items`, `config_sync_log` | KV 配置/同步日志 |
|
||||
| Prompt | `prompt_templates`, `prompt_versions`, `prompt_sync_status` | 模板/版本/同步 |
|
||||
@@ -92,89 +88,66 @@ tags: [module, database, schema]
|
||||
| 设备 | `devices` | 设备管理 |
|
||||
| 遥测 | `operation_logs`, `telemetry_reports`, `saas_schema_version` | 操作日志/统计/版本 |
|
||||
| 调度 | `scheduled_tasks` | 定时任务 |
|
||||
| 限流 | `rate_limit_events` | 限流事件日志 |
|
||||
| 限流 | `rate_limit_events` | 限流事件 (持久化到 PG) |
|
||||
| Webhook | `webhook_subscriptions`, `webhook_deliveries` | Webhook 订阅/投递 |
|
||||
| 行业 | `industries`, `account_industries` | 行业配置/账户关联 |
|
||||
|
||||
### SQLite 本地存储
|
||||
|
||||
**zclaw-memory** (`crates/zclaw-memory/src/schema.rs`):
|
||||
**data.db** (`zclaw-memory/schema.rs`): agents, sessions, messages, kv_store, facts, user_profiles, trajectory_events, compressed_trajectories, hand_runs, schema_version
|
||||
|
||||
| 表 | 说明 | 版本 |
|
||||
|----|------|------|
|
||||
| `agents` | Agent 定义 | v1 |
|
||||
| `sessions` | 聊天会话 | v1, FK → agents |
|
||||
| `messages` | 会话消息 | v1, FK → sessions |
|
||||
| `kv_store` | Agent KV 存储 | v1, FK → agents |
|
||||
| `facts` | 提取的事实 | v2, FK → agents |
|
||||
| `user_profiles` | 用户画像 | v2 |
|
||||
| `trajectory_events` | 工具调用链事件 | v3 |
|
||||
| `compressed_trajectories` | 压缩轨迹摘要 | v3 |
|
||||
| `hand_runs` | Hand 执行追踪 | v1 |
|
||||
| `schema_version` | 迁移版本 | v1 |
|
||||
**memories.db** (`zclaw-growth/storage/sqlite.rs`): memories (uri, memory_type, content, keywords, importance, access_count), metadata (KV)
|
||||
|
||||
**zclaw-growth** (`crates/zclaw-growth/src/storage/sqlite.rs`):
|
||||
### FTS5 虚拟表
|
||||
|
||||
| 表 | 说明 |
|
||||
|----|------|
|
||||
| `memories` | 记忆条目 (uri, memory_type, content, keywords, importance, access_count) |
|
||||
| `metadata` | KV 元数据 |
|
||||
|
||||
**FTS5 虚拟表**:
|
||||
|
||||
| 虚拟表 | 定义 | 分词器 |
|
||||
|--------|------|--------|
|
||||
| `memories_fts` | `fts5(uri, content, keywords)` | `trigram` (CJK 支持) |
|
||||
|
||||
> FTS5 使用 `trigram` 分词器(从 `unicode61` 迁移)支持中文/日文/韩文。CJK 查询零结果时 fallback 到 LIKE 搜索。
|
||||
|
||||
## 数据流
|
||||
|
||||
```
|
||||
桌面端聊天
|
||||
→ SQLite: sessions + messages (本地持久化)
|
||||
→ SaaS Relay: relay_tasks (异步任务追踪)
|
||||
→ PostgreSQL: usage_records (用量记录)
|
||||
|
||||
记忆管道
|
||||
→ SQLite: memories + memories_fts (FTS5 全文索引)
|
||||
→ SQLite: facts + user_profiles (结构化提取)
|
||||
→ PostgreSQL: knowledge_chunks (pgvector 向量, embedding deferred)
|
||||
|
||||
计费闭环
|
||||
→ PostgreSQL: billing_usage_quotas (实时递增)
|
||||
→ PostgreSQL: billing_subscriptions → invoices → payments
|
||||
→ Worker: aggregate_usage (聚合器调度)
|
||||
```sql
|
||||
CREATE VIRTUAL TABLE memories_fts USING fts5(uri, content, keywords, tokenize='trigram');
|
||||
```
|
||||
|
||||
## 测试链路
|
||||
> trigram 分词器从 unicode61 迁移,原生支持 CJK。零结果时 fallback 到 LIKE 搜索。
|
||||
|
||||
| 功能 | 测试文件 | 覆盖状态 |
|
||||
|------|---------|---------|
|
||||
| 全模块 | `crates/zclaw-saas/tests/` (17 文件) | ✅ |
|
||||
| SQL 迁移 | `crates/zclaw-saas/migrations/` (21 up) | ✅ 启动时自动执行 |
|
||||
| 本地存储 | `crates/zclaw-memory/src/store.rs` (20 tests) | ✅ |
|
||||
| 用户画像 | `crates/zclaw-memory/src/user_profile_store.rs` (20 tests) | ✅ |
|
||||
| 轨迹存储 | `crates/zclaw-memory/src/trajectory_store.rs` (9 tests) | ✅ |
|
||||
| 记忆存储 | `crates/zclaw-growth/src/storage/sqlite.rs` (6 tests) | ✅ |
|
||||
### 不变量
|
||||
|
||||
> **SaaS 用 PostgreSQL,本地记忆用 SQLite,两者完全隔离。** 数据不自动同步,仅通过 SaaS relay API 手动触发。
|
||||
> **FTS5 使用 trigram 分词器,中文搜索依赖正确分词。** 极短查询 (1-2 字) 可能 fallback 到 LIKE。
|
||||
> **data.db 与 memories.db 是两个独立的 SQLite 数据库。** zclaw-memory 管理 data.db (会话/画像),zclaw-growth 管理 memories.db (记忆/FTS5)。跨库查询不适用,数据交换通过 Rust API。
|
||||
|
||||
### 测试链路
|
||||
|
||||
| 功能 | 测试文件 | 测试数 |
|
||||
|------|---------|--------|
|
||||
| SaaS 全模块 | `crates/zclaw-saas/tests/` (17 文件) | 集成测试 |
|
||||
| SQL 迁移 | `crates/zclaw-saas/migrations/` (21 up) | 启动时自动执行 |
|
||||
| 本地存储 | `zclaw-memory/src/store.rs` | 20 |
|
||||
| 用户画像 | `zclaw-memory/src/user_profile_store.rs` | 20 |
|
||||
| 轨迹存储 | `zclaw-memory/src/trajectory_store.rs` | 9 |
|
||||
| 记忆存储 | `zclaw-growth/src/storage/sqlite.rs` | 6 |
|
||||
|
||||
## 4. 活跃问题 + 注意事项
|
||||
|
||||
| 优先级 | 问题 | 说明 |
|
||||
|--------|------|------|
|
||||
| P2 | pgvector embedding 未激活 | knowledge_chunks 表索引就绪,generate_embedding Worker 逻辑 deferred |
|
||||
| P3 | FTS5 CJK 极短查询 | trigram 已启用,1-2 字查询可能 fallback 到 LIKE,待真实用户反馈 |
|
||||
| — | 迁移幂等性 | PG 迁移用 `IF NOT EXISTS`,SQLite 迁移用 schema_version 表跟踪 |
|
||||
|
||||
**注意事项**: PostgreSQL 连接需要 `ZCLAW_DATABASE_URL` 或 `saas-config.toml` 中的 `database_url` 配置。本地 SQLite 数据库文件存储在 Tauri 应用数据目录下,卸载应用会丢失数据。`schema.rs` 中的 SQLite 迁移通过 `schema_version` 表跟踪版本号,仅执行增量迁移,不会重建已存在的表。环境变量 `DB_PASSWORD` 支持 `saas-config.toml` 中 `${VAR_NAME}` 插值引用。
|
||||
|
||||
## 关联模块
|
||||
|
||||
- [[saas]] — PostgreSQL 由 SaaS 后端管理
|
||||
- [[memory]] — SQLite 本地记忆存储 + FTS5
|
||||
- [[routing]] — relay_tasks 异步任务追踪
|
||||
- [[saas]] — PostgreSQL 由 SaaS 后端管理,所有 API 端点的数据源
|
||||
- [[memory]] — SQLite 本地记忆存储 + FTS5 全文搜索 + TF-IDF 权重
|
||||
- [[routing]] — relay_tasks 异步任务追踪,连接前端请求和 SaaS 后端
|
||||
- [[security]] — 数据加密: provider_keys AES-256-GCM, 密码 Argon2id, TOTP 独立加密密钥
|
||||
|
||||
## 关键文件
|
||||
## 5. 变更日志
|
||||
|
||||
| 文件 | 职责 |
|
||||
> 最近 5 条与数据模型相关的变更。完整日志见 [[log]]。
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| `crates/zclaw-saas/migrations/` | 21 up SQL 迁移 (42 CREATE TABLE) |
|
||||
| `crates/zclaw-saas/src/models/` | 数据模型 struct 定义 |
|
||||
| `crates/zclaw-memory/src/schema.rs` | SQLite schema 定义 |
|
||||
| `crates/zclaw-growth/src/storage/sqlite.rs` | FTS5 + TF-IDF 存储 |
|
||||
| `docker-compose.yml` | PostgreSQL 容器配置 |
|
||||
|
||||
## 已知问题
|
||||
|
||||
- ⚠️ **pgvector embedding 生成未实现** — 索引就绪,`generate_embedding.rs` Worker 逻辑 deferred
|
||||
- ⚠️ **FTS5 CJK 零结果** — trigram 分词器已启用,极短查询可能仍 fallback 到 LIKE
|
||||
| 2026-04-22 | 跨会话记忆修复: profile_store 连接 + 双数据库统一 + 诊断日志 |
|
||||
| 2026-04-21 | Phase 0+1: 经验积累 reuse_count 修复 + 跨会话检索增强 IdentityRecall 26→54 模式 |
|
||||
| 2026-04-19 | TRUTH.md 数字校准: 42 CREATE TABLE, 38 迁移文件, Rust 101,967 行 |
|
||||
| 2026-04-17 | E2E 测试: 记忆去重+记忆注入+invoice_id+agent隔离修复 |
|
||||
| 2026-04-15 | Heartbeat: health_snapshot 统一收集器,删除 intelligence-client/ 9 废弃文件 |
|
||||
|
||||
Reference in New Issue
Block a user