010.005.system-config-custom-routes-cache-refresh.story.md 12 KB

Story 010.005: system-config-custom-routes-cache-refresh

Status

Completed

Story

As a 系统管理员, I want 用自定义路由替代通用CRUD路由,实现缓存自动刷新, so that 在管理后台更新系统配置时能自动刷新相应的key的Redis缓存

Acceptance Criteria

  1. 参照packages/orders-module-mt/src/routes/user/orders.mt.ts中的聚合写法
  2. 创建自定义路由替代现有的通用CRUD路由
  3. 在配置创建、更新、删除操作时自动刷新对应key的Redis缓存
  4. 保持API接口兼容性,不影响现有客户端调用
  5. 验证缓存刷新机制正确工作,确保数据一致性
  6. 所有现有功能测试通过,无回归

Tasks / Subtasks

  • 任务 1 (AC: 1, 2): 创建系统配置自定义路由目录结构
    • 创建 packages/core-module-mt/system-config-module-mt/src/routes/custom/ 目录
    • 参照订单模块聚合写法,创建自定义路由文件 [对照: packages/orders-module-mt/src/routes/user/orders.mt.ts]
    • 创建自定义路由聚合文件
  • 任务 2 (AC: 2, 3): 实现创建配置的自定义路由
    • 创建 packages/core-module-mt/system-config-module-mt/src/routes/custom/create-system-config.mt.ts
    • 参照createOrderRoutes实现POST路由 [对照: packages/orders-module-mt/src/routes/user/create-order.mt.ts]
    • 调用SystemConfigServiceMt的setConfig方法 [对照: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts:128-158]
    • 在路由处理中自动刷新对应配置键的Redis缓存
    • 保持与现有CRUD路由相同的请求/响应格式 [对照: packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts]
    • 确保多租户隔离: 从上下文中提取tenantId,确保只刷新当前租户的缓存
  • 任务 3 (AC: 2, 3): 实现更新配置的自定义路由
    • 创建 packages/core-module-mt/system-config-module-mt/src/routes/custom/update-system-config.mt.ts
    • 参照createOrderRoutes模式实现PUT路由 [对照: packages/orders-module-mt/src/routes/user/create-order.mt.ts]
    • 调用SystemConfigServiceMt的update方法 [对照: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts:189-199]
    • 在路由处理中自动刷新对应配置键的Redis缓存
    • 保持与现有CRUD路由相同的请求/响应格式 [对照: packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts]
    • 确保多租户隔离: 验证更新操作只影响当前租户的配置和缓存
  • 任务 4 (AC: 2, 3): 实现删除配置的自定义路由
    • 创建 packages/core-module-mt/system-config-module-mt/src/routes/custom/delete-system-config.mt.ts
    • 参照createOrderRoutes模式实现DELETE路由 [对照: packages/orders-module-mt/src/routes/user/create-order.mt.ts]
    • 调用SystemConfigServiceMt的delete方法 [对照: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts:204-217]
    • 在路由处理中自动刷新对应配置键的Redis缓存
    • 保持与现有CRUD路由相同的请求/响应格式 [对照: packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts]
    • 确保多租户隔离: 验证删除操作只删除当前租户的配置和缓存
  • 任务 5 (AC: 1, 2): 重构系统配置路由聚合
    • 修改 packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts
    • 参照订单模块聚合写法,将自定义路由与CRUD路由聚合 [对照: packages/orders-module-mt/src/routes/user/orders.mt.ts:34-38]
    • 保持现有API接口兼容性
    • 确保多租户中间件正确应用: 保持authMiddleware和tenantOptions配置
  • 任务 6 (AC: 4, 5): 验证缓存刷新机制
    • 创建缓存刷新验证测试
    • 验证创建配置时缓存正确刷新
    • 验证更新配置时缓存正确刷新
    • 验证删除配置时缓存正确刷新
    • 验证多租户缓存隔离: 确保不同租户的配置缓存完全隔离
  • 任务 7 (AC: 6): 更新现有集成测试文件
    • 修改 packages/core-module-mt/system-config-module-mt/tests/integration/system-config.routes.integration.test.ts
    • 添加自定义路由的集成测试
    • 验证自定义路由与CRUD路由的兼容性
    • 验证缓存刷新机制
    • 验证多租户隔离
  • 任务 8 (AC: 6): 验证现有功能无回归
    • 运行现有系统配置模块测试 [对照: packages/core-module-mt/system-config-module-mt/tests/integration/system-config.routes.integration.test.ts]
    • 验证认证和支付模块集成正常 [对照: packages/core-module-mt/auth-module-mt/src/services/mini-auth.service.mt.ts]
    • 验证管理后台UI包集成正常 [对照: packages/system-config-management-ui-mt/src/api/systemConfigClient.ts]
    • 运行所有相关集成测试

