12 KiB
12 KiB
| 1 | ID | Title | Description | Acceptance | Test_Method | Tools | Dev_Status | Review1_Status | Regression_Status | Files | Dependencies | Notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | A1 | R47 执行合同与范围冻结 | 创建 R47 Issue CSV,冻结范围为薪资模板、员工薪资档案、工资条生成与发放、员工查看、薪资统计与导出、/payroll 管理页;锁定薪资路由独立于 employees.js,薪资统计仅对 system.users 返回。 | issues/2026-03-29_r47-payroll.csv 列完整、依赖清晰、测试方法可复现;范围仅覆盖本轮薪资管理核心流程。 | 对照 AGENTS.md 与 issues/README.md 检查列完整、Dependencies 为 JSON 数组字符串、Test_Method 含命令与业务流程步骤;确认范围不包含外部薪酬系统、银行打款、审批流、个税规则引擎或消息通知。 | manual | DONE | DONE | DONE | issues/2026-03-29_r47-payroll.csv | [] | QA 2026-03-29:Issue CSV 已创建并按批准方案冻结范围,依赖与测试口径已落地。 |
| 3 | A2 | R47 薪资模板与员工薪资档案后端 | 新增 SalaryItem、EmployeeSalary 模型与 payroll 路由基础能力;实现薪资模板管理与员工薪资快照档案 API,档案以 effectiveDate 为整套快照保存,历史保留不删除。 | system.users 可创建/编辑/停用薪资模板,可为员工保存指定 effectiveDate 的整套薪资快照;同一 effectiveDate 的快照重复保存时在事务内整套替换;非 system.users 访问或修改薪资模板/薪资档案返回 403。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/payroll.js && node --check src/app.js && npm test -- tests/unit/routes/payroll.items.test.js tests/unit/routes/payroll.salary-profile.test.js。业务:1) 管理员创建 earning/deduction 两类薪资模板成功并可停用;2) 为员工保存一套含多条薪资项的 effectiveDate 快照成功;3) 同一 effectiveDate 再次保存会替换该日快照而不会删除历史日期快照;4) 按员工查询薪资快照历史返回正确;5) 普通员工和 report.dashboard.view 访问薪资模板/薪资档案均返回 403。 | manual | DONE | DONE | DONE | server/prisma/schema.prisma|server/prisma/migrations|server/src/routes/payroll.js|server/src/app.js|server/tests/unit/routes/payroll.items.test.js|server/tests/unit/routes/payroll.salary-profile.test.js | ["A1"] | 回滚:先清理 payslip_items / payslips / employee_salaries / salary_items 数据,再回滚 Prisma migration 与 payroll route 注册。本轮不自动 seed 默认薪资模板,列表中的基础工资/津贴/奖金/扣除由管理员通过 UI/API 建立。QA 2026-03-29:Prisma validate、node --check src/routes/payroll.js、vitest payroll.items/payroll.salary-profile 通过,system.users 独占模板与快照权限。 |
| 4 | A3 | R47 工资条生成、调整与发放后端 | 新增 Payslip、PayslipItem 模型与工资条 API;实现按月批量生成 draft、逐人调整 draft、整月发放 issued,以及员工/管理员工资条查询。 | 管理员可按 YYYY-MM 为 active 员工批量生成工资条;任一员工缺少目标月生效薪资快照或目标月已存在工资条时整批失败并回滚;draft 可编辑明细且服务端重算应发/应扣/实发;issued 后冻结且员工本人仅能看到 issued。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/payroll.js && npm test -- tests/unit/routes/payroll.payslips.test.js。业务:1) 管理员先创建薪资模板和员工薪资快照,再按指定月份批量生成工资条成功;2) draft 明细可修改绩效奖金/缺勤扣款,gross/deduction/net 由服务端重算;3) 目标月已有工资条时再次生成返回冲突;4) active 员工缺少生效薪资快照时整批生成失败且不落库;5) 发放后状态变为 issued,员工本人查询只能看到 issued,管理员可看到该员工全部月份工资条;6) issued 工资条再次修改返回 409。 | manual | DONE | DONE | DONE | server/prisma/schema.prisma|server/prisma/migrations|server/src/routes/payroll.js|server/tests/unit/routes/payroll.payslips.test.js | ["A2"] | 回滚:先清理 payslip_items / payslips 数据,再回滚 Prisma migration 与工资条相关代码。pay_month 统一存为目标月第一天;生成口径按目标月月末生效的最新薪资快照,不做月内比例拆分。QA 2026-03-29:vitest payroll.payslips.test.js 通过;已复核生成与发放均包裹事务、issued 后冻结、员工本人仅能看到 issued。 |
| 5 | A4 | R47 薪资导出与统计后端 | 在 exports.js 增加指定月份工资条导出,在 employeeStats 中增加 salarySummary;薪资统计仅对 system.users 返回,其他角色拿到 null。 | system.users 可导出指定月份工资条 CSV/XLSX,导出写审计日志且列包含工号、姓名、部门、各薪资项、应发、应扣、实发;/api/employees/stats 对 system.users 返回 currentMonth/previousMonth 薪资汇总,对 report.dashboard.view 不返回薪资数据。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/payroll.js && node --check src/routes/exports.js && node --check src/routes/employees.js && node --check src/services/employeeStats.js && npm test -- tests/unit/routes/payroll.exports.test.js tests/unit/routes/employees.stats.test.js。业务:1) 在已有指定月份工资条后导出 CSV/XLSX 成功,列顺序正确且金额与工资条一致;2) 导出审计日志写入 action/月份/匹配数量;3) system.users 请求员工统计可看到当月/上月薪资总支出与人均薪资;4) report.dashboard.view 请求员工统计时 salarySummary 为 null,且无法通过任何 payroll/export 接口获取薪资数据。 | manual | DONE | DONE | DONE | server/src/routes/exports.js|server/src/routes/employees.js|server/src/services/employeeStats.js|server/src/routes/payroll.js|server/tests/unit/routes/payroll.exports.test.js|server/tests/unit/routes/employees.stats.test.js | ["A2","A3"] | 回滚:删除 payslip export 路由与 salarySummary 字段,恢复 employeeStats 原结构。薪资统计仅统计 issued 工资条的 net_amount。QA 2026-03-29:node --check exports/employees/employeeStats 与 vitest payroll.exports/employees.stats 通过;salarySummary 仅对 system.users 返回,导出链路含审计日志。 |
| 6 | A5 | R47 薪资管理页与前端 API | 新增 payroll 前端 API、/payroll 页面、PeoplePage 入口和导出接入;管理员可管理薪资模板、按月生成/调整/发放工资条并导出。 | system.users 可从 PeoplePage 进入 /payroll;页面可维护薪资模板、选择月份生成工资条、编辑 draft 明细、发放当月工资条并导出 CSV/XLSX;非 system.users 直接访问 /payroll 被拦截。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build。业务:1) 管理员从 PeoplePage 进入 /payroll 成功;2) 在 /payroll 创建/编辑/停用薪资模板成功;3) 选择月份生成工资条后可看到员工列表与各项金额;4) 调整一名员工 draft 金额后 totals 刷新;5) 发放后该月工资条状态变为 issued;6) 导出指定月份 CSV/XLSX 成功;7) 非管理员访问 /payroll 进入 403。 | manual | DONE | DONE | DONE | client/src/api/payroll.ts|client/src/api/exports.ts|client/src/pages/PayrollPage.tsx|client/src/pages/PeoplePage.tsx|client/src/router/index.tsx|client/src/router/lazy/index.ts|client/src/router/lazy/PayrollPage.ts | ["A2","A3","A4"] | /payroll 为独立路由,不加入全局主导航;入口放 PeoplePage 页头。QA 2026-03-29:client typecheck/build 通过;/payroll 路由守卫、PeoplePage 入口、模板管理、月度生成/发放/导出接线静态复核完成。 |
| 7 | A6 | R47 档案页薪资标签与员工自助查看 | 在 EmployeeProfilePage 增加薪资标签;管理员查看/编辑员工薪资快照并查看全部工资条,员工本人仅查看自己已发放工资条,其他角色不可见。 | 档案页支持 ?tab=salary 直达;system.users 可维护该员工薪资档案并查看全部工资条;员工本人只能查看自己的 issued 工资条列表与明细展开;report.dashboard.view 和其他非本人角色不显示薪资标签,也没有降级薪资视图。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build。业务:1) 管理员打开任意员工档案可见薪资标签、薪资快照历史和全部工资条;2) 管理员保存新的 effectiveDate 薪资快照后列表刷新;3) 员工本人打开 /people/:me?tab=salary 只能看到已发放工资条;4) draft 工资条对员工本人不可见;5) report.dashboard.view 打开员工档案不显示薪资标签。 | manual | DONE | DONE | DONE | client/src/pages/EmployeeProfilePage.tsx|client/src/api/payroll.ts | ["A2","A3","A5"] | 薪资数据不并入现有 employee profile 响应,前端通过 payroll 专用接口加载,避免在现有档案权限模型下泄露。QA 2026-03-29:EmployeeProfilePage salary tab 与 EmployeeSalaryPanel 接入完成;本人仅看 issued、管理员可管理快照与全部工资条的权限分支静态复核通过。 |
| 8 | A7 | R47 统计页薪资卡片前端扩展 | 扩展员工统计前端类型与 PeopleStatsPage,在 system.users 场景展示当月/上月薪资总支出与人均薪资;其他角色维持无薪资卡片。 | PeopleStatsPage 在 system.users 下显示 4 张薪资卡片(当月总支出、人均薪资、上月总支出、人均薪资);report.dashboard.view 仍可访问员工统计页,但不显示任何薪资数据;原有统计卡片和列表不回归。 | 命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build。业务:1) system.users 进入 /people/stats 可看到薪资汇总卡片;2) report.dashboard.view 进入同页看不到薪资卡片但原有人员统计仍正常;3) 无已发放工资条时显示薪资空态,不影响原有统计。 | manual | DONE | DONE | DONE | client/src/api/employees.ts|client/src/pages/PeopleStatsPage.tsx | ["A4"] | 薪资卡片仅依赖 salarySummary 是否为非空,不新增新的统计页或图表库。QA 2026-03-29:PeopleStatsPage salarySummary 条件渲染完成;client typecheck/build 通过,非 system.users 依赖 salarySummary=null 不渲染薪资卡片。 |
| 9 | A8 | Reviewer 与 QA 收口 | 按 AGENTS 编排启用 reviewer 与 qa,重点审查 Prisma 迁移、薪资高敏权限隔离、批量生成/发放事务安全、issued 冻结与导出审计,并回填 CSV 状态。 | A2-A7 的 Review1_Status 与 Regression_Status 均有证据地回填;reviewer 风险项关闭;R43-R46 员工模块能力不回归。 | Reviewer:审查 4 个新模型迁移回滚路径、system.users/self 权限边界、salarySummary 对 report.dashboard.view 的隔离、工资条生成/发放事务安全、issued 后不可修改、导出审计日志是否完整。QA:运行 backend post-check、frontend post-check,并手工回归 5 条主线:薪资模板与员工薪资快照、工资条生成/编辑/发放、员工本人查看工资条、指定月份导出、统计页薪资卡片权限;同时确认 R43 合同/培训证书、R44 人员筛选批量统计、R46 绩效模块与 EmployeeProfilePage 既有标签不回归。 | manual | DONE | DONE | DONE | issues/2026-03-29_r47-payroll.csv | ["A2","A3","A4","A5","A6","A7"] | reviewer 必启用:本轮涉及 4 个新模型、高敏薪资数据、批量生成事务和导出链路。Review/QA 2026-03-29:Prisma validate、server node --check、vitest 5 个 payroll/stats 用例、client typecheck/build 全通过;已复核 payroll.js 事务生成/发放、self-only issued 可见、salarySummary 权限隔离与 exports 审计链路。 |