新增: 三实体列表查询维度补全(status/关键词/排序/分页下沉后端)

任务/项目/灵感三实体新增 list_by_query 动态 WHERE(累积式 where_clauses
+params_vec 收口)+ order_by 白名单防注入 + limit/offset 钳制。命令层
list_{tasks,projects,ideas} 吃 Option<XxxQuery> 双参向后兼容(旧无参/单参
路径等价全量)。前端 Tasks/Ideas status/keyword 筛选下沉后端 query。

F-260621-02
This commit is contained in:
2026-06-22 01:03:37 +08:00
parent 72e57c6232
commit c9b6e28433
18 changed files with 878 additions and 76 deletions

View File

@@ -0,0 +1,114 @@
# F-260621-02 查询能力维度补全方案(任务/项目/灵感)
> **状态**:方案设计(待办登记),待排期实施
> **日期**:2026-06-21
> **范围**:DevFlow 任务/项目/灵感三实体**列表查询维度**补全
> **关联**:[PERF-260619-01 查询效率优化方案](./查询效率优化方案-2026-06-19.md)(查询**性能**,与本方案正交) / todo.md F-15-03 分页(本方案细化)
> **本轮排查结论**:本轮仅登记待办,不实施代码。
---
## 一、现状盘点
### 1.1 详情查询(已齐全,无需动)
| 实体 | 详情接口 | 位置 |
|------|---------|------|
| 任务 | `get_task_by_id` | `src-tauri/src/commands/task.rs:58` |
| 项目 | `get_project(id)` | `src-tauri/src/commands/project.rs:193` |
| 灵感 | `get_idea`(宏生成) | `src-tauri/src/commands/idea.rs` |
均按主键查,返回 `Option<Record>`/`Record`。这部分能力完整。
### 1.2 列表查询(本方案重点,维度薄弱)
| 实体 | 后端 WHERE 维度 | 前端筛选 | 分页 | 搜索 | 排序 |
|------|----------------|---------|------|------|------|
| 任务 | `project_id`(仅此 1 维,`task.rs:41`) | status 内存 filter | ❌ | ❌ | 固定 created_at DESC |
| 项目 | 仅软删(`deleted_at`) | ❌ 无 UI | ❌ | ❌ | 固定 created_at DESC |
| 灵感 | `status`(宏 `query`,单字段) | status+关键词+排序**全前端** | ❌ | ❌(后端) | 前端 computed |
| 知识库 | status+kind+LIKE+向量 | — | ✅ limit | ✅ LIKE+向量 | ✅ 多维 |
**核心问题**:任务/项目/灵感的筛选全堆在**前端内存**(`Tasks.vue:177` `.filter()` / `Ideas.vue:184` computed),后端只给"按 project_id 拉"或"全量拉"。数据量增长后线性退化,且无法做关键词/多条件。
> 注:AI agent 用的 `list_tasks` 工具(`tool_registry.rs`)另有 status 内存过滤,但那是给 LLM 调的,非 UI 查询链路。
---
## 二、缺口清单
1. **status 未下沉后端**:任务/灵感的 status 过滤是前端 `.filter()`,后端 `list_tasks`/`list_ideas` 未支持 status 维度 SQL WHERE。
2. **无关键词搜索**:三实体均无 title/description 文本检索。
3. **无排序选项**:全固定 `created_at DESC`,无按优先级/状态/更新时间排序。
4. **无分页**:全量返回,无 LIMIT/OFFSET。数据量大时撑爆前端内存 + IPC。
5. **索引缺口**:tasks 缺 `idx_tasks_priority`/`idx_tasks_assignee`(已有 `idx_tasks_status`/`idx_tasks_project_id`,`migrations.rs:763-764`);projects/ideas 表无任何显式索引(仅主键)。
---
## 三、可复用基建(非从零造)
知识库模块(`KnowledgeRepo`)是唯一查询能力完善的实体,其模式可直接推广:
| 模式 | 位置 | 复用点 |
|------|------|--------|
| **动态 WHERE 拼接** | `crates/df-storage/src/crud/idea_repo.rs:200` `KnowledgeRepo::search` | if-let 分支按可选条件拼 SQL + 分支化参数绑定 |
| **分页 + 上限钳制** | `crates/df-storage/src/crud/conversation_repo.rs:270` `list_recent` | `LIMIT ?1 OFFSET ?2` + `limit.min(200)` 防滥用 |
| **统一查询入口** | `crates/df-storage/src/crud/mod.rs` `impl_repo!``query(field,value)` | 单字段白名单动态查询,可扩展为多条件 |
SQL 库为 `rusqlite`,`?N` 占位符 + `params![]` 宏绑定参数。
---
## 四、设计方向
### 4.1 统一查询结构(对齐 [[no-patch-groundwork]],根本设计非补丁堆砌)
三实体各引入可选字段的 `XxxQuery` struct,而非逐个加 IPC 参数:
```rust
// 示意:TaskQuery(项目/灵感同构)
pub struct TaskQuery {
pub project_id: Option<String>,
pub status: Option<String>,
pub priority: Option<i32>,
pub assignee: Option<String>,
pub keyword: Option<String>, // title/description LIKE %kw%
pub order_by: Option<String>, // created_at/updated_at/priority/status
pub limit: Option<u32>, // 钳制上限(对齐 list_recent)
pub offset: Option<u32>,
}
```
### 4.2 repo 层:`list_by_query` 动态 WHERE
复用 `KnowledgeRepo::search` 模式:动态拼 `WHERE` 子句 + 参数绑定。`order_by` 走白名单(防 SQL 注入,对齐 `impl_repo!` 宏的 `validate_column_name`)。
### 4.3 命令层:`list_xxx` 吃 query,向后兼容
`list_tasks(query: Option<TaskQuery>)`。旧调用方不传(或传空 query)→ 等价全量(当前行为),零破坏。新调用方按需传筛选。
### 4.4 前端对接
- `api/{task,project,idea}.ts`:暴露 query 参数
- `stores/project/*.ts`:`loadXxx(query)` 透传
- 视图:现有前端内存 filter 改为构造 query 调后端;补 UI 控件(优先级筛选/搜索框;分页器待数据量大再加)
---
## 五、实施分阶段
| 阶段 | 维度 | 优先级 | 说明 |
|------|------|--------|------|
| P1 | status 下沉后端 | 中 | 任务 + 灵感 status 过滤从前端 filter 改后端 WHERE(已有 `idx_tasks_status` 索引) |
| P2 | 关键词搜索(LIKE) | 中 | title/description `LIKE %kw%`,对齐知识库。加搜索框 UI。不上 FTS5(需虚拟表 + 触发器同步,过度) |
| P3 | 排序 + 分页 | 低 | 排序选项(优先级/状态/更新时间)+ limit 钳制防爆。UI 分页器待数据量 > 百级再加 |
> 数据量:当前 ~6 项目 ~15 任务,性能无感。P1/P2 是能力补全,P3 性能驱动——数据量上来才有必要,与 PERF-260619-01 性能方案协同。
---
## 六、关联文档
- [PERF-260619-01 查询效率优化方案](./查询效率优化方案-2026-06-19.md)——查询**性能**(全量加载/无缓存/无字段投影),与本方案(查询**维度**)正交,实施时协同改 `list_xxx`
- todo.md `F-15-03 分页`——本方案 P3 细化。
- todo.md `BUG-260621-01`——run_workflow 空 dag 缺陷(本轮同批登记,与本查询方案独立)。

