# 故事 012.001：数据库架构扩展

## 状态
草稿

## 故事
**作为**系统开发人员，
**我希望**扩展数据库架构以支持用人方小程序功能，
**以便**后续的API实现有完整的数据支持和准确的年龄统计。

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

1. [ ] `disabled_person`表成功添加`birth_date`字段，现有记录该字段值为NULL
2. [ ] `order_person_asset`表的`asset_type`枚举扩展完成，新增视频类型枚举值
3. [ ] `users2`表成功添加`company_id`字段，现有admin用户的该字段值为NULL
4. [ ] TypeORM实体定义更新完成
5. [ ] 现有业务功能不受影响，测试通过

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

- [ ] 任务1：向`disabled_person`表添加可为空的`birth_date`字段（AC：1）
  - [ ] 修改`allin-packages/disability-module/src/entities/disabled-person.entity.ts`以添加`birthDate`字段
  - [ ] 在disability-module中更新对应的schema验证
- [ ] 任务2：扩展`order_person_asset`表中的`asset_type`枚举（AC：2）
  - [ ] 更新`allin-packages/order-module/src/schemas/order.schema.ts`中的`AssetType`枚举
  - [ ] 添加新的视频类型：`salary_video`、`tax_video`、`checkin_video`、`work_video`
  - [ ] 确保向后兼容现有的枚举值
  - [ ] 更新`order-person-asset.entity.ts`中的实体验证
- [ ] 任务3：向`users2`表添加可为空的`company_id`字段（AC：3）
  - [ ] 修改`packages/core-module/user-module/src/entities/user.entity.ts`以添加`companyId`字段
  - [ ] 添加`@ManyToOne`关联到`Company`实体（`allin-packages/company-module/src/entities/company.entity.ts`）
  - [ ] 添加`companyId`字段，外键引用`employer_company.company_id`
- [ ] 任务4：更新TypeORM实体定义（AC：4）
  - [ ] 更新实体定义以反映新字段和枚举值
  - [ ] 验证所有模块中的schema一致性
- [ ] 任务5：验证和测试（AC：5）
  - [ ] 运行现有测试以确保没有回归
  - [ ] 为新字段和枚举值添加单元测试
  - [ ] 测试与现有数据的向后兼容性
  - [ ] 验证所有现有业务功能正常工作

## 开发笔记
仅填充从docs文件夹中的实际工件提取的相关信息，与此故事相关：

### 先前故事洞察
史诗012中无先前故事（这是第一个故事）。

### 数据模型
基于现有实体定义：

