# Story 007.001: 租户基础包创建和租户管理 ## Status Draft ## Story **As a** 系统管理员 **I want** 创建租户基础包和租户管理功能 **so that** 能够为多租户系统提供基础的租户管理和上下文支持 ## Acceptance Criteria 1. 成功复制 `@d8d/merchant-module` 为 `@d8d/tenant-module-mt` 租户管理模块 2. 修改商户实体为租户实体,调整字段和业务逻辑 3. 实现租户管理API,包括租户的CRUD操作 4. 创建租户上下文管理机制 5. 验证租户管理功能正常工作 6. 确保现有单租户系统功能完全不受影响 ## Tasks / Subtasks - [ ] 复制 `@d8d/merchant-module` 为 `@d8d/tenant-module-mt` (AC: 1) - [ ] 创建新的包目录结构 - [ ] 复制并修改package.json配置 - [ ] 更新包名和描述信息 - [ ] 修改商户实体为租户实体 (AC: 2) - [ ] 重命名Merchant实体为TenantEntityMt - [ ] 调整字段映射(商户名称→租户名称,用户名→租户代码等) - [ ] 移除商户特定字段(登录统计、密码等) - [ ] 添加租户特定字段(状态、配置等) - [ ] 实现租户管理API (AC: 3) - [ ] 创建租户服务层,基于现有商户服务修改 - [ ] 实现租户CRUD路由 - [ ] 更新Schema定义 - [ ] 添加租户类型定义 - [ ] 创建租户认证中间件 (AC: 4) - [ ] 实现tenantAuthMiddleware函数 - [ ] 添加JWT验证和租户ID提取 - [ ] 创建租户认证中间件 - [ ] 验证租户管理功能 (AC: 5) - [ ] 编写API集成测试 - [ ] 验证租户数据隔离 - [ ] 验证现有单租户系统功能完整性 (AC: 6) ## Dev Notes ### 相关源树信息 ``` packages/ ├── merchant-module/ (源包) │ ├── src/ │ │ ├── entities/merchant.entity.ts │ │ ├── services/merchant.service.ts │ │ ├── routes/ │ │ ├── schemas/ │ │ └── types/ │ └── package.json └── tenant-module-mt/ (目标包) ├── src/ │ ├── entities/tenant.entity.ts │ ├── services/tenant.service.ts │ ├── routes/ │ ├── schemas/ │ └── types/ └── package.json ``` ### 技术上下文 - **现有系统**: TypeScript + Node.js + TypeORM + Hono - **数据库**: PostgreSQL - **包管理**: pnpm workspace - **架构模式**: 模块化架构,CRUD操作,认证中间件 ### 实体映射关系 从商户实体到租户实体的字段映射: - `name` (商户名称) → `name` (租户名称) - `username` (用户名) → `code` (租户代码,唯一标识) - 移除:`password`, `loginNum`, `loginTime`, `loginIp`, `lastLoginTime`, `lastLoginIp` - 添加:`status` (租户状态), `config` (租户配置) ### 租户认证中间件设计 **重要说明**:此租户认证中间件仅用于租户管理API,与认证模块的认证中间件是独立的两套系统。 采用Hono中间件模式与现有技术栈统一: ```typescript import { Context, Next } from 'hono'; export async function tenantAuthMiddleware(c: Context, next: Next) { try { const authHeader = c.req.header('Authorization'); if (!authHeader) { return c.json({ message: 'Authorization header missing' }, 401); } const tokenParts = authHeader.split(' '); if (tokenParts.length !== 2 || tokenParts[0] !== 'Bearer') { return c.json({ message: 'Authorization header missing' }, 401); } const token = tokenParts[1]; if (!token) { return c.json({ message: 'Token missing' }, 401); } // 验证JWT并提取租户ID const decoded = jwt.verify(token, process.env.JWT_SECRET!) as any; const tenantId = decoded.tenantId; if (!tenantId) { return c.json({ message: 'Tenant ID not found in token' }, 401); } // 设置租户上下文 c.set('tenantId', tenantId); await next(); } catch (error) { console.error('Tenant auth middleware error:', error); return c.json({ message: 'Invalid token or tenant context' }, 401); } } ``` ### 依赖关系 - 共享包依赖:`@d8d/shared-crud`, `@d8d/shared-types`, `@d8d/shared-utils` - 不依赖其他业务包,避免循环依赖 - 保持与单租户系统相同的技术栈和架构模式 ### 测试 #### 测试标准 - **测试文件位置**: `tests/` 目录下 - **测试框架**: Vitest - **测试模式**: API集成测试 - **测试覆盖**: 租户管理API接口 #### 具体测试要求 - 租户CRUD操作API测试 - 租户上下文管理集成测试 - 租户数据隔离验证 - 现有单租户系统回归测试 ## Change Log | Date | Version | Description | Author | |------|---------|-------------|---------| | 2025-11-13 | 1.0 | 初始故事创建 | Claude | ## Dev Agent Record *此部分将由开发代理在实施过程中填写* ### Agent Model Used {{agent_model_name_version}} ### Debug Log References ### Completion Notes List ### File List ## QA Results *此部分将由QA代理在QA审查后填写*