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

📝 docs(epic-007): 添加区域包依赖设计决策和模块改造要求

### 主要更新内容:
1. **设计决策:区域数据统一使用@d8d/geo-areas包**
   - 背景分析:残疾人管理模块和薪资管理模块使用区域数据
   - 问题分析:数据不一致、缺乏验证、维护困难、重复功能
   - 设计决策:采用方案A(完全依赖区域包)
   - 改造方案:移除字符串字段,添加外键引用AreaEntity
   - 优势:数据一致性、类型安全、维护简单、功能完整、性能优化

2. **故事4更新**(残疾人管理模块):
   - 添加区域包集成要求
   - 更新验收标准:包含区域数据验证
   - 更新API测试要求:添加区域测试重点

3. **故事7更新**(薪资管理模块):
   - 添加区域包集成要求
   - 更新验收标准:添加区域ID字段和验证
   - 更新API测试要求:添加区域测试重点,包括唯一性约束测试

### 改造方案要点:
- 残疾人模块:province/city/district字符串 → provinceId/cityId/districtId外键
- 薪资模块:province/city字符串 → provinceId/cityId外键,唯一约束(provinceId, cityId)
- API兼容性:DTO转换器支持区域名称自动转ID,响应返回区域完整信息

🤖 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 3 недель назад
Родитель
Сommit
6498c59e73
1 измененных файлов с 77 добавлено и 17 удалено
  1. 77 17
      docs/prd/epic-007-allin-system-transplant.md

+ 77 - 17
docs/prd/epic-007-allin-system-transplant.md

@@ -408,6 +408,53 @@ export type CreateChannelDto = z.infer<typeof CreateChannelSchema>;
 - ✅ 维护简单:集中管理,一处修改处处生效
 - ✅ 维护简单:集中管理,一处修改处处生效
 - ✅ 版本控制:枚举定义与代码一起版本控制
 - ✅ 版本控制:枚举定义与代码一起版本控制
 
 
+## 设计决策:区域数据统一使用@d8d/geo-areas包
+
+### 背景分析
+经过对Allin系统模块的分析,发现以下模块使用行政区划数据:
+
+1. **残疾人管理模块** (`disability_person`):
+   - 存储`province`、`city`、`district`字段(字符串类型)
+   - 用于记录残疾人的户籍地址和居住地址
+
+2. **薪资管理模块** (`salary`):
+   - 存储`province`、`city`、`district`字段(字符串类型)
+   - 用于按地区管理薪资水平,有唯一性约束`(province, city)`
+
+### 问题分析
+当前实现存在以下问题:
+1. **数据不一致**:字符串存储,容易输入错误或格式不一致
+2. **缺乏验证**:没有验证区域数据的有效性
+3. **维护困难**:区域变更需要手动更新所有相关记录
+4. **重复功能**:与已有的`@d8d/geo-areas`包功能重叠
+
+### 设计决策
+**采用方案A:完全依赖区域包**,将所有区域数据改为引用`@d8d/geo-areas`包中的`AreaEntity`。
+
+### 改造方案
+1. **残疾人管理模块改造**:
+   - 移除`province`、`city`、`district`字符串字段
+   - 添加`provinceId`、`cityId`、`districtId`字段(外键引用`AreaEntity`)
+   - 使用`AreaService`验证区域数据的有效性和层级关系
+
+2. **薪资管理模块改造**:
+   - 移除`province`、`city`、`district`字符串字段
+   - 添加`provinceId`、`cityId`、`districtId`字段(外键引用`AreaEntity`)
+   - 修改唯一性约束为`(provinceId, cityId)`
+   - 使用区域包API获取区域完整信息
+
+3. **API兼容性处理**:
+   - 创建DTO转换器,支持前端传递区域名称自动转换为ID
+   - 在响应中返回区域完整信息(名称+ID+层级)
+   - 提供区域查询API,支持按名称搜索区域
+
+### 优势
+- ✅ **数据一致性**:统一使用区域包数据,避免数据不一致
+- ✅ **类型安全**:外键引用提供编译时检查
+- ✅ **维护简单**:区域变更只需更新区域包数据
+- ✅ **功能完整**:利用区域包的树形结构、层级验证等功能
+- ✅ **性能优化**:减少重复数据存储,提高查询效率
+
 ### 故事4:移植残疾人管理模块(disability_person → @d8d/allin-disability-module)
 ### 故事4:移植残疾人管理模块(disability_person → @d8d/allin-disability-module)
 **目标**:移植最复杂的模块,处理5个实体和跨模块依赖,完成文件实体集成,使用枚举常量
 **目标**:移植最复杂的模块,处理5个实体和跨模块依赖,完成文件实体集成,使用枚举常量
 
 
@@ -415,15 +462,16 @@ export type CreateChannelDto = z.infer<typeof CreateChannelSchema>;
 1. ✅ 创建`allin-packages/disability-module`目录结构
 1. ✅ 创建`allin-packages/disability-module`目录结构
 2. ✅ 完成实体转换:5个实体(DisabledPerson、DisabledBankCard等)转换
 2. ✅ 完成实体转换:5个实体(DisabledPerson、DisabledBankCard等)转换
 3. ✅ **枚举常量集成**:使用`@d8d/allin-enums`包中的`DisabilityType`和`DisabilityLevel`枚举
 3. ✅ **枚举常量集成**:使用`@d8d/allin-enums`包中的`DisabilityType`和`DisabilityLevel`枚举