**DisabledPerson实体**（allin-packages/disability-module/src/entities/disabled-person.entity.ts）：
- 主键：`id`（映射到`person_id`列）[来源：architecture/backend-module-package-standards.md#实体设计规范]
- 字段命名约定：数据库下划线 → TypeScript驼峰命名 [来源：architecture/backend-module-package-standards.md#字段命名转换]
- 当前字段包括：`name`、`gender`、`idCard`、`disabilityId`、`disabilityType`、`disabilityLevel`、`phone`、`jobStatus`等
- 缺少`birth_date`字段（DATE类型）用于准确年龄计算
- 新字段应为可为空：`birthDate?: Date` [来源：docs/prd/epic-012-api-supplement-for-employer-mini-program.md#故事012-01]
- **注意**：`birth_date`字段应为DATE类型，用于存储出生日期而非时间戳

**OrderPersonAsset实体**（allin-packages/order-module/src/entities/order-person-asset.entity.ts）：
- 主键：`id`（映射到`op_id`列）
- `assetType`字段使用`AssetType`枚举（varchar(50)）
- 当前枚举值：`tax`（税务）、`salary`（薪资）、`job_result`（工作成果）、`contract_sign`（合同签署）、`disability_cert`（残疾证明）、`other`（其他）[来源：allin-packages/order-module/src/schemas/order.schema.ts]
- 需要扩展的视频类型：`salary_video`（工资视频）、`tax_video`（个税视频）、`checkin_video`（打卡视频）、`work_video`（工作视频）
- 枚举值应为小写字符串加下划线 [来源：architecture/backend-module-package-standards.md#枚举值一致性]
- **枚举值对比**：
  - 现有：`tax`, `salary`, `job_result`, `contract_sign`, `disability_cert`, `other`
  - 新增：`salary_video`, `tax_video`, `checkin_video`, `work_video`
  - 全部：`tax`, `salary`, `job_result`, `contract_sign`, `disability_cert`, `other`, `salary_video`, `tax_video`, `checkin_video`, `work_video`

**用户实体**（`packages/core-module/user-module/src/entities/user.entity.ts`）：
- 对应数据库表：`users2`（@Entity({ name: 'users2' })）
- 当前字段包括：`username`、`password`、`phone`、`email`、`nickname`、`name`、`avatarFileId`、`openid`、`unionid`、`registrationSource`、`roles`关联等
- 需要添加`company_id`字段，外键引用`employer_company.company_id`
- 字段应为可为空（现有admin用户为NULL）[来源：docs/prd/epic-012-api-supplement-for-employer-mini-program.md#故事012-01]
- **注意**：实体类名为`UserEntity`，需要添加`companyId`字段和对应的`@ManyToOne`关联到`Company`实体（employer_company表）

**Company实体**（`allin-packages/company-module/src/entities/company.entity.ts`）：
- 对应数据库表：`employer_company`（@Entity('employer_company')）
- 主键：`id`（映射到`company_id`列）
- 用于外键关联的字段是`company_id`列

### API规范
不适用于此仅schema的故事。后续故事将使用这些schema变更实现API。

### 组件规范
不适用（后端schema故事）。

### 文件位置
基于项目结构 [来源：architecture/source-tree.md]：
- `allin-packages/disability-module/src/entities/disabled-person.entity.ts`
- `allin-packages/order-module/src/entities/order-person-asset.entity.ts`
- `allin-packages/order-module/src/schemas/order.schema.ts`
- `packages/core-module/user-module/src/entities/user.entity.ts`（users2表）
- `allin-packages/company-module/src/entities/company.entity.ts`（employer_company表）
- 注：数据库迁移脚本将在上线前统一生成，开发阶段通过TypeORM自动同步

### 技术约束
- **向后兼容性**：所有新字段必须可为空，现有数据不受影响 [来源：docs/prd/epic-012-api-supplement-for-employer-mini-program.md#兼容性要求]
- **数据库**：PostgreSQL 17，TypeORM 0.3.25 [来源：architecture/tech-stack.md]
- **枚举扩展**：必须保留现有枚举值，添加新值 [来源：docs/prd/epic-012-api-supplement-for-employer-mini-program.md#风险缓解]

### 项目结构说明
- Monorepo结构，`allin-packages/`用于业务模块 [来源：architecture/source-tree.md]
- 每个模块遵循后端模块包标准 [来源：architecture/backend-module-package-standards.md]
- 实体命名：`disabled-person.entity.ts`（kebab-case）[来源：architecture/source-tree.md#集成指南]
- 字段映射：数据库`birth_date` → TypeScript`birthDate` [来源：architecture/backend-module-package-standards.md#字段命名转换]

### 测试
列出开发者需要遵循的相关测试标准：

#### 测试文件位置
- 单元测试：`allin-packages/{模块名称}/tests/unit/**/*.test.ts` [来源：architecture/testing-strategy.md#单元测试]
- 集成测试：`allin-packages/{模块名称}/tests/integration/**/*.test.ts` [来源：architecture/testing-strategy.md#集成测试]

#### 测试标准
- 测试框架：Vitest [来源：architecture/testing-strategy.md#单元测试]
- 数据库测试：使用测试数据库和事务回滚 [来源：architecture/testing-strategy.md#数据库测试策略]
- 覆盖率要求：单元测试 ≥ 80%，集成测试 ≥ 60% [来源：architecture/testing-strategy.md#测试覆盖率标准]

#### 测试框架和模式
- **单元测试**：测试单个实体和schema
- **集成测试**：测试数据库schema变更
- **向后兼容性测试**：验证现有数据和查询正常工作
- **枚举验证测试**：测试新枚举值是否被接受

#### 此故事的特定测试要求
1. **Schema验证测试**：验证新字段是否正确可为空
2. **枚举扩展测试**：验证新枚举值适用于现有代码
3. **回归测试**：运行现有模块测试以确保没有破坏
4. **外键测试**：验证`company_id`外键关系

## 变更日志
跟踪对此故事文档所做的更改

| 日期 | 版本 | 描述 | 作者 |
|------|------|------|------|
| 2025-12-13 | 1.0 | 初始故事创建 | Bob（Scrum Master） |
| 2025-12-13 | 1.1 | 转换为中文，应用检查清单改进建议 | Bob（Scrum Master） |
| 2025-12-13 | 1.2 | 更新用户实体和Company实体位置信息 | Bob（Scrum Master） |
| 2025-12-13 | 1.3 | 移除数据库迁移任务，调整为上线前统一生成迁移脚本 | John（产品经理） |

## 开发代理记录
此部分由开发代理在实施过程中填充

### 使用的代理模型
{{agent_model_name_version}}

### 调试日志引用
引用在开发过程中生成的任何调试日志或跟踪

### 完成笔记列表
关于任务完成和遇到的任何问题的笔记

### 文件列表
列出在故事实施过程中创建、修改或受影响的所有文件

## QA结果
来自QA代理对已完成故事实施的QA审查结果