# n05-salary-calc 实施任务 ## Delivery / Proof Map | 交付批次 | 交付结果 | 依赖 | 证明 | |---|---|---|---| | 1 数据基础 | 两张表、实体、Repository、全量城市种子可迁移 | 无 | 迁移与种子集成测试 | | 2 查询与计算 | 城市政策接口和精确计算引擎可用 | 1 | Service/Controller 测试与金额边界测试 | | 3 历史与安全 | 计算落库、幂等、历史 CRUD、权限和注销清理闭环 | 2 | 持久化、MockMvc、E2E、账号注销测试 | | 4 发布证明 | OpenAPI、联调文档、全量回归和 MySQL 黑盒验收通过 | 3 | Maven、OpenAPI 校验、MySQL/Docker 验收记录 | ## Tasks - [ ] 1 新增 V40 表结构和薪资领域持久化基础**:修改 `mydreamjob-server/src/main/resources/db/migration/V40__salary_calculator_schema.sql`,新增城市政策与历史表、`data_level` 精度字段、索引和唯一约束;在 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 新增实体和 Repository。完成后 H2/MySQL 可创建两张表,并能按城市编码和用户历史分页查询。证明:`cd mydreamjob-server; mvn -Dtest=SalaryMigrationTest,SalaryRepositoryIntegrationTest test`。依赖:无。 - [ ] 2 新增 V41 全量城市政策种子和完整性校验**:修改 `mydreamjob-server/src/main/resources/db/migration/V41__salary_city_policy_seed.sql`,按采集截止日官方行政区划清单写入大陆目标城市政策;在 `mydreamjob-server/src/test/java/com/mydreamjob/salarycalculator/` 新增种子测试。完成后目标城市全量覆盖,编码唯一,字段、比例、上下限、日期和版本均合法。证明:`cd mydreamjob-server; mvn -Dtest=SalaryCityPolicySeedTest,SalaryMigrationTest test`。依赖:1。 - [ ] 3 实现城市政策查询接口**:在 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 新增城市查询 Service、Controller 和 DTO;修改 `SecurityConfig.java` 明确 `/salary-calculator/**` 认证入口。完成后 `GET /salary-calculator/cities` 返回全部启用城市摘要,`GET /salary-calculator/cities/{cityCode}` 返回完整默认参数,并仅允许 STUDENT。证明:`cd mydreamjob-server; mvn -Dtest=SalaryCityPolicyServiceTest,SalaryCityPolicyControllerTest test`。依赖:1,2。 - [ ] 4 实现 BigDecimal 薪资计算引擎**:在 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 新增计算器、税率表、输入/结果 DTO 和校验器。完成后基数截断、覆盖优先、个人缴费、大病费用、累计月份、专项附加扣除、累计预扣、税额下限和两位小数结果均有精确单元测试。证明:`cd mydreamjob-server; mvn -Dtest=SalaryCalculationEngineTest test`。依赖:1。 - [ ] 5 实现计算并保存接口及政策版本校验**:在 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 新增计算 Service、Controller、幂等指纹和事务逻辑;在 `ErrorCode.java` 新增 `9801–9805`。完成后合法请求返回完整结果和历史 ID,版本不匹配返回 `409/9805`,同键重放返回原历史,同键不同请求返回 `409/9804`。证明:`cd mydreamjob-server; mvn -Dtest=SalaryCalculationServiceTest,SalaryCalculationControllerTest,SalaryPolicyVersionIntegrationTest,SalaryIdempotencyIntegrationTest test`。依赖:2,3,4。 - [ ] 6 实现历史列表、详情和物理删除**:在 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 新增历史 Service、Controller 和响应 DTO。完成后本人历史上限分页、摘要列表、完整详情、物理删除和跨用户 404 隔离均可验证,城市停用不影响旧历史。证明:`cd mydreamjob-server; mvn -Dtest=SalaryHistoryServiceTest,SalaryHistoryControllerTest,SalaryHistoryPrivacyTest test`。依赖:5。 - [ ] 7 接入权限、日志和账号注销清理**:修改 `mydreamjob-server/src/main/java/com/mydreamjob/salarycalculator/` 和 `mydreamjob-server/src/main/java/com/mydreamjob/deletion/AccountDeletionCompletionWorker.java`,复用 STUDENT 角色检查、注销守卫和物理清理。完成后非 STUDENT 被拒绝,PENDING 写操作被现有守卫阻止,COMPLETED 时历史物理删除且日志不含金额。证明:`cd mydreamjob-server; mvn -Dtest=SalaryAuthorizationIntegrationTest,SalaryAccountDeletionIntegrationTest,SalaryLoggingPrivacyTest test`。依赖:3,5,6。 - [ ] 8 完成模块测试与 OpenAPI/联调文档**:在 `mydreamjob-server/src/test/java/com/mydreamjob/salarycalculator/` 补齐迁移、金额、权限、幂等、并发、历史快照、删除和 E2E 测试;修改 `docs/openapi-rc.json`、`docs/salary-calculator-api.md`、`docs/frontend-integration.md`。完成后六个接口、请求响应、错误码、版本冲突、幂等和计算假设与运行时一致。证明:`cd mydreamjob-server; mvn -Dtest=Salary*Test test`;`python docs/verify_openapi.py`。依赖:1,2,3,4,5,6,7。 - [ ] 9 执行全量回归和真实 MySQL/Docker 黑盒验收并更新路线图**:修改 `docs/backend-development-roadmap.md`、`README.md`;在真实 MySQL 环境执行 Flyway、六个接口和账号注销清理验收。完成后全量构建通过,路线图状态更新为已实现/待验收,真实数据库行为与 H2 一致。证明:`cd mydreamjob-server; mvn clean verify`;MySQL/Docker 黑盒脚本与验收记录。依赖:8。 ## Requirement-to-Task Coverage | Spec Requirement | Covered By | |---|---| | 仅已登录 STUDENT 可访问薪资计算模块 | 3,5,6,7 | | 查询当前启用的城市政策目录 | 2,3 | | 城市配置以地级行政区和省直辖县级市为最小单元 | 2 | | 校验城市政策版本和元数据 | 2,5 | | 用户覆盖参数优先于城市默认值 | 4,5 | | 计算个人五险一金和大病固定费 | 4,5 | | 使用累计月份和专项附加扣除计算应纳税所得额 | 4,5 | | 按居民个人综合所得累计预扣法计算个税 | 4,5 | | 输出到手工资和完整计算拆解 | 4,5,6 | | 校验工资输入并限制金额精度 | 4,5 | | 返回稳定的城市和历史错误语义 | 5,6,7 | | 成功计算自动保存历史 | 5 | | 历史保存完整且可重建的快照 | 1,5,6 | | 计算保存使用幂等键防重 | 5 | | 同一幂等键并发只能生成一条历史 | 5 | | 历史列表和详情仅返回本人数据 | 6 | | 历史不可编辑且可以物理删除单条 | 1,6 | | 历史列表采用统一分页且不提供额外筛选 | 6 | | 历史数据按用户长期保留 | 6 | | 历史不进入审计日志或个人数据导出 | 7,8 | | 账号注销清理薪资历史 | 7 | | 数据库迁移保证城市政策和历史完整性 | 1,2,8 | ## Completion Gate - `V41` 目标城市全量覆盖、字段合法且采集截止日基线明确;不得以示例城市或缺失城市代替正式发布。 - 六个接口、计算边界、政策版本冲突、幂等并发、用户隔离、物理删除和账号注销清理全部有自动化证据。 - `mvn -Dtest=Salary*Test test`、`mvn clean verify`、`python docs/verify_openapi.py` 和真实 MySQL/Docker 黑盒验收通过后才能进入 release-archivist。