007.004.transplant-disability-management-module.story.md 32 KB

Story 007.004: 移植残疾人管理模块(disability_person → @d8d/allin-disability-module)

Status

Completed

Story

As a 开发者, I want 将disability_person模块从allin_system-master移植为独立包@d8d/allin-disability-module,完成实体重构和文件模块集成, so that 我们可以将Allin系统的残疾人管理功能集成到当前项目中,遵循现有的模块化架构和编码标准,并实现与@d8d/file-module的文件集成。

Acceptance Criteria

  1. ✅ 创建allin-packages/disability-module目录结构
  2. ✅ 完成实体转换:DisabledPersonDisabledBankCardDisabledPhotoDisabledRemarkDisabledVisit实体转换
  3. 文件模块集成:使用@d8d/file-module包管理照片文件,修改DisabledPhoto实体添加fileId字段
  4. ✅ 完成服务层转换:残疾人业务逻辑,包含聚合服务
  5. ✅ 完成路由层转换:Hono路由实现,包含聚合路由
  6. ✅ 完成验证系统转换:Zod Schema定义
  7. ✅ 配置package.json:依赖管理,包含对@d8d/file-module的依赖
  8. ✅ 编写API集成测试:验证残疾人管理功能,包含文件集成测试
  9. ✅ 通过类型检查和基本测试验证
  10. ✅ 整体验证:与其他模块的集成测试