View File

@@ -50,6 +50,16 @@
---
### 🔍 2026-06-21 查询能力缺口 + run_workflow 缺陷(本轮排查登记·未实施)
> 用户排查任务/项目/灵感查询能力现状,登记缺口为待办/缺陷,本轮不实施代码。详单见 [查询能力补全方案-2026-06-21.md](./02-架构设计/专项设计/查询能力补全方案-2026-06-21.md)。
- [ ] BUG-260621-01 [P1🔴·确定修法] — **run_workflow 空 dag 反序列化失败(missing field nodes),阻塞任务工作流推进**。前端 TaskDetail.vue:333 传 `{}` 空 dag(设计意图:空 dag+target_status→template_for 选模板),但 DagDef.nodes/edges(dag_def.rs:9-10)无 #[serde(default)],serde 反序列化挡在选模板逻辑(workflow.rs:91)之前。修法(2 行):nodes/edges 各加 #[serde(default)]。非空 dag 零回归,空 dag 走选模板分支符合设计。— `crates/df-workflow/src/dag_def.rs`(:9-10) + `src/views/TaskDetail.vue`(:333)
- [x] F-260621-02 [P2] — **任务/项目/灵感列表查询维度补全(下沉后端+关键词搜索+排序分页)****2026-06-22 实施**:三实体新增 `list_by_query` 动态 WHERE(累积式 where_clauses+params_vec 收口)+ order_by 白名单防注入 + limit/offset 钳制;命令层 `list_{tasks,projects,ideas}``Option<XxxQuery>` 双参向后兼容(旧无参/单参路径等价全量);前端 Tasks/Ideas status/keyword 筛选下沉后端 query(Tasks.vue buildTaskQuery / Ideas.vue watch 防抖)。索引缺口(idx_tasks_priority/assignee)与 P3 排序分页 UI 待数据量驱动再加。详见查询能力补全方案-2026-06-21.md。— `commands/{task,project,idea}.rs` + `crates/df-storage/src/crud/{task,project,idea}_repo.rs` + `src/api/{task,project,idea}.ts` + `src/views/{Tasks,Projects,Ideas}.vue`
---
### 📋 编排推进总览2026-06-18 更新)
未完成待办按可执行性分 8 组(详细条目见下方各分类,勿重复记录):