012.013.story.md 9.8 KB

故事 012.013:工作状态统一优化 - 基于order_person.work_status的长期方案

状态

Draft

故事

作为企业用户, 我希望人才列表和详情API使用order_person.work_status作为统一工作状态源, 以便能够精确筛选"在职"、"待入职"、"离职"状态,解决当前状态映射不准确的问题。

验收标准

从史诗文件复制的验收标准编号列表

  1. 人才列表API的"在职"筛选精确返回work_status='working'的人员
  2. 人才列表API的"待入职"筛选精确返回work_status='pre_working'的人员
  3. 人才列表API的"离职"筛选精确返回work_status='resigned'的人员
  4. 人才详情页工作状态显示准确,基于最新的order_person.work_status
  5. 状态映射完整:前端中文状态、Schema验证、数据库枚举值保持一致
  6. 查询性能优化,添加必要的数据库索引,响应时间<200ms
  7. 集成测试全面覆盖所有状态场景,测试覆盖率≥60%
  8. API文档更新,包含完整的状态映射说明
  9. 现有功能不受影响,企业统计等依赖工作状态的功能仍能正常工作

任务 / 子任务

将故事分解为实施所需的具体任务和子任务。 在相关处引用适用的验收标准编号。

  • [ ] 任务1:查询逻辑重构(disability-module扩展)(AC: 1, 2, 3, 4, 5)

    • disabled-person.service.tsfindAllForCompany方法中,修改查询逻辑:使用order_person.work_status而不是disabled_person.job_status作为工作状态源
    • 获取人员最新的order_person记录(按join_date降序)来确定当前工作状态
    • 在SELECT语句中添加MAX(op.work_status)或通过子查询获取最新状态
    • 更新结果映射逻辑,将WorkStatus枚举值转换为中文状态:'working'→"在职"、'pre_working'→"待入职"、'resigned'→"离职"、'not_working'→"未就业"(后备)
  • [ ] 任务2:筛选条件优化(AC: 1, 2, 3, 5)

    • 修改jobStatus筛选逻辑,直接使用order_person.work_status进行过滤
    • 支持前端中文状态到WorkStatus枚举值的映射:"在职"→'working'、"待入职"→'pre_working'、"离职"→'resigned'
    • 更新Schema验证(CompanyPersonListQuerySchema),明确状态映射关系
  • [ ] 任务3:人才详情API统一(AC: 4, 5)

    • findOneForCompany方法中,同样使用order_person.work_status作为工作状态源
    • 获取人员最新的订单关联记录,确定当前工作状态
    • 保持与人才列表API一致的状态转换逻辑
  • [ ] 任务4:数据库性能优化(AC: 6)

    • 分析现有索引:order_person表已有['personId', 'workStatus']['joinDate']等索引
    • 考虑添加复合索引优化最新状态查询:['personId', 'joinDate', 'workStatus']
    • 验证查询性能,确保响应时间<200ms
  • [ ] 任务5:Schema和类型更新(AC: 5, 8)

    • 更新CompanyPersonListQuerySchema,明确状态筛选选项和映射关系
    • 更新CompanyPersonListSchemaCompanyPersonDetailSchema,使用一致的枚举类型
    • 生成准确的TypeScript类型定义,确保前端类型安全
  • [ ] 任务6:前端状态显示统一(AC: 5)

    • 更新人才管理UI包中的状态显示逻辑,使用新的状态值
    • 确保人才列表页、人才详情页的状态标签显示一致
    • 更新状态筛选组件的选项说明
  • [ ] 任务7:集成测试全面覆盖(AC: 7)

    • person-extension.integration.test.ts中新增测试用例,覆盖所有状态场景
    • 测试状态筛选的精确性:"待入职"和"离职"筛选应返回不同结果
    • 测试边界条件:无订单关联的人员状态(显示"未就业"或空值)
    • 测试性能:大数据量下的状态查询性能
    • 确保测试覆盖率≥60%
  • [ ] 任务8:兼容性保障(AC: 9)

    • 验证现有数据迁移:所有已有关联订单的人员应有正确的work_status
    • 对于无订单关联的人员,提供合理的默认状态(空值或'not_working')
    • 确保企业统计中的在职状态分布统计仍能正常工作

开发笔记

仅填充从docs文件夹中的实际工件提取的相关信息,与此故事相关:

先前故事洞察

故事012.011(企业专用人才管理API)已完成的变更:

  • 企业专用人才列表和详情API已在disabled-person.service.ts中实现findAllForCompanyfindOneForCompany方法[来源:docs/stories/012.011.story.md]
  • person-extension.route.ts文件已包含企业专用人才路由[来源:docs/stories/012.011.story.md]
  • 企业用户认证中间件enterpriseAuthMiddleware已实现(故事012.002)[来源:docs/stories/012.002.story.md]

数据模型

基于现有实体定义和架构文档:

残疾人实体allin-packages/disability-module/src/entities/disabled-person.entity.ts):

  • 表名:disabled_person@Entity('disabled_person'))
  • 主键:id(映射到person_id列)
  • 字段:namegenderidCarddisabilityIddisabilityTypedisabilityLevelbirthDatephonejobStatus等[来源:docs/stories/012.011.story.md#数据模型]

订单人员实体allin-packages/order-module/src/entities/order-person.entity.ts):

  • 表名:order_person@Entity('order_person'))
  • 主键:id(映射到op_id列)
  • 字段:orderIdpersonIdjoinDatesalaryDetailworkStatus等[来源:docs/stories/012.011.story.md#数据模型]
  • 关联:personId关联DisabledPerson,orderId关联EmploymentOrder

工作状态枚举@d8d/allin-enums包):

  • WorkStatus枚举包含:'not_working'、'pre_working'、'working'、'resigned'[来源:docs/prd/epic-012-api-supplement-for-employer-mini-program.md#故事012-13]

API规范

API路径约定(来自史诗012):

  • 所有用人方小程序的API路径统一使用 api/v1/yongren 前缀[来源:docs/prd/epic-012-api-supplement-for-employer-mini-program.md#api路径约定]
  • 企业专用人才API路径:GET /api/v1/yongren/disability-person(列表)、GET /api/v1/yongren/disability-person/{id}(详情)[来源:docs/stories/012.011.story.md#api规范]

验证系统规范(来自架构文档):

  • 使用Zod Schema进行请求验证和响应类型定义[来源:docs/architecture/backend-module-package-standards.md#验证系统规范]
  • 枚举验证使用z.nativeEnum(WorkStatus)[来源:docs/architecture/backend-module-package-standards.md#枚举验证]
  • Schema定义位置:allin-packages/disability-module/src/schemas/person-extension.schema.ts[来源:项目结构]

文件位置

基于项目结构指南:

  • 服务文件:allin-packages/disability-module/src/services/disabled-person.service.ts[来源:docs/architecture/source-tree.md]
  • 路由文件:allin-packages/disability-module/src/routes/person-extension.route.ts[来源:项目结构验证]
  • Schema文件:allin-packages/disability-module/src/schemas/person-extension.schema.ts[来源:项目结构验证]
  • 集成测试文件:allin-packages/disability-module/tests/integration/person-extension.integration.test.ts[来源:项目结构验证]

技术栈约束

  • 运行时:Node.js 20.18.3[来源:docs/architecture/tech-stack.md]
  • 框架:Hono 4.8.5(Web框架和API路由)[来源:docs/architecture/tech-stack.md]
  • ORM:TypeORM 0.3.25(数据库操作抽象)[来源:docs/architecture/tech-stack.md]
  • 数据库:PostgreSQL 17[来源:docs/architecture/tech-stack.md]
  • 测试框架:Vitest[来源:docs/architecture/tech-stack.md]

测试要求

测试策略(来自架构文档):

  • 单元测试覆盖率目标:≥ 80%[来源:docs/architecture/testing-strategy.md#单元测试]
  • 集成测试覆盖率目标:≥ 60%[来源:docs/architecture/testing-strategy.md#集成测试]
  • 测试文件位置:tests/integration/文件夹与源码并列[来源:docs/architecture/testing-strategy.md#集成测试]
  • 测试框架:Vitest + hono/testing[来源:docs/architecture/testing-strategy.md#集成测试]
  • 集成测试应验证完整的用户流程,而不仅仅是单个操作[来源:docs/architecture/testing-strategy.md#验证完整的用户流程]

测试数据管理

  • 集成测试使用专用测试数据库,事务回滚[来源:docs/architecture/testing-strategy.md#数据库测试策略]
  • 使用测试数据工厂模式创建测试数据[来源:docs/architecture/testing-strategy.md#测试数据工厂模式]

编码标准

  • 代码风格:TypeScript严格模式,一致的缩进和命名[来源:docs/architecture/coding-standards.md#现有标准合规性]
  • linting规则:已配置ESLint,支持TypeScript和React[来源:docs/architecture/coding-standards.md#现有标准合规性]
  • 实体设计规范:主键使用id作为属性名(映射到数据库列如person_id)[来源:docs/architecture/backend-module-package-standards.md#主键命名]
  • 字段命名转换:数据库下划线命名 → TypeScript驼峰命名[来源:docs/architecture/backend-module-package-standards.md#字段命名转换]

项目结构注意事项

  • 模块包结构遵循allin-packages/{module-name}-module/模式[来源:docs/architecture/backend-module-package-standards.md#包结构规范]
  • 服务层应继承GenericCrudService或扩展其功能[来源:docs/architecture/backend-module-package-standards.md#genericcrudservice继承]
  • 路由聚合模式:主路由文件聚合自定义路由和CRUD路由[来源:docs/architecture/backend-module-package-standards.md#路由聚合模式]

变更日志

日期 版本 描述 作者
2025-12-20 1.0 初始故事创建 Bob (Scrum Master)

Dev Agent Record

此部分由开发代理在实施期间填写