Dev Notes

技术栈信息 [Source: architecture/tech-stack.md]

  • 运行时: Node.js 20.18.3
  • 框架: Hono 4.8.5 (Web框架和API路由)
  • 数据库: PostgreSQL 17 (通过TypeORM)
  • ORM: TypeORM 0.3.25 (实体管理)
  • 验证: Zod + @hono/zod-openapi
  • 缓存: Redis 7 (系统配置缓存)

项目结构信息 [Source: architecture/source-tree.md]

  • 包位置: packages/core-module-mt/system-config-module-mt/
  • 包架构层次: 多租户核心包中的业务模块
  • 文件组织:
    • src/entities/ - 实体定义 (使用 .mt.ts 后缀)
    • src/schemas/ - Zod Schema定义 (使用 .mt.ts 后缀)
    • src/services/ - 服务实现 (使用 .mt.ts 后缀)
    • src/routes/ - API路由 (使用 .mt.ts 后缀)
    • src/routes/custom/ - 自定义路由 (新增)
    • tests/ - 测试文件
  • 现有模块参考:
    • auth-module-mt/ - 认证模块
    • user-module-mt/ - 用户模块
    • file-module-mt/ - 文件模块
    • orders-module-mt/ - 订单模块 (聚合写法参考)

订单模块聚合写法参考 [Source: packages/orders-module-mt/src/routes/user/orders.mt.ts]

// 订单模块的聚合写法示例
const userOrderRoutes = new OpenAPIHono()
  .route('/', createOrderRoutes)
  .route('/', cancelOrderRoutes)
  .route('/', userOrderCrudRoutes);

系统配置服务缓存方法 [Source: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts]

  • setConfig: 设置配置值,自动清除缓存
  • update: 重写方法,在更新时清除缓存
  • deleteConfig: 删除配置,自动清除缓存
  • getConfigByKey: 获取配置值,带缓存逻辑
  • getConfigsByKeys: 批量获取配置,带缓存逻辑

Redis缓存键格式 [Source: packages/shared-utils/src/utils/redis.util.ts]

  • 缓存键格式: system_config:{tenantId}:{configKey}
  • 默认TTL: 1小时 (3600秒)
  • 空值缓存TTL: 5分钟 (300秒)

现有系统配置路由结构 [Source: packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts]

当前使用通用CRUD路由:

const systemConfigCrudRoutes = createCrudRoutes({
  entity: SystemConfigMt,
  createSchema: CreateSystemConfigSchema,
  updateSchema: UpdateSystemConfigSchema,
  getSchema: SystemConfigSchema,
  listSchema: SystemConfigSchema,
  searchFields: ['configKey', 'description'],
  middleware: [authMiddleware],
  tenantOptions: {
    enabled: true,
    tenantIdField: 'tenantId',
    autoExtractFromContext: true
  }
});

共享CRUD集成模式 [Source: packages/shared-crud/src/services/generic-crud.service.ts]

  • 继承模式: 继承 GenericCrudService<T> 抽象类
  • 租户配置: 通过 tenantOptions 配置租户隔离
  • 用户跟踪: 通过 userTracking 配置用户跟踪
  • 核心方法: getList(), getById(), create(), update(), delete()

多租户隔离关键要求

强制多租户隔离要求:

  • 租户ID提取: 所有自定义路由必须从上下文中提取tenantId [对照: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts:11-13]
  • 缓存键隔离: Redis缓存键必须包含tenantId前缀 system_config:{tenantId}:{configKey} [对照: packages/shared-utils/src/utils/redis.util.ts:68]
  • 数据库查询隔离: 所有数据库查询必须包含tenantId条件 [对照: packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts:40]
  • 操作范围限制: 创建、更新、删除操作只能影响当前租户的配置
  • 缓存刷新隔离: 缓存刷新操作只能清除当前租户的缓存

