故事007.033: 单租户文件管理界面独立包实现
状态
Draft
故事
作为 系统管理员,
我想要 有一个独立的单租户文件管理界面包,
以便 可以在单租户系统中独立管理文件上传下载和CRUD操作,而不影响现有的多租户系统。
验收标准
- AC 1: 成功创建单租户文件管理界面包
@d8d/file-management-ui,包含正确的包配置和依赖管理
- AC 2: 复制前端文件管理界面
web/src/client/admin/pages/Files.tsx 为单租户文件管理界面包
- AC 3: 实现完整的文件CRUD操作和上传下载管理
- AC 4: 基于React + TypeScript + TanStack Query + React Hook Form技术栈
- AC 5: 依赖共享UI组件包
@d8d/shared-ui-components 中的基础组件
- AC 6: 依赖文件模块包
@d8d/file-module 提供API客户端和类型定义
- AC 7: 提供workspace包依赖复用机制
- AC 8: 支持独立测试和部署
- AC 9: 验证现有功能无回归
任务 / 子任务
[ ] 任务 1 (AC: 1, 7): 创建单租户文件管理界面包结构
[ ] 任务 2 (AC: 1): 配置包依赖和构建
[ ] 任务 3 (AC: 3, 6): 创建RPC客户端架构和类型定义
[ ] 任务 4 (AC: 2, 3): 复制并调整文件管理界面组件
[ ] 任务 5 (AC: 3, 4): 实现完整的文件管理功能
[ ] 任务 6 (AC: 8): 创建测试套件
[ ] 任务 7 (AC: 1, 7): 配置包导出接口
[ ] 任务 8 (AC: 9): 验证功能无回归
Dev Notes
技术栈和架构上下文
- 技术栈: React 19 + TypeScript + TanStack Query + React Hook Form [Source: architecture/tech-stack.md#现有技术栈维护]
- 前端框架: React 19.1.0 用于用户界面构建 [Source: architecture/tech-stack.md#现有技术栈维护]
- 状态管理: React Query 5.83.0 用于服务端状态管理 [Source: architecture/tech-stack.md#现有技术栈维护]
- 构建工具: Vite 7.0.0 用于开发服务器和构建 [Source: architecture/tech-stack.md#现有技术栈维护]
项目结构
- 包位置:
packages/file-management-ui/ [Source: architecture/source-tree.md#实际项目结构]
- 源码结构:
src/components/ - React组件
src/hooks/ - 自定义React hooks
src/api/ - API客户端
src/types/ - TypeScript类型定义
tests/unit/ - 单元测试
tests/integration/ - 集成测试
- 依赖管理: 使用pnpm workspace依赖管理 [Source: architecture/source-tree.md#集成指南]
依赖关系
- 共享UI组件包:
@d8d/shared-ui-components - 提供基础UI组件 [Source: architecture/source-tree.md#实际项目结构]
- 单租户文件模块:
@d8d/file-module - 提供文件管理API [Source: docs/prd/epic-007-multi-tenant-package-replication.md#文件管理界面包]
从前一个故事吸取的经验教训
- useQuery测试策略: 使用真实的QueryClientProvider而不是mock react-query,在TestWrapper中提供完整的react-query上下文 [Source: docs/stories/007.017.user-management-ui-package.story.md#从前一个故事吸取的经验教训]
- UI组件测试策略: 使用data-testid进行元素定位比placeholder/role更准确稳定,避免因UI变化导致测试失败 [Source: docs/stories/007.017.user-management-ui-package.story.md#从前一个故事吸取的经验教训]
- React Hook Form处理: 需要过滤React Hook Form的props避免React警告,改进mock策略 [Source: docs/stories/007.017.user-management-ui-package.story.md#从前一个故事吸取的经验教训]
- Router上下文: 需要提供BrowserRouter上下文或mock useNavigate [Source: docs/stories/007.017.user-management-ui-package.story.md#从前一个故事吸取的经验教训]
文件模块API结构
- 文件实体: 包含id、name、type、size、path、fullUrl、description、uploadUserId、uploadUser、uploadTime等字段 [Source: packages/file-module/src/schemas/file.schema.ts]
- 文件Schema: FileSchema、CreateFileDto、UpdateFileDto [Source: packages/file-module/src/schemas/file.schema.ts]
- 文件路由: 包含upload-policy、multipart-policy、multipart-complete、get-url、download、delete等路由 [Source: packages/file-module/src/routes/index.ts]
- CRUD操作: 通过通用CRUD路由提供基础的CRUD操作 [Source: packages/file-module/src/routes/index.ts]
文件管理功能特性
- 文件列表: 支持分页、搜索、过滤功能
- 文件CRUD: 完整的创建、读取、更新、删除操作
- 文件上传: 支持单文件上传,最大500MB [Source: web/src/client/admin/pages/Files.tsx:378]
- 文件下载: 支持文件下载功能
- 文件预览: 支持图片和视频文件预览
- 文件信息编辑: 支持文件名称和描述编辑
- 文件删除: 支持文件记录删除
文件管理相关组件
- FileSelector组件: 文件选择器,支持单选/多选、文件预览、拖拽上传 [Source: web/src/client/admin/components/FileSelector.tsx]
- 支持图片预览和文件类型图标
- 集成MinioUploader进行文件上传
- 支持文件搜索和过滤
- 统一选择器架构: 文件选择器已覆盖头像选择器和图片选择器的所有功能,所有需要头像、图片选择的场景统一使用此组件
- MinioUploader组件: MinIO文件上传组件,支持拖拽上传、进度显示 [Source: web/src/client/admin/components/MinioUploader.tsx]
- 支持多种尺寸模式(default、compact、minimal)
- 支持多种显示模式(full、card)
- 支持上传进度跟踪和状态显示
- minio工具: MinIO上传工具函数,提供文件上传策略和进度处理 [Source: web/src/client/utils/minio.ts]
- 支持分片上传和大文件处理
- 提供上传进度回调
- 支持上传策略获取
测试标准
- 测试框架: Vitest + Testing Library [Source: architecture/testing-strategy.md#单元测试]
- 测试位置:
packages/file-management-ui/tests/unit/ 和 packages/file-management-ui/tests/integration/ [Source: architecture/testing-strategy.md#单元测试]
- 测试覆盖率目标: ≥ 80% 单元测试覆盖率 [Source: architecture/testing-strategy.md#各层覆盖率要求]
- 测试执行: 使用
pnpm test 运行所有测试 [Source: architecture/testing-strategy.md#本地开发测试]
- 测试模式: 遵循测试金字塔模型,包含单元测试、组件测试和集成测试 [Source: architecture/testing-strategy.md#测试金字塔策略]
关键实施要点
- 包命名: 使用标准命名约定,不添加特殊后缀 [Source: docs/prd/epic-007-multi-tenant-package-replication.md#包命名约定]
- API客户端: 使用Hono客户端调用单租户文件API [Source: docs/stories/007.017.user-management-ui-package.story.md#关键实施要点]
- 导出接口: 提供完整的组件、hook和类型定义导出 [Source: docs/stories/007.017.user-management-ui-package.story.md#关键实施要点]
- 组件复用: 基于现有文件管理界面实现,确保功能完整性和一致性
RPC客户端架构最佳实践
- 单例模式: 使用单例模式管理客户端实例,确保全局唯一 [Source: packages/user-management-ui/src/api/userClient.ts:4-15]
- 延迟初始化: 客户端在首次使用时初始化,避免不必要的资源消耗 [Source: packages/user-management-ui/src/api/userClient.ts:17-33]
- 类型安全: 使用Hono的InferRequestType和InferResponseType确保类型安全 [Source: web/src/client/admin/pages/Files.tsx:23-26]
- 客户端重置: 提供reset方法用于测试或重新初始化场景 [Source: packages/user-management-ui/src/api/userClient.ts:30-33]
- 主应用集成: 验证RPC客户端在主应用中的正确集成模式 [Source: web/src/client/api_init.ts]
测试
测试标准和框架
- 测试框架: Vitest 3.2.4 + Testing Library 16.3.0 [Source: architecture/testing-strategy.md#工具版本]
- 测试位置:
- 集成测试:
packages/file-management-ui/tests/integration/**/*.test.tsx
[Source: architecture/testing-strategy.md#单元测试]
测试模式和策略
- useQuery测试: 使用真实的QueryClientProvider而不是mock react-query [Source: docs/stories/007.017.user-management-ui-package.story.md#测试模式和策略]
- 元素定位: 使用data-testid进行元素定位,比placeholder/role更准确稳定 [Source: docs/stories/007.017.user-management-ui-package.story.md#测试模式和策略]
- Mock策略: 使用智能mock过滤React Hook Form props [Source: docs/stories/007.017.user-management-ui-package.story.md#测试模式和策略]
- 测试工具: 提供QueryClientProvider和必要的上下文 [Source: docs/stories/007.017.user-management-ui-package.story.md#测试模式和策略]
特定测试要求
- 文件CRUD测试: 验证文件创建、读取、更新、删除功能
- 文件上传测试: 验证文件上传功能正常工作
- 文件下载测试: 验证文件下载功能正常工作
- 文件预览测试: 验证文件预览功能正常工作
- 搜索过滤测试: 验证搜索和过滤功能正常工作
- API集成测试: 验证与文件模块的API集成
- FileSelector组件测试: 验证文件选择器功能,包括单选/多选、预览、搜索
- MinioUploader组件测试: 验证文件上传组件功能,包括拖拽上传、进度显示
- minio工具测试: 验证MinIO上传工具函数正常工作
测试执行命令
- 运行所有测试:
cd packages/file-management-ui && pnpm test
- 运行单元测试:
cd packages/file-management-ui && pnpm test:unit
- 运行集成测试:
cd packages/file-management-ui && pnpm test:integration
- 生成覆盖率报告:
cd packages/file-management-ui && pnpm test:coverage
变更日志
| 日期 |
版本 |
描述 |
作者 |
| 2025-11-16 |
1.0 |
初始故事创建 |
Bob (Scrum Master) |
Dev Agent Record
此部分将在开发过程中由开发代理填充
QA Results
此部分将在质量保证审查过程中由QA代理填充