Просмотр исходного кода

feat(story-007.008): 集成Allin系统模块到packages/server

- 在package.json中添加所有Allin模块的workspace依赖
- 在index.ts中导入并注册Allin模块的路由
- 在数据库初始化中注册Allin模块的实体
- 创建allin-modules.integration.test.ts集成测试文件
- 更新故事文档的Dev Agent Record

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 1 месяц назад
Родитель
Сommit
bf8654fb3d

+ 91 - 3
docs/stories/007.008.integrate-allin-modules-to-server.story.md

@@ -298,13 +298,101 @@ Draft
 Claude Code (d8d-model)
 
 ### Debug Log References
-*待实现时填写*
+1. **依赖导入错误修复**:`disabilityRoutes`不存在,修复为`disabledPersonRoutes`
+2. **实体导入错误修复**:`Company`被当作类型使用,修复为从`/entities`路径导入
+3. **测试语法错误修复**:`$get()`需要`query: {}`参数,修复所有模块的测试调用
+4. **端点名称错误修复**:`getAllOrders`和`getAllSalaryLevels`端点不存在,修复为`list`端点
 
 ### Completion Notes List
-*待实现时填写*
+1. ✅ **任务1**:分析packages/server的当前结构
+   - 分析了`packages/server/package.json`的依赖配置
+   - 分析了`packages/server/src/index.ts`的路由注册方式
+   - 分析了现有模块的导入和导出模式
+
+2. ✅ **任务2**:在package.json中添加Allin模块的workspace依赖
+   - 添加了所有7个Allin模块的依赖:
+     - `@d8d/allin-channel-module: workspace:*`
+     - `@d8d/allin-company-module: workspace:*`
+     - `@d8d/allin-disability-module: workspace:*`
+     - `@d8d/allin-order-module: workspace:*`
+     - `@d8d/allin-platform-module: workspace:*`
+     - `@d8d/allin-salary-module: workspace:*`
+     - `@d8d/allin-enums: workspace:*`
+   - 运行`pnpm install`验证依赖配置正确性
+
+3. ✅ **任务3**:在index.ts中导入并注册Allin模块的路由
+   - 添加了所有Allin模块的路由导入:
+     ```typescript
+     import { channelRoutes } from '@d8d/allin-channel-module'
+     import { companyRoutes } from '@d8d/allin-company-module'
+     import { disabledPersonRoutes } from '@d8d/allin-disability-module'
+     import { orderRoutes } from '@d8d/allin-order-module'
+     import { platformRoutes } from '@d8d/allin-platform-module'
+     import { salaryRoutes } from '@d8d/allin-salary-module'
+     ```
+   - 注册了所有路由到对应的API路径:
+     ```typescript
+     export const channelApiRoutes = api.route('/api/v1/channel', channelRoutes)
+     export const companyApiRoutes = api.route('/api/v1/company', companyRoutes)
+     export const disabilityApiRoutes = api.route('/api/v1/disability', disabledPersonRoutes)
+     export const orderApiRoutes = api.route('/api/v1/order', orderRoutes)
+     export const platformApiRoutes = api.route('/api/v1/platform', platformRoutes)
+     export const salaryApiRoutes = api.route('/api/v1/salary', salaryRoutes)
+     ```
+
+4. ✅ **任务4**:在数据库初始化中注册Allin模块的实体
+   - 导入所有Allin模块的实体:
+     ```typescript
+     import { Channel } from '@d8d/allin-channel-module/entities'
+     import { Company } from '@d8d/allin-company-module/entities'
+     import { DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit } from '@d8d/allin-disability-module/entities'
+     import { EmploymentOrder, OrderPerson, OrderPersonAsset } from '@d8d/allin-order-module/entities'
+     import { Platform } from '@d8d/allin-platform-module/entities'
+     import { SalaryLevel } from '@d8d/allin-salary-module/entities'
+     ```
+   - 更新`initializeDataSource`调用,添加所有实体:
+     ```typescript
+     initializeDataSource([
+       UserEntity, Role, File, SystemConfig, AreaEntity,
+       Channel,
+       Company,
+       DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit,
+       EmploymentOrder, OrderPerson, OrderPersonAsset,
+       Platform,
+       SalaryLevel
+     ])
+     ```
+
+5. ⚠️ **任务5**:验证API端点可访问性
+   - 根据用户反馈,集成测试不需要启动开发服务器
+   - 通过集成测试验证API端点连通性
+
+6. ✅ **任务6**:添加Allin模块的集成测试
+   - 创建了`packages/server/tests/integration/allin-modules.integration.test.ts`文件
+   - 按照现有测试模式编写了路由连通性测试
+   - 修复了测试文件中的类型错误:
+     - 为所有`$get()`调用添加`query: {}`参数
+     - 修复端点名称:`getAllOrders` → `list`,`getAllSalaryLevels` → `list`
+   - 按照用户要求,测试响应判断改为先用if判断状态码是否为200,再将响应判断放在if里面
+
+7. ⚠️ **任务7**:通过类型检查和基本测试验证
+   - 运行类型检查:集成测试文件无类型错误
+   - 主要剩余问题:缺少核心模块依赖(`@d8d/user-module`等),这是项目整体依赖问题,不影响Allin模块集成
+
+8. ⚠️ **任务8**:确保与现有模块的兼容性
+   - 需要进一步测试现有功能是否受影响
 
 ### File List
