# Implementation Plan: 对话历史租户分组展示 (conversation-tenant-view) ## Overview 将对话历史页面从扁平会话列表改造为两层结构:第一层按 `tenant_id` 分组展示租户汇总卡片,第二层展示租户下的会话列表。改造涉及 ConversationHistoryManager 业务逻辑层、Flask API 层、前端 dashboard.js 三个层面。交互模式与知识库租户分组视图保持一致。 ## Tasks - [x] 1. ConversationHistoryManager 新增 get_tenant_summary 方法 - [x] 1.1 在 `src/dialogue/conversation_history.py` 中新增 `get_tenant_summary()` 方法 - 使用 SQLAlchemy `GROUP BY ChatSession.tenant_id` 聚合所有 ChatSession 记录 - 计算每个租户的 `session_count`(会话总数)、`message_count`(消息总数,sum of message_count)、`active_session_count`(status=='active' 的会话数)、`last_active_time`(max of updated_at) - 按 `last_active_time` 降序排列 - 数据库异常时返回空列表 `[]`,记录 error 日志 - 无 ChatSession 记录时返回空列表 `[]` - _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6_ - [ ]* 1.2 为 get_tenant_summary 编写属性测试 - **Property 1: Tenant summary aggregation correctness** - **Property 2: Tenant summary sorted by last_active_time descending** - 使用 `hypothesis` 生成随机 ChatSession 列表(混合 tenant_id、status、message_count),验证聚合正确性和排序 - **Validates: Requirements 1.1, 1.2, 1.3, 1.4, 1.5** - [x] 2. ConversationHistoryManager 现有方法增加 tenant_id 过滤 - [x] 2.1 为 `get_sessions_paginated()` 增加 `tenant_id` 可选参数 - 在 `src/dialogue/conversation_history.py` 中修改方法签名,增加 `tenant_id: Optional[str] = None` - 当 `tenant_id` 不为 None 时,在查询中增加 `ChatSession.tenant_id == tenant_id` 过滤条件 - 返回结构不变,仅过滤范围缩小 - _Requirements: 2.1, 2.2, 2.3, 2.5_ - [ ]* 2.2 为 get_sessions_paginated 的 tenant_id 过滤编写属性测试 - **Property 3: Session filtering by tenant, status, and search** - **Property 4: Pagination consistency with tenant filter** - **Validates: Requirements 2.1, 2.2, 2.3** - [x] 2.3 为 `get_conversation_analytics()` 增加 `tenant_id` 可选参数 - 当 `tenant_id` 不为 None 时,所有统计查询增加 `ChatSession.tenant_id == tenant_id` 和 `Conversation.tenant_id == tenant_id` 过滤 - 返回结构不变 - _Requirements: 8.3, 8.4_ - [ ]* 2.4 为 get_conversation_analytics 的 tenant_id 过滤编写属性测试 - **Property 7: Analytics scoped to tenant** - **Validates: Requirements 8.3, 8.4** - [x] 3. Checkpoint - 确保后端业务逻辑层完成 - Ensure all tests pass, ask the user if questions arise. - [x] 4. Conversations API 层新增和修改端点 - [x] 4.1 在 `src/web/blueprints/conversations.py` 中新增 `GET /api/conversations/tenants` 端点 - 调用 `history_manager.get_tenant_summary()` 返回租户汇总 JSON 数组 - 使用 try/except 包裹,异常时返回 HTTP 500 - _Requirements: 1.1, 1.5, 1.6, 1.7_ - [x] 4.2 修改 `GET /api/conversations/sessions` 端点,增加 `tenant_id` 查询参数支持 - 从 `request.args` 获取 `tenant_id` 参数,传递给 `history_manager.get_sessions_paginated()` - _Requirements: 2.1, 2.2, 2.3, 2.4_ - [x] 4.3 修改 `GET /api/conversations/analytics` 端点,增加 `tenant_id` 查询参数支持 - 从 `request.args` 获取 `tenant_id` 参数,传递给 `history_manager.get_conversation_analytics()` - _Requirements: 8.3, 8.4_ - [ ]* 4.4 为新增和修改的 API 端点编写单元测试 - 测试 `/api/conversations/tenants` 返回正确的汇总数据 - 测试各端点的 `tenant_id` 参数过滤行为 - 测试空数据和异常情况 - _Requirements: 1.1, 1.6, 1.7, 2.4_ - [x] 5. Checkpoint - 确保后端 API 层完成 - Ensure all tests pass, ask the user if questions arise. - [x] 6. 前端 Tenant_List_View(租户列表视图) - [x] 6.1 在 `src/web/static/js/dashboard.js` 中实现 `loadConversationTenantList()` 函数 - 请求 `GET /api/conversations/tenants` 获取租户汇总数据 - 渲染租户卡片列表,每张卡片展示 `tenant_id`、`session_count`、`message_count`、`active_session_count`、`last_active_time` - 添加加载中 spinner 状态 - 无租户时展示空状态占位提示 - 卡片点击事件绑定,调用 `loadConversationTenantDetail(tenantId)` - _Requirements: 3.1, 3.2, 3.3, 3.4_ - [x] 6.2 实现刷新按钮功能 - 在对话历史 tab 区域添加刷新按钮,点击时重新调用 `loadConversationTenantList()` - _Requirements: 3.5_ - [x] 7. 前端 Tenant_Detail_View(租户详情视图) - [x] 7.1 实现 `loadConversationTenantDetail(tenantId, page)` 函数 - 请求 `GET /api/conversations/sessions?tenant_id=X&page=P&per_page=N` 获取会话列表 - 渲染会话表格,展示 title、message_count、status、source、created_at、updated_at - 实现分页控件 - 支持 status 和 date_filter 筛选 - _Requirements: 4.1, 4.2, 4.5, 4.6_ - [x] 7.2 实现面包屑导航 `renderConversationBreadcrumb(tenantId, sessionTitle)` - 展示 "对话历史 > {tenant_id}" 面包屑(租户详情视图) - 展示 "对话历史 > {tenant_id} > {session_title}" 面包屑(消息详情视图) - 点击 "对话历史" 链接时调用 `loadConversationTenantList()` 返回租户列表视图 - 点击 "{tenant_id}" 链接时调用 `loadConversationTenantDetail(tenantId)` 返回租户详情视图 - 管理 `conversationCurrentTenantId` 状态变量控制视图层级 - _Requirements: 4.3, 4.4, 5.3, 5.4_ - [x] 7.3 在 Tenant_Detail_View 中集成会话管理操作 - 每行会话提供删除按钮,调用 `DELETE /api/conversations/sessions/` - 删除成功后刷新当前租户详情视图 - 删除所有会话后自动返回租户列表视图并移除空租户卡片 - 操作失败时通过 `showNotification` 展示错误提示 - _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5_ - [ ]* 7.4 为删除操作编写属性测试 - **Property 5: Session deletion removes session and all associated messages** - **Validates: Requirements 6.2** - [x] 8. 前端搜索和统计面板适配 - [x] 8.1 修改搜索功能 `searchConversationSessions()` - 在 Tenant_Detail_View 中搜索时自动附加 `tenant_id` 参数 - 清空搜索时恢复当前租户的完整分页列表 - _Requirements: 7.1, 7.2, 7.3_ - [ ]* 8.2 为搜索范围限定编写属性测试 - **Property 6: Search results scoped to tenant** - **Validates: Requirements 7.1, 7.2** - [x] 8.3 修改 `loadConversationStats(tenantId)` 函数 - 当 `conversationCurrentTenantId` 为 null 时请求全局统计 - 当 `conversationCurrentTenantId` 有值时请求 `GET /api/conversations/analytics?tenant_id=X` - _Requirements: 8.1, 8.2_ - [x] 9. 前端 HTML 模板更新 - [x] 9.1 在 `src/web/templates/dashboard.html` 的 `#conversation-history-tab` 区域添加必要的 DOM 容器 - 添加面包屑容器、租户卡片列表容器、租户详情容器 - 确保与现有 Bootstrap 5 样式一致,与知识库租户视图风格统一 - _Requirements: 3.1, 4.3_ - [x] 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 - 数据模型 `ChatSession` 和 `Conversation` 已有 `tenant_id` 字段且已建索引,无需数据库迁移 - 交互模式与知识库租户分组视图 (knowledge-tenant-view) 保持一致