# Story 009.001: 区域选择优化

## Status
Ready for Review

## Story
**As a** 系统管理员
**I want** 在薪资管理中添加薪资时，区域选择无需精确到区县
**so that** 简化操作流程，提高工作效率

## Acceptance Criteria
1. 区域选择组件支持只选择到市级
2. 区县字段不再设为必选项
3. 现有数据兼容性保持

## Tasks / Subtasks
- [x] 修改AreaSelect组件，移除区县必填验证 (AC: 1, 2)
  - [x] 更新packages/area-management-ui/src/components/AreaSelect.tsx中的验证逻辑
  - [x] 确保当required=true时，区县字段不显示为必填
  - [x] 更新组件文档和类型定义
- [x] 验证薪资管理UI包中的AreaSelect使用 (AC: 1, 2)
  - [x] 检查allin-packages/salary-management-ui/src/components/SalaryManagement.tsx中AreaSelect组件的使用
  - [x] 确保required参数传递正确
  - [x] 验证表单提交时区县字段可为空
- [x] 优化薪资管理表单的地区选择实现 (AC: 1, 2)
  - [x] 将创建表单中的AreaSelect替换为AreaSelectForm
  - [x] 将编辑表单中的静态显示替换为AreaSelectForm
  - [x] 清理不再需要的状态同步逻辑
  - [x] 更新AreaSelectForm组件，添加根元素data-testid支持
- [x] 验证后端schema兼容性 (AC: 3)
  - [x] 检查allin-packages/salary-module/src/schemas/salary.schema.ts中的CreateSalarySchema和UpdateSalarySchema
  - [x] 确认districtId字段已经是optional
  - [x] 验证数据库实体allin-packages/salary-module/src/entities/salary-level.entity.ts中districtId字段为nullable
- [x] 编写单元测试 (AC: 1, 2, 3)
  - [x] 为AreaSelect组件添加测试，验证区县非必填场景
  - [x] 为薪资管理表单添加测试，验证区县可为空的表单提交
  - [x] 添加集成测试验证端到端功能
- [x] 执行回归测试 (AC: 3)
  - [x] 测试现有薪资数据的显示和编辑功能
  - [x] 验证数据库查询兼容性
  - [x] 确保API响应格式不变

## Dev Notes

