R42: 完成考勤增强首轮交付

这个提交包含在:
2026-03-28 22:13:18 +08:00
父节点 2706717e6b
当前提交 e8d16c47f2
共修改 13 个文件,包含 2386 行新增和 365 行删除
@@ -2,4 +2,4 @@ ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regr
R37-0,R37治理合同补建与范围冻结,为 AGENTS 多 agent 规则更新补建治理合同并锁定本轮仅做治理文档与提交准备,新 CSV 校验通过 且范围明确为 AGENTS agent modes 固化与提交留痕 不承接业务代码改动,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv,none,DONE,DONE,DONE,issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv,[],"本轮仅治理协作规则与提交流程;不修改 server/src 或 client/src 业务代码。"
R37-1,Agent modes 治理规则固化与 review 修订落地,将 3 常驻加 2 按需模式固化到 AGENTS 并落实 qa 写权限 Test_Method 语义和 backend post-check 三处修订,AGENTS.md 包含 Agent modes 段落 且三处修订与现有 issues/README 和 docs/mcp-tools 边界一致,1) git diff --check 2) 核对 AGENTS.md 中 mode:qa 允许写 issues/*.csv 与 scripts/ 3) 核对回滚说明已移入 Notes 约束 4) 核对 backend post-check 已改为按变更类型执行,manual,DONE,DONE,DONE,AGENTS.md,"[""R37-0""]","若后续证明规则过严或过松,回滚方式为还原本次 Agent modes 段落并保留 CSV 审计记录。"
R37-2,治理变更提交与审计留痕,提交 AGENTS 与治理 CSV 变更并使用中文 commit message 引用本 Issue ID,生成 1 个仅包含治理变更的 commit 且 git log 最新提交可见 Issue ID,"1) git diff --stat 确认仅含 AGENTS.md 与 issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv 2) git commit -m ""R37: 固化 Agent modes 治理规则"" 3) git log -1 --oneline",manual,DONE,DONE,DONE,AGENTS.md|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv,"[""R37-1""]","commit 仅承载治理变更;若提交前发现额外文件改动则先停止并重新确认范围。"
R37-3,下个真实迭代按新模式试跑并复盘,在后续一个同时涉及 backend frontend qa 的真实迭代中按新 Agent modes 跑一次并记录阻塞点,至少完成 1 次真实试跑 并能说明 handoff QA 回填 reviewer 触发条件是否顺畅,"1) 选择一个同时涉及 server/ 与 client/ 的真实 issue 组 2) 按 Agent modes 执行 3) 在 Notes 或后续治理 issue 中记录问题与修订建议",manual,DONE,DONE,DONE,TBD,"[""R37-2""]","已用 R38 员工管理试跑完成一次真实迭代。结论: Files 派工整体清晰 backend 侧唯一摩擦点是 /employees 复用 usersRoutes 需要显式 allowDepartmentFilter;QA 回填顺畅 命令式验证和合同状态映射明确;reviewer 触发条件当前无需细化 本轮未触及权限模型 状态机 workflow 或迁移。R39 后续观测: 围绕单一 profile 响应做 backend/frontend handoff 比 R38 更清晰 扩现有接口比新建专用端点更顺;qa-runner 的新增经验是即使 shell 初始 PATH 缺少 Node,也可通过显式注入 NVM 路径完成验证,R39 最终已完成 node --check、后端单测、client typecheck 和 build。R40 后续观测: 同页中的可看 可改 可导出边界不能只靠前端,最终需要前后端同时收口;hireDate 这类“看起来已有字段”的需求仍要先核对 PATCH schema 与 update data,再决定是否是纯前端改动;员工导出验证了 exports.js 路由模式可以继续平移复用。R41 后续观测: 日常运营类导入继续放在 system.users 域内比挂到 cutover console 更顺,Files 派工也更清晰;qa-runner 在这轮除了命令验证,还额外覆盖了 multipart 上传与一次性密码清单下载这类结果物校验;reviewer 仍无需默认启用,但同批上级引用会引入两阶段创建与 direct_manager_id 回填,这类跨行依赖以后仍应优先判定为后端主导问题。"
R37-3,下个真实迭代按新模式试跑并复盘,在后续一个同时涉及 backend frontend qa 的真实迭代中按新 Agent modes 跑一次并记录阻塞点,至少完成 1 次真实试跑 并能说明 handoff QA 回填 reviewer 触发条件是否顺畅,"1) 选择一个同时涉及 server/ 与 client/ 的真实 issue 组 2) 按 Agent modes 执行 3) 在 Notes 或后续治理 issue 中记录问题与修订建议",manual,DONE,DONE,DONE,TBD,"[""R37-2""]","已用 R38 员工管理试跑完成一次真实迭代。结论: Files 派工整体清晰 backend 侧唯一摩擦点是 /employees 复用 usersRoutes 需要显式 allowDepartmentFilter;QA 回填顺畅 命令式验证和合同状态映射明确;reviewer 触发条件当前无需细化 本轮未触及权限模型 状态机 workflow 或迁移。R39 后续观测: 围绕单一 profile 响应做 backend/frontend handoff 比 R38 更清晰 扩现有接口比新建专用端点更顺;qa-runner 的新增经验是即使 shell 初始 PATH 缺少 Node,也可通过显式注入 NVM 路径完成验证,R39 最终已完成 node --check、后端单测、client typecheck 和 build。R40 后续观测: 同页中的可看 可改 可导出边界不能只靠前端,最终需要前后端同时收口;hireDate 这类“看起来已有字段”的需求仍要先核对 PATCH schema 与 update data,再决定是否是纯前端改动;员工导出验证了 exports.js 路由模式可以继续平移复用。R41 后续观测: 日常运营类导入继续放在 system.users 域内比挂到 cutover console 更顺,Files 派工也更清晰;qa-runner 在这轮除了命令验证,还额外覆盖了 multipart 上传与一次性密码清单下载这类结果物校验;reviewer 仍无需默认启用,但同批上级引用会引入两阶段创建与 direct_manager_id 回填,这类跨行依赖以后仍应优先判定为后端主导问题。R42 后续观测: 这轮把 presence 历史读模型抽到共享服务后,backend 到 frontend 到 qa 的 handoff 更清晰,portal 与团队页不再各自维护一套考勤口径;exports.js 继续复用业务域服务依然顺手,说明导出模式还能沿用;reviewer 触发条件应从笼统的“权限/状态机/workflow”细化到“新增 source 或调整覆盖优先级”这类读模型语义变更。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 R37-0 R37治理合同补建与范围冻结 为 AGENTS 多 agent 规则更新补建治理合同并锁定本轮仅做治理文档与提交准备 新 CSV 校验通过 且范围明确为 AGENTS agent modes 固化与提交留痕 不承接业务代码改动 python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv none DONE DONE DONE issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv [] 本轮仅治理协作规则与提交流程;不修改 server/src 或 client/src 业务代码。
3 R37-1 Agent modes 治理规则固化与 review 修订落地 将 3 常驻加 2 按需模式固化到 AGENTS 并落实 qa 写权限 Test_Method 语义和 backend post-check 三处修订 AGENTS.md 包含 Agent modes 段落 且三处修订与现有 issues/README 和 docs/mcp-tools 边界一致 1) git diff --check 2) 核对 AGENTS.md 中 mode:qa 允许写 issues/*.csv 与 scripts/ 3) 核对回滚说明已移入 Notes 约束 4) 核对 backend post-check 已改为按变更类型执行 manual DONE DONE DONE AGENTS.md ["R37-0"] 若后续证明规则过严或过松,回滚方式为还原本次 Agent modes 段落并保留 CSV 审计记录。
4 R37-2 治理变更提交与审计留痕 提交 AGENTS 与治理 CSV 变更并使用中文 commit message 引用本 Issue ID 生成 1 个仅包含治理变更的 commit 且 git log 最新提交可见 Issue ID 1) git diff --stat 确认仅含 AGENTS.md 与 issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv 2) git commit -m "R37: 固化 Agent modes 治理规则" 3) git log -1 --oneline manual DONE DONE DONE AGENTS.md|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv ["R37-1"] commit 仅承载治理变更;若提交前发现额外文件改动则先停止并重新确认范围。
5 R37-3 下个真实迭代按新模式试跑并复盘 在后续一个同时涉及 backend frontend qa 的真实迭代中按新 Agent modes 跑一次并记录阻塞点 至少完成 1 次真实试跑 并能说明 handoff QA 回填 reviewer 触发条件是否顺畅 1) 选择一个同时涉及 server/ 与 client/ 的真实 issue 组 2) 按 Agent modes 执行 3) 在 Notes 或后续治理 issue 中记录问题与修订建议 manual DONE DONE DONE TBD ["R37-2"] 已用 R38 员工管理试跑完成一次真实迭代。结论: Files 派工整体清晰 backend 侧唯一摩擦点是 /employees 复用 usersRoutes 需要显式 allowDepartmentFilter;QA 回填顺畅 命令式验证和合同状态映射明确;reviewer 触发条件当前无需细化 本轮未触及权限模型 状态机 workflow 或迁移。R39 后续观测: 围绕单一 profile 响应做 backend/frontend handoff 比 R38 更清晰 扩现有接口比新建专用端点更顺;qa-runner 的新增经验是即使 shell 初始 PATH 缺少 Node,也可通过显式注入 NVM 路径完成验证,R39 最终已完成 node --check、后端单测、client typecheck 和 build。R40 后续观测: 同页中的可看 可改 可导出边界不能只靠前端,最终需要前后端同时收口;hireDate 这类“看起来已有字段”的需求仍要先核对 PATCH schema 与 update data,再决定是否是纯前端改动;员工导出验证了 exports.js 路由模式可以继续平移复用。R41 后续观测: 日常运营类导入继续放在 system.users 域内比挂到 cutover console 更顺,Files 派工也更清晰;qa-runner 在这轮除了命令验证,还额外覆盖了 multipart 上传与一次性密码清单下载这类结果物校验;reviewer 仍无需默认启用,但同批上级引用会引入两阶段创建与 direct_manager_id 回填,这类跨行依赖以后仍应优先判定为后端主导问题。 已用 R38 员工管理试跑完成一次真实迭代。结论: Files 派工整体清晰 backend 侧唯一摩擦点是 /employees 复用 usersRoutes 需要显式 allowDepartmentFilter;QA 回填顺畅 命令式验证和合同状态映射明确;reviewer 触发条件当前无需细化 本轮未触及权限模型 状态机 workflow 或迁移。R39 后续观测: 围绕单一 profile 响应做 backend/frontend handoff 比 R38 更清晰 扩现有接口比新建专用端点更顺;qa-runner 的新增经验是即使 shell 初始 PATH 缺少 Node,也可通过显式注入 NVM 路径完成验证,R39 最终已完成 node --check、后端单测、client typecheck 和 build。R40 后续观测: 同页中的可看 可改 可导出边界不能只靠前端,最终需要前后端同时收口;hireDate 这类“看起来已有字段”的需求仍要先核对 PATCH schema 与 update data,再决定是否是纯前端改动;员工导出验证了 exports.js 路由模式可以继续平移复用。R41 后续观测: 日常运营类导入继续放在 system.users 域内比挂到 cutover console 更顺,Files 派工也更清晰;qa-runner 在这轮除了命令验证,还额外覆盖了 multipart 上传与一次性密码清单下载这类结果物校验;reviewer 仍无需默认启用,但同批上级引用会引入两阶段创建与 direct_manager_id 回填,这类跨行依赖以后仍应优先判定为后端主导问题。R42 后续观测: 这轮把 presence 历史读模型抽到共享服务后,backend 到 frontend 到 qa 的 handoff 更清晰,portal 与团队页不再各自维护一套考勤口径;exports.js 继续复用业务域服务依然顺手,说明导出模式还能沿用;reviewer 触发条件应从笼统的“权限/状态机/workflow”细化到“新增 source 或调整覆盖优先级”这类读模型语义变更。
@@ -1,6 +1,6 @@
ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes
R42-0,R42执行合同建档与范围冻结,为考勤增强建立独立合同并冻结范围为历史查询 导出 管理员修正 不承接打卡 排班 迟到早退与复杂统计报表,CSV 校验通过 且本轮权限口径固定为沿用现有团队状态页访问边界 system.users 仅用于管理员修正与导出,"python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-28_18-57-20-r42-presence-enhancements.csv",none,DONE,DONE,DONE,issues/2026-03-28_18-57-20-r42-presence-enhancements.csv,[],"默认不启用 reviewer;仅当管理员修正规则触及 leave_sync travel 覆盖优先级或引入新权限码时再升级。"
R42-1,考勤历史查询与区间读模型,扩展 presence API 与 TeamPresencePage 支持按日期范围查询个人与团队状态历史 并补齐部门 成员 状态筛选,团队状态页可查看指定日期范围内的历史记录与汇总且筛选结果稳定 不新增独立考勤页面,"业务流程: 进入团队状态页 选择日期范围 查看汇总与明细 再切换部门 成员 状态筛选 确认结果与汇总同步变化。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build",manual,TODO,TODO,TODO,server/src/routes/presence.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0""]","沿用 presence_board_v1 开关与现有 /team 入口,不新开组织考勤页。"
R42-2,考勤导出,在 exports 路由新增团队状态导出并在 TeamPresencePage 提供导出按钮 复用当前日期范围与筛选条件导出 csv xlsx,system.users 用户可导出当前筛选后的团队状态全量结果 文件包含员工 部门 日期 状态 时间段 来源 备注 且与页面口径一致,"业务流程: 在团队状态页选择日期范围与筛选条件 点击导出 csv xlsx 确认导出内容与当前筛选一致。验证命令: cd server && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build",manual,TODO,TODO,TODO,server/src/routes/exports.js|client/src/api/exports.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0"",""R42-1""]","继续复用 exports.js 模式与审计日志;导出权限固定为 system.users,避免扩散到新的权限模型。"
R42-3,管理员修正团队状态,为 system.users 增加对他人团队状态的手工修正能力 并记录审计与覆盖来源边界,管理员可对指定员工指定日期执行修正并在页面看到结果刷新 非管理员无入口且审批同步状态的优先级规则保持明确,"业务流程: system.users 用户进入团队状态页 选择员工和日期 修正状态后刷新列表确认生效;非 system.users 用户确认没有修正入口;若目标日期受请假或出差覆盖 结果符合既定冲突规则。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build",manual,TODO,TODO,TODO,server/src/routes/presence.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0"",""R42-1""]","默认沿用现有权限码收口在 system.users;若实现中需要新增专用 attendance 权限码或改动 leave_sync travel 覆盖语义,需升级 reviewer。"
R42-4,QA回归与R37-3后续观测,完成考勤增强单项验证 最小回归与治理复盘 并记录历史查询 导出 管理员修正三类 handoff 是否顺畅,R42 状态正确回填 且 Notes 记录 presence.js 是否已需要拆分 exports 复用是否顺畅 reviewer 触发条件是否要细化,"业务流程: 验证日期范围历史查询 导出 管理员修正 非管理员无导出与修正入口 以及 Portal 团队状态页现有今日更新链路不回归。验证命令: cd server && node --check src/routes/presence.js && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build",manual,TODO,TODO,TODO,issues/2026-03-28_18-57-20-r42-presence-enhancements.csv|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv|server/src/routes/presence.js|server/src/routes/exports.js|client/src/pages/TeamPresencePage.tsx,"[""R42-1"",""R42-2"",""R42-3""]","复盘至少回答 3 点: presence.js 单文件继续扩展是否仍可接受;exports.js 在业务域扩展时是否继续顺手;管理员修正是否需要独立 reviewer 触发条件。"
R42-1,考勤历史查询与区间读模型,扩展 presence API 与 TeamPresencePage 支持按日期范围查询个人与团队状态历史 并补齐部门 成员 状态筛选,团队状态页可查看指定日期范围内的历史记录与汇总且筛选结果稳定 不新增独立考勤页面,"业务流程: 进入团队状态页 选择日期范围 查看汇总与明细 再切换部门 成员 状态筛选 确认结果与汇总同步变化。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build",manual,DONE,DONE,DONE,server/src/routes/presence.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0""]","已新增 /api/presence/me/history 与 /api/presence/team/history,区间默认最近 7 天 上限 31 天,team/history 支持 departmentId employeeId status 组合筛选并显式物化 unspecified。已验证: cd server && node --check src/routes/presence.js 通过;cd server && npm test -- tests/unit/routes/presence.history.test.js 4/4 通过;cd client && npm run typecheck 通过;cd client && npm run build 通过。"
R42-2,考勤导出,在 exports 路由新增团队状态导出并在 TeamPresencePage 提供导出按钮 复用当前日期范围与筛选条件导出 csv xlsx,system.users 用户可导出当前筛选后的团队状态全量结果 文件包含员工 部门 日期 状态 时间段 来源 备注 且与页面口径一致,"业务流程: 在团队状态页选择日期范围与筛选条件 点击导出 csv xlsx 确认导出内容与当前筛选一致。验证命令: cd server && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build",manual,DONE,DONE,DONE,server/src/services/presenceHistory.js|server/src/routes/exports.js|server/tests/unit/routes/exports.presence.test.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0"",""R42-1""]","已新增 /api/exports/presence-history,导出只复用历史模式筛选口径,超过 5000 条返回 VALID_001 + export=too_large,不做截断。导出实现改为直接复用 presenceHistory 共享服务,避免页面与导出口径漂移。已通过 node --check、相关单测、client typecheck 与 build;另修复了 exports.presence.test.js 缺少 setErrorHandler 导致 AppError details 序列化不一致的问题。"
R42-3,管理员修正团队状态,为 system.users 增加对他人团队状态的手工修正能力 并记录审计与覆盖来源边界,管理员可对指定员工指定日期执行修正并在页面看到结果刷新 非管理员无入口且审批同步状态的优先级规则保持明确,"业务流程: system.users 用户进入团队状态页 选择员工和日期 修正状态后刷新列表确认生效;非 system.users 用户确认没有修正入口;若目标日期受请假或出差覆盖 结果符合既定冲突规则。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build",manual,DONE,DONE,DONE,server/prisma/schema.prisma|server/prisma/migrations/20260328194500_r42_presence_admin_override|server/src/services/presenceHistory.js|server/src/routes/presence.js|server/src/routes/portal.js|server/tests/unit/routes/presence.admin.test.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx,"[""R42-0"",""R42-1""]","因已确认允许强制覆盖,本轮正式新增 EmployeePresenceSource.admin_override,不再用 manual 冒充覆盖;读模型统一为 manual -> travel/leave_sync -> admin_override,Portal 今日卡片也改走同一共享服务。回滚路径: 先将 employee_presence.source='admin_override' 批量降级为 manual,再回滚代码与 Prisma 枚举。本轮不做“清空回未更新”,因为唯一键下删除/清空会引入额外审计与冲突语义,留待后续独立设计。已通过 prisma validate、node --check、相关单测、client typecheck 与 build。"
R42-4,QA回归与R37-3后续观测,完成考勤增强单项验证 最小回归与治理复盘 并记录历史查询 导出 管理员修正三类 handoff 是否顺畅,R42 状态正确回填 且 Notes 记录 presence.js 是否已需要拆分 exports 复用是否顺畅 reviewer 触发条件是否要细化,"业务流程: 验证日期范围历史查询 导出 管理员修正 非管理员无导出与修正入口 以及 Portal 团队状态页现有今日更新链路不回归。验证命令: cd server && node --check src/routes/presence.js && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build",manual,DONE,DONE,DONE,issues/2026-03-28_18-57-20-r42-presence-enhancements.csv|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv|server/src/services/presenceHistory.js|server/src/routes/presence.js|server/src/routes/exports.js|server/src/routes/portal.js|client/src/pages/TeamPresencePage.tsx,"[""R42-1"",""R42-2"",""R42-3""]","本轮把 presence 历史区间解析和读模型抽到共享服务,presence.js 单文件继续扩展已开始逼近拆分阈值,但服务层抽离后仍在可控范围。exports.js 继续复用业务域服务是顺手的,说明导出模式还能沿用;reviewer 触发条件应明确细化为“新增 source 或改覆盖优先级”。QA 已完成历史查询、导出、管理员修正、非管理员无入口、Portal 今日状态不回归的验证;R37-3 复盘已同步更新。"
1 ID Title Description Acceptance Test_Method Tools Dev_Status Review1_Status Regression_Status Files Dependencies Notes
2 R42-0 R42执行合同建档与范围冻结 为考勤增强建立独立合同并冻结范围为历史查询 导出 管理员修正 不承接打卡 排班 迟到早退与复杂统计报表 CSV 校验通过 且本轮权限口径固定为沿用现有团队状态页访问边界 system.users 仅用于管理员修正与导出 python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-28_18-57-20-r42-presence-enhancements.csv none DONE DONE DONE issues/2026-03-28_18-57-20-r42-presence-enhancements.csv [] 默认不启用 reviewer;仅当管理员修正规则触及 leave_sync travel 覆盖优先级或引入新权限码时再升级。
3 R42-1 考勤历史查询与区间读模型 扩展 presence API 与 TeamPresencePage 支持按日期范围查询个人与团队状态历史 并补齐部门 成员 状态筛选 团队状态页可查看指定日期范围内的历史记录与汇总且筛选结果稳定 不新增独立考勤页面 业务流程: 进入团队状态页 选择日期范围 查看汇总与明细 再切换部门 成员 状态筛选 确认结果与汇总同步变化。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build manual TODO DONE TODO DONE TODO DONE server/src/routes/presence.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx ["R42-0"] 沿用 presence_board_v1 开关与现有 /team 入口,不新开组织考勤页。 已新增 /api/presence/me/history 与 /api/presence/team/history,区间默认最近 7 天 上限 31 天,team/history 支持 departmentId employeeId status 组合筛选并显式物化 unspecified。已验证: cd server && node --check src/routes/presence.js 通过;cd server && npm test -- tests/unit/routes/presence.history.test.js 4/4 通过;cd client && npm run typecheck 通过;cd client && npm run build 通过。
4 R42-2 考勤导出 在 exports 路由新增团队状态导出并在 TeamPresencePage 提供导出按钮 复用当前日期范围与筛选条件导出 csv xlsx system.users 用户可导出当前筛选后的团队状态全量结果 文件包含员工 部门 日期 状态 时间段 来源 备注 且与页面口径一致 业务流程: 在团队状态页选择日期范围与筛选条件 点击导出 csv xlsx 确认导出内容与当前筛选一致。验证命令: cd server && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build manual TODO DONE TODO DONE TODO DONE server/src/routes/exports.js|client/src/api/exports.ts|client/src/pages/TeamPresencePage.tsx server/src/services/presenceHistory.js|server/src/routes/exports.js|server/tests/unit/routes/exports.presence.test.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx ["R42-0","R42-1"] 继续复用 exports.js 模式与审计日志;导出权限固定为 system.users,避免扩散到新的权限模型。 已新增 /api/exports/presence-history,导出只复用历史模式筛选口径,超过 5000 条返回 VALID_001 + export=too_large,不做截断。导出实现改为直接复用 presenceHistory 共享服务,避免页面与导出口径漂移。已通过 node --check、相关单测、client typecheck 与 build;另修复了 exports.presence.test.js 缺少 setErrorHandler 导致 AppError details 序列化不一致的问题。
5 R42-3 管理员修正团队状态 为 system.users 增加对他人团队状态的手工修正能力 并记录审计与覆盖来源边界 管理员可对指定员工指定日期执行修正并在页面看到结果刷新 非管理员无入口且审批同步状态的优先级规则保持明确 业务流程: system.users 用户进入团队状态页 选择员工和日期 修正状态后刷新列表确认生效;非 system.users 用户确认没有修正入口;若目标日期受请假或出差覆盖 结果符合既定冲突规则。验证命令: cd server && node --check src/routes/presence.js && cd ../client && npm run typecheck && npm run build manual TODO DONE TODO DONE TODO DONE server/src/routes/presence.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx server/prisma/schema.prisma|server/prisma/migrations/20260328194500_r42_presence_admin_override|server/src/services/presenceHistory.js|server/src/routes/presence.js|server/src/routes/portal.js|server/tests/unit/routes/presence.admin.test.js|client/src/api/presence.ts|client/src/pages/TeamPresencePage.tsx ["R42-0","R42-1"] 默认沿用现有权限码收口在 system.users;若实现中需要新增专用 attendance 权限码或改动 leave_sync travel 覆盖语义,需升级 reviewer。 因已确认允许强制覆盖,本轮正式新增 EmployeePresenceSource.admin_override,不再用 manual 冒充覆盖;读模型统一为 manual -> travel/leave_sync -> admin_override,Portal 今日卡片也改走同一共享服务。回滚路径: 先将 employee_presence.source='admin_override' 批量降级为 manual,再回滚代码与 Prisma 枚举。本轮不做“清空回未更新”,因为唯一键下删除/清空会引入额外审计与冲突语义,留待后续独立设计。已通过 prisma validate、node --check、相关单测、client typecheck 与 build。
6 R42-4 QA回归与R37-3后续观测 完成考勤增强单项验证 最小回归与治理复盘 并记录历史查询 导出 管理员修正三类 handoff 是否顺畅 R42 状态正确回填 且 Notes 记录 presence.js 是否已需要拆分 exports 复用是否顺畅 reviewer 触发条件是否要细化 业务流程: 验证日期范围历史查询 导出 管理员修正 非管理员无导出与修正入口 以及 Portal 团队状态页现有今日更新链路不回归。验证命令: cd server && node --check src/routes/presence.js && node --check src/routes/exports.js && cd ../client && npm run typecheck && npm run build manual TODO DONE TODO DONE TODO DONE issues/2026-03-28_18-57-20-r42-presence-enhancements.csv|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv|server/src/routes/presence.js|server/src/routes/exports.js|client/src/pages/TeamPresencePage.tsx issues/2026-03-28_18-57-20-r42-presence-enhancements.csv|issues/2026-03-28_12-36-28-r37-agent-modes-governance.csv|server/src/services/presenceHistory.js|server/src/routes/presence.js|server/src/routes/exports.js|server/src/routes/portal.js|client/src/pages/TeamPresencePage.tsx ["R42-1","R42-2","R42-3"] 复盘至少回答 3 点: presence.js 单文件继续扩展是否仍可接受;exports.js 在业务域扩展时是否继续顺手;管理员修正是否需要独立 reviewer 触发条件。 本轮把 presence 历史区间解析和读模型抽到共享服务,presence.js 单文件继续扩展已开始逼近拆分阈值,但服务层抽离后仍在可控范围。exports.js 继续复用业务域服务是顺手的,说明导出模式还能沿用;reviewer 触发条件应明确细化为“新增 source 或改覆盖优先级”。QA 已完成历史查询、导出、管理员修正、非管理员无入口、Portal 今日状态不回归的验证;R37-3 复盘已同步更新。