-*待实现时填写*
+1. **修改文件**:
+   - `packages/server/package.json` - 添加Allin模块依赖
+   - `packages/server/src/index.ts` - 导入并注册Allin模块路由和实体
+   - `docs/stories/007.008.integrate-allin-modules-to-server.story.md` - 更新Dev Agent Record
+
+2. **新增文件**:
+   - `packages/server/tests/integration/allin-modules.integration.test.ts` - Allin模块集成测试
+
+3. **依赖更新**:
+   - `pnpm-lock.yaml` - 自动生成的依赖锁文件
 
 ## QA Results
 Results from QA Agent QA review of the completed story implementation

+ 7 - 0
packages/server/package.json

@@ -36,6 +36,13 @@
     "@d8d/shared-crud": "workspace:*",
     "@d8d/core-module": "workspace:*",
     "@d8d/geo-areas": "workspace:*",
+    "@d8d/allin-channel-module": "workspace:*",
+    "@d8d/allin-company-module": "workspace:*",
+    "@d8d/allin-disability-module": "workspace:*",
+    "@d8d/allin-order-module": "workspace:*",
+    "@d8d/allin-platform-module": "workspace:*",
+    "@d8d/allin-salary-module": "workspace:*",
+    "@d8d/allin-enums": "workspace:*",
     "axios": "^1.12.2",
     "bcrypt": "^6.0.0",
     "debug": "^4.4.3",

+ 33 - 1
packages/server/src/index.ts

@@ -12,8 +12,28 @@ import { UserEntity, Role } from '@d8d/core-module/user-module'
 import { File } from '@d8d/core-module/file-module'
 import { SystemConfig } from '@d8d/core-module/system-config-module'
 import { areasRoutes, adminAreasRoutes, AreaEntity } from '@d8d/geo-areas'
+import { channelRoutes } from '@d8d/allin-channel-module'
+import { Channel } from '@d8d/allin-channel-module/entities'
+import { companyRoutes } from '@d8d/allin-company-module'
+import { Company } from '@d8d/allin-company-module/entities'
+import { disabledPersonRoutes } from '@d8d/allin-disability-module'
+import { DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit } from '@d8d/allin-disability-module/entities'
+import { orderRoutes } from '@d8d/allin-order-module'
+import { EmploymentOrder, OrderPerson, OrderPersonAsset } from '@d8d/allin-order-module/entities'
+import { platformRoutes } from '@d8d/allin-platform-module'
+import { Platform } from '@d8d/allin-platform-module/entities'
+import { salaryRoutes } from '@d8d/allin-salary-module'
+import { SalaryLevel } from '@d8d/allin-salary-module/entities'
 
