2
0
Эх сурвалжийг харах

📝 docs(story): add tenant module integration story documentation

- 创建租户模块集成到server的故事文档
- 包含集成目标、验收标准和详细任务分解
- 提供技术栈信息、项目结构和集成模式说明

♻️ refactor(auth-ui): update auth module dependency to multi-tenant version

- 将@d8d/auth-module替换为@d8d/auth-module-mt依赖
- 确保认证管理UI与多租户认证模块兼容

♻️ refactor(goods-category-ui): update goods category routes import

- 从goods-module-mt导入adminGoodsCategoriesRoutesMt替代原路由
- 调整客户端类型定义以匹配新的路由导出

♻️ refactor(shared-ui): improve rpcClient type definition

- 添加Hono类型导入并明确rpcClient泛型约束
- 移除@ts-ignore注释,增强类型安全性
yourname 1 сар өмнө
parent
commit
072dfce0dc

+ 159 - 0
docs/stories/008.003.tenant-module-server-integration.story.md

@@ -0,0 +1,159 @@
+# Story 008.003: 租户模块集成到server
+
+## Status
+Draft
+
+## Story
+**As a** 系统超级管理员
+**I want** 将租户模块包集成到server中
+**so that** server能够支持租户管理操作,包括租户CRUD、超级管理员认证和租户数据隔离
+
+## Acceptance Criteria
+1. 将租户模块包(@d8d/tenant-module-mt)集成到server中
+2. 包括租户管理路由、超级管理员认证和租户数据隔离功能
+3. 确保server能够支持租户管理操作
+
+## Tasks / Subtasks
+- [ ] 验证租户模块包可用性和导出 (AC: 1)
+  - [ ] 检查租户模块包的package.json配置
+  - [ ] 验证包有正确的路由导出(tenantRoutes、authRoutes)
+  - [ ] 验证包有正确的实体导出(TenantEntityMt)
+  - [ ] 验证包有正确的中间件导出(tenantAuthMiddleware)
+- [ ] 添加租户模块包依赖到server (AC: 1)
+  - [ ] 在packages/server/package.json中添加@d8d/tenant-module-mt依赖
+  - [ ] 验证依赖版本兼容性
+- [ ] 导入租户模块包实体到数据库初始化 (AC: 2)
+  - [ ] 在packages/server/src/index.ts中导入TenantEntityMt
+  - [ ] 将TenantEntityMt添加到initializeDataSource实体列表
+  - [ ] 验证数据库初始化正确性
+- [ ] 注册租户管理路由到server (AC: 1)
+  - [ ] 在packages/server/src/index.ts中导入tenantRoutes
+  - [ ] 注册租户管理路由到/api/v1/tenants路径
+  - [ ] 验证路由配置正确性
+- [ ] 注册租户认证路由到server (AC: 2)
+  - [ ] 在packages/server/src/index.ts中导入authRoutes
+  - [ ] 注册租户认证路由到/api/v1/tenant-auth路径
+  - [ ] 验证认证路由配置正确性
+- [ ] 验证租户管理功能 (AC: 3)
+  - [ ] 测试租户CRUD操作(创建、读取、更新、删除)
+  - [ ] 测试超级管理员认证功能
+  - [ ] 验证租户数据隔离机制
+- [ ] 执行回归测试 (AC: 3)
+  - [ ] 运行现有功能回归测试
+  - [ ] 验证向后兼容性
+  - [ ] 确保性能无明显下降
+
+## Dev Notes
+
+### 技术栈信息 [Source: architecture/tech-stack.md]
+- **后端框架**: Node.js 20.18.3 + TypeScript
+- **Web框架**: Hono 4.8.5
+- **数据库**: PostgreSQL 17
+- **ORM**: TypeORM 0.3.25
+- **认证**: JWT 9.0.2
+
+### 项目结构信息 [Source: architecture/source-tree.md]
+- **Server位置**: `packages/server/`
+- **路由配置**: `packages/server/src/index.ts`
+- **租户模块包位置**: `packages/tenant-module-mt/`
+- **数据库连接**: `packages/shared-utils/src/data-source.ts`
+
+### 租户模块包实际结构 [基于实际包检查]
+租户模块包(@d8d/tenant-module-mt)提供以下功能:
+
+**实体**:
+- `TenantEntityMt` - 租户实体,包含租户名称、代码、状态、配置等字段
+
+**路由**:
+- `tenantRoutes` - 租户管理路由,使用通用CRUD服务,支持租户CRUD操作
+- `authRoutes` - 超级管理员认证路由,支持固定超级管理员账号登录
+
+**中间件**:
+- `tenantAuthMiddleware` - 租户认证中间件,验证超级管理员权限
+
+**服务**:
+- `TenantService` - 租户服务,提供租户业务逻辑
+
+### 现有集成模式 [Source: packages/server/src/index.ts]
+当前server已经集成了多个多租户模块包,集成模式为:
+```typescript
+// 包导入
+import { userRoutesMt as userModuleRoutes } from '@d8d/user-module-mt'
+import { authRoutes as authModuleRoutes } from '@d8d/auth-module-mt'
+
+// 路由注册
+export const userRoutes = api.route('/api/v1/users', userModuleRoutes)
+export const authRoutes = api.route('/api/v1/auth', authModuleRoutes)
+
+// 实体初始化
+initializeDataSource([
+  UserEntityMt, RoleMt, FileMt,
+  // ... 其他实体
+])
+```
+
+### 租户模块包集成模式 [基于实际包结构]
+```typescript
+// 租户模块包导入
+import { tenantRoutes } from '@d8d/tenant-module-mt'
+import { authRoutes as tenantAuthRoutes } from '@d8d/tenant-module-mt'
+import { TenantEntityMt } from '@d8d/tenant-module-mt'
+
+// 租户路由注册
+export const tenantApiRoutes = api.route('/api/v1/tenants', tenantRoutes)
+export const tenantAuthApiRoutes = api.route('/api/v1/tenant-auth', tenantAuthRoutes)
+
+// 租户实体添加到数据库初始化
+initializeDataSource([
+  // ... 现有实体
+  TenantEntityMt  // 添加租户实体
+])
+```
+
+### 超级管理员认证机制 [Source: packages/tenant-module-mt/src/routes/auth.routes.ts]
+- 使用固定的超级管理员账号:用户名 `superadmin`,密码 `admin123`
+- 超级管理员ID固定为 `1`
+- 登录成功后生成JWT token
+- 租户管理操作需要超级管理员权限
+
+### 租户管理功能 [Source: packages/tenant-module-mt/src/routes/index.ts]
+- 使用通用CRUD服务创建租户管理路由
+- 支持租户CRUD操作(创建、读取、更新、删除)
+- 支持搜索字段:租户名称、代码、联系人姓名、电话
+- 使用租户认证中间件保护路由
+- 不使用数据权限控制,由超级管理员统一管理
+
+### 基于故事008.001和008.002实现经验的注意事项
+- **包命名一致性**: 确保server使用的租户模块包名与包实际名称一致
+- **导出验证**: 基于故事008.001经验,需要验证租户模块包有正确的路由和实体导出
+- **依赖管理**: 需要更新server的package.json,添加租户模块包依赖
+- **实体初始化**: 需要将租户实体添加到数据库初始化列表
+- **向后兼容性**: 保持现有API接口路径不变,新增租户相关API
+- **测试策略**: 基于故事008.001经验,需要验证包导入、路由注册和功能测试
+
+### 测试要求
+- 使用Vitest进行集成测试 [Source: architecture/tech-stack.md#新技术添加]
+- 验证租户管理路由在server环境下的正确性
+- 测试超级管理员认证功能
+- 确保租户数据管理功能正常工作
+- 执行回归测试确保现有功能不受影响
+
+## Change Log
+| Date | Version | Description | Author |
+|------|---------|-------------|--------|
+| 2025-11-18 | 1.1 | 基于实际租户模块包结构重写故事 | Bob (Scrum Master) |
+| 2025-11-18 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
+
+## Dev Agent Record
+*This section is populated by the development agent during implementation*
+
+### Agent Model Used
+
+### Debug Log References
+
+### Completion Notes List
+
+### File List
+
+## QA Results
+*Results from QA Agent QA review of the completed story implementation*

+ 1 - 1
packages/auth-management-ui-mt/package.json

@@ -40,7 +40,7 @@
     "typecheck": "tsc --noEmit"
   },
   "dependencies": {
-    "@d8d/auth-module": "workspace:*",
+    "@d8d/auth-module-mt": "workspace:*",
     "@d8d/shared-types": "workspace:*",
     "@d8d/shared-ui-components": "workspace:*",
     "@hookform/resolvers": "^5.2.1",

+ 5 - 5
packages/goods-category-management-ui-mt/src/api/goodsCategoryClient.ts

@@ -1,9 +1,9 @@
-import { adminGoodsCategoriesRoutes } from '@d8d/goods-module-mt';
+import { adminGoodsCategoriesRoutesMt } from '@d8d/goods-module-mt';
 import { rpcClient } from '@d8d/shared-ui-components/utils/hc'
 
 class GoodsCategoryClientManager {
   private static instance: GoodsCategoryClientManager;
-  private client: ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutes>> | null = null;
+  private client: ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutesMt>> | null = null;
 
   private constructor() {}
 
@@ -15,12 +15,12 @@ class GoodsCategoryClientManager {
   }
 
   // 初始化客户端
-  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutes>> {
-    return this.client = rpcClient<typeof adminGoodsCategoriesRoutes>(baseUrl);
+  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutesMt>> {
+    return this.client = rpcClient<typeof adminGoodsCategoriesRoutesMt>(baseUrl);
   }
 
   // 获取客户端实例
-  public get(): ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutes>> {
+  public get(): ReturnType<typeof rpcClient<typeof adminGoodsCategoriesRoutesMt>> {
     if (!this.client) {
       return this.init()
     }

+ 2 - 3
packages/shared-ui-components/src/utils/hc.ts

@@ -1,5 +1,6 @@
 import axios, { isAxiosError } from 'axios';
 import { hc } from 'hono/client'
+import type { Hono } from 'hono'
 
 // 创建 axios 适配器
 const axiosFetch = async (url: RequestInfo | URL, init?: RequestInit) => {
@@ -56,9 +57,7 @@ const axiosFetch = async (url: RequestInfo | URL, init?: RequestInit) => {
 }
 
 // 创建Hono RPC客户端
-// @ts-types="node_modules/hono/dist/types/client/types"
-export const rpcClient = <T extends any>(aptBaseUrl: string) => {
-  // @ts-ignore
+export const rpcClient = <T extends Hono<any, any, any>>(aptBaseUrl: string): ReturnType<typeof hc<T>> => {
   return hc<T>(aptBaseUrl, {
     fetch: axiosFetch
   })

+ 2 - 2
pnpm-lock.yaml

@@ -1035,9 +1035,9 @@ importers:
 
   packages/auth-management-ui-mt:
     dependencies:
-      '@d8d/auth-module':
+      '@d8d/auth-module-mt':
         specifier: workspace:*
-        version: link:../auth-module
+        version: link:../auth-module-mt
       '@d8d/shared-types':
         specifier: workspace:*
         version: link:../shared-types