-4. ✅ **文件实体集成**:修改`DisabledPhoto`实体,添加`fileId`字段引用`File`实体
-5. ✅ 处理跨模块依赖:引用order、platform、company、channel模块实体
-6. ✅ 完成服务层转换:复杂业务逻辑处理,包含文件ID验证逻辑
-7. ✅ 完成路由层转换:多个控制器转换为Hono路由,API接收`fileId`参数
-8. ✅ 完成验证系统转换:复杂数据验证,包含文件ID验证和枚举值验证
-9. ✅ 配置package.json:处理多个依赖,包含对`@d8d/file-module`和`@d8d/allin-enums`的依赖
-10. ✅ 编写API集成测试:覆盖所有5个实体的管理功能,包含文件ID关联测试和枚举值测试
-11. ✅ 通过类型检查和基本测试验证
-12. ✅ 解决与order-module的循环依赖问题
+4. ✅ **区域包集成**:使用`@d8d/geo-areas`包管理区域数据
+5. ✅ **文件实体集成**:修改`DisabledPhoto`实体,添加`fileId`字段引用`File`实体
+6. ✅ 处理跨模块依赖:引用order、platform、company、channel模块实体
+7. ✅ 完成服务层转换:复杂业务逻辑处理,包含文件ID验证和区域数据验证逻辑
+8. ✅ 完成路由层转换:多个控制器转换为Hono路由,API接收`fileId`参数和区域数据
+9. ✅ 完成验证系统转换:复杂数据验证,包含文件ID验证、枚举值验证和区域数据验证
+10. ✅ 配置package.json:处理多个依赖,包含对`@d8d/file-module`、`@d8d/allin-enums`和`@d8d/geo-areas`的依赖
+11. ✅ 编写API集成测试:覆盖所有5个实体的管理功能,包含文件ID关联测试、枚举值测试和区域数据测试
+12. ✅ 通过类型检查和基本测试验证
+13. ✅ 解决与order-module的循环依赖问题
 
 
 **API集成测试要求**:
 **API集成测试要求**:
 - 测试文件:`tests/integration/disability.integration.test.ts`
 - 测试文件:`tests/integration/disability.integration.test.ts`
@@ -432,6 +480,11 @@ export type CreateChannelDto = z.infer<typeof CreateChannelSchema>;
   - 验证残疾类型枚举值正确性
   - 验证残疾类型枚举值正确性
   - 验证残疾等级枚举值正确性
   - 验证残疾等级枚举值正确性
   - 测试无效枚举值的错误处理
   - 测试无效枚举值的错误处理
+- **区域测试重点**:
+  - 验证区域ID的有效性检查
+  - 测试区域层级关系验证(省→市→区)
+  - 验证区域不存在时的错误处理
+  - 测试区域数据在响应中的完整性
 - **文件测试重点**:
 - **文件测试重点**:
   - 验证`fileId`参数接收和处理
   - 验证`fileId`参数接收和处理
   - 测试文件不存在时的错误处理
   - 测试文件不存在时的错误处理
@@ -498,18 +551,25 @@ export type CreateChannelDto = z.infer<typeof CreateChannelSchema>;
 
 
 **验收标准**:
 **验收标准**:
 1. ✅ 创建`allin-packages/salary-module`目录结构
 1. ✅ 创建`allin-packages/salary-module`目录结构
-2. ✅ 完成实体转换:`SalaryLevel`实体转换
-3. ✅ 完成服务层转换:薪资业务逻辑
-4. ✅ 完成路由层转换:Hono路由实现
-5. ✅ 完成验证系统转换:Zod Schema定义
-6. ✅ 配置package.json:独立包配置
-7. ✅ 编写API集成测试:验证薪资管理功能
-8. ✅ 通过类型检查和基本测试验证
-9. ✅ 整体验证:所有7个模块的集成测试
+2. ✅ 完成实体转换:`SalaryLevel`实体转换,添加区域ID字段
+3. ✅ **区域包集成**:使用`@d8d/geo-areas`包管理区域数据
+4. ✅ 完成服务层转换:薪资业务逻辑,包含区域数据验证
+5. ✅ 完成路由层转换:Hono路由实现,支持区域ID参数
+6. ✅ 完成验证系统转换:Zod Schema定义,包含区域ID验证
+7. ✅ 配置package.json:依赖管理,包含对`@d8d/geo-areas`的依赖
+8. ✅ 编写API集成测试:验证薪资管理功能,包含区域数据测试
+9. ✅ 通过类型检查和基本测试验证
+10. ✅ 整体验证:所有7个模块的集成测试
 
 
 **API集成测试要求**:
 **API集成测试要求**:
 - 测试文件:`tests/integration/salary.integration.test.ts`
 - 测试文件:`tests/integration/salary.integration.test.ts`
 - 测试覆盖:薪资等级管理、关联查询
 - 测试覆盖:薪资等级管理、关联查询
+- **区域测试重点**:
+  - 验证区域ID的有效性检查
+  - 测试区域层级关系验证(省→市→区)
+  - 验证区域不存在时的错误处理
+  - 测试区域唯一性约束`(provinceId, cityId)`
+  - 验证区域数据在响应中的完整性
 - 验证:数值计算、等级规则
 - 验证:数值计算、等级规则
 - 包含整体集成测试:验证所有模块协同工作
 - 包含整体集成测试:验证所有模块协同工作