新增: Phase2 阶段收尾(Sprint 1-20)

重构:删 5 零引用 crate(df-evolve/plugin/stages/task/traceability)+ 清死模块、ai.rs 拆 11 子 module、ai.ts 拆 6 composable、i18n 拆目录
功能:知识库全栈(df-project/scan + CRUD + 时间线 + 前端)、Settings 拆分、appSettings KV 迁移、模型池、LLM 并发 Semaphore
修复:审批持久化根治、ConditionEngine 默认拒绝、NodeRegistry unimplemented 清除、promote 补偿删除、工具结果截断 50KB、路径校验防 symlink 逃逸
文档:B-03 人工审批设计、决策记录三分档、规格契约自检、经验记录、todo 看板、PROGRESS 更新

详见 PROGRESS.md。src-tauri/儿童每日打卡应用/ 与本项目无关,已排除。
This commit is contained in:
2026-06-14 14:08:20 +08:00
parent 98393b4908
commit cf017f81e2
167 changed files with 19549 additions and 6886 deletions

View File

@@ -1,52 +1,140 @@
# df-storage 存储层
> 创建: 2026-06-10 | 状态: 初稿
> 创建: 2026-06-10 | 最后更新: 2026-06-13
---
## 概述
df-storage 是 DevFlow 的数据持久化层,基于 SQLite (rusqlite)负责连接管理、Schema 迁移和 CRUD 操作。
df-storage 是 DevFlow 的数据持久化层,基于 SQLite (rusqlite)负责连接管理、Schema 迁移V1-V8和 CRUD 操作。全部 Repo 由 `impl_repo!` 宏自动生成。
---
## 当前状态
| 功能 | 状态 |
|------|------|
| SQLite 连接管理 | ✅ 已实现 |
| Schema 迁移 (6 张表) | ✅ 已实现 |
| CRUD 操作 | ⬜ 待实施 |
| 事务支持 | ⬜ 待实施 |
| SQLite 连接管理 | ✅ |
| Schema 迁移 V1-V8 | ✅ |
| impl_repo! 宏 CRUD | ✅ |
| KnowledgeRepo含向量| ✅ Sprint 15 |
| 事务支持 | ⬜ 按需 |
## 数据表
---
Phase 1 已创建的 6 张核心表:
## 数据表V1-V8 迁移历史)
1. **ideas** — 想法池
2. **projects** — 项目
3. **tasks** — 任务
4. **workflow_defs** — 工作流定义
5. **workflow_runs** — 工作流执行
6. **artifacts** — 产出物
| 版本 | 新增/变更 |
|------|-----------|
| V1 | ideas / projects / tasks / releases / workflow_executions / node_executions6 张基础表 + 4 索引)|
| V2 | ideas 加 promoted_to/ai_analysis/scorestasks 加 workflow_def_id/base_branchworkflow_executions 加 project_id/task_id新建 branches 表(含 2 索引)|
| V3 | ai_providers / ai_conversations / ai_tool_executionsAI 功能 3 张表)|
| V4 | 幂等补列ai_conversations.archivedPRAGMA 探测,兼容坏库)|
| V5 | 幂等补列ai_conversations.prompt_tokens / completion_tokens / model / modelsToken 用量)|
| V6 | 幂等补列ai_conversations.skill技能注入|
| V7 | 新建 **knowledges**Sprint 15|
| V8 | 幂等补列knowledges.embedding BLOBPhase 5.5 向量检索)|
完整表结构见 `ARCHITECTURE.md` 数据模型章节。
## 依赖关系
### knowledges 表V7
```sql
CREATE TABLE IF NOT EXISTS knowledges (
id TEXT PRIMARY KEY,
kind TEXT NOT NULL DEFAULT 'pitfall',
title TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
tags TEXT, -- JSON array string
status TEXT NOT NULL DEFAULT 'candidate',
confidence TEXT, -- 'high'|'medium'|'low'
reuse_count INTEGER NOT NULL DEFAULT 0,
verified INTEGER NOT NULL DEFAULT 0, -- 0/1
source_project TEXT,
source_ref TEXT,
created_at TEXT NOT NULL, -- 毫秒字符串
updated_at TEXT NOT NULL,
embedding BLOB -- V8 补列f32 little-endian
);
CREATE INDEX IF NOT EXISTS idx_knowledges_status ON knowledges(status);
CREATE INDEX IF NOT EXISTS idx_knowledges_kind ON knowledges(kind);
CREATE INDEX IF NOT EXISTS idx_knowledges_reuse_count ON knowledges(reuse_count DESC);
```
df-core (错误类型、ID 生成)
← df-storage
---
## impl_repo! 宏
自动生成以下方法:`insert` / `get_by_id` / `list_all` / `query` / `update_field` / `update_full` / `delete`
列名白名单ALLOWED_COLUMNS防 SQL 注入,各 Repo 声明各自允许的列。
### 已注册 Repo 列表
| Repo | 表 |
|------|----|
| IdeaRepo | ideas |
| ProjectRepo | projects |
| TaskRepo | tasks |
| ReleaseRepo | releases |
| WorkflowRepo | workflow_executions |
| NodeExecutionRepo | node_executions |
| BranchRepo | branches |
| AiProviderRepo | ai_providers |
| AiConversationRepo | ai_conversations |
| AiToolExecutionRepo | ai_tool_executions |
| **KnowledgeRepo** | **knowledges** |
---
## KnowledgeRepo 自定义方法Sprint 15
| 方法 | 说明 |
|------|------|
| `search(query, kind?, limit)` | LIKE 双分支(有/无 kind 过滤),均含 `WHERE status='published'``ORDER BY reuse_count DESC LIMIT ?`top-N≤3 用于注入 |
| `list_by_status(status)` | CASE WHEN confidence 语义排序High→Medium→Low用于审核收件箱 |
| `increment_reuse_count(id)` | `UPDATE SET reuse_count = reuse_count + 1, updated_at = ?`SQL 原子操作,连带刷 updated_at|
| `top_used(limit)` | published 按 reuse_count DESC热门列表 |
| `set_embedding(id, &[f32])` | UPDATE embedding BLOBf32 little-endian|
| `search_vector(query_vec, limit)` | SELECT published + embedding IS NOT NULL → 纯 Rust 余弦批量比较skip 维度不匹配 |
| `list_non_archived()` | `WHERE status != 'archived'` 全量CASE confidence 语义排序high>medium>low次 created_at DESC → `Vec<KnowledgeRecord>` |
### 向量工具函数
```rust
fn f32s_to_blob(v: &[f32]) -> Vec<u8> // f32 → little-endian bytes
fn blob_to_f32s(b: &[u8]) -> Vec<f32> // bytes → f32chunks_exact(4),尾部非 4 倍数残字节截断丢弃)
fn cosine_similarity(a: &[f32], b: &[f32]) -> f32 // 点积 / (‖a‖‖b‖ + 1e-8 防零除),零向量返回有限值
```
> **不引入 sqlite-vec**:规避 Windows MSVC 下编译 C 扩展的风险。纯 Rust 实现,零外部 C 依赖。
---
## 迁移幂等设计
迁移机制:`schema_version` 表记录当前版本,`MIGRATION_VERSION` 常量为目标版本,`run()``current_version < N` 顺序应用各版本。
### v4 解法PRAGMA 探测列存在性
关键列补建不依赖版本号,用 `PRAGMA table_info(<table>)` 探测实际 schema缺列才 `ALTER TABLE ADD COLUMN`
- 对新库列已由建表带入、老库DDL 正常生效)、坏库(版本号已写入但 DDL 漏生效)三种情况都安全幂等。
- V5/V6/V8 均复用此模式。
---
## 文件结构
```
crates/df-storage/src/
├── lib.rs — 模块入口,导出公共 API
├── connection.rs — SQLite 连接管理
├── schema.rs Schema 定义与迁移
── crud.rs — CRUD 操作 (待创建)
├── lib.rs — 模块入口,导出公共 API
├── db.rs — SQLite 连接管理Database struct
├── migrations.rs — V1-V8 迁移逻辑MIGRATION_VERSION=8
── models.rs — 全部 *Record struct含 KnowledgeRecord
└── crud.rs — impl_repo! 宏 + 全部 Repo含 KnowledgeRepo
```
---
## 相关文档
- [SQLite CRUD 模式](../01-技术文档/SQLite-CRUD模式.md)