先前故事实施经验

从Epic 010的前4个故事中提取的关键经验:

  • 缓存穿透保护: 实现空值缓存机制防止缓存穿透攻击 [Source: docs/stories/010.002.system-config-redis-cache.story.md]
  • 多租户隔离: 修复了多租户隔离概念,强制要求tenantId参数 [Source: docs/stories/010.002.system-config-redis-cache.story.md]
  • TypeORM语法: 修复了{ configKey: missingKeys }语法错误,改为{ configKey: In(missingKeys) } [Source: docs/stories/010.002.system-config-redis-cache.story.md]
  • 包导出配置: 修复了system-config-module-mt包导出配置问题 [Source: docs/stories/010.003.system-config-auth-payment-integration.story.md]

测试

测试标准 [Source: architecture/testing-strategy.md]

  • 测试框架: Vitest + hono/testing
  • 测试位置: packages/core-module-mt/system-config-module-mt/tests/
  • 测试类型: 单元测试 + 集成测试
  • 覆盖率目标: 单元测试 ≥ 80%,集成测试 ≥ 60%

测试文件结构

  • tests/integration/ - 集成测试
    • system-config.routes.integration.test.ts - 现有路由集成测试
    • system-config-custom-routes.integration.test.ts - 新增自定义路由集成测试

测试要求

  • 验证自定义路由与CRUD路由聚合正确
  • 验证缓存刷新机制正确工作
  • 验证多租户缓存隔离: 确保不同租户的配置缓存完全隔离
  • 验证多租户数据隔离: 确保操作只影响当前租户的数据
  • 验证租户ID提取: 确保从上下文中正确提取tenantId
  • 验证API接口兼容性
  • 验证现有功能无回归

Change Log

Date Version Description Author
2025-11-22 1.0 初始故事创建 Bob (Scrum Master)
2025-11-22 1.1 添加对照文件路径标注,强调多租户隔离要求 Bob (Scrum Master)

Dev Agent Record

Agent Model Used

  • Claude Code (d8d-model)

Debug Log References

  • 修复认证模块导入路径问题:从 @d8d/auth-module-mt 改为 @d8d/core-module-mt/auth-module-mt
  • 修复测试文件类型错误:参数类型不匹配,将 config.id.toString() 改为字符串参数
  • 修复删除路由响应状态码:从200改为204
  • 修复缓存刷新机制:重写 SystemConfigServiceMtdelete 方法
  • 修复OpenAPI响应定义:为所有错误响应添加 content 字段
  • 修复类型错误:错误响应格式符合 ErrorSchema 要求

Completion Notes List

  1. 成功创建自定义路由目录结构:src/routes/custom/
  2. 实现三个自定义路由:创建、更新、删除,均自动处理缓存刷新
  3. 重构路由聚合:将通用CRUD路由设为 readOnly: true
  4. 重写 SystemConfigServiceMt.delete() 方法确保缓存刷新
  5. 更新集成测试:添加自定义路由缓存刷新验证和多租户隔离测试
  6. 所有13个集成测试通过,类型检查通过
  7. 确保多租户隔离:从上下文中提取 tenantId,缓存键包含租户前缀

File List

创建的文件:

  • packages/core-module-mt/system-config-module-mt/src/routes/custom/create-system-config.mt.ts
  • packages/core-module-mt/system-config-module-mt/src/routes/custom/update-system-config.mt.ts
  • packages/core-module-mt/system-config-module-mt/src/routes/custom/delete-system-config.mt.ts

修改的文件:

  • packages/core-module-mt/system-config-module-mt/src/routes/system-config.routes.mt.ts
  • packages/core-module-mt/system-config-module-mt/src/services/system-config.service.mt.ts
  • packages/core-module-mt/system-config-module-mt/tests/integration/system-config.routes.integration.test.ts

QA Results

  • 所有13个集成测试通过
  • 类型检查通过
  • 缓存自动刷新功能正常工作
  • 多租户隔离正常工作
  • API兼容性保持
  • 无功能回归