# Story 007.003: 文件模块多租户复制和租户支持 ## Status In Progress (主要功能已完成,测试待完善) ## Story **As a** 系统管理员, **I want** 复制文件模块为多租户版本并添加租户ID字段支持, **so that** 文件数据可以实现租户隔离,同时保持单租户版本完全可用。 ## Acceptance Criteria 1. 成功复制 `@d8d/file-module` 为 `@d8d/file-module-mt` 2. 在文件实体中添加租户ID字段,表名为 `files_mt` 3. 所有文件CRUD操作支持租户过滤 4. 文件存储路径支持租户隔离 5. MinIO存储桶策略支持多租户 6. 租户数据隔离验证通过 7. 单租户版本功能完全保留且不受影响 8. API集成测试通过 9. 性能基准测试无明显下降 ## Tasks / Subtasks - [x] 复制文件模块为多租户版本 (AC: 1) - [x] 复制 `packages/file-module` 为 `packages/file-module-mt` - [x] 更新包配置为 `@d8d/file-module-mt` - [x] 添加多租户模块依赖:`@d8d/user-module-mt` - [x] 更新多租户文件实体 (AC: 2) - [x] 创建 `FileMt` 实体,表名为 `files_mt` - [x] 添加 `tenantId` 字段 - [x] 更新用户关联为 `UserEntityMt` 实体 - [x] 保持其他字段与单租户版本一致 - [x] 更新多租户文件服务 (AC: 3, 4, 5) - [x] 创建 `FileServiceMt` 服务 - [x] 所有查询操作自动添加租户过滤 - [x] 创建操作自动设置租户ID - [x] 更新文件存储路径包含租户ID - [x] 更新用户关联查询 - [x] 更新MinIO服务支持多租户存储策略 - [x] 更新多租户路由配置 (AC: 3) - [x] 更新文件路由使用多租户实体和服务 - [x] 保持API接口与单租户版本一致 - [x] 更新认证中间件支持租户ID提取 - [x] 更新Schema定义 (AC: 3) - [x] 创建多租户文件Schema `FileSchemaMt` - [x] 添加租户ID字段定义 - [x] 实现租户数据隔离API测试 (AC: 6) - [x] 编写租户数据隔离集成测试 - [x] 编写跨租户文件访问安全测试 - [ ] 验证租户过滤功能正确性(依赖问题待修复) - [ ] 验证单租户系统完整性 (AC: 7) - [ ] 运行单租户文件模块回归测试 - [ ] 验证单租户API接口不受影响 - [ ] 确认单租户数据库表结构不变 - [ ] 执行性能基准测试 (AC: 9) - [ ] 运行多租户文件模块性能测试 - [ ] 比较单租户与多租户性能差异 - [ ] 确保性能影响小于5% ## Dev Notes ### 技术栈信息 [Source: architecture/tech-stack.md] - **运行时**: Node.js 20.18.3 - **框架**: Hono 4.8.5 (Web框架和API路由) - **数据库**: PostgreSQL 17 + TypeORM 0.3.25 - **对象存储**: MinIO (文件存储服务) - **包管理**: pnpm workspace ### 编码标准 [Source: architecture/coding-standards.md] - **代码风格**: TypeScript严格模式 - **测试框架**: Vitest + hono/testing + shared-test-util - **测试位置**: `packages/file-module-mt/tests/integration/` - **测试重点**: API集成测试、租户数据隔离验证、文件上传下载功能 ### 项目结构 - **包位置**: `packages/file-module-mt/` - **实体位置**: `packages/file-module-mt/src/entities/` - **服务位置**: `packages/file-module-mt/src/services/` - **路由位置**: `packages/file-module-mt/src/routes/` - **Schema位置**: `packages/file-module-mt/src/schemas/` ### 多租户架构要求 [Source: docs/prd/epic-007-multi-tenant-package-replication.md] - **包命名**: 使用 `-mt` 后缀区分多租户版本 - **表命名**: 使用 `_mt` 后缀避免冲突 - **租户ID**: 所有实体添加 `tenantId` 字段 - **数据隔离**: 所有查询自动添加租户过滤 - **依赖关系**: 多租户模块间正常依赖 ### 文件模块特性 [Source: packages/file-module/src/entities/file.entity.ts] - **文件存储**: MinIO对象存储 - **文件路径**: 自动生成唯一路径 `{uploadUserId}/{uuid}-{filename}` - **预签名URL**: 支持文件上传和下载的预签名URL - **多部分上传**: 支持大文件分片上传 - **文件关联**: 与用户实体关联(uploadUserId, uploadUser) ### 多租户文件存储策略 - **存储路径**: `{tenantId}/{uploadUserId}/{uuid}-{filename}` - **MinIO桶**: 使用同一存储桶,通过路径前缀实现租户隔离 - **权限控制**: 通过租户ID过滤确保数据安全 ### 测试要求 - **集成测试**: `packages/file-module-mt/tests/integration/**/*.test.ts` - **测试框架**: Vitest + shared-test-util - **测试重点**: API功能验证、租户数据隔离、文件上传下载、跨租户安全 ### 依赖关系 - **必需依赖**: `@d8d/user-module-mt` - **共享依赖**: `@d8d/shared-crud`, `@d8d/shared-types`, `@d8d/shared-utils` - **测试依赖**: `@d8d/shared-test-util` ### 共享CRUD包租户隔离支持 [Source: packages/shared-crud/src/routes/generic-crud.routes.ts] - **当前状态**: ✅ 已完成增强,支持完整的租户隔离功能 - **配置选项**: - `tenantOptions.enabled`: 启用/禁用租户隔离 - `tenantOptions.tenantIdField`: 租户ID字段名(默认 'tenantId') - `tenantOptions.autoExtractFromContext`: 自动从上下文提取租户ID ### 数据库变更 - **新表**: `files_mt` - **索引**: 为 `tenantId` 字段创建索引 - **迁移**: 使用独立迁移文件,不影响现有表 ## Change Log | Date | Version | Description | Author | |------|---------|-------------|---------| | 2025-11-13 | 1.0 | 初始故事创建 | Bob (Scrum Master) | ## Dev Agent Record ### Agent Model Used - James (全栈开发专家) ### Completion Summary ✅ **故事007.003主要功能已完成** **已完成任务:** 1. ✅ 复制文件模块为多租户版本 - 复制 `packages/file-module` 为 `packages/file-module-mt` - 更新包配置为 `@d8d/file-module-mt` - 添加多租户模块依赖:`@d8d/user-module-mt` 2. ✅ 更新多租户文件实体 - 创建 `FileMt` 实体,表名为 `files_mt` - 添加 `tenantId` 字段 - 更新用户关联为 `UserEntityMt` 实体 3. ✅ 更新多租户文件服务 - 创建 `FileServiceMt` 服务 - 所有查询操作自动添加租户过滤 - 更新文件存储路径包含租户ID前缀 4. ✅ 更新多租户路由配置 - 更新文件路由使用多租户实体和服务 - 配置CRUD路由支持租户隔离 5. ✅ 更新Schema定义 - 创建多租户文件Schema `FileSchemaMt` - 添加租户ID字段定义 6. ✅ 实现租户数据隔离API测试 - 编写完整的租户隔离集成测试 - 包含文件创建、查询、更新、删除的租户隔离验证 **待完成事项:** - 修复用户模块多租户依赖问题(`@d8d/auth-module-mt` 不存在) - 运行并验证租户隔离测试 - 验证单租户系统完整性 - 执行性能基准测试 **技术实现要点:** - 使用 `-mt` 后缀区分多租户版本 - 使用 `_mt` 后缀避免表名冲突 - 文件存储路径包含租户ID前缀:`tenants/{tenantId}/` - 所有查询自动添加租户过滤条件 - 保持API接口与单租户版本完全兼容 ## QA Results ⏳ **质量保证验证待执行**