# Story 015.006: 就业状态API空数据处理优化

## Status
Ready for Review

## Story
**作为** 人才小程序用户,
**我想要** 当我没有就业记录时,页面显示友好的"未就业"状态而不是错误提示,
**以便** 我能够清楚了解当前的就业状态,避免产生混淆和焦虑

## Background

**问题描述**:
当前 `GET /api/v1/rencai/employment/status` 接口在用户没有就业记录时返回 **404 状态码**和"用户不存在"消息。这导致前端显示错误提示,但实际上:
1. 用户是存在的（JWT认证已通过）
2. 该残疾人只是**还没有被分配到任何订单**（无就业记录）
3. 这是一种正常的业务状态,不应被视为错误

**当前行为** (talent-employment.routes.ts:196-200):
```typescript
if (!employmentStatus) {
  return c.json({
    code: 404,
    message: '用户不存在'
  }, 404);
}
```

**期望行为**:
- 返回 **200 状态码**
- 数据为空或表示"未就业"状态
- 前端显示友好的"未就业"提示

**影响范围**:
- 史诗015.005: 就业信息API (已完成)
- 史诗017.005: 就业信息功能实现 (已完成)

## Acceptance Criteria

1. **后端API修改**:
   - [ ] 当用户无就业记录时,返回 **200 状态码** 而非 404
   - [ ] 返回数据明确表示"未就业"状态
   - [ ] Schema 支持空数据响应

2. **前端页面优化**:
   - [ ] 就业信息页显示友好的"未就业"提示
   - [ ] 不显示错误Toast
   - [ ] 薪资记录和就业历史正确处理空数据

3. **测试覆盖**:
   - [ ] 后端集成测试验证无就业记录场景返回200
   - [ ] 前端测试验证"未就业"状态正确显示

4. **向后兼容**:
   - [ ] 已有就业记录的用户功能不受影响
   - [ ] 其他就业接口(薪资记录、就业历史)保持一致性

## Tasks / Subtasks

### 任务1: 修改后端就业状态API响应逻辑 (AC: 1)
- [ ] 1.1 修改 `talent-employment.routes.ts` 中的 `/employment/status` 路由
  - 移除无就业记录时的404响应
  - 返回200状态码,数据为null或表示"未就业"的对象
- [ ] 1.2 更新 `EmploymentStatusResponseSchema` 支持空数据
  - 考虑使用可选字段或null值
- [ ] 1.3 确保薪资记录和就业历史接口保持一致性
  - 无记录时返回空数组,而非404

### 任务2: 优化前端就业信息页空状态显示 (AC: 2)
- [ ] 2.1 修改 `CurrentEmploymentStatus` 组件
  - 当 `status` 为 null 或 undefined 时显示"未就业"状态
  - 设计友好的空状态UI (图标 + 提示文字)
- [ ] 2.2 修改 `EmploymentPage` 页面
  - 移除针对404错误的Toast提示
  - 正确处理200状态但数据为空的情况
- [ ] 2.3 修改 `SalaryRecords` 和 `EmploymentHistory` 组件
  - 确保空数组时显示友好提示

### 任务3: 更新测试 (AC: 3)
- [ ] 3.1 更新后端集成测试
  - 修改无就业记录场景的断言,验证返回200而非404
  - 文件: `allin-packages/order-module/tests/integration/talent-employment.integration.test.ts`
- [ ] 3.2 更新前端组件测试
  - 添加"未就业"状态的测试用例
  - 验证空状态UI正确显示
- [ ] 3.3 运行完整测试套件确保无回归

### 任务4: 更新文档 (AC: 4)
- [ ] 4.1 更新故事015.005的Dev Notes,记录API行为变更
- [ ] 4.2 更新故事017.005的Dev Notes,记录前端处理变更

## Dev Notes

### 当前API行为分析

**来源**: 史诗015.005就业信息API

**当前接口**:
- `GET /api/v1/rencai/employment/status` - 当前就业状态
- `GET /api/v1/rencai/employment/salary-records` - 薪资记录
- `GET /api/v1/rencai/employment/history` - 就业历史

**问题代码位置**:
`allin-packages/order-module/src/routes/talent-employment.routes.ts:196-200`

