# 史诗007 - Allin System有实体模块移植到独立包 ## 史诗目标 将allin_system-master/server/src目录下有对应数据库实体的模块移植到packages目录下,作为非多租户独立包,遵循项目现有的独立包结构和命名规范,实现模块的现代化重构和标准化管理。 ## 史诗描述 ### 现有系统上下文 - **当前相关功能**:allin_system-master是一个基于NestJS的后端系统,根据allin_2025-11-25.sql分析,有以下有实体的模块: 1. channel_info模块 - 对应channel_info表 2. company模块 - 对应employer_company表 3. dict_management模块 - 对应sys_dict表 4. disability_person模块 - 对应disabled_person、disabled_bank_card、disabled_photo、disabled_remark、disabled_visit表 5. order模块 - 对应employment_order、order_person、order_person_asset表 6. platform模块 - 对应employer_platform表 7. salary模块 - 对应salary_level表 - **无实体模块(本次不移植)**:admin、auth、users模块 - **技术栈**:TypeScript、NestJS、PostgreSQL、Redis、MinIO - **集成点**:模块间通过NestJS模块系统集成,共享数据库连接和配置 ### 增强详情 - **新增/变更内容**:将7个有实体的现有模块从allin_system-master/server/src移植到packages目录下的独立包 - **集成方式**:每个模块将重构为独立的npm包,遵循@d8d命名规范,通过workspace依赖管理 - **成功标准**: 1. 7个有实体模块成功移植为独立包 2. 保持原有功能完整性 3. 遵循现有独立包结构模式 4. 通过类型检查和基本测试验证 ## 模块分析结果 ### 1. 模块依赖关系分析 根据对每个模块`module.ts`文件的分析,依赖关系如下: 1. **channel_info模块** (`channel.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`Channel` (对应`channel_info`表) - 无其他模块依赖 2. **company模块** (`company.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm`, `PlatformModule` - 实体:`Company` (对应`employer_company`表) - 依赖模块:`platform` 3. **dict_management模块** (`dict.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`Dict` (对应`sys_dict`表) - 无其他模块依赖 4. **disability_person模块** (`disability_person.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`DisabledPerson`, `DisabledBankCard`, `DisabledPhoto`, `DisabledRemark`, `DisabledVisit` - 引用其他模块实体:`EmploymentOrder`, `OrderPerson` (order模块), `Platform` (platform模块), `Company` (company模块), `Channel` (channel_info模块) - 复杂度:高(5个实体,多个控制器和服务) 5. **order模块** (`order.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`EmploymentOrder`, `OrderPerson`, `OrderPersonAsset` - 引用其他模块实体:`DisabledPerson` (disability_person模块), `Platform` (platform模块), `Company` (company模块), `Channel` (channel_info模块) - 复杂度:中高(3个实体,跨模块依赖) 6. **platform模块** (`platform.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`Platform` (对应`employer_platform`表) - 无其他模块依赖 - 被依赖:`company`模块依赖此模块 7. **salary模块** (`salary.module.ts`) - 依赖:`@nestjs/common`, `@nestjs/typeorm` - 实体:`SalaryLevel` (对应`salary_level`表) - 无其他模块依赖 ### 2. 依赖关系图 ``` platform ───┐ ↓ company ────┐ ↓ channel_info ─┐ ↓ ↓ order ───────┘ ↑ disability_person ↑ dict_management (独立) salary (独立) ``` **关键发现**: - `platform`模块是基础依赖,被`company`模块直接依赖 - `company`、`channel_info`模块被`order`和`disability_person`模块引用 - `order`和`disability_person`模块相互引用实体,形成循环依赖 - `dict_management`和`salary`模块完全独立 ### 3. 模块到独立包的映射方案 基于现有项目命名规范,并考虑这是Allin系统专属模块,制定以下映射方案: | 原模块名 | 独立包名 | 目录名 | 说明 | |---------|---------|--------|------| | channel_info | `@d8d/allin-channel-module` | `channel-module` | 渠道管理模块 | | company | `@d8d/allin-company-module` | `company-module` | 公司管理模块,依赖platform-module | | dict_management | `@d8d/allin-dict-module` | `dict-module` | 字典管理模块 | | disability_person | `@d8d/allin-disability-module` | `disability-module` | 残疾人管理模块(简化名称) | | order | `@d8d/allin-order-module` | `order-module` | 订单管理模块 | | platform | `@d8d/allin-platform-module` | `platform-module` | 平台管理模块 | | salary | `@d8d/allin-salary-module` | `salary-module` | 薪资管理模块 | **命名原则**: 1. **包名前缀**:使用`@d8d/allin-`前缀,明确表明是Allin系统专属包 2. **目录名**:使用简洁的`{模块名}-module`格式,便于在`allin-packages`目录中管理 3. **模块名**:使用单数形式 + `-module`后缀 4. **名称简洁**:反映模块核心功能 5. **非多租户**:不使用`-mt`后缀(本次移植为非多租户版本) ### 4. 目录结构和包规范 #### 目录结构决策 由于这些模块是`allin_system-master`项目独有的业务模块(非通用模块),将在项目根目录创建独立目录: ``` 项目根目录/ ├── allin-packages/ # Allin系统专属包目录 │ ├── channel-module/ # 渠道管理模块 │ ├── company-module/ # 公司管理模块 │ ├── dict-module/ # 字典管理模块 │ ├── disability-module/ # 残疾人管理模块 │ ├── order-module/ # 订单管理模块 │ ├── platform-module/ # 平台管理模块 │ └── salary-module/ # 薪资管理模块 ├── packages/ # 现有通用包目录(保持不变) └── allin_system-master/ # 原始代码目录(移植源) ``` **目录命名说明**:`allin-packages`清晰表明这是Allin系统专属的包目录,与`allin_system-master`源目录对应,区别于通用的`packages`目录。 #### 包结构规范 参考现有`auth-module`结构,每个独立包应包含: ``` allin-packages/{module-name}/ ├── package.json # 包配置,workspace依赖管理 ├── tsconfig.json # TypeScript配置 ├── vitest.config.ts # 测试配置(如需要) ├── src/ │ ├── index.ts # 主导出文件 │ ├── schemas/ # Zod模式定义(如需要) │ │ └── index.ts │ ├── entities/ # 数据库实体 │ ├── services/ # 业务服务 │ ├── controllers/ # API控制器 │ ├── dtos/ # 数据传输对象 │ └── types/ # TypeScript类型定义 └── dist/ # 构建输出 ``` **关键配置要求**: 1. `package.json`中设置`"type": "module"` 2. 主入口为`src/index.ts` 3. 使用workspace依赖:`"@d8d/core-module": "workspace:*"` 4. 包名使用`@d8d/allin-`前缀,如`@d8d/allin-channel-module` 5. 导出必要的服务和实体 ### 5. 技术栈差异分析与移植方案 #### 技术栈对比分析 | 方面 | 当前项目(目标) | allin_system-master(源) | 差异程度 | |------|------------------|---------------------------|----------| | **Web框架** | Hono(轻量级) | NestJS(重量级) | **重大** | | **路由系统** | Hono路由 | NestJS装饰器路由 | **重大** | | **验证库** | Zod + @hono/zod-openapi | class-validator + class-transformer | **中等** | | **服务架构** | GenericCrudService继承 | 自定义Service类 | **中等** | | **实体配置** | 详细TypeORM装饰器 | 简单TypeORM装饰器 | **轻微** | | **命名规范** | 驼峰命名(channelId) | 下划线命名(channel_id) | **轻微** | | **模块系统** | npm包 + workspace | NestJS模块系统 | **重大** | | **API风格** | RESTful + OpenAPI | 自定义端点 | **中等** | #### 关键依赖对比 - **当前项目**:`@d8d/core-module`、`@d8d/shared-crud`、`@d8d/shared-utils`、TypeORM、Hono、Zod - **allin_system**:`@nestjs/*`、TypeORM、class-validator、Passport/JWT #### 移植调整方案 ##### A. 架构转换策略 1. **NestJS控制器 → Hono路由**:重写路由层 2. **自定义Service → GenericCrudService继承**:重构服务层 3. **class-validator DTO → Zod Schema**:转换验证逻辑 4. **NestJS模块 → npm包**:重新组织模块结构 ##### B. 实体层转换示例 ```typescript // 原allin实体(下划线命名) @Entity('channel_info') export class Channel { @PrimaryGeneratedColumn('increment') channel_id: number; // 下划线 @Column() channel_name: string; } // 转换后实体(驼峰命名,详细配置) @Entity('channel_info') export class Channel { @PrimaryGeneratedColumn({ name: 'channel_id', type: 'int' }) channelId!: number; // 驼峰 @Column({ name: 'channel_name', type: 'varchar', length: 100 }) channelName!: string; } ``` ##### C. 服务层转换示例 ```typescript // 原allin服务(NestJS风格) @Injectable() export class ChannelService { constructor(@InjectRepository(Channel) private repo: Repository) {} async createChannel(data: CreateChannelDto): Promise { // 自定义逻辑 } } // 转换后服务(Hono + GenericCrudService) export class ChannelService extends GenericCrudService { constructor(dataSource: DataSource) { super(dataSource, Channel, { searchFields: ['channelName', 'contactPerson'], }); } // 保留特殊业务方法 async createChannel(data: CreateChannelDto): Promise { // 复用或重写逻辑 } } ``` ##### D. 路由层转换示例 ```typescript // 原NestJS控制器 @Controller('channel') @UseGuards(JwtAuthGuard) export class ChannelController { @Post('createChannel') createChannel(@Body() req: CreateChannelDto) { return this.service.createChannel(req); } } // 转换后Hono路由 import { OpenAPIHono } from '@hono/zod-openapi'; const channelRoutes = new OpenAPIHono() .post('/createChannel', async (c) => { const data = await c.req.json(); const result = await channelService.createChannel(data); return c.json({ success: result }); }); ``` ##### E. 验证系统转换 ```typescript // 原class-validator DTO export class CreateChannelDto { @IsString() channel_name: string; } // 转换后Zod Schema export const CreateChannelSchema = z.object({ channelName: z.string().min(1).max(100), }); export type CreateChannelDto = z.infer; ``` #### 依赖关系解决方案 针对发现的循环依赖问题(order ↔ disability_person),解决方案: 1. **创建共享实体包**:将相互引用的实体提取到共享包 2. **接口抽象**:使用接口而非具体实体引用 3. **依赖注入调整**:重构服务层减少直接实体依赖 4. **移植顺序策略**:按依赖顺序移植,先移植基础模块 **建议移植顺序**: 1. `allin-platform-module`(基础) 2. `allin-channel-module`、`allin-dict-module`、`allin-salary-module`(独立) 3. `allin-company-module`(依赖platform) 4. `allin-order-module`和`allin-disability-module`(最后处理,解决循环依赖) #### 兼容性保证 - **保持**:数据库表结构、核心业务逻辑、数据关系 - **调整**:API端点路径、请求/响应格式、错误处理 - **新增**:OpenAPI文档、标准化CRUD操作、类型安全验证 ## 故事分解(按模块拆分) **注**:每个故事对应一个模块的完整移植,包括技术栈转换和API集成测试。 ### 故事1:移植渠道管理模块(channel_info → @d8d/allin-channel-module) **目标**:将channel_info模块移植为独立包,完成技术栈转换并验证功能完整性 **验收标准**: 1. ✅ 创建`allin-packages/channel-module`目录结构 2. ✅ 完成实体转换:`Channel`实体从下划线命名转换为驼峰命名 3. ✅ 完成服务层转换:从NestJS自定义Service转换为GenericCrudService继承 4. ✅ 完成路由层转换:从NestJS控制器转换为Hono路由 5. ✅ 完成验证系统转换:从class-validator DTO转换为Zod Schema 6. ✅ 配置package.json:使用`@d8d/allin-channel-module`包名,workspace依赖 7. ✅ 编写API集成测试:覆盖所有路由端点,验证CRUD操作 8. ✅ 通过类型检查和基本测试验证 **API集成测试要求**: - 测试文件:`tests/integration/channel.integration.test.ts` - 测试覆盖:GET/POST/PUT/DELETE所有端点 - 验证:认证、授权、数据验证、错误处理 - 遵循现有集成测试模式(参考advertisements-module) ### 故事2:移植公司管理模块(company → @d8d/allin-company-module) **目标**:将company模块移植为独立包,处理对platform-module的依赖 **验收标准**: 1. ✅ 创建`allin-packages/company-module`目录结构 2. ✅ 完成实体转换:`Company`实体转换 3. ✅ 处理模块依赖:正确配置对`@d8d/allin-platform-module`的依赖 4. ✅ 完成服务层转换:处理跨模块业务逻辑 5. ✅ 完成路由层转换:Hono路由实现 6. ✅ 完成验证系统转换:Zod Schema定义 7. ✅ 配置package.json:workspace依赖管理 8. ✅ 编写API集成测试:验证模块间依赖正常工作 9. ✅ 通过类型检查和基本测试验证 **API集成测试要求**: - 测试文件:`tests/integration/company.integration.test.ts` - 测试覆盖:公司管理的所有业务场景 - 验证:与platform-module的集成、数据关联查询 - 包含跨模块数据一致性测试 ### 故事3:移植字典管理模块(dict_management → @d8d/allin-dict-module) **目标**:将dict_management模块移植为独立包,验证独立模块移植模式 **验收标准**: 1. ✅ 创建`allin-packages/dict-module`目录结构 2. ✅ 完成实体转换:`Dict`实体转换 3. ✅ 完成服务层转换:独立业务逻辑处理 4. ✅ 完成路由层转换:Hono路由实现 5. ✅ 完成验证系统转换:Zod Schema定义 6. ✅ 配置package.json:独立包配置 7. ✅ 编写API集成测试:验证字典CRUD操作 8. ✅ 通过类型检查和基本测试验证 9. ✅ 验证技术栈转换模板的适用性 **API集成测试要求**: - 测试文件:`tests/integration/dict.integration.test.ts` - 测试覆盖:字典分类、字典项管理 - 验证:树形结构处理、状态管理、排序功能 - 包含复杂查询场景测试 ### 故事4:移植残疾人管理模块(disability_person → @d8d/allin-disability-module) **目标**:移植最复杂的模块,处理5个实体和跨模块依赖 **验收标准**: 1. ✅ 创建`allin-packages/disability-module`目录结构 2. ✅ 完成实体转换:5个实体(DisabledPerson、DisabledBankCard等)转换 3. ✅ 处理跨模块依赖:引用order、platform、company、channel模块实体 4. ✅ 完成服务层转换:复杂业务逻辑处理 5. ✅ 完成路由层转换:多个控制器转换为Hono路由 6. ✅ 完成验证系统转换:复杂数据验证 7. ✅ 配置package.json:处理多个依赖 8. ✅ 编写API集成测试:覆盖所有5个实体的管理功能 9. ✅ 通过类型检查和基本测试验证 10. ✅ 解决与order-module的循环依赖问题 **API集成测试要求**: - 测试文件:`tests/integration/disability.integration.test.ts` - 测试覆盖:残疾人信息、银行卡、照片、备注、走访记录 - 验证:多实体关联、文件上传、复杂业务规则 - 包含性能测试:大数据量查询 ### 故事5:移植订单管理模块(order → @d8d/allin-order-module) **目标**:移植订单模块,处理与disability-module的循环依赖 **验收标准**: 1. ✅ 创建`allin-packages/order-module`目录结构 2. ✅ 完成实体转换:3个实体(EmploymentOrder、OrderPerson等)转换 3. ✅ 解决循环依赖:与disability-module的相互引用处理 4. ✅ 完成服务层转换:订单业务逻辑 5. ✅ 完成路由层转换:Hono路由实现 6. ✅ 完成验证系统转换:订单相关验证 7. ✅ 配置package.json:依赖管理 8. ✅ 编写API集成测试:覆盖订单全生命周期 9. ✅ 通过类型检查和基本测试验证 10. ✅ 验证循环依赖解决方案的有效性 **API集成测试要求**: - 测试文件:`tests/integration/order.integration.test.ts` - 测试覆盖:订单创建、人员分配、资产关联、状态流转 - 验证:与disability-module的集成、业务规则执行 - 包含工作流测试:订单状态机 ### 故事6:移植平台管理模块(platform → @d8d/allin-platform-module) **目标**:移植基础模块,作为其他模块的依赖 **验收标准**: 1. ✅ 创建`allin-packages/platform-module`目录结构 2. ✅ 完成实体转换:`Platform`实体转换 3. ✅ 完成服务层转换:基础CRUD服务 4. ✅ 完成路由层转换:Hono路由实现 5. ✅ 完成验证系统转换:Zod Schema定义 6. ✅ 配置package.json:作为基础依赖包 7. ✅ 编写API集成测试:验证基础功能 8. ✅ 通过类型检查和基本测试验证 9. ✅ 验证作为依赖包被其他模块引用的能力 **API集成测试要求**: - 测试文件:`tests/integration/platform.integration.test.ts` - 测试覆盖:平台CRUD操作 - 验证:作为基础数据的完整性和一致性 - 包含被引用场景的模拟测试 ### 故事7:移植薪资管理模块(salary → @d8d/allin-salary-module) **目标**:移植独立模块,完成所有模块移植 **验收标准**: 1. ✅ 创建`allin-packages/salary-module`目录结构 2. ✅ 完成实体转换:`SalaryLevel`实体转换 3. ✅ 完成服务层转换:薪资业务逻辑 4. ✅ 完成路由层转换:Hono路由实现 5. ✅ 完成验证系统转换:Zod Schema定义 6. ✅ 配置package.json:独立包配置 7. ✅ 编写API集成测试:验证薪资管理功能 8. ✅ 通过类型检查和基本测试验证 9. ✅ 整体验证:所有7个模块的集成测试 **API集成测试要求**: - 测试文件:`tests/integration/salary.integration.test.ts` - 测试覆盖:薪资等级管理、关联查询 - 验证:数值计算、等级规则 - 包含整体集成测试:验证所有模块协同工作 ## 兼容性要求 - [ ] 现有API接口保持不变 - [ ] 数据库schema保持向后兼容 - [ ] 遵循现有TypeScript配置和构建模式 - [ ] 性能影响最小化 ## 风险缓解 - **主要风险**:模块间依赖关系复杂,移植过程中可能破坏现有功能 - **缓解措施**:逐个模块移植,每个模块完成后进行功能验证 - **回滚计划**:保留原始allin_system-master目录作为备份,可随时恢复 ## 完成定义 - [ ] 所有4个故事完成,验收标准满足 - [ ] 现有功能通过测试验证 - [ ] 集成点正常工作 - [ ] 文档更新适当 - [ ] 现有功能无回归 ## 验证清单 ### 范围验证 - [ ] 史诗可在4个故事内完成 - [ ] 不需要架构文档变更 - [ ] 增强遵循现有模式 - [ ] 集成复杂度可管理 ### 风险评估 - [ ] 对现有系统风险较低 - [ ] 回滚计划可行 - [ ] 测试方法覆盖现有功能 - [ ] 团队对集成点有足够了解 ### 完整性检查 - [ ] 史诗目标清晰可实现 - [ ] 故事范围适当 - [ ] 成功标准可衡量 - [ ] 依赖关系已识别 --- ## 故事经理交接说明 "模块分析和技术栈分析已完成,关键发现: 1. **依赖关系分析完成**:7个模块的依赖关系已明确,发现order和disability_person模块存在循环依赖 2. **技术栈差异分析完成**:源系统使用NestJS,目标系统使用Hono,存在重大架构差异 3. **命名方案确定**:使用`@d8d/allin-`前缀,`-module`后缀,非多租户版本 4. **目录结构**:在根目录创建`allin-packages/`目录存放专属包 5. **移植顺序建议**:platform → channel/dict/salary → company → order/disability 6. **技术栈转换方案**:已制定从NestJS到Hono的详细转换策略 7. **故事拆分完成**:按模块拆分为7个故事,每个故事包含API集成测试要求 **新的故事拆分方案**: - **故事1**:移植渠道管理模块(channel_info → @d8d/allin-channel-module) - **故事2**:移植公司管理模块(company → @d8d/allin-company-module) - **故事3**:移植字典管理模块(dict_management → @d8d/allin-dict-module) - **故事4**:移植残疾人管理模块(disability_person → @d8d/allin-disability-module) - **故事5**:移植订单管理模块(order → @d8d/allin-order-module) - **故事6**:移植平台管理模块(platform → @d8d/allin-platform-module) - **故事7**:移植薪资管理模块(salary → @d8d/allin-salary-module) **每个故事的关键要求**: 1. **技术栈转换**:必须完成实体、服务、路由、验证的完整转换 2. **API集成测试**:必须编写`tests/integration/{module}.integration.test.ts`文件 3. **测试覆盖**:必须覆盖所有路由端点,验证CRUD操作 4. **遵循现有模式**:参考advertisements-module的集成测试模式 5. **验证要求**:认证、授权、数据验证、错误处理 **执行顺序建议**: 1. 先执行**故事6**(platform-module):基础依赖模块 2. 然后执行**故事1、3、7**(channel、dict、salary):独立模块 3. 接着执行**故事2**(company-module):依赖platform 4. 最后执行**故事4、5**(disability、order):处理循环依赖 **技术栈转换关键点**: - **NestJS控制器 → Hono路由**:使用OpenAPIHono - **class-validator DTO → Zod Schema**:使用z.object()定义 - **自定义Service → GenericCrudService继承**:复用现有CRUD模式 - **下划线命名 → 驼峰命名**:实体字段名转换 - **模块间依赖**:通过workspace依赖管理 **API集成测试模板参考**: 参考`/packages/advertisements-module/tests/integration/advertisements.integration.test.ts` - 使用`testClient`创建测试客户端 - 使用`setupIntegrationDatabaseHooksWithEntities`设置测试数据库 - 包含认证测试、数据验证测试、错误处理测试 - 每个端点都要有成功和失败场景测试 史诗应在保持系统完整性的同时实现将有实体模块从NestJS架构移植到Hono架构的标准化独立包,每个模块都要有完整的API集成测试验证。"