- 新增 ConversationHistoryManager.get_tenant_summary() 按租户聚合会话统计 - get_sessions_paginated() 和 get_conversation_analytics() 增加 tenant_id 过滤 - 新增 GET /api/conversations/tenants 租户汇总端点 - sessions 和 analytics API 端点支持 tenant_id 查询参数 - 前端实现租户卡片列表视图和租户详情会话表格视图 - 实现面包屑导航、搜索范围限定、统计面板上下文切换 - 会话删除后自动检测空租户并返回列表视图 - dashboard.html 添加租户视图 DOM 容器 - 交互模式与知识库租户分组视图保持一致
7.9 KiB
Implementation Plan: 知识库租户分组展示 (knowledge-tenant-view)
Overview
将知识库管理页面从扁平列表改造为两层结构:第一层按租户分组展示汇总卡片,第二层展示租户下的知识条目列表。改造涉及 KnowledgeManager 业务逻辑层、Flask API 层、前端 dashboard.js 三个层面。
Tasks
-
1. KnowledgeManager 新增 get_tenant_summary 方法
-
1.1 在
src/knowledge_base/knowledge_manager.py中新增get_tenant_summary()方法- 使用 SQLAlchemy
GROUP BY tenant_id聚合is_active == True的知识条目 - 返回包含
tenant_id、entry_count、verified_count、category_distribution的字典列表 - 按
entry_count降序排列 - 数据库异常时返回空列表
[],记录 error 日志 - Requirements: 1.1, 1.2, 1.3, 1.4, 1.5
- 使用 SQLAlchemy
-
* 1.2 为 get_tenant_summary 编写属性测试
- Property 1: Tenant summary correctly aggregates active entries
- Property 2: Tenant summary sorted by entry_count descending
- 使用
hypothesis生成随机 KnowledgeEntry 列表,验证聚合正确性和排序 - Validates: Requirements 1.1, 1.2, 1.3
-
-
2. KnowledgeManager 现有方法增加 tenant_id 过滤
-
2.1 为
get_knowledge_paginated()增加tenant_id可选参数- 在
src/knowledge_base/knowledge_manager.py中修改方法签名,增加tenant_id: Optional[str] = None - 当
tenant_id不为 None 时,在查询中增加KnowledgeEntry.tenant_id == tenant_id过滤条件 - 返回结构不变,仅过滤范围缩小
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5
- 在
-
* 2.2 为 get_knowledge_paginated 的 tenant_id 过滤编写属性测试
- Property 3: Knowledge entry filtering by tenant, category, and verified status
- Property 4: Pagination consistency with tenant filter
- Validates: Requirements 2.1, 2.2, 2.3
-
2.3 为
search_knowledge()增加tenant_id可选参数- 修改
search_knowledge()、_search_by_embedding()、_search_by_keyword()方法签名 - 当
tenant_id不为 None 时,在查询中增加 tenant_id 过滤条件 - Requirements: 6.2, 6.4
- 修改
-
* 2.4 为 search_knowledge 的 tenant_id 过滤编写属性测试
- Property 6: Search results scoped to tenant
- Validates: Requirements 6.2
-
2.5 为
get_knowledge_stats()增加tenant_id可选参数- 当
tenant_id不为 None 时,所有统计查询增加 tenant_id 过滤 - 返回结构中增加
tenant_id字段(仅当按租户筛选时) - Requirements: 7.3, 7.4
- 当
-
* 2.6 为 get_knowledge_stats 的 tenant_id 过滤编写属性测试
- Property 7: Stats scoped to tenant
- Validates: Requirements 7.3, 7.4
-
2.7 为
add_knowledge_entry()增加tenant_id可选参数- 当
tenant_id不为 None 时,新建条目的tenant_id设为该值 - 当
tenant_id为 None 时,使用get_config().server.tenant_id作为默认值 - Requirements: 5.2
- 当
-
* 2.8 为 add_knowledge_entry 的 tenant_id 关联编写属性测试
- Property 5: New entry tenant association
- Validates: Requirements 5.2
-
-
3. Checkpoint - 确保后端业务逻辑层完成
- Ensure all tests pass, ask the user if questions arise.
-
4. Knowledge API 层新增和修改端点
-
4.1 在
src/web/blueprints/knowledge.py中新增GET /api/knowledge/tenants端点- 调用
knowledge_manager.get_tenant_summary()返回租户汇总 JSON 数组 - 使用
@handle_api_errors装饰器处理异常 - Requirements: 1.1, 1.2, 1.3, 1.4, 1.5
- 调用
-
4.2 修改
GET /api/knowledge端点,增加tenant_id查询参数支持- 从
request.args获取tenant_id参数,传递给get_knowledge_paginated() - Requirements: 2.1, 2.2, 2.3, 2.4
- 从
-
4.3 修改
GET /api/knowledge/stats端点,增加tenant_id查询参数支持- 从
request.args获取tenant_id参数,传递给get_knowledge_stats() - Requirements: 7.3, 7.4
- 从
-
4.4 修改
GET /api/knowledge/search端点,增加tenant_id查询参数支持- 从
request.args获取tenant_id参数,传递给search_knowledge() - Requirements: 6.2
- 从
-
4.5 修改
POST /api/knowledge端点,从请求体读取tenant_id字段- 将
tenant_id传递给add_knowledge_entry() - Requirements: 5.2
- 将
-
* 4.6 为新增和修改的 API 端点编写单元测试
- 测试
/api/knowledge/tenants返回正确的汇总数据 - 测试各端点的
tenant_id参数过滤行为 - 测试空数据和异常情况
- Requirements: 1.1, 1.4, 1.5, 2.4
- 测试
-
-
5. Checkpoint - 确保后端 API 层完成
- Ensure all tests pass, ask the user if questions arise.
-
6. 前端 Tenant_List_View(租户列表视图)
-
6.1 在
src/web/static/js/dashboard.js中实现loadTenantList()函数- 请求
GET /api/knowledge/tenants获取租户汇总数据 - 渲染租户卡片列表,每张卡片展示
tenant_id、entry_count、verified_count - 添加加载中 spinner 状态
- 无租户时展示空状态占位提示
- 卡片点击事件绑定,调用
loadTenantDetail(tenantId) - Requirements: 3.1, 3.2, 3.3, 3.4
- 请求
-
6.2 实现刷新按钮功能
- 在知识库 tab 区域添加刷新按钮,点击时重新调用
loadTenantList() - Requirements: 3.5
- 在知识库 tab 区域添加刷新按钮,点击时重新调用
-
-
7. 前端 Tenant_Detail_View(租户详情视图)
-
7.1 实现
loadTenantDetail(tenantId, page)函数- 请求
GET /api/knowledge?tenant_id=X&page=P&per_page=N获取知识条目 - 渲染知识条目表格,展示 question、answer、category、confidence_score、usage_count、is_verified
- 实现分页控件
- 支持 category 和 verified 筛选下拉框
- Requirements: 4.1, 4.2, 4.5, 4.6
- 请求
-
7.2 实现面包屑导航
renderBreadcrumb(tenantId)- 展示 "知识库 > {tenant_id}" 面包屑
- 点击 "知识库" 链接时调用
loadTenantList()返回租户列表视图 - 管理
currentTenantId状态变量控制视图层级 - Requirements: 4.3, 4.4
-
7.3 在 Tenant_Detail_View 中集成知识条目操作按钮
- 复用现有的添加、删除、验证、取消验证按钮逻辑
- 添加知识条目时自动设置
tenant_id为当前选中的租户 - 批量操作(批量删除、批量验证、批量取消验证)后刷新当前视图
- 删除所有条目后自动返回租户列表视图
- 操作失败时通过
showNotification展示错误提示 - Requirements: 5.1, 5.2, 5.3, 5.4, 5.5
-
-
8. 前端搜索和统计面板适配
-
8.1 修改搜索功能,在 Tenant_Detail_View 中自动附加
tenant_id参数- 搜索请求附加
&tenant_id=currentTenantId - 清空搜索时恢复当前租户的完整分页列表
- Requirements: 6.1, 6.2, 6.3
- 搜索请求附加
-
8.2 修改
loadKnowledgeStats()函数,根据视图层级请求不同统计- 当
currentTenantId为 null 时请求全局统计 - 当
currentTenantId有值时请求GET /api/knowledge/stats?tenant_id=X - Requirements: 7.1, 7.2
- 当
-
-
9. 前端 HTML 模板更新
- 9.1 在
src/web/templates/dashboard.html的#knowledge-tab区域添加必要的 DOM 容器- 添加面包屑容器、租户卡片列表容器、租户详情容器
- 确保与现有 Bootstrap 5 样式一致
- Requirements: 3.1, 4.3
- 9.1 在
-
10. Final checkpoint - 确保所有功能集成完成
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks marked with
*are optional and can be skipped for faster MVP - Each task references specific requirements for traceability
- Checkpoints ensure incremental validation
- Property tests validate universal correctness properties from the design document
- 数据模型
KnowledgeEntry已有tenant_id字段且已建索引,无需数据库迁移