Files
zn-ai/docs/Knowledge-Docs-Refactor-Plan.md
duanshuwen 5cc9b86e1f refactor: update knowledge document types and API client interfaces
- Refactored types in `Knowledge/types.ts` to introduce new interfaces for document handling.
- Added `KnowledgeDocItem`, `KnowledgeDocsListResponse`, `KnowledgeDocsUploadInput`, `KnowledgeDocsUploadResponse`, and `KnowledgeDocsDeleteResponse` for better structure and clarity.
- Updated `KnowledgeDocsApiClient` interface to include methods for listing, uploading, and deleting documents.

fix: replace deprecated icons in AccountSettingsPanel and SettingMenu

- Replaced `CheckCircleIcon` with `CheckCircle` from `lucide-react` in `AccountSettingsPanel.tsx`.
- Updated `SettingMenu.tsx` to use `Settings` and `User` from `lucide-react` instead of custom icons.

test: add tests for knowledge docs routes and KnowledgePage

- Created `knowledge-docs-routes.test.ts` to test API routes for listing, uploading, and deleting knowledge documents.
- Added `knowledge-page.test.tsx` to test the rendering and functionality of the KnowledgePage component, including document loading and deletion.
2026-04-19 09:40:07 +08:00

556 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Knowledge 页面文档管理重构计划
## 1. 目标
本次重构不是继续扩展当前 `Knowledge/index.tsx` 里的“房型管理 / 事件管理”演示逻辑,也不是在旧页面里增加一个“文档 Tab”。
本次方案明确采用替换式重构:
1. 直接抛弃 `Knowledge` 现有功能
2. 直接删除 `roomType` / `event` 双业务模型
3. 直接把 `Knowledge` 页面改造成面向本地文档目录的管理页
4. 不做旧交互兼容,不保留旧状态,不做混合页过渡
产品需求:
1. 提供上传文件按钮
2. 上传文件保存到 `zn-ai/docs` 目录
3. 文件列表展示:
- 文件名称
- 文件大小
- 修改日期
- 文件类型
4. 每条文件支持删除
5. 视觉 UI 沿用当前 `Knowledge` 页和站内已有风格
一句话目标:
-`Knowledge` 页面从“重业务 demo 页”直接替换成“本地 docs 目录文件管理页”。
## 2. 当前现状
## 2.1 渲染层现状
当前 [`src/pages/Knowledge/index.tsx`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/index.tsx:1) 是一个单文件重页面,主要问题有:
1. 页面职责和产品目标不一致
- 当前是 `roomType` / `event` 双 Tab
- 上传行为只是 `ImageManagerDialog` 中的本地临时对象 URL
- 没有真正写入主进程或磁盘
2. 页面状态过重
- 房型列表、事件列表、图片管理、反馈提示都堆在一个文件里
3. 当前上传能力只是前端临时态
- 使用 `File` + `URL.createObjectURL`
- 刷新后数据丢失
- 没有真正的文件列表 API
结论:
- 当前 `Knowledge` 页需要被整体替换,而不是增量补按钮。
## 2.2 主进程现状
当前主进程已经有本地 Host API 分发能力:
- [`electron/main.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/electron/main.ts:1)
- [`electron/api/router.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/electron/api/router.ts:1)
其中已有可复用的文件路由:
- [`electron/api/routes/files.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/electron/api/routes/files.ts:1)
已有能力主要是:
1. `/api/files/stage-buffer`
- 接收 `base64`
- 写入 `userData/openclaw-media/outbound`
2. `/api/files/stage-paths`
- 拷贝已有路径文件到暂存目录
这说明仓库已经接受“渲染层读文件 -> base64 -> Host API 落盘”的模式Knowledge 重构可以沿用这条链路。
## 2.3 风格现状
当前 `Knowledge` 页可复用的视觉资产很明确:
1. 顶部大标题 + 副标题
2. 圆角胶囊按钮
3. 圆角卡片 / 表格容器
4. 浅色背景 + serif 标题
5. 轻量 feedback 提示条
所以 UI 不需要另起视觉体系,但只复用视觉语言,不复用旧业务结构。
## 2.4 迁移策略结论
这次不采用“兼容式迁移”,而采用“一刀切替换”:
1. `/knowledge` 路由保持不变
2. `Knowledge/index.tsx` 内部逻辑整体重写
3. 旧的 `roomType` / `event` / `ImageManagerDialog` 相关状态、组件、文案直接移除
4. 不保留旧功能入口
5. 不做旧数据迁移
## 3. 重构范围
## 3.1 渲染层范围
建议重构目标文件:
1. [`src/pages/Knowledge/index.tsx`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/index.tsx:1)
- 从单文件重业务页直接替换成 docs 文件管理页
2. [`src/pages/Knowledge/copy.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/copy.ts:1)
- 新增文档管理相关文案
3. [`src/pages/Knowledge/types.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/types.ts:1)
- 删除旧 room/event 类型
- 视情况改成 docs 列表类型,或直接移除
4. 新增 `src/pages/Knowledge/components/*`
- `KnowledgeDocsToolbar.tsx`
- `KnowledgeDocsTable.tsx`
- `KnowledgeDocsEmpty.tsx`
- `KnowledgeDocDeleteButton.tsx`
## 3.2 主进程范围
建议新增 / 修改:
1. 新增 `electron/utils/knowledge-docs.ts`
- docs 根目录解析
- 文件列表读取
- 上传写入
- 删除
- 文件名安全校验
2. 新增 `electron/api/routes/knowledge.ts`
- 暴露 Knowledge 专用 Host API
3. 修改 `electron/api/router.ts`
- 注册 `handleKnowledgeRoutes`
## 3.3 测试范围
建议新增:
1. `tests/knowledge-docs-routes.test.ts`
2. `tests/knowledge-page.test.tsx`
## 4. 推荐目标结构
## 4.1 页面 IA
重构后的 `Knowledge` 页面建议只有一层核心任务流:
1. 顶部标题区
- `Knowledge Management`
- 副标题
- `刷新`
- `上传文件`
2. 列表区
- 文件总数卡片或摘要
- 文档表格
3. 空态 / 错误态
4. 删除确认
明确删除:
1. `roomType` / `event` Tab
2. `EventDialog`
3. `ImageManagerDialog`
4. 事件图片本地临时态
5. 房型映射查询能力
## 4.2 前端组件拆分建议
推荐拆法:
1. `KnowledgePage`
- 页面壳
- 拉取列表
- 调度上传 / 删除 / 刷新
2. `KnowledgeDocsToolbar`
- 上传按钮
- 刷新按钮
- 简要统计
3. `KnowledgeDocsTable`
- 表头
- 行渲染
4. `KnowledgeDocsEmpty`
- 空态
5. `useKnowledgeCopy`
- 补齐新文案,不另起 i18n 体系
注意:
- 这里的组件拆分是为了替代旧页面,不是为了与旧功能并存。
## 4.3 主进程模块拆分建议
推荐拆法:
1. `knowledge-docs.ts`
- `getKnowledgeDocsDir()`
- `listKnowledgeDocsFiles()`
- `saveKnowledgeDocsFile()`
- `deleteKnowledgeDocsFile()`
2. `routes/knowledge.ts`
- `GET /api/knowledge/docs`
- `POST /api/knowledge/docs`
- `DELETE /api/knowledge/docs/:name`
这样可以避免把 Knowledge 领域继续塞进通用 `files.ts`,后续如果增加“重命名 / 下载 / 打开目录”,也更好扩展。
## 5. 推荐数据契约
## 5.1 列表项结构
建议前端使用以下结构:
```ts
interface KnowledgeDocItem {
name: string;
size: number;
modifiedAt: string;
type: string;
}
```
字段解释:
1. `name`
- 文件名,作为主键展示
2. `size`
- 字节数,前端转成 `KB / MB`
3. `modifiedAt`
- ISO 时间字符串
4. `type`
- 优先用扩展名,例如 `md` / `pdf` / `json`
- 无扩展名时回退为 `unknown`
## 5.2 Host API 设计
推荐 API
### `GET /api/knowledge/docs`
返回:
```ts
{
success: true,
files: KnowledgeDocItem[]
}
```
### `POST /api/knowledge/docs`
请求体:
```ts
{
fileName: string;
base64: string;
mimeType?: string;
}
```
返回:
```ts
{
success: true,
file: KnowledgeDocItem
}
```
### `DELETE /api/knowledge/docs/:name`
返回:
```ts
{
success: true
}
```
## 5.3 上传链路建议
推荐复用当前 chat store 已采用的模式:
1. 渲染层通过 `input[type=file]` 选中文件
2. `FileReader.readAsDataURL`
3. 取出 `base64`
4. 调用 `POST /api/knowledge/docs`
5. 主进程写入 `zn-ai/docs`
6. 刷新列表
原因:
1. 与现有 [`src/stores/chat.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/stores/chat.ts:943) 的上传思路一致
2. 不依赖浏览器侧暴露绝对路径
3. 更适配现在的 `hostapi:fetch` JSON body 结构
## 6. 文件系统策略
## 6.1 目标目录
产品要求是写入 `zn-ai/docs`,建议在开发阶段明确采用仓库目录:
```ts
path.join(process.cwd(), 'docs')
```
注意:
1. 这满足当前本地开发诉求
2. 但在打包态里,`app.getAppPath()` 目录通常不适合作为可写目录
所以建议把这条约束写死在 Phase 0 决策里:
1. 当前版本按“开发工作区 docs 目录”实现
2. 若未来进入打包态,再增加 fallback
- `userData/knowledge-docs`
## 6.2 安全约束
主进程必须加的边界:
1. 禁止路径穿越
- 只允许文件名,不允许相对路径
2. 删除时二次校验目标文件真实路径仍在 `docs` 根目录内
3. 文件名规范化
- 去掉控制字符
- 过滤危险分隔符
4. 默认不覆盖已有文件
- 推荐同名自动追加后缀
- 例如 `foo.md` -> `foo-1.md`
## 6.3 排序与展示规则
建议默认按 `modifiedAt` 倒序展示,让最新上传或最近修改的文件排最前。
## 7. 具体实施计划
## Phase 0替换边界冻结
目标:
- 先冻结“替换式重构”的边界,避免后续又回到兼容旧功能的路线。
产出:
1. 确定页面只保留“文档上传 + 列表 + 删除”
2. 确定 `docs` 目录路径策略
3. 确定列表项结构
4. 确定上传冲突策略
5. 确定旧 `roomType/event` 代码直接下线
完成标准:
- 渲染层、主进程、测试都基于同一套字段命名
- 不再保留任何旧业务能力的开发任务
## Phase 1主进程与文件能力
目标:
- 先让本地 `docs` 目录具备可读、可写、可删能力。
交付:
1. 新增 `electron/utils/knowledge-docs.ts`
2. 新增 `electron/api/routes/knowledge.ts`
3.`electron/api/router.ts` 接入新路由
4. 支持:
- list
- upload
- delete
完成标准:
- 不依赖前端 mock即可从主进程拿到真实 docs 列表
## Phase 2渲染层替换
目标:
-`Knowledge/index.tsx` 从 demo 页整体替换成文件管理页。
交付:
1. 删除旧的 room/event 双 Tab 结构与相关状态
2. 新增上传按钮与隐藏文件输入
3. 新增文件表格
4. 新增删除操作和确认
5. 保留当前视觉语言
完成标准:
- 页面刷新后仍能看到真实文件列表
- 上传与删除可以闭环
## Phase 3验证与收口
目标:
- 补齐最基本的回归保护。
交付:
1. 主进程 route / util 测试
2. 页面交互测试
3. 手动 smoke checklist
完成标准:
- 上传、刷新、删除、空态、异常态都可验证
## 8. sub-agent 数量估算
由于这次采用“直接抛弃旧功能”的替换式重构复杂度比“兼容旧页面并逐步迁移”明显更低sub-agent 编制也可以相应收缩。
## 8.1 最小编制3 个 sub-agent
适合当前任务,也已经足够覆盖主链路:
1. 渲染层 owner
2. 主进程 / 文件系统 owner
3. 测试 / 联调 owner
推荐原因:
1. 已经没有旧功能兼容成本
2. 页面职责单一
3. API 面很小
4. 测试面可控
## 8.2 推荐编制3 个 sub-agent
推荐采用:
1. Agent AKnowledge 页面壳与视觉对齐
2. Agent B主进程 docs 文件服务与 Host API
3. Agent C测试、copy、前后端收口
结论:
- 对这次 Knowledge 替换式重构,推荐 `3` 个 sub-agent + `1` 个主控 Codex。
## 8.3 峰值编制4 个 sub-agent
仅在想压缩工期时启用:
1. Agent A页面壳
2. Agent B文件服务
3. Agent CHost API 路由
4. Agent D测试 / copy / 收口
不建议长期保持 `4` 个,因为当前任务已经不再需要兼容旧功能,继续加人收益很有限。
## 9. 推荐 sub-agent 分工
## Agent A渲染层 Owner
负责文件:
1. [`src/pages/Knowledge/index.tsx`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/index.tsx:1)
2. `src/pages/Knowledge/components/*`
职责:
1. 页面布局重构
2. 上传按钮与刷新按钮
3. 文件表格与空态
4. 删除确认
5. 保持当前视觉风格
## Agent B主进程 docs 文件服务 Owner
负责文件:
1. `electron/utils/knowledge-docs.ts`
2. `electron/api/routes/knowledge.ts`
3. [`electron/api/router.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/electron/api/router.ts:1)
职责:
1. 解析 `zn-ai/docs` 路径
2. 列出文件元数据
3. 保存文件
4. 删除文件
5. 文件名安全与根目录校验
6. 暴露 list / upload / delete 的本地 Host API
## Agent C测试 / copy / 前后端收口 Owner
负责文件:
1. [`src/pages/Knowledge/copy.ts`](/Users/duanshuwen/Documents/workspace/electron/zn-ai/src/pages/Knowledge/copy.ts:1)
2. 可选新增 `src/lib/knowledge-docs-api.ts`
3. `tests/knowledge-docs-routes.test.ts`
4. `tests/knowledge-page.test.tsx`
5. `docs/*` 中的 smoke checklist
职责:
1. 补齐文案
2. 连接 `FileReader -> base64 -> hostApiFetch`
3. 校验上传
4. 校验删除
5. 校验空态 / 错误态
6. 校验文件元数据展示
7. 保证前后端字段一致
## 10. 并行推进顺序
建议按下面顺序推进:
1. Agent B 先完成文件服务
2. 主控 Codex / Agent B 接上 Host API 契约
3. Agent A 在 API 稳定后整体替换页面
4. Agent C 最后补测试、copy 与回归
原因:
- 这次需求本质上是“主进程文件能力先行,渲染层消费其结果”,而且旧页面不再需要兼容。
## 11. 风险与决策点
1. `zn-ai/docs` 目录写入策略
- 当前需求明确指向仓库目录
- 打包态写入需要后续额外决策
2. 同名文件冲突
- 建议先采用“自动追加后缀,不覆盖原文件”
3. 大文件上传
-`base64` 会增加体积
- 本期只要满足常规文档文件即可
4. 页面是否保留旧房型 / 事件能力
- 本计划已明确直接移除,不做混合页
## 12. 验收标准
重构完成后,至少满足:
1. `Knowledge` 页能从主进程读取 `zn-ai/docs` 真实文件
2. 用户可上传文件到 `zn-ai/docs`
3. 列表展示:
- 文件名称
- 文件大小
- 修改日期
- 文件类型
4. 用户可删除文件
5. 页面风格与当前 `Knowledge` 页一致
6. 页面刷新后状态不丢失
7. 主进程具备基本路径安全校验
## 13. 当前建议结论
这次任务不适合在现有 `Knowledge/index.tsx` 上继续堆条件分支,也不适合保留旧功能做过渡。
最合理的推进方式是:
1. 直接下线 `Knowledge` 现有房型 / 事件功能
2.`Knowledge` 页面整体替换成单一职责的 docs 文件管理页
3. 新增专门的 `knowledge-docs` 主进程文件服务
4. 用本地 Host API 打通上传、列表、删除
5.`3` 个 sub-agent 作为推荐编制推进开发
这样改动面最小、职责边界最清晰,也最符合当前仓库已经建立起来的本地 Host API 架构。