-initializeDataSource([UserEntity, Role, File, SystemConfig, AreaEntity])
+initializeDataSource([
+  UserEntity, Role, File, SystemConfig, AreaEntity,
+  Channel,
+  Company,
+  DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit,
+  EmploymentOrder, OrderPerson, OrderPersonAsset,
+  Platform,
+  SalaryLevel
+])
 
 if(!AppDataSource || !AppDataSource.isInitialized) {
   await AppDataSource.initialize();
@@ -116,6 +136,12 @@ export const fileApiRoutes = api.route('/api/v1/files', fileModuleRoutes)
 export const roleRoutes = api.route('/api/v1/roles', roleModuleRoutes)
 export const areaApiRoutes = api.route('/api/v1/areas', areasRoutes)
 export const adminAreaApiRoutes = api.route('/api/v1/admin/areas', adminAreasRoutes)
+export const channelApiRoutes = api.route('/api/v1/channel', channelRoutes)
+export const companyApiRoutes = api.route('/api/v1/company', companyRoutes)
+export const disabilityApiRoutes = api.route('/api/v1/disability', disabledPersonRoutes)
+export const orderApiRoutes = api.route('/api/v1/order', orderRoutes)
+export const platformApiRoutes = api.route('/api/v1/platform', platformRoutes)
+export const salaryApiRoutes = api.route('/api/v1/salary', salaryRoutes)
 
 export type AuthRoutes = typeof authRoutes
 export type UserRoutes = typeof userRoutes
@@ -123,6 +149,12 @@ export type FileRoutes = typeof fileApiRoutes
 export type RoleRoutes = typeof roleRoutes
 export type AreaRoutes = typeof areaApiRoutes
 export type AdminAreaRoutes = typeof adminAreaApiRoutes
+export type ChannelRoutes = typeof channelApiRoutes
+export type CompanyRoutes = typeof companyApiRoutes
+export type DisabilityRoutes = typeof disabilityApiRoutes
+export type OrderRoutes = typeof orderApiRoutes
+export type PlatformRoutes = typeof platformApiRoutes
+export type SalaryRoutes = typeof salaryApiRoutes
 
 app.route('/', api)
 export default app

+ 122 - 0
packages/server/tests/integration/allin-modules.integration.test.ts

@@ -0,0 +1,122 @@
+import { describe, it, expect } from 'vitest';
+import { testClient } from 'hono/testing';
+
+// 导入Allin模块路由
+import { channelApiRoutes } from '../../src/index';
+import { companyApiRoutes } from '../../src/index';
+import { disabilityApiRoutes } from '../../src/index';
+import { orderApiRoutes } from '../../src/index';
+import { platformApiRoutes } from '../../src/index';
+import { salaryApiRoutes } from '../../src/index';
+
+describe('Allin模块API路由连通性集成测试', () => {
+  describe('渠道管理模块路由连通性测试', () => {
+    it('应该能够访问渠道列表端点 (GET /api/v1/channel/getAllChannels)', async () => {
+      const client = testClient(channelApiRoutes);
+      const response = await client.api.v1.channel.getAllChannels.$get({
+        query: {}
+      });
+
+      // 只测试路由连通性,不测试具体业务逻辑
+      // 可能返回401(需要认证)或200(如果端点不需要认证)
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+
+  describe('公司管理模块路由连通性测试', () => {
+    it('应该能够访问公司列表端点 (GET /api/v1/company/getAllCompanies)', async () => {
+      const client = testClient(companyApiRoutes);
+      const response = await client.api.v1.company.getAllCompanies.$get({
+        query: {}
+      });
+
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+
+  describe('残疾人管理模块路由连通性测试', () => {
+    it('应该能够访问残疾人列表端点 (GET /api/v1/disability/getAllDisabledPersons)', async () => {
+      const client = testClient(disabilityApiRoutes);
+      const response = await client.api.v1.disability.getAllDisabledPersons.$get({
+        query: {}
+      });
+
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+
+  describe('订单管理模块路由连通性测试', () => {
+    it('应该能够访问订单列表端点 (GET /api/v1/order/list)', async () => {
+      const client = testClient(orderApiRoutes);
+      const response = await client.api.v1.order.list.$get({
+        query: {}
+      });
+
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+
+  describe('平台管理模块路由连通性测试', () => {
+    it('应该能够访问平台列表端点 (GET /api/v1/platform/getAllPlatforms)', async () => {
+      const client = testClient(platformApiRoutes);
+      const response = await client.api.v1.platform.getAllPlatforms.$get({
+        query: {}
+      });
+
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+
+  describe('薪资管理模块路由连通性测试', () => {
+    it('应该能够访问薪资列表端点 (GET /api/v1/salary/list)', async () => {
+      const client = testClient(salaryApiRoutes);
+      const response = await client.api.v1.salary.list.$get({
+        query: {}
+      });
+
+      expect([200, 401]).toContain(response.status);
+
+      if (response.status === 200) {
+        const responseData = await response.json();
+        expect(responseData).toHaveProperty('success');
+        expect(responseData).toHaveProperty('data');
+        expect(responseData).toHaveProperty('message');
+      }
+    });
+  });
+});