### 技术架构信息
**前端技术栈**:
- React 19.1.0 + TypeScript [Source: architecture/tech-stack.md#前端框架]
- UI组件库: shadcn/ui (基于Radix UI) [Source: architecture/component-architecture.md#技术栈配置]
- 状态管理: @tanstack/react-query (服务端状态) + Context (本地状态) [Source: architecture/component-architecture.md#技术栈配置]
- 构建工具: Vite 7.0.0 [Source: architecture/tech-stack.md#构建工具]

**项目结构**:
- 区域管理UI包: `packages/area-management-ui` [Source: architecture/ui-package-standards.md#参考实现]
- 薪资管理UI包: `allin-packages/salary-management-ui` [Source: 实际项目结构检查]
- 薪资模块: `allin-packages/salary-module` [Source: 实际项目结构检查]
- 地区模块: `packages/geo-areas` [Source: architecture/source-tree.md#业务模块层]

### 组件规范
**UI包开发规范**:
- 必须遵循[UI包开发规范](./ui-package-standards.md) [Source: architecture/coding-standards.md#UI包开发提示]
- API路径映射验证：开发前必须验证故事中的API路径映射与实际后端路由定义的一致性 [Source: architecture/coding-standards.md#关键检查点]
- 类型推断最佳实践：必须使用RPC推断类型，而不是直接导入schema类型 [Source: architecture/coding-standards.md#关键检查点]
- 测试选择器优化：必须为关键交互元素添加`data-testid`属性 [Source: architecture/coding-standards.md#关键检查点]

### 现有实现分析
**AreaSelect组件现状**:
- 文件位置: `packages/area-management-ui/src/components/AreaSelect.tsx`
- 当前问题：当`required=true`且选择了城市时，区县字段显示为必填（红色星号）
- 需要修改：移除区县字段的必填验证，即使`required=true`且选择了城市

**薪资管理表单现状**:
- 文件位置: `allin-packages/salary-management-ui/src/components/SalaryManagement.tsx`
- AreaSelect使用：在创建表单中传递`required={true}`参数
- 表单提交：通过`handleAreaChange`函数处理区域选择变化

**后端schema现状**:
- 创建DTO: `allin-packages/salary-module/src/schemas/salary.schema.ts:76` - `districtId`字段已经是`.optional()`
- 更新DTO: `allin-packages/salary-module/src/schemas/salary.schema.ts:112` - `districtId`字段已经是`.optional()`
- 数据库实体: `allin-packages/salary-module/src/entities/salary-level.entity.ts:37` - `districtId`字段为`nullable: true`

### 文件位置参考
1. **AreaSelect组件**: `packages/area-management-ui/src/components/AreaSelect.tsx`
2. **薪资管理组件**: `allin-packages/salary-management-ui/src/components/SalaryManagement.tsx`
3. **薪资schema**: `allin-packages/salary-module/src/schemas/salary.schema.ts`
4. **薪资实体**: `allin-packages/salary-module/src/entities/salary-level.entity.ts`

### 技术约束
- 保持向后兼容性：现有数据必须能正常显示和编辑
- API兼容性：不能修改现有API的请求/响应格式
- 数据库兼容性：`districtId`字段已经是`nullable: true`，无需修改数据库结构

### 测试
**测试策略**:
- 单元测试：使用Vitest框架 [Source: architecture/testing-strategy.md#单元测试]
- 组件测试：使用Testing Library [Source: architecture/testing-strategy.md#单元测试]
- 测试位置：`__tests__`文件夹与源码并列 [Source: architecture/coding-standards.md#测试位置]

**测试要求**:
- 覆盖率目标：核心业务逻辑 > 80% [Source: architecture/coding-standards.md#覆盖率目标]
- 测试类型：单元测试、集成测试 [Source: architecture/coding-standards.md#测试类型]
- 错误处理：测试各种错误场景和边界条件 [Source: architecture/coding-standards.md#错误处理]

**具体测试场景**:
1. AreaSelect组件：验证区县字段在`required=true`时不为必填
2. 薪资表单：验证提交时区县字段可为空
3. 数据兼容性：验证现有含区县数据的显示和编辑

## Testing
### 测试标准
- **测试框架**: Vitest + Testing Library [Source: architecture/tech-stack.md#新技术添加]
- **测试位置**: `__tests__`文件夹与源码并列 [Source: architecture/coding-standards.md#测试位置]
- **覆盖率要求**: 核心业务逻辑 > 80% [Source: architecture/coding-standards.md#覆盖率目标]

### 组件测试要求
- 必须为关键交互元素添加`data-testid`属性 [Source: architecture/coding-standards.md#关键检查点]
- 测试AreaSelect组件在`required=true`时的行为
- 验证区县字段不为必填的多种场景

### 集成测试要求
- 测试薪资管理表单的完整提交流程
- 验证区县字段为空的表单提交
- 测试现有数据的兼容性

### 测试文件位置
1. AreaSelect组件测试: `packages/area-management-ui/tests/integration/area-select-form.integration.test.tsx`
2. 薪资管理测试: `allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx`

## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-09 | 1.0 | 初始故事创建 | Scrum Master Bob |

## Dev Agent Record
*此部分由开发代理在实施期间填写*

### 实施进度
- **开始时间**: 2025-12-09
- **开发代理**: James (dev agent)

### Agent Model Used
d8d-model

### Debug Log References

### Completion Notes List
1. 修改了AreaSelect组件，移除了区县字段的必填标记显示逻辑
2. 验证了薪资管理UI包中AreaSelect组件的使用正确，required参数传递正确
3. 优化了薪资管理表单的地区选择实现：
   - 将创建表单中的AreaSelect替换为AreaSelectForm，实现更好的表单集成
   - 将编辑表单中的静态显示替换为AreaSelectForm，支持编辑时修改地区信息
   - 清理了不再需要的状态同步逻辑，简化了代码
   - 更新了AreaSelectForm组件，添加根元素data-testid支持
4. 验证了后端schema兼容性：districtId字段已经是optional和nullable
5. 添加了AreaSelect组件的单元测试，验证区县字段不为必填
6. 添加了薪资管理表单的集成测试，验证区县字段可为空的表单提交
7. 所有测试通过，无回归问题

### File List
- packages/area-management-ui/src/components/areas/composite/AreaSelect.tsx
- packages/area-management-ui/src/components/areas/composite/AreaSelectForm.tsx
- allin-packages/salary-management-ui/src/components/SalaryManagement.tsx
- allin-packages/salary-module/src/schemas/salary.schema.ts
- allin-packages/salary-module/src/entities/salary-level.entity.ts
- packages/area-management-ui/tests/unit/AreaSelect.test.tsx
- allin-packages/salary-management-ui/tests/integration/salary.integration.test.tsx
- allin-packages/salary-management-ui/tests/integration/salary-area-select.integration.test.tsx

## QA Results
*此部分由QA代理在审查期间填写*