```typescript
// 当前代码 - 返回404
if (!employmentStatus) {
  return c.json({
    code: 404,
    message: '用户不存在'
  }, 404);
}
```

### 建议的修改方案

**方案1: 返回null值** (推荐)
```typescript
// 返回200 + null
if (!employmentStatus) {
  return c.json(null, 200);
}
```
- 前端判断: `status === null` 时显示"未就业"
- 优点: 语义清晰,前端易于判断

**方案2: 返回空对象**
```typescript
// 返回200 + 空对象
return c.json({
  companyName: null,
  positionName: null,
  workStatus: 'not_working'
}, 200);
```
- 前端判断: 根据 `workStatus` 字段显示对应状态
- 优点: 数据结构一致

**推荐使用方案1**,因为:
1. 更简洁明了
2. 前端可以通过null快速判断
3. 与薪资记录(空数组)保持一致的"无数据"语义

### 前端处理建议

**CurrentEmploymentStatus 组件**:
```typescript
interface Props {
  status: CurrentEmploymentStatusType | null
  loading: boolean
}

export function CurrentEmploymentStatus({ status, loading }: Props) {
  if (loading) return <LoadingSpinner />
  if (!status) return <EmptyState />  // 显示"未就业"状态

  return (
    // 正常显示就业信息
  )
}
```

**EmptyState 组件设计**:
- 图标: Heroicons `briefcase` 或 `user`
- 提示文字: "暂无就业信息"
- 说明文字: "您还没有被分配到任何订单"
- 颜色: 灰色主题

### 技术栈要求
- **后端**: Hono 4.8.5, TypeORM 0.3.20
- **前端**: Taro 4.1.4, React 19.1.0
- **测试**: Vitest (后端), Jest (前端)

### 相关文件
**需要修改的文件**:
- `allin-packages/order-module/src/routes/talent-employment.routes.ts` - 后端路由
- `mini-ui-packages/rencai-employment-ui/src/components/CurrentEmploymentStatus.tsx` - 前端组件
- `mini-ui-packages/rencai-employment-ui/src/pages/EmploymentPage/EmploymentPage.tsx` - 前端页面
- `allin-packages/order-module/tests/integration/talent-employment.integration.test.ts` - 后端测试
- `mini-ui-packages/rencai-employment-ui/tests/unit/components/CurrentEmploymentStatus.test.tsx` - 前端测试

### 参考实现
- **参考**: 故事015.005中薪资记录接口的处理方式
  - 薪资记录无数据时返回 `data: []`
  - 就业状态应采用类似逻辑,返回null或空对象

## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-28 | 1.0 | 初始故事创建 | James (Claude Code) |

## Dev Agent Record
*此部分由开发代理在实施过程中填写*

### Agent Model Used
claude-sonnet

### Debug Log References
无重大调试问题

### Completion Notes List
- 后端API修改: `/employment/status` 路由在无就业记录时返回 200 + null 而非 404
- Schema更新: 添加 `EmploymentStatusNullableSchema` 支持null响应
- 前端组件: 已正确处理null状态,显示友好的"未就业"UI
- 测试通过: 更新集成测试验证200状态码和null响应
- API语义一致性: 就业状态(null)、薪资记录([])、就业历史([]) 保持统一的"无数据"语义

### Known Issues
无

### File List
**修改的文件**:
- `allin-packages/order-module/src/schemas/talent-employment.schema.ts` - 添加 EmploymentStatusNullableSchema
- `allin-packages/order-module/src/routes/talent-employment.routes.ts` - 修改就业状态路由返回200+null
- `allin-packages/order-module/tests/integration/talent-employment.integration.test.ts` - 更新测试用例
- `mini-ui-packages/rencai-employment-ui/src/components/CurrentEmploymentStatus.tsx` - 改进空状态UI
- `mini-ui-packages/rencai-employment-ui/src/components/SalaryRecords.tsx` - 改进空状态UI
- `mini-ui-packages/rencai-employment-ui/src/components/EmploymentHistory.tsx` - 改进空状态UI
- `mini-ui-packages/rencai-employment-ui/src/pages/EmploymentPage/EmploymentPage.tsx` - 添加null处理注释

## QA Results
*此部分由QA代理在审查完成后填写*
