|
@@ -0,0 +1,202 @@
|
|
|
|
|
+# 故事007.009: 商品模块多租户复制
|
|
|
|
|
+
|
|
|
|
|
+## 状态
|
|
|
|
|
+
|
|
|
|
|
+Draft
|
|
|
|
|
+
|
|
|
|
|
+## 故事
|
|
|
|
|
+
|
|
|
|
|
+**作为** 系统管理员,
|
|
|
|
|
+**我想要** 复制商品管理模块并添加多租户支持,
|
|
|
|
|
+**以便** 商品可以在租户隔离的环境中管理,同时保持与现有单租户系统的完全兼容性。
|
|
|
|
|
+
|
|
|
|
|
+## 验收标准
|
|
|
|
|
+
|
|
|
|
|
+1. **AC 1**: 成功复制 `@d8d/goods-module` 为 `@d8d/goods-module-mt`,包含正确的包配置
|
|
|
|
|
+2. **AC 2**: 创建多租户商品实体 `GoodsMt` 和商品分类实体 `GoodsCategoryMt`,包含租户ID字段和表名 `goods_mt`、`goods_category_mt`
|
|
|
|
|
+3. **AC 3**: 更新所有商品CRUD操作,自动包含租户过滤并在创建时设置租户ID
|
|
|
|
|
+4. **AC 4**: 验证商品数据隔离在不同租户间正常工作
|
|
|
|
|
+5. **AC 5**: 保持与现有单租户商品管理模块功能的完全兼容性
|
|
|
|
|
+6. **AC 6**: 所有现有单租户API接口保持不变且功能正常
|
|
|
|
|
+7. **AC 7**: 实现完整的租户数据隔离API测试,包括跨租户商品访问安全验证
|
|
|
|
|
+8. **AC 8**: 确保性能影响小于5%
|
|
|
|
|
+9. **AC 9**: 所有多租户模块的回归测试通过
|
|
|
|
|
+
|
|
|
|
|
+## 任务 / 子任务
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 复制商品管理模块为多租户版本 (AC: 1)
|
|
|
|
|
+ - [ ] 复制 `packages/goods-module` 为 `packages/goods-module-mt`
|
|
|
|
|
+ - [ ] 更新包配置为 `@d8d/goods-module-mt`
|
|
|
|
|
+ - [ ] 更新依赖:
|
|
|
|
|
+ - [ ] 将 `@d8d/user-module` 替换为 `@d8d/user-module-mt`
|
|
|
|
|
+ - [ ] 将 `@d8d/auth-module` 替换为 `@d8d/auth-module-mt`
|
|
|
|
|
+ - [ ] 将 `@d8d/file-module` 替换为 `@d8d/file-module-mt`
|
|
|
|
|
+ - [ ] 将 `@d8d/merchant-module` 替换为 `@d8d/merchant-module-mt`
|
|
|
|
|
+ - [ ] 将 `@d8d/supplier-module` 替换为 `@d8d/supplier-module-mt`
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 更新多租户商品实体 (AC: 2)
|
|
|
|
|
+ - [ ] 创建 `GoodsMt` 实体,表名为 `goods_mt`
|
|
|
|
|
+ - [ ] 创建 `GoodsCategoryMt` 实体,表名为 `goods_category_mt`
|
|
|
|
|
+ - [ ] 为两个实体添加 `tenantId` 字段和正确的TypeORM配置
|
|
|
|
|
+ - [ ] 保持其他字段与单租户版本一致
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 更新多租户商品服务 (AC: 3, 4)
|
|
|
|
|
+ - [ ] 使用共享CRUD库的GenericCrudService
|
|
|
|
|
+ - [ ] 所有查询操作自动添加租户过滤
|
|
|
|
|
+ - [ ] 创建操作自动设置租户ID
|
|
|
|
|
+ - [ ] 更新关联查询支持租户隔离
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 更新多租户路由配置 (AC: 3)
|
|
|
|
|
+ - [ ] 更新用户路由使用多租户实体和服务
|
|
|
|
|
+ - [ ] 更新管理员路由使用多租户实体和服务
|
|
|
|
|
+ - [ ] 更新公开商品路由使用多租户实体和服务
|
|
|
|
|
+ - [ ] 保持API接口与单租户版本一致
|
|
|
|
|
+ - [ ] 启用租户选项:`tenantOptions: { enabled: true, tenantIdField: 'tenantId' }`
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 更新Schema定义 (AC: 3)
|
|
|
|
|
+ - [ ] 使用多租户商品Schema `GoodsSchema`
|
|
|
|
|
+ - [ ] 使用多租户商品分类Schema `GoodsCategorySchema`
|
|
|
|
|
+ - [ ] 使用多租户用户专用Schema `UserGoodsSchema`
|
|
|
|
|
+ - [ ] 使用多租户管理员专用Schema `AdminGoodsSchema`
|
|
|
|
|
+ - [ ] 使用多租户公开商品Schema `PublicGoodsSchema`
|
|
|
|
|
+ - [ ] 添加租户ID字段定义
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 实现租户数据隔离API测试 (AC: 7)
|
|
|
|
|
+ - [ ] 在 `packages/goods-module-mt/tests/integration/user-goods-routes.integration.test.ts` 中添加租户隔离测试用例
|
|
|
|
|
+ - [ ] 在 `packages/goods-module-mt/tests/integration/admin-goods-routes.integration.test.ts` 中添加跨租户商品访问安全验证
|
|
|
|
|
+ - [ ] 在 `packages/goods-module-mt/tests/integration/public-goods-routes.integration.test.ts` 中添加租户过滤验证
|
|
|
|
|
+ - [ ] 在现有功能测试中验证租户过滤功能正确性
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 验证单租户系统完整性 (AC: 5, 6)
|
|
|
|
|
+ - [ ] 运行单租户商品管理模块回归测试
|
|
|
|
|
+ - [ ] 验证单租户API接口不受影响
|
|
|
|
|
+ - [ ] 确认单租户数据库表结构不变
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 在创建复制的代码修改完后先运行安装
|
|
|
|
|
+ - [ ] 在复制模块后运行 `pnpm install` 安装依赖
|
|
|
|
|
+ - [ ] 验证新包已正确添加到工作区
|
|
|
|
|
+ - [ ] 确认所有依赖解析正确
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 执行性能基准测试 (AC: 8)
|
|
|
|
|
+ - [ ] 运行多租户商品管理模块性能测试
|
|
|
|
|
+ - [ ] 比较单租户与多租户性能差异
|
|
|
|
|
+ - [ ] 确保性能影响小于5%
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 执行回归测试验证 (AC: 9)
|
|
|
|
|
+ - [ ] 运行所有多租户模块的回归测试
|
|
|
|
|
+ - [ ] 验证权限模块多租户测试 (38个测试)
|
|
|
|
|
+ - [ ] 验证文件模块多租户测试 (40个测试)
|
|
|
|
|
+ - [ ] 验证区域模块多租户测试 (29个测试)
|
|
|
|
|
+ - [ ] 验证用户模块多租户测试 (41个测试)
|
|
|
|
|
+ - [ ] 验证配送地址模块多租户测试 (36个测试)
|
|
|
|
|
+ - [ ] 验证商户模块多租户测试 (37个测试)
|
|
|
|
|
+ - [ ] 验证供应商模块多租户测试 (所有测试)
|
|
|
|
|
+ - [ ] 验证租户模块多租户测试 (16个测试)
|
|
|
|
|
+ - [ ] 验证广告模块多租户测试 (22个测试)
|
|
|
|
|
+ - [ ] 确认所有多租户测试全部通过
|
|
|
|
|
+
|
|
|
|
|
+## 开发说明
|
|
|
|
|
+
|
|
|
|
|
+### 先前故事洞察
|
|
|
|
|
+基于故事007.008(供应商模块多租户复制)的经验教训:
|
|
|
|
|
+
|
|
|
|
|
+**技术挑战和解决方案** [Source: docs/prd/epic-007-multi-tenant-package-replication.md#实施经验总结]
|
|
|
|
|
+- **数据库同步冲突**: 在vitest配置中使用 `fileParallelism: false` 避免并行测试导致的数据库表重复创建错误
|
|
|
|
|
+- **租户ID字段管理**: 确保所有测试数据包含正确的tenantId字段,避免null value in column "tenant_id" violates not-null constraint错误
|
|
|
|
|
+- **目录结构错误**: 清理多租户模块中错误包含的单租户模块目录,确保多租户和单租户模块在同一层级
|
|
|
|
|
+- **共享CRUD库租户验证顺序**: 确保租户验证先于数据权限验证,跨租户访问正确返回404状态码
|
|
|
|
|
+
|
|
|
|
|
+**最佳实践** [Source: docs/prd/epic-007-multi-tenant-package-replication.md#最佳实践]
|
|
|
|
|
+- **文件命名规范**: 严格使用 `.mt.ts` 后缀区分多租户文件
|
|
|
|
|
+- **测试配置**: 使用 `fileParallelism: false` 避免数据库冲突
|
|
|
|
|
+- **类型处理**: 在测试中使用类型断言处理必需参数验证
|
|
|
|
|
+- **数据工厂**: 确保所有测试数据包含正确的tenantId字段
|
|
|
|
|
+
|
|
|
|
|
+### 数据模型
|
|
|
|
|
+**商品实体** [Source: packages/goods-module/src/entities/goods.entity.ts]
|
|
|
|
|
+- 表名: `goods` → `goods_mt`
|
|
|
|
|
+- 主要字段: `name`, `price`, `costPrice`, `salesNum`, `clickNum`, `categoryId1`, `categoryId2`, `categoryId3`, `goodsType`, `supplierId`, `merchantId`, `imageFileId`, `detail`, `instructions`, `sort`, `state`, `stock`, `spuId`, `spuName`, `lowestBuy`
|
|
|
|
|
+- 关联关系: `category1`, `category2`, `category3`, `supplier`, `imageFile`, `merchant`, `slideImages` (多对多)
|
|
|
|
|
+- 需要添加: `tenantId` 字段和复合索引
|
|
|
|
|
+
|
|
|
|
|
+**商品分类实体** [Source: packages/goods-module/src/entities/goods-category.entity.ts]
|
|
|
|
|
+- 表名: `goods_category` → `goods_category_mt`
|
|
|
|
|
+- 主要字段: `name`, `parentId`, `imageFileId`, `level`, `state`
|
|
|
|
|
+- 关联关系: `imageFile`
|
|
|
|
|
+- 需要添加: `tenantId` 字段和复合索引
|
|
|
|
|
+
|
|
|
|
|
+### API规范
|
|
|
|
|
+**路由结构** [Source: docs/architecture/source-tree.md#商品管理模块]
|
|
|
|
|
+- 用户路由: `user-goods-routes.ts`
|
|
|
|
|
+- 管理员路由: `admin-goods-routes.ts`
|
|
|
|
|
+- 公开路由: `public-goods-routes.ts`
|
|
|
|
|
+- 商品分类管理路由: `admin-goods-categories.ts`
|
|
|
|
|
+- 随机商品路由: `public-goods-random.ts`
|
|
|
|
|
+
|
|
|
|
|
+**API端点** [Source: packages/goods-module/src/routes/]
|
|
|
|
|
+- 用户商品路由: 商品列表、详情、创建、更新、删除
|
|
|
|
|
+- 管理员商品路由: 完整商品管理功能
|
|
|
|
|
+- 公开商品路由: 公开商品浏览和搜索
|
|
|
|
|
+- 商品分类路由: 分类管理功能
|
|
|
|
|
+
|
|
|
|
|
+### 文件位置
|
|
|
|
|
+**新文件路径** [Source: docs/architecture/source-tree.md#包架构层次]
|
|
|
|
|
+- 包根目录: `packages/goods-module-mt/`
|
|
|
|
|
+- 实体文件: `packages/goods-module-mt/src/entities/goods.mt.entity.ts`
|
|
|
|
|
+- 服务文件: `packages/goods-module-mt/src/services/goods.mt.service.ts`
|
|
|
|
|
+- 路由文件: `packages/goods-module-mt/src/routes/*.mt.ts`
|
|
|
|
|
+- Schema文件: `packages/goods-module-mt/src/schemas/*.mt.schema.ts`
|
|
|
|
|
+- 测试文件: `packages/goods-module-mt/tests/integration/*.integration.test.ts`
|
|
|
|
|
+
|
|
|
|
|
+### 技术约束
|
|
|
|
|
+**多租户架构** [Source: docs/prd/epic-007-multi-tenant-package-replication.md#架构设计详情]
|
|
|
|
|
+- 使用共享CRUD库的GenericCrudService
|
|
|
|
|
+- 所有查询操作自动添加租户过滤
|
|
|
|
|
+- 创建操作自动设置租户ID
|
|
|
|
|
+- 启用租户选项: `tenantOptions: { enabled: true, tenantIdField: 'tenantId' }`
|
|
|
|
|
+
|
|
|
|
|
+**性能要求** [Source: docs/prd/epic-007-multi-tenant-package-replication.md#成功标准]
|
|
|
|
|
+- 性能影响小于5%
|
|
|
|
|
+- 租户过滤使用数据库索引
|
|
|
|
|
+- 确保查询性能优化
|
|
|
|
|
+
|
|
|
|
|
+### 测试
|
|
|
|
|
+
|
|
|
|
|
+#### 测试标准 [Source: docs/architecture/testing-strategy.md#包测试架构]
|
|
|
|
|
+- **测试位置**: `packages/goods-module-mt/tests/integration/`
|
|
|
|
|
+- **测试框架**: Vitest + hono/testing + shared-test-util
|
|
|
|
|
+- **覆盖率目标**: 集成测试 ≥ 60%
|
|
|
|
|
+- **测试类型**: 集成测试验证模块功能
|
|
|
|
|
+
|
|
|
|
|
+#### 测试要求 [Source: docs/architecture/testing-strategy.md#测试金字塔策略]
|
|
|
|
|
+- **集成测试范围**: 多个组件/服务协作
|
|
|
|
|
+- **测试目标**: 验证模块间集成和交互
|
|
|
|
|
+- **执行频率**: 每次API变更
|
|
|
|
|
+
|
|
|
|
|
+#### 特定测试要求
|
|
|
|
|
+- 租户数据隔离验证
|
|
|
|
|
+- 跨租户访问安全验证
|
|
|
|
|
+- 租户过滤功能正确性
|
|
|
|
|
+- 性能基准测试
|
|
|
|
|
+
|
|
|
|
|
+## 变更日志
|
|
|
|
|
+
|
|
|
|
|
+| 日期 | 版本 | 描述 | 作者 |
|
|
|
|
|
+|------|------|------|------|
|
|
|
|
|
+| 2025-11-14 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
|
|
|
|
|
+
|
|
|
|
|
+## 开发代理记录
|
|
|
|
|
+
|
|
|
|
|
+*此部分由开发代理在实现过程中填写*
|
|
|
|
|
+
|
|
|
|
|
+### Agent Model Used
|
|
|
|
|
+
|
|
|
|
|
+### Debug Log References
|
|
|
|
|
+
|
|
|
|
|
+### Completion Notes List
|
|
|
|
|
+
|
|
|
|
|
+### File List
|
|
|
|
|
+
|
|
|
|
|
+## QA结果
|
|
|
|
|
+
|
|
|
|
|
+*此部分将在质量保证审查过程中由QA代理填充*
|