文件
hyb-oa/issues/2026-03-29_r43-employee-enhancements.csv

10 行
8.2 KiB
CSV

ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes
A1,R43合同建档与范围冻结,创建并冻结员工头像 组织架构页 员工合同管理三项能力的执行合同 且拆分为可独立验收的 A1-A8,Issue CSV 校验通过 且范围仅含头像 组织架构 合同管理 不扩散到附件上传 删除头像 删除合同 与额外权限模型调整,命令:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-29_r43-employee-enhancements.csv;业务流程:检查 CSV 含 A1-A8 全量条目 且 Dependencies Files Notes 均符合仓库规范,manual,DONE,DONE,DONE,issues/2026-03-29_r43-employee-enhancements.csv,[],none
A2,员工头像后端与数据模型,为 Employee 增加 avatar_path 并提供头像上传与读取能力 同时扩展员工列表 档案 团队状态所依赖的后端读模型返回 avatarUrl,本人可上传自己的头像 system.users 可为任意员工上传 仅允许 jpg/png/webp 且 2MB 内 服务端统一缩放并保存为 webp 列表 档案 团队页接口均返回 avatarUrl 公开头像路由可正确读取,业务流程:员工上传本人头像成功 再次上传可覆盖;管理员为他人上传成功;普通员工为他人上传返回 403;上传超过 2MB 或错误格式返回校验错误;访问 GET /api/avatars/:employeeId 可读取图片;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/employees.js && node --check src/routes/users.js && node --check src/routes/presence.js && node --check src/services/presenceHistory.js,manual,DONE,DONE,DONE,server/package.json|server/package-lock.json|server/prisma/schema.prisma|server/prisma/migrations|server/src/routes/employees.js|server/src/routes/users.js|server/src/routes/presence.js|server/src/services/presenceHistory.js,"[""A1""]","新增 sharp 用于头像缩放与 webp 转换;存储复用 services/storage 本地 driver 实际写入 generated/storage/avatars/<employeeId>.webp;回滚路径:回滚代码与 avatar_path 字段 若需清理文件则删除 generated/storage/avatars/ 下对应文件"
A3,头像前端接入与展示,新增统一头像组件 并在人员列表 员工档案 团队状态页接入 avatarUrl 与上传交互,头像存在时展示图片 不存在时展示占位样式 管理员与本人可在档案页上传头像 上传成功后列表 档案 团队页展示一致,业务流程:本人在档案页上传头像后 PeoplePage EmployeeProfilePage TeamPresencePage 均显示新头像;管理员查看他人档案可上传头像;无头像员工显示占位;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/api/employees.ts|client/src/api/presence.ts|client/src/pages/EmployeeProfilePage.tsx|client/src/pages/PeoplePage.tsx|client/src/pages/TeamPresencePage.tsx|client/src/components/common/EmployeeAvatar.tsx,"[""A2""]",不新增重型 UI 依赖 占位样式由轻量组件统一处理
A4,组织架构读模型与接口,新增按部门分组的组织架构读模型与 GET /api/employees/organization 接口 仅返回 active 员工 并标注跨部门上级摘要,接口按部门返回可构建组织树的数据 每个部门内根节点规则稳定 跨部门汇报节点带 externalManager 摘要 且权限沿用 /people,业务流程:具备 /people 权限的用户访问组织接口可拿到 active 员工部门分组树;部门内无上级或上级不在本部门者为根;跨部门汇报节点含 externalManager;无权限用户返回 403;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && node --check src/routes/employees.js && node --check src/services/organization.js,manual,DONE,DONE,DONE,server/src/routes/employees.js|server/src/services/organization.js,"[""A2""]","只读接口 不新增权限码 沿用 system.users 与 report.dashboard.view;组织视图只展示 active 员工"
A5,组织架构页面与导航,新增 /organization 页面 并把导航与工作区入口补齐 前端以部门折叠 section + 缩进树展示组织架构节点,用户可进入 /organization 按部门折叠展开 查看头像 姓名 职位 部门 点击节点跳转到 /people/:employeeId 导航可见性与 /people 一致,业务流程:有权限用户进入 /organization 默认看到部门分组;展开部门后可递归查看下级;跨部门汇报节点显示汇报给某部门某人;点击节点跳到员工档案;无权限用户不可进入;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/pages/OrganizationPage.tsx|client/src/router/index.tsx|client/src/router/lazy/index.ts|client/src/router/lazy/OrganizationPage.ts|client/src/components/navigation/NavLinks.tsx|server/src/services/workspaceSettings.js,"[""A4""]",不引入重型图表库 使用现有卡片与递归缩进树实现
A6,员工合同后端模型与接口,新增 EmployeeContract 模型与员工合同接口 仅管理员可查看和维护 合同状态按 terminatedDate endDate 自动推导,管理员可新增与编辑合同 合同类型固定为 labor nda non_compete internship 返回状态固定为 active expired terminated 非管理员访问合同接口返回 403,业务流程:管理员为员工新增劳动合同 NDA 合同并保存成功;修改 terminatedDate 后状态变为 terminated;清空 terminatedDate 且 endDate 早于今天时状态变为 expired;普通员工访问合同接口返回 403;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/employees.js,manual,DONE,DONE,DONE,server/prisma/schema.prisma|server/prisma/migrations|server/src/routes/employees.js|client/src/api/employees.ts,"[""A1""]","新增 EmployeeContract 与 EmployeeContractType;不复用 ContractRegistry;回滚路径:先删除 employee_contracts 数据 再回滚迁移与代码;合同附件本轮只存 attachment_path 字符串 不做上传"
A7,档案页合同标签与头像上传入口,将员工档案页改为 tabs 并新增仅管理员可见的 合同 标签 同时加入头像上传入口 维持原档案内容不回归,档案页默认保留现有档案信息 汇报链 资产 Checklist 管理员可见并维护合同标签 管理员与本人可上传头像 report.dashboard.view 与普通员工看不到合同标签,业务流程:管理员打开员工档案可在 档案 与 合同 两个标签间切换 并新增编辑合同;管理员或本人可上传头像;report.dashboard.view 用户与员工本人看不到合同标签;命令:export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,client/src/pages/EmployeeProfilePage.tsx|client/src/api/employees.ts,"[""A3"",""A6""]","当前档案页改为 tabs 但 档案 标签承载原有内容与行为 不改变现有生命周期与汇报链功能"
A8,Reviewer与QA收口,按 reviewer→qa 顺序完成迁移 公开头像读取接口 组织架构树与合同管理的独立审查与回归 并回填状态,reviewer 对 Prisma 迁移 头像公开读取边界 组织树口径与合同状态推导无阻塞意见 QA 跑通头像 组织架构 合同三条主线 且回填 CSV 状态,Review:独立审查 employees routes organization service avatar route 和合同迁移相关 diff;QA:执行各 Issue Test_Method 并补跑 export PATH=/home/shunli/.nvm/versions/node/v22.20.0/bin:$PATH && cd server && npx prisma validate && node --check src/routes/employees.js && node --check src/services/organization.js && cd ../client && npm run typecheck && npm run build,manual,DONE,DONE,DONE,issues/2026-03-29_r43-employee-enhancements.csv|server/src/routes/employees.js|server/src/services/organization.js|client/src/pages/EmployeeProfilePage.tsx|client/src/pages/OrganizationPage.tsx,"[""A3"",""A5"",""A7""]","本轮 reviewer 必启用 因涉及 Prisma 迁移 与公开头像文件读取;若实现新增公开头像路由 需重点审查是否只暴露员工头像而非整个 storage 根目录;review 结论:未发现阻塞问题,残余风险为头像地址按方案保持公开,合同编号当前为同员工内唯一"