Tasks / Subtasks

  • 创建allin-packages/disability-module目录结构 (AC: 1)
    • 创建allin-packages/disability-module/目录
    • 创建package.json文件,配置包名@d8d/allin-disability-module和workspace依赖
    • 参考文件: allin-packages/platform-module/package.json
    • 修改点: 包名改为@d8d/allin-disability-module,添加对@d8d/file-module的依赖
    • 关键依赖: @d8d/file-module, @d8d/core-module, @d8d/shared-crud, @d8d/shared-utils
    • 注意吸取经验: 根据故事007.006的经验,需要在pnpm-workspace.yaml中添加allin-packages/*配置
    • 创建tsconfig.json文件,配置TypeScript编译选项
    • 参考文件: allin-packages/platform-module/tsconfig.json
    • 创建vitest.config.ts文件,配置测试环境
    • 参考文件: allin-packages/platform-module/vitest.config.ts
    • 创建src/目录结构:entities/, services/, routes/, schemas/, types/
    • 参考结构: allin-packages/platform-module/src/目录结构
  • 完成实体转换:DisabledPersonDisabledBankCardDisabledPhotoDisabledRemarkDisabledVisit实体转换 (AC: 2)
    • 分析源实体allin_system-master/server/src/disability_person/disabled_person.entity.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_person.entity.ts
    • 关键字段: person_id, name, gender, id_card, disability_id, disability_type, disability_level, id_address, phone, province, city, district
    • 注意吸取经验: 根据故事007.006的经验,主键属性名应直接定义为id(而不是personId)以遵循GenericCrudService约定
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-person.entity.ts
    • 创建转换后的实体文件src/entities/disabled-person.entity.ts
    • 参考文件: allin-packages/platform-module/src/entities/platform.entity.ts
    • 转换要点: 下划线命名 → 驼峰命名,添加详细TypeORM配置
    • 将下划线字段名转换为驼峰命名: person_idid, id_cardidCard, disability_iddisabilityId
    • 添加详细的TypeORM装饰器配置: @Column({ name: 'person_id', type: 'int', primary: true, generated: true })
    • 保持数据库表名不变: @Entity('disabled_person')
    • 区域包集成: 考虑添加provinceId, cityId, districtId字段引用AreaEntity(可选)
    • 分析源实体allin_system-master/server/src/disability_person/disabled_bank_card.entity.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_bank_card.entity.ts
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-bank-card.entity.ts
    • 分析源实体allin_system-master/server/src/disability_person/disabled_photo.entity.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_photo.entity.ts
    • 关键字段: photo_id, person_id, photo_type, photo_url, upload_time
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-photo.entity.ts
    • 分析源实体allin_system-master/server/src/disability_person/disabled_remark.entity.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_remark.entity.ts
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-remark.entity.ts
    • 分析源实体allin_system-master/server/src/disability_person/disabled_visit.entity.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_visit.entity.ts
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-visit.entity.ts
  • 文件模块集成:使用@d8d/file-module包管理照片文件,修改DisabledPhoto实体添加fileId字段 (AC: 3)
    • 分析@d8d/file-module包结构和API
    • 参考文件: packages/file-module/src/entities/file.entity.ts
    • 关键方法: 文件上传、下载、删除、获取URL
    • 修改DisabledPhoto实体,添加fileId字段引用File实体
    • 修改方案: 移除photo_url字符串字段,添加fileId外键字段
    • 外键关系: @ManyToOne(() => FileEntity)@JoinColumn({ name: 'file_id' })
    • 数据迁移: 需要制定现有URL数据迁移到files表的方案
    • 在服务层集成文件验证逻辑
    • 验证逻辑: 创建照片记录时验证fileId的有效性
    • 错误处理: 文件不存在时返回相应错误信息
    • 在API响应中返回文件完整信息
    • 响应格式: 包含文件ID和文件URL的完整信息
  • 完成服务层转换:残疾人业务逻辑,包含聚合服务 (AC: 4)
    • 分析源服务allin_system-master/server/src/disability_person/disabled_person.service.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_person.service.ts
    • 关键方法: create, findOne, findAll, findByIdCard, update, delete
    • 业务逻辑: 身份证号唯一性检查,关联查询其他模块实体
    • 创建转换后的服务文件src/services/disabled-person.service.ts
    • 参考文件: allin-packages/platform-module/src/services/platform.service.ts
    • 架构: 继承GenericCrudService<DisabledPerson>
    • 迁移文件路径: allin-packages/disability-module/src/services/disabled-person.service.ts
    • 分析源聚合服务allin_system-master/server/src/disability_person/aggregated.service.ts
    • 源文件: allin_system-master/server/src/disability_person/aggregated.service.ts
    • 关键方法: createDisabledPersonWithAllData, findDisabledPersonWithAllData
    • 聚合逻辑: 一次性创建/查询残疾人所有相关信息
    • 创建聚合服务文件src/services/aggregated.service.ts
    • 迁移文件路径: allin-packages/disability-module/src/services/aggregated.service.ts
    • 继承GenericCrudService<DisabledPerson>,配置搜索字段
    • 参考: packages/shared-crud/src/services/generic-crud.service.ts
    • 搜索字段: 姓名、身份证号、残疾证号、残疾类型、残疾等级等
    • 覆盖create方法:添加身份证号唯一性检查
    • 源逻辑: disabled_person.controller.ts:18-22 - 检查身份证号是否已存在
    • 新逻辑: 在服务层检查idCard的唯一性
    • 覆盖findAll方法:需要返回{ data: DisabledPerson[], total: number }格式
    • 源逻辑: disabled_person.service.ts:44-... - 支持多条件查询和分页
    • 新逻辑: 支持按姓名、身份证号、残疾类型等条件查询
    • 自定义findByIdCard方法:按身份证号查询
    • 源逻辑: disabled_person.service.ts:... - 根据身份证号查询
    • 新逻辑: 根据idCard查询,支持身份证号参数
    • 集成文件服务验证逻辑
    • 文件验证: 使用FileService验证文件ID的有效性
    • 错误处理: 文件不存在时抛出相应异常
  • 完成路由层转换:Hono路由实现,包含聚合路由 (AC: 5)
    • 分析源控制器allin_system-master/server/src/disability_person/disabled_person.controller.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_person.controller.ts
    • API端点:
      • POST /disability-persons - 创建残疾人基本信息
      • GET /disability-persons/:id - 根据ID获取残疾人信息
      • GET /disability-persons - 获取所有残疾人信息(分页+条件查询)
      • PUT /disability-persons/:id - 更新残疾人信息
      • DELETE /disability-persons/:id - 删除残疾人信息
    • 认证: 所有端点需要JWT认证 (@UseGuards(JwtAuthGuard))
    • 分析源聚合控制器allin_system-master/server/src/disability_person/aggregated.controller.ts
    • 源文件: allin_system-master/server/src/disability_person/aggregated.controller.ts
    • API端点:
      • POST /disability-persons/aggregated/create - 聚合创建残疾人所有信息
      • GET /disability-persons/aggregated/:personId - 聚合查询残疾人所有信息
    • 创建自定义路由文件src/routes/disabled-person-custom.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform-custom.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts
    • 实现功能: 创建残疾人、删除残疾人、更新残疾人、获取所有残疾人、搜索残疾人、获取单个残疾人、根据身份证号查询、批量创建残疾人
    • 创建聚合路由文件src/routes/aggregated.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/aggregated.routes.ts
    • 实现功能: 创建聚合残疾人信息、获取聚合残疾人信息、更新聚合残疾人信息
    • 创建CRUD路由文件src/routes/disabled-person-crud.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform-crud.routes.ts
    • 架构: 使用createCrudRoutes生成标准CRUD路由
    • 配置: 设置readOnly: true,关联关系包含所有5个关联实体
    • 创建主路由文件src/routes/disabled-person.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform.routes.ts
    • 功能: 聚合自定义路由、CRUD路由和聚合路由,导出路由实例
    • 创建路由导出文件src/routes/index.ts
    • 功能: 导出所有路由模块
  • 完成验证系统转换:Zod Schema定义 (AC: 6)
    • 分析源DTOallin_system-master/server/src/disability_person/disabled_person.dto.ts
    • 源文件: allin_system-master/server/src/disability_person/disabled_person.dto.ts
    • DTO类型: CreateDisabledPersonDto, UpdateDisabledPersonDto, QueryDisabledPersonDto
    • 分析源聚合DTOallin_system-master/server/src/disability_person/aggregated.dto.ts
    • 源文件: allin_system-master/server/src/disability_person/aggregated.dto.ts
    • DTO类型: CreateDisabledPersonWithAllDataDto
    • 分析源关联实体DTO:disabled_bank_card.dto.ts, disabled_photo.dto.ts, disabled_remark.dto.ts, disabled_visit.dto.ts
    • 创建转换后的Schema文件src/schemas/disabled-person.schema.ts
    • 参考文件: allin-packages/platform-module/src/schemas/platform.schema.ts
    • 迁移文件路径: allin-packages/disability-module/src/schemas/disabled-person.schema.ts
    • 包含Schema:
      • DisabledPersonSchema: 残疾人实体Schema
      • CreateDisabledPersonSchema: 创建残疾人DTO
      • UpdateDisabledPersonSchema: 更新残疾人DTO
      • DeleteDisabledPersonSchema: 删除残疾人DTO
      • PaginationQuerySchema: 分页查询参数
      • SearchDisabledPersonQuerySchema: 搜索残疾人参数
      • DisabledBankCardSchema: 银行卡实体Schema
      • DisabledPhotoSchema: 照片实体Schema(已集成文件模块,使用fileId字段)
      • DisabledRemarkSchema: 备注实体Schema
      • DisabledVisitSchema: 回访实体Schema
      • CreateAggregatedDisabledPersonSchema: 创建聚合残疾人信息Schema
      • AggregatedDisabledPersonSchema: 聚合残疾人信息Schema
    • 创建schemas导出文件src/schemas/index.ts
    • 功能: 导出所有Schema定义
    • 添加详细的验证规则:身份证号格式、手机号格式、日期格式、必填字段、可选字段
    • 身份证号: 长度1-20字符
    • 手机号: 长度1-20字符
    • 日期: 使用datetime格式验证
    • 必填字段: 姓名、性别、身份证号、残疾证号、残疾类型、残疾等级、身份证地址、联系方式、省级、市级
    • 可选字段: 身份证有效期、残疾证有效期、是否可直接联系、是否已婚、民族、出生日期、年龄、学历、毕业院校、专业、区县级、详细地址、邮政编码、是否在黑名单中、在职状态
  • 配置package.json:依赖管理,包含对@d8d/file-module的依赖 (AC: 7)
    • 配置package.json中的name字段为@d8d/allin-disability-module
    • 参考文件: allin-packages/platform-module/package.json
    • 设置type: "module"和主入口src/index.ts
    • 添加workspace依赖:@d8d/shared-crud, @d8d/shared-utils, @d8d/file-module, @d8d/auth-module, @d8d/user-module
    • 添加外部依赖:@hono/zod-openapi, typeorm, zod
    • 配置导出路径:services, schemas, routes, entities
  • 编写API集成测试:验证残疾人管理功能,包含文件集成测试 (AC: 8)
    • 创建测试文件tests/integration/disability.integration.test.ts
    • 参考文件: allin-packages/platform-module/tests/integration/platform.integration.test.ts
    • 迁移文件路径: allin-packages/disability-module/tests/integration/disability.integration.test.ts
    • 参考platform-module的集成测试模式
    • 测试模式: 使用testClient, setupIntegrationDatabaseHooksWithEntities
    • 使用testClient创建测试客户端
    • 使用setupIntegrationDatabaseHooksWithEntities设置测试数据库
    • 工具: @d8d/shared-test-util中的测试基础设施
    • 实体: 包含DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit, FileEntity
    • 编写测试用例覆盖所有端点:创建、查询、更新、删除、聚合创建、聚合查询
    • 文件集成测试重点:
    • 验证文件ID的有效性检查
    • 测试文件不存在时的错误处理
    • 验证文件数据在响应中的完整性
    • 添加认证测试、数据验证测试、错误处理测试
    • 包含边界条件和异常场景测试
    • 特别测试身份证号唯一性检查和聚合服务功能
  • 通过类型检查和基本测试验证 (AC: 9)
    • 运行pnpm typecheck确保无类型错误
    • 运行pnpm test确保所有测试通过
    • 运行pnpm test:integration验证集成测试
    • 检查测试覆盖率是否满足要求
    • 标准: 集成测试 ≥ 60% [Source: architecture/testing-strategy.md#测试覆盖率标准]
    • 验证模块可以正确导入和使用
  • 整体验证:与其他模块的集成测试 (AC: 10)
    • 验证disability模块与其他Allin模块的兼容性
    • 测试跨模块数据一致性
    • 验证整体系统功能完整性

Dev Notes

先前故事洞察

  • 故事007.006:已完成平台管理模块移植,提供了完整的参考实现 [Source: docs/stories/007.006.transplant-platform-management-module.story.md]
  • 关键经验教训
    1. 实体主键命名:根据用户反馈,主键属性名应直接定义为id(而不是platformId)以遵循GenericCrudService约定
    2. workspace配置:需要在pnpm-workspace.yaml中添加allin-packages/*配置
    3. 测试依赖:需要添加@d8d/user-module@d8d/file-module依赖
    4. 类型检查:需要注意导出重复和路由返回类型问题
    5. API兼容性:需要保持原始API的返回格式

数据模型

  • 源实体结构DisabledPerson实体包含以下字段 [Source: allin_system-master/server/src/disability_person/disabled_person.entity.ts]:
    • person_id: number (主键,自增)
    • name: string (姓名)
    • gender: string (性别:男/女)
    • id_card: string (身份证号,唯一)
    • disability_id: string (残疾证号,唯一)
    • disability_type: string (残疾类型)
    • disability_level: string (残疾等级)
    • id_address: string (身份证地址)
    • phone: string (联系方式)
    • province: string (省级)
    • city: string (市级)
    • district: string (区县级)
    • can_direct_contact: number (是否可直接联系:1-是,0-否)
    • is_married: number (是否已婚:1-是,0-否)
    • is_in_black_list: number (是否在黑名单中:1-是,0-否)
    • job_status: number (在职状态:0-未在职,1-已在职)
    • create_time: Date (创建时间)
    • update_time: Date (更新时间)
  • 关联实体
    • DisabledBankCard: 银行卡信息 (一对多)
    • DisabledPhoto: 照片信息 (一对多)
    • DisabledRemark: 备注信息 (一对多)
    • DisabledVisit: 回访记录 (一对多)
  • 转换要求
    • 下划线命名 → 驼峰命名
    • 添加详细TypeORM配置
    • 文件模块集成:修改DisabledPhoto实体,移除photo_url字段,添加fileId字段引用FileEntity
    • 区域包集成:可选添加provinceId, cityId, districtId字段引用AreaEntity
  • 表名保持disabled_person表名不变

文件模块集成方案

  • 采用方案:完全依赖文件模块,将所有照片数据改为引用@d8d/file-module包中的FileEntity [Source: docs/prd/epic-007-allin-system-transplant.md#文件实体集成方案]
  • 改造方案
    1. 移除URL字段DisabledPhoto实体中的photo_url字符串字段
    2. 添加外键字段DisabledPhoto实体添加fileId字段(外键引用FileEntity
    3. 使用文件服务FileService验证文件ID的有效性
    4. 数据迁移:制定现有URL数据迁移到files表的方案
  • 优势
    • 数据一致性:统一使用文件模块数据,避免数据不一致
    • 类型安全:外键引用提供编译时检查
    • 维护简单:文件变更只需更新文件模块数据
    • 功能完整:利用文件模块的上传、下载、删除等功能
    • 安全控制:统一的文件权限和访问控制

自定义实现分析

  • 需要覆盖GenericCrudService的方法
    • create方法:需要添加身份证号唯一性检查
    • 源逻辑: disabled_person.controller.ts:18-22 - 检查idCard是否已存在
    • 新逻辑: 检查idCard的唯一性
    • findAll方法:需要返回{ data: DisabledPerson[], total: number }格式
    • 源逻辑: disabled_person.service.ts:44-... - 支持多条件查询和分页
    • 新逻辑: 支持按姓名、身份证号、残疾类型等条件查询
    • 自定义findByIdCard方法:按身份证号查询
    • 源逻辑: disabled_person.service.ts:... - 根据身份证号查询
    • 新逻辑: 根据idCard查询,支持身份证号参数
  • 聚合服务
    • createDisabledPersonWithAllData: 一次性创建残疾人所有相关信息
    • findDisabledPersonWithAllData: 一次性查询残疾人所有相关信息
  • 与GenericCrudService的差异
    • 身份证号唯一性:需要检查idCard字段的唯一性
    • 关联实体多:需要处理5个关联实体的CRUD操作
    • 聚合服务:需要实现复杂的聚合创建和查询逻辑
    • 文件集成:需要集成文件服务验证文件ID

API规范

  • 现有API端点 [Source: allin_system-master/server/src/disability_person/disabled_person.controller.ts]:
    • POST /disability-persons - 创建残疾人基本信息
    • GET /disability-persons/:id - 根据ID获取残疾人信息
    • GET /disability-persons - 获取所有残疾人信息(分页+条件查询)
    • PUT /disability-persons/:id - 更新残疾人信息
    • DELETE /disability-persons/:id - 删除残疾人信息
  • 聚合API端点 [Source: allin_system-master/server/src/disability_person/aggregated.controller.ts]:
    • POST /disability-persons/aggregated/create - 聚合创建残疾人所有信息
    • GET /disability-persons/aggregated/:personId - 聚合查询残疾人所有信息
  • 认证要求:所有端点需要JWT认证 (@UseGuards(JwtAuthGuard))
  • 转换策略:NestJS控制器 → Hono路由,保持相同的端点路径和功能
  • 参数变更:照片参数从URL改为fileId,需要兼容性处理

服务规范

  • 源服务逻辑 [Source: allin_system-master/server/src/disability_person/disabled_person.service.ts]:
    • create: 创建残疾人基本信息
    • findOne: 根据ID查询单个残疾人(包含关联数据)
    • findAll: 分页查询,支持多条件过滤
    • findByIdCard: 根据身份证号查询
    • update: 更新残疾人信息
    • delete: 删除残疾人信息
  • 聚合服务逻辑 [Source: allin_system-master/server/src/disability_person/aggregated.service.ts]:
    • createDisabledPersonWithAllData: 创建残疾人所有信息(基本信息+银行卡+照片+备注+回访)
    • findDisabledPersonWithAllData: 查询残疾人所有信息
  • 转换策略:继承GenericCrudService,复用现有CRUD模式,集成文件服务,保持业务逻辑

验证系统

  • 源DTO结构 [Source: allin_system-master/server/src/disability_person/disabled_person.dto.ts]:
    • CreateDisabledPersonDto: name(必填), gender(必填), idCard(必填), disabilityId(必填), disabilityType(必填), disabilityLevel(必填), idAddress(必填), phone(必填)等
    • UpdateDisabledPersonDto: name(可选), gender(可选), idCard(可选), disabilityId(可选)等
    • QueryDisabledPersonDto: name(可选), idCard(可选), disabilityType(可选), disabilityLevel(可选)等
  • 聚合DTO结构 [Source: allin_system-master/server/src/disability_person/aggregated.dto.ts]:
    • CreateDisabledPersonWithAllDataDto: 包含残疾人基本信息、银行卡列表、照片列表、备注列表、回访列表
  • 转换策略class-validatorZod Schema,照片字段从URL改为fileId,添加详细的验证规则

文件位置

  • 包目录allin-packages/disability-module/ (根据史诗007的目录结构决策)
  • 源文件位置
    • 实体源文件: allin_system-master/server/src/disability_person/disabled_person.entity.ts
    • 服务源文件: allin_system-master/server/src/disability_person/disabled_person.service.ts
    • 控制器源文件: allin_system-master/server/src/disability_person/disabled_person.controller.ts
    • DTO源文件: allin_system-master/server/src/disability_person/disabled_person.dto.ts
    • 聚合源文件: allin_system-master/server/src/disability_person/aggregated.*.ts
  • 目标文件位置
    • 实体文件: src/entities/disabled-person.entity.ts
    • 参考文件: allin-packages/platform-module/src/entities/platform.entity.ts
    • 迁移文件路径: allin-packages/disability-module/src/entities/disabled-person.entity.ts
    • 服务文件: src/services/disabled-person.service.ts
    • 参考文件: allin-packages/platform-module/src/services/platform.service.ts
    • 迁移文件路径: allin-packages/disability-module/src/services/disabled-person.service.ts
    • 聚合服务文件: src/services/aggregated.service.ts
    • 迁移文件路径: allin-packages/disability-module/src/services/aggregated.service.ts
    • 主路由文件: src/routes/disabled-person.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/disabled-person.routes.ts
    • 自定义路由文件: src/routes/disabled-person-custom.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform-custom.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts
    • 聚合路由文件: src/routes/aggregated.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/aggregated.routes.ts
    • CRUD路由文件: src/routes/disabled-person-crud.routes.ts
    • 参考文件: allin-packages/platform-module/src/routes/platform-crud.routes.ts
    • 迁移文件路径: allin-packages/disability-module/src/routes/disabled-person-crud.routes.ts
    • Schema文件: src/schemas/disabled-person.schema.ts
    • 参考文件: allin-packages/platform-module/src/schemas/platform.schema.ts
    • 迁移文件路径: allin-packages/disability-module/src/schemas/disabled-person.schema.ts
    • 聚合Schema文件: src/schemas/aggregated.schema.ts
    • 迁移文件路径: allin-packages/disability-module/src/schemas/aggregated.schema.ts
    • 测试文件: tests/integration/disability.integration.test.ts
    • 参考文件: allin-packages/platform-module/tests/integration/platform.integration.test.ts
    • 迁移文件路径: allin-packages/disability-module/tests/integration/disability.integration.test.ts
    • 包配置: package.json, tsconfig.json, vitest.config.ts
    • 参考文件: allin-packages/platform-module/中的对应配置文件

测试要求

  • 测试框架:Vitest [Source: architecture/testing-strategy.md#单元测试]
  • 测试位置tests/integration/目录 [Source: architecture/testing-strategy.md#测试金字塔策略]
  • 测试类型:集成测试,验证API端点和数据库交互 [Source: architecture/testing-strategy.md#集成测试]
  • 覆盖率目标:集成测试 ≥ 60% [Source: architecture/testing-strategy.md#测试覆盖率标准]
  • 测试模式:参考platform-module的集成测试模式 [Source: allin-packages/platform-module/tests/integration/platform.integration.test.ts]
  • 测试工具:使用@d8d/shared-test-util中的测试基础设施 [Source: architecture/testing-strategy.md#包测试架构]
  • 文件集成测试重点
    • 验证文件ID的有效性检查
    • 测试文件不存在时的错误处理
    • 验证文件数据在响应中的完整性
    • 测试聚合创建和查询功能
    • 验证身份证号唯一性检查

技术约束

  • 技术栈:Node.js 20.19.2, Hono 4.8.5, TypeORM 0.3.25, PostgreSQL 17 [Source: architecture/tech-stack.md]
  • 编码标准:TypeScript严格模式,一致的缩进和命名 [Source: architecture/coding-standards.md]
  • API设计:RESTful API设计,使用Hono框架 [Source: architecture/source-tree.md#API设计]
  • 包管理:使用pnpm workspace管理依赖 [Source: architecture/source-tree.md#集成指南]
  • 模块导出:通过src/index.ts统一导出 [Source: architecture/source-tree.md#包结构规范]
  • 文件模块依赖:必须集成@d8d/file-module包进行文件管理

项目结构注意事项

  • 目录结构冲突:根据史诗007决策,Allin系统专属包放在allin-packages/目录,而非通用的packages/目录
  • 命名规范:使用@d8d/allin-前缀,-module后缀,非多租户版本
  • 依赖管理:通过workspace依赖引用@d8d/core-module@d8d/shared-crud@d8d/shared-utils@d8d/file-module
  • 文件模块集成:必须正确配置对@d8d/file-module的依赖,确保文件验证功能正常工作

测试标准

  1. API端点测试:必须覆盖所有7个端点(创建、查询单个、查询列表、更新、删除、聚合创建、聚合查询)
  2. 认证测试:验证所有端点需要有效的JWT令牌
  3. 数据验证测试:测试输入验证规则(身份证号格式、手机号格式、必填字段)
  4. 业务逻辑测试:测试身份证号唯一性检查、文件ID验证、聚合服务功能
  5. 错误处理测试:测试各种错误场景(无效文件ID、重复身份证号、缺失字段、无效数据格式)
  6. 数据库集成测试:验证数据正确持久化和查询,文件外键关系
  7. 文件集成测试:验证与@d8d/file-module包的集成,文件数据验证和查询
  8. 测试数据管理:使用测试数据工厂模式,每个测试后清理数据

测试执行流程

  1. 设置测试数据库,包含DisabledPersonDisabledBankCardDisabledPhotoDisabledRemarkDisabledVisitFileEntity实体
  2. 创建测试文件数据
  3. 创建测试用户和认证令牌
  4. 为每个端点编写成功场景测试
  5. 为每个端点编写失败场景测试
  6. 验证响应格式和数据正确性,包含文件完整信息
  7. 检查数据库状态变化和外键关系

Change Log

Date Version Description Author
2025-12-02 1.0 初始故事创建 Bob (Scrum Master)

Dev Agent Record

此部分由开发代理在实现过程中填写

Agent Model Used

  • Claude Code (d8d-model)

Debug Log References

  • 修复TypeScript类型错误:PostgreSQL类型兼容问题(tinyint → smallint,datetime → timestamp)
  • 修复schema验证错误:实体字段与schema定义不匹配(createTime/updateTime → uploadTime/remarkTime/visitTime)
  • 修复测试数据问题:缺少subBankName、operatorId等必填字段
  • 修复错误处理:DELETE端点返回404而不是200,GET聚合端点返回404而不是500
  • 修复文件模块集成:银行卡实体使用fileId字段而不是cardPhotoUrl

Completion Notes List

  1. ✅ 所有TypeScript类型检查通过
  2. ✅ 所有22个集成测试通过
  3. ✅ 修复了PostgreSQL类型兼容性问题
  4. ✅ 正确集成了文件模块(@d8d/file-module)
  5. ✅ 修复了schema验证与实体字段不匹配问题
  6. ✅ 修复了所有测试数据验证错误
  7. ✅ 完善了错误处理逻辑(404、400、500响应)
  8. ✅ 保持了API兼容性

File List

修改的文件:

  • allin-packages/disability-module/src/entities/disabled-bank-card.entity.ts - 添加文件实体关联
  • allin-packages/disability-module/src/entities/disabled-person.entity.ts - 移除education字段
  • allin-packages/disability-module/src/routes/aggregated.routes.ts - 添加404错误处理
  • allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts - 添加404响应定义
  • allin-packages/disability-module/src/schemas/disabled-person.schema.ts - 更新schema匹配实体字段
  • allin-packages/disability-module/src/services/aggregated.service.ts - 添加文件ID验证
  • allin-packages/disability-module/tests/integration/disability.integration.test.ts - 修复测试数据

关键修复:

  1. 银行卡实体改用文件实体关联(fileId字段)
  2. 移除不存在的education字段
  3. 修复schema验证错误(时间字段命名)
  4. 修复测试数据完整性(subBankName、operatorId等)
  5. 完善错误响应(404、400)

QA Results

测试结果:22个集成测试全部通过 ✅ 类型检查:TypeScript类型检查通过 ✅ 功能验证:残疾人管理模块功能完整 ✅ 文件集成:与@d8d/file-module正确集成 ✅ API兼容性:保持原始API功能 ✅ 错误处理:完善的错误响应机制