Ver código fonte

docs(story-008.005): 创建残疾人管理UI移植故事

- 创建故事008.005:移植残疾人管理UI(disability → @d8d/allin-disability-management-ui)
- 吸取之前故事经验:Schema一致性验证、API路径验证、测试精度优化
- 在任务中直接标注文件路径:需要迁移的源文件和需要参考对照的文件
- 基于后端实际路由定义:查看残疾人模块集成测试和路由文件
- 包含完整的区域选择器集成方案:集成@d8d/area-management-ui组件
- 遵循UI包开发规范:使用ClientManager单例模式、RPC类型推导

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

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 2 semanas atrás
pai
commit
9d253e75d0

+ 263 - 0
docs/stories/008.005.transplant-disability-management-ui.story.md

@@ -0,0 +1,263 @@
+# Story 008.005: 移植残疾人管理UI(disability → @d8d/allin-disability-management-ui)
+
+## Status
+Draft
+
+## Story
+**As a** 开发者,
+**I want** 将disability管理页面从allin_system-master/client移植为独立UI包@d8d/allin-disability-management-ui,完成技术栈转换并集成区域选择器组件,
+**so that** 我们可以将Allin系统的残疾人管理UI模块集成到当前项目中,遵循现有的UI包结构和编码标准,并正确集成区域选择器组件用于残疾人区域信息管理。
+
+## Acceptance Criteria
+1. 创建`allin-packages/disability-management-ui`目录结构
+2. 完成组件转换:残疾人列表管理组件
+3. **区域包集成**:集成`@d8d/area-management-ui`的区域选择器组件用于残疾人区域信息管理
+4. 完成API客户端转换:与disability-module集成
+5. 完成状态管理转换:残疾人数据状态
+6. 完成表单转换:基础残疾人信息表单(包含区域选择)
+7. 配置package.json:依赖`@d8d/allin-disability-module`和`@d8d/area-management-ui`
+8. 编写组件测试:验证残疾人管理功能(包含区域选择验证)
+9. 通过类型检查和基本测试验证
+
+## Tasks / Subtasks
+- [ ] 任务1:创建残疾人管理UI包基础结构 (AC: 1)
+  - [ ] 创建目录结构:`allin-packages/disability-management-ui/`
+    - **目标目录**:`allin-packages/disability-management-ui/`
+    - **参考结构**:`allin-packages/platform-management-ui/`目录结构
+  - [ ] 创建package.json:配置包名、依赖、脚本
+    - **目标文件**:`allin-packages/disability-management-ui/package.json`
+    - **包名**:`@d8d/allin-disability-management-ui`
+    - **依赖**:`@d8d/allin-disability-module`、`@d8d/area-management-ui`、`@d8d/shared-ui-components`、`@tanstack/react-query`、`react-hook-form`、`zod`
+    - **参考文件**:`allin-packages/platform-management-ui/package.json`
+  - [ ] 创建TypeScript配置:`tsconfig.json`
+    - **目标文件**:`allin-packages/disability-management-ui/tsconfig.json`
+    - **参考文件**:`allin-packages/platform-management-ui/tsconfig.json`
+  - [ ] 创建测试配置:`vitest.config.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/vitest.config.ts`
+    - **参考文件**:`allin-packages/platform-management-ui/vitest.config.ts`
+  - [ ] 创建主入口文件:`src/index.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/index.ts`
+    - **参考文件**:`allin-packages/platform-management-ui/src/index.ts`
+
+- [ ] 任务2:分析源系统文件并创建API客户端 (AC: 4)
+  - [ ] 分析源系统残疾人管理页面:`allin_system-master/client/app/admin/dashboard/disability/page.tsx`
+    - **源文件**:`allin_system-master/client/app/admin/dashboard/disability/page.tsx`
+    - **查看要点**:数据结构、API调用方式、表单字段、区域信息处理
+  - [ ] 查看残疾人模块RPC路由定义:`allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts`
+    - **路由文件**:`allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts`
+    - **查看要点**:路由路径、请求方法、Schema定义
+  - [ ] 查看残疾人模块集成测试:`allin-packages/disability-module/tests/integration/disability.integration.test.ts`
+    - **测试文件**:`allin-packages/disability-module/tests/integration/disability.integration.test.ts`
+    - **查看要点**:API调用方式、参数格式、响应格式
+  - [ ] 创建RPC客户端管理器:`src/api/disabilityClient.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/api/disabilityClient.ts`
+    - **参考文件**:`allin-packages/platform-management-ui/src/api/platformClient.ts`
+    - **模式**:ClientManager单例模式,遵循现有UI包规范
+  - [ ] 创建API类型定义:`src/api/types.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/api/types.ts`
+    - **类型推导**:使用RPC推断类型,避免直接导入schema类型
+    - **参考文件**:`allin-packages/platform-management-ui/src/api/types.ts`
+
+- [ ] 任务3:创建残疾人管理主组件 (AC: 2, 3, 6)
+  - [ ] 创建主管理组件:`src/components/DisabilityManagement.tsx`
+    - **目标文件**:`allin-packages/disability-management-ui/src/components/DisabilityManagement.tsx`
+    - **参考文件**:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
+  - [ ] 创建表格组件:`src/components/DisabilityTable.tsx`
+    - **目标文件**:`allin-packages/disability-management-ui/src/components/DisabilityTable.tsx`
+    - **功能**:显示残疾人列表,支持搜索、分页、操作按钮
+    - **参考文件**:`allin-packages/platform-management-ui/src/components/PlatformTable.tsx`
+  - [ ] 创建表单组件:`src/components/DisabilityForm.tsx`
+    - **目标文件**:`allin-packages/disability-management-ui/src/components/DisabilityForm.tsx`
+    - **模式**:必须使用条件渲染两个独立的Form组件(创建表单和更新表单)
+    - **参考文件**:`allin-packages/platform-management-ui/src/components/PlatformForm.tsx`
+  - [ ] 集成区域选择器:在表单中集成`AreaSelect`组件
+    - **组件来源**:`@d8d/area-management-ui`的`AreaSelect`组件
+    - **参考文件**:`packages/area-management-ui/src/components/AreaSelect.tsx`
+    - **集成方式**:替换原有的省份、城市选择逻辑,使用三级联动区域选择器
+  - [ ] 创建模态框组件:`src/components/DisabilityModal.tsx`
+    - **目标文件**:`allin-packages/disability-management-ui/src/components/DisabilityModal.tsx`
+    - **参考文件**:`allin-packages/platform-management-ui/src/components/PlatformModal.tsx`
+
+- [ ] 任务4:创建自定义Hook和状态管理 (AC: 5)
+  - [ ] 创建查询Hook:`src/hooks/useDisabilityQuery.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/hooks/useDisabilityQuery.ts`
+    - **功能**:封装残疾人数据查询逻辑,使用React Query
+    - **参考文件**:`allin-packages/platform-management-ui/src/hooks/usePlatformQuery.ts`
+  - [ ] 创建变更Hook:`src/hooks/useDisabilityMutation.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/hooks/useDisabilityMutation.ts`
+    - **功能**:封装创建、更新、删除等变更操作
+    - **参考文件**:`allin-packages/platform-management-ui/src/hooks/usePlatformMutation.ts`
+  - [ ] 创建表单Hook:`src/hooks/useDisabilityForm.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/hooks/useDisabilityForm.ts`
+    - **功能**:封装表单状态管理、验证逻辑
+    - **参考文件**:`allin-packages/platform-management-ui/src/hooks/usePlatformForm.ts`
+  - [ ] 创建Hook导出文件:`src/hooks/index.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/hooks/index.ts`
+    - **参考文件**:`allin-packages/platform-management-ui/src/hooks/index.ts`
+
+- [ ] 任务5:创建表单Schema和验证 (AC: 6)
+  - [ ] 分析后端Schema:`allin-packages/disability-module/src/schemas/disabled-person.schema.ts`
+    - **源文件**:`allin-packages/disability-module/src/schemas/disabled-person.schema.ts`
+    - **查看要点**:`CreateDisabledPersonSchema`、`UpdateDisabledPersonSchema`、字段定义、验证规则
+  - [ ] 创建前端Zod Schema:`src/schemas/disability.schema.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/schemas/disability.schema.ts`
+    - **模式**:基于后端Schema创建前端Zod Schema,保持一致性
+    - **参考文件**:`allin-packages/platform-management-ui/src/schemas/platform.schema.ts`
+  - [ ] 集成区域字段验证:在Schema中添加区域字段验证
+    - **字段**:`provinceId`、`cityId`、`districtId`(可选)
+    - **验证**:与`AreaSelect`组件返回格式保持一致
+  - [ ] 创建表单类型定义:`src/types/form.ts`
+    - **目标文件**:`allin-packages/disability-management-ui/src/types/form.ts`
+    - **类型**:创建表单类型、更新表单类型、表单值类型
+    - **参考文件**:`allin-packages/platform-management-ui/src/types/form.ts`
+
+- [ ] 任务6:编写集成测试 (AC: 8)
+  - [ ] 创建主测试文件:`tests/integration/disability.integration.test.tsx`
+    - **目标文件**:`allin-packages/disability-management-ui/tests/integration/disability.integration.test.tsx`
+    - **参考文件**:`allin-packages/platform-management-ui/tests/integration/platform.integration.test.tsx`
+  - [ ] 实现完整CRUD流程测试:创建残疾人 → 查询残疾人列表 → 更新残疾人 → 删除残疾人
+    - **测试场景**:创建残疾人记录 → 查询残疾人列表 → 更新残疾人记录 → 删除残疾人记录
+    - **测试ID**:为关键交互元素添加`data-testid`属性,避免使用文本查找
+  - [ ] 实现区域选择器集成测试:验证区域选择器与表单的集成
+    - **测试场景**:区域选择器组件集成,区域选择后表单字段更新
+    - **验证点**:区域ID正确传递,表单验证正常工作
+  - [ ] 实现表单验证测试:验证必填字段、身份证号唯一性等
+    - **测试场景**:必填字段验证、身份证号格式验证、身份证号唯一性验证
+    - **参考模式**:残疾人模块集成测试中的验证逻辑
+  - [ ] 实现错误处理测试:API错误、网络错误、验证错误
+    - **测试场景**:API错误、网络错误、表单验证错误
+    - **参考模式**:平台管理集成测试中的错误处理
+
+- [ ] 任务7:验证和测试 (AC: 9)
+  - [ ] 运行`pnpm typecheck`确保无类型错误
+  - [ ] 运行`pnpm test`确保所有集成测试通过
+  - [ ] 验证区域选择器组件集成正常工作
+  - [ ] 验证表单验证和错误处理功能
+  - [ ] 验证组件导出和类型定义正确
+
+## Dev Notes
+
+### 从前一个故事学到的关键经验(故事008.004):
+1. **Schema设计一致性验证**:必须查看后端模块的集成测试和路由定义来确保Schema设计正确,不能仅凭前端使用场景假设。
+2. **API路径一致性验证**:必须根据后端实际路由设计前端API调用,不能假设为标准CRUD模式。
+3. **测试精度优化**:在测试中使用test ID比文本查找更精确可靠。
+4. **类型推导优化**:遵循现有UI包的模式,使用正确的RPC类型推导语法。
+5. **表单组件模式规范**:必须使用条件渲染两个独立的Form组件,避免在单个Form组件上动态切换props。
+
+### 技术栈规范 [Source: docs/architecture/ui-package-standards.md]
+- **包结构规范**:标准目录结构,包含components、api、hooks、types目录
+- **RPC客户端实现规范**:必须使用ClientManager单例模式管理RPC客户端生命周期
+- **组件开发规范**:使用@d8d/shared-ui-components组件库,React Query进行状态管理
+- **类型定义规范**:使用RPC推断类型,避免重新定义类型
+- **测试规范**:集成测试、组件测试、单元测试分层结构
+- **表单组件模式规范**:必须使用条件渲染两个独立的Form组件,避免在单个Form组件上动态切换props
+
+### 项目结构信息 [Source: docs/architecture/source-tree.md]
+- **UI包位置**:`allin-packages/disability-management-ui/`(Allin系统专属包目录)
+- **参考实现**:
+  - `allin-packages/platform-management-ui/`(已完成的平台管理UI包)
+  - `allin-packages/channel-management-ui/`(已完成的渠道管理UI包)
+  - `allin-packages/company-management-ui/`(已完成的公司管理UI包)
+  - `allin-packages/salary-management-ui/`(已完成的薪资管理UI包)
+- **后端模块**:`allin-packages/disability-module/`(对应的后端模块)
+- **区域管理UI包**:`packages/area-management-ui/`(需要集成的区域选择器组件)
+
+### 源系统文件路径
+- **需要移植的源文件**:`allin_system-master/client/app/admin/dashboard/disability/page.tsx`
+- **需要对照参考的文件**:
+  - `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
+  - `allin-packages/platform-management-ui/src/api/platformClient.ts`
+  - `allin-packages/platform-management-ui/src/api/types.ts`
+  - `allin-packages/platform-management-ui/tests/integration/platform.integration.test.tsx`
+  - `allin-packages/company-management-ui/src/components/CompanyManagement.tsx`
+  - `allin-packages/company-management-ui/src/api/companyClient.ts`
+  - `allin-packages/company-management-ui/src/types/index.ts`
+- **区域选择器组件文件**:
+  - `packages/area-management-ui/src/components/AreaSelect.tsx`
+  - `packages/area-management-ui/src/api/areaClient.ts`
+
+### 残疾人模块RPC API调用信息(基于集成测试和路由定义)
+- **RPC客户端调用方式**(来自`allin-packages/disability-module/tests/integration/disability.integration.test.ts`和`allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts`):
+  - `disabilityClientManager.get().createDisabledPerson.$post({ json: personData })` - 创建残疾人记录
+  - `disabilityClientManager.get().updateDisabledPerson.$post({ json: personData })` - 更新残疾人记录
+  - `disabilityClientManager.get().deleteDisabledPerson.$post({ json: { id } })` - 删除残疾人记录
+  - `disabilityClientManager.get().getDisabledPersonList.$get({ query: { page, pageSize, filters, sortBy, sortOrder } })` - 获取残疾人列表(分页)
+  - `disabilityClientManager.get().getDisabledPersonById.$get({ query: { id } })` - 获取残疾人详情
+
+- **API路径映射**(来自`allin-packages/disability-module/src/routes/disabled-person-custom.routes.ts`):
+  - `POST /createDisabledPerson` → `disabilityClientManager.get().createDisabledPerson.$post`
+  - `POST /updateDisabledPerson` → `disabilityClientManager.get().updateDisabledPerson.$post`
+  - `POST /deleteDisabledPerson` → `disabilityClientManager.get().deleteDisabledPerson.$post`
+  - `GET /getDisabledPersonList` → `disabilityClientManager.get().getDisabledPersonList.$get`
+  - `GET /getDisabledPersonById` → `disabilityClientManager.get().getDisabledPersonById.$get`
+
+- **残疾人数据字段**(来自`allin-packages/disability-module/src/schemas/disabled-person.schema.ts`):
+  - `name: string` - 姓名
+  - `gender: string` - 性别
+  - `idCard: string` - 身份证号
+  - `disabilityId: string` - 残疾证号
+  - `disabilityType: string` - 残疾类型
+  - `disabilityLevel: string` - 残疾等级
+  - `idAddress: string` - 身份证地址
+  - `phone: string` - 联系电话
+  - `province: string` - 省份
+  - `city: string` - 城市
+  - **注意**:源系统使用字符串省份城市,需要转换为区域ID格式
+
+### 区域选择器集成方案
+- **组件使用**:导入`AreaSelect`组件从`@d8d/area-management-ui`
+- **数据转换**:将源系统的字符串省份城市转换为区域ID
+  - 表单提交时:区域ID → 后端API
+  - 数据显示时:区域ID → 区域名称显示
+- **三级联动**:使用`AreaSelect`组件内置的省份→城市→区县三级联动功能
+- **表单集成**:在残疾人表单中集成区域选择器,替换原有的省份、城市选择逻辑
+- **数据格式**:`AreaSelect`组件返回`{ provinceId?, cityId?, districtId? }`格式
+- **验证集成**:残疾人Schema中的区域字段验证与`AreaSelect`组件集成
+
+### 表单验证要求
+- **必填字段**:姓名、性别、身份证号、残疾证号、残疾类型、残疾等级、联系电话
+- **身份证号验证**:格式验证、唯一性验证(后端验证)
+- **联系电话验证**:手机号格式验证
+- **区域验证**:省份和城市必须选择
+
+### Testing
+**测试标准**:
+- **测试框架**:Vitest + Testing Library
+- **测试位置**:
+  - 集成测试:`tests/integration/disability.integration.test.tsx`
+- **测试覆盖要求**:
+  - 完整CRUD流程测试
+  - 区域选择器集成测试
+  - 表单验证测试(必填字段、身份证号格式、联系电话格式)
+  - 错误处理测试(API错误、验证错误)
+- **测试模式**:参考现有UI包的集成测试模式
+
+**测试策略**:
+- 使用`data-testid`进行元素定位,避免文本查找
+- 模拟完整的用户交互流程
+- 验证区域选择器的集成和数据转换
+- 测试表单验证和错误提示
+- 覆盖各种错误场景
+
+## Change Log
+| Date | Version | Description | Author |
+|------|---------|-------------|--------|
+| 2025-12-03 | 1.0 | 初始创建故事008.005 | Scrum Master Bob |
+
+## Dev Agent Record
+*This section is populated by the development agent during implementation*
+
+### Agent Model Used
+*To be filled by dev agent*
+
+### Debug Log References
+*To be filled by dev agent*
+
+### Completion Notes List
+*To be filled by dev agent*
+
+### File List
+*To be filled by dev agent*
+
+## QA Results
+*Results from QA Agent QA review of the completed story implementation*