Completed
作为 系统管理员, 我想要 复制广告管理模块并添加多租户支持, 以便 广告和广告类型可以在租户隔离的环境中管理,同时保持与现有单租户系统的完全兼容性。
@d8d/advertisements-module 为 @d8d/advertisements-module-mt,包含正确的包配置AdvertisementMt 和广告类型实体 AdvertisementTypeMt,包含租户ID字段和表名 ads_mt 和 ad_types_mt[x] 复制广告管理模块为多租户版本 (AC: 1)
packages/advertisements-module 为 packages/advertisements-module-mt@d8d/advertisements-module-mt@d8d/user-module 替换为 @d8d/user-module-mt@d8d/auth-module 替换为 @d8d/auth-module-mt@d8d/file-module 替换为 @d8d/file-module-mt[x] 更新多租户广告实体和广告类型实体 (AC: 2)
Advertisement 实体,表名为 ad_mtAdvertisementType 实体,表名为 ad_type_mttenantId 字段和正确的TypeORM配置[x] 更新多租户广告和广告类型服务 (AC: 3, 4)
[x] 更新多租户路由配置 (AC: 3)
tenantOptions: { enabled: true, tenantIdField: 'tenantId' }[x] 更新Schema定义 (AC: 3)
AdvertisementSchemaAdvertisementTypeSchema[x] 实现租户数据隔离API测试 (AC: 7)
packages/advertisements-module-mt/tests/integration/advertisements.integration.test.ts 中添加租户隔离测试用例packages/advertisements-module-mt/tests/integration/advertisement-types.integration.test.ts 中添加跨租户广告访问安全验证[x] 验证单租户系统完整性 (AC: 5, 6)
[x] 在创建复制的代码修改完后先运行安装
pnpm install 安装依赖[x] 执行性能基准测试 (AC: 8)
[x] 执行回归测试验证 (AC: 9)
从故事007.007(商户模块)学到的关键经验:
.mt.ts 后缀区分多租户文件 [Source: epic-007-multi-tenant-package-replication.md#最佳实践]fileParallelism: false 避免数据库冲突 [Source: epic-007-multi-tenant-package-replication.md#技术挑战和解决方案]update和delete方法中的权限验证抛出错误逻辑,确保路由层能正确捕获并返回相应状态码 [Source: story-007.007.merchant-module-multi-tenant-replication.md#技术挑战解决]广告实体结构:
ads_mt (多租户版本)tenantId (必需,已索引)title, typeId, code, url, imageFileId, sort, status, actionType [Source: source-tree.md#广告管理模块]imageFile (关联FileMt), advertisementType (关联AdvertisementTypeMt)createdBy, updatedBy [Source: source-tree.md#广告管理模块]createdAt, updatedAt [Source: source-tree.md#广告管理模块]广告类型实体结构:
ad_types_mt (多租户版本)tenantId (必需,已索引)name, code, remark, status [Source: source-tree.md#广告管理模块]createdBy, updatedBy [Source: source-tree.md#广告管理模块]createdAt, updatedAt [Source: source-tree.md#广告管理模块]广告路由:
/api/advertisementsauthMiddleware 来自 @d8d/auth-module-mt [Source: source-tree.md#广告管理模块]['title', 'code'] [Source: source-tree.md#广告管理模块]['imageFile', 'advertisementType'] [Source: source-tree.md#广告管理模块]createdByField: 'createdBy', updatedByField: 'updatedBy' [Source: source-tree.md#广告管理模块]广告类型路由:
/api/advertisement-typesauthMiddleware 来自 @d8d/auth-module-mt [Source: source-tree.md#广告管理模块]['name', 'code'] [Source: source-tree.md#广告管理模块]createdByField: 'createdBy', updatedByField: 'updatedBy' [Source: source-tree.md#广告管理模块]广告服务方法:
广告类型服务方法:
要创建的源文件:
packages/advertisements-module-mt/src/entities/advertisement.mt.entity.ts (多租户广告实体)packages/advertisements-module-mt/src/entities/advertisement-type.mt.entity.ts (多租户广告类型实体)packages/advertisements-module-mt/src/services/advertisement.mt.service.ts (多租户广告服务)packages/advertisements-module-mt/src/services/advertisement-type.mt.service.ts (多租户广告类型服务)packages/advertisements-module-mt/src/routes/advertisements.mt.ts (多租户广告路由)packages/advertisements-module-mt/src/routes/advertisement-types.mt.ts (多租户广告类型路由)packages/advertisements-module-mt/src/schemas/advertisement.mt.schema.ts (多租户广告schemas)packages/advertisements-module-mt/src/schemas/advertisement-type.mt.schema.ts (多租户广告类型schemas)要删除的文件(单租户清理):
.mt.ts 后缀的文件数据库索引:
tenantId 字段上创建索引以提高性能 [Source: epic-007-multi-tenant-package-replication.md#数据库迁移策略]认证集成:
@d8d/auth-module-mt 的更新版 authMiddleware,从用户上下文中提取租户ID [Source: epic-007-multi-tenant-package-replication.md#租户上下文管理]关联关系处理:
测试文件位置: packages/advertisements-module-mt/tests/integration/ [Source: testing-strategy.md#集成测试]
测试框架: Vitest + hono/testing + shared-test-util [Source: testing-strategy.md#集成测试]
测试模式: 使用测试数据工厂并显式设置tenantId [Source: testing-strategy.md#测试数据管理]
覆盖率目标: ≥ 60% 集成测试覆盖率 [Source: testing-strategy.md#各层覆盖率要求]
数据库策略: 使用测试数据库和事务回滚 [Source: testing-strategy.md#数据库测试策略]
| 日期 | 版本 | 描述 | 作者 |
|---|---|---|---|
| 2025-11-14 | 1.0 | 初始故事创建,包含从前面的故事中学到的全面经验教训 | Bob (Scrum Master) |
实施过程总结 (James - 开发工程师):
packages/advertisements-module 为 packages/advertisements-module-mt@d8d/advertisements-module-mt,更新依赖为多租户版本Advertisement 实体,表名 ad_mt,添加 tenantId 字段AdvertisementType 实体,表名 ad_type_mt,添加 tenantId 字段@ManyToOne('File') 改为 @ManyToOne('FileMt'),确保关联到正确的多租户实体tenantOptions: { enabled: true, tenantIdField: 'tenantId' }imageFile 关联需要指向正确的多租户实体 FileMttenantId 字段实施时间: 2025-11-14 开发者: James (开发工程师)
此部分将在质量保证审查过程中由QA代理填充