# 企业 OKR 闭环重构实现计划 > **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。 **目标:** 让项目完整支撑周期配置、CEO 公司目标、逐级 OKR 承接与审核、执行跟踪、逐级绩效评定、申诉沟通和不可变归档,并使 18 个页面符合 Open Design 企业化原型。 **架构:** 保持 Vue 3、Spring Boot、MyBatis-Plus 与单 JAR 架构;通过幂等 SQLite 增量迁移补充周期快照、多 Objective、规范化对齐、真实执行日期和绩效闭环状态。前端按闭环垂直切片接入显式 DTO,最后统一做视觉对照。 **技术栈:** Vue 3、Vite、Pinia、Element Plus、Vitest、Spring Boot 3.2、MyBatis-Plus、JUnit 5、MockMvc、SQLite。 --- ## 文件结构 - 修改 `backend/src/main/resources/schema.sql`:新库完整结构。 - 修改 `backend/src/main/java/com/emoon/okr/config/DatabaseMigrationRunner.java`:只追加新版本迁移。 - 修改 `backend/src/main/java/com/emoon/okr/entity/*`、`mapper/*`:周期快照、对齐、评审和维度实体。 - 修改 `backend/src/main/java/com/emoon/okr/service/AssessmentPeriodService.java`:参与人快照、状态流转和归档 readiness。 - 修改 `backend/src/main/java/com/emoon/okr/service/OkrService.java`:多 Objective、三级目标、逐级审核和统一查询。 - 修改 `backend/src/main/java/com/emoon/okr/service/PerformanceService.java`、`ScoreAppealService.java`、`FeedbackService.java`:考评人快照、申诉修正和沟通闭环。 - 修改 `backend/src/main/java/com/emoon/okr/controller/*` 与 `dto/*`:显式请求/响应契约。 - 修改 `frontend/src/api/*`、`stores/workspace.js`、`router/index.js`:新契约、成员详情和角色路由。 - 修改 18 个 `frontend/src/views/**` 页面与共享 shell/styles:Open Design 企业化页面。 - 新增/修改后端单元及集成测试、前端契约和交互测试。 ### 任务 1:冻结周期汇报关系与自动豁免 **文件:** - 修改:`backend/src/main/resources/schema.sql` - 修改:`backend/src/main/java/com/emoon/okr/config/DatabaseMigrationRunner.java` - 修改:`backend/src/main/java/com/emoon/okr/entity/AssessmentPeriod.java` - 修改:`backend/src/main/java/com/emoon/okr/entity/PeriodParticipant.java` - 修改:`backend/src/main/java/com/emoon/okr/service/AssessmentPeriodService.java` - 测试:`backend/src/test/java/com/emoon/okr/config/DatabaseMigrationRunnerTest.java` - 测试:`backend/src/test/java/com/emoon/okr/service/AssessmentPeriodServiceTest.java` - [ ] 编写失败测试:发布周期时保存 department/position/role/superior/evaluator 快照;没有直属上级的参与人状态为 `EXEMPT_NO_EVALUATOR`。 - [ ] 运行 `cd backend && mvn -Dtest=AssessmentPeriodServiceTest,DatabaseMigrationRunnerTest test`,确认因字段和规则缺失而失败。 - [ ] 追加新迁移版本,增加阶段日期、参与人快照字段和必要索引;不改写迁移 1~4。 - [ ] 实现发布时的快照与自动豁免;readiness 只统计 `ACTIVE` 参与人。 - [ ] 重跑定向测试,确认通过。 ### 任务 2:实现多 Objective 和规范化对齐 **文件:** - 创建:`backend/src/main/java/com/emoon/okr/entity/OkrAlignment.java` - 创建:`backend/src/main/java/com/emoon/okr/entity/OkrReviewRecord.java` - 创建:`backend/src/main/java/com/emoon/okr/mapper/OkrAlignmentMapper.java` - 创建:`backend/src/main/java/com/emoon/okr/mapper/OkrReviewRecordMapper.java` - 创建:`backend/src/main/java/com/emoon/okr/dto/OkrSetSubmitRequest.java` - 修改:`backend/src/main/java/com/emoon/okr/entity/OkrObjective.java` - 修改:`backend/src/main/java/com/emoon/okr/service/OkrService.java` - 修改:`backend/src/main/java/com/emoon/okr/controller/OkrController.java` - 测试:`backend/src/test/java/com/emoon/okr/service/OkrServiceTest.java` - 测试:`backend/src/test/java/com/emoon/okr/integration/PerformanceLifecycleApiIntegrationTest.java` - [ ] 编写失败测试:一个用户可提交多个 O,O 权重合计 100;每个 O 的 KR 权重合计 100。 - [ ] 编写失败测试:只有周期快照中的唯一顶级业务负责人能创建 `COMPANY` O;下级必须等待快照上级已有已批准目标。 - [ ] 编写失败测试:审核权限使用参与人快照而不是实时 `sys_user.superior_id`。 - [ ] 运行定向测试并确认正确失败。 - [ ] 增加 Objective 描述/权重、规范化 alignment 和 review record 表及实体。 - [ ] 新增集合提交接口,保留旧接口作为兼容适配器;查询统一返回 Objective 列表。 - [ ] 重跑定向测试,确认通过。 ### 任务 3:补齐真实执行日期与成员详情 **文件:** - 修改:`backend/src/main/java/com/emoon/okr/entity/KrKeyResult.java` - 修改:`backend/src/main/java/com/emoon/okr/dto/OkrExecutionTimelineDto.java` - 修改:`backend/src/main/java/com/emoon/okr/service/OkrService.java` - 修改:`frontend/src/router/index.js` - 创建:`frontend/src/views/okr/TeamMemberOkrDetailView.vue` - 修改:`frontend/src/views/okr/TeamOkrView.vue` - 修改:`frontend/src/views/okr/OkrExecutionView.vue` - 测试:`backend/src/test/java/com/emoon/okr/integration/Phase3ApiIntegrationTest.java` - 测试:`frontend/src/__tests__/open-design-page-contract.test.js` - [ ] 编写失败测试:timeline 返回每个 KR 的真实 `startDate`、`dueDate`,且日期必须位于周期范围内。 - [ ] 编写失败前端测试:团队成员卡片导航至 `/okr/team/:userId` 并携带 `periodId`。 - [ ] 运行后端和前端定向测试,确认失败。 - [ ] 增加 KR 日期、单位和基线字段;实现真实 timeline。 - [ ] 增加成员详情路由与页面,复用统一 Objective DTO。 - [ ] 重跑定向测试,确认通过。 ### 任务 4:闭合绩效、申诉和沟通状态机 **文件:** - 创建:`backend/src/main/java/com/emoon/okr/dto/ScoreSubmissionRequest.java` - 修改:`backend/src/main/java/com/emoon/okr/service/PerformanceService.java` - 修改:`backend/src/main/java/com/emoon/okr/service/ScoreAppealService.java` - 修改:`backend/src/main/java/com/emoon/okr/service/FeedbackService.java` - 修改:`backend/src/main/java/com/emoon/okr/controller/PerformanceController.java` - 修改:`backend/src/main/java/com/emoon/okr/controller/ScoreAppealController.java` - 修改:`backend/src/main/java/com/emoon/okr/controller/FeedbackController.java` - 测试:`backend/src/test/java/com/emoon/okr/service/PerformanceServiceTest.java` - 测试:`backend/src/test/java/com/emoon/okr/service/ScoreAppealServiceTest.java` - 测试:`backend/src/test/java/com/emoon/okr/service/FeedbackServiceTest.java` - 测试:`backend/src/test/java/com/emoon/okr/integration/PerformanceLifecycleApiIntegrationTest.java` - [ ] 编写失败测试:上级评分只允许 `period_participant.evaluator_id`;HR 普通入口不能越级评分。 - [ ] 编写失败测试:员工能查询自己的申诉;接受申诉会把最终分改为待修正并清除发布/确认时间。 - [ ] 编写失败测试:员工能查询和回复自己的绩效沟通;主管只能在回复后关闭。 - [ ] 编写失败测试:存在 OPEN/REVISION_REQUIRED 申诉时归档失败。 - [ ] 运行定向测试,确认失败。 - [ ] 实现显式 DTO、我的申诉、我的沟通、申诉修正状态和归档 blocker。 - [ ] 重跑定向测试,确认通过。 ### 任务 5:周期维度和绩效模板实例化 **文件:** - 创建:`backend/src/main/java/com/emoon/okr/entity/PeriodDimension.java` - 创建:`backend/src/main/java/com/emoon/okr/entity/KpiTemplateAssignment.java` - 创建相应 mapper。 - 修改:`backend/src/main/java/com/emoon/okr/service/DimensionService.java` - 修改:`backend/src/main/java/com/emoon/okr/service/KpiService.java` - 修改:`backend/src/main/java/com/emoon/okr/service/AssessmentPeriodService.java` - 测试:`backend/src/test/java/com/emoon/okr/service/AssessmentPeriodServiceTest.java` - 测试:`backend/src/test/java/com/emoon/okr/integration/PerformanceLifecycleApiIntegrationTest.java` - [ ] 编写失败测试:维度增删改失败时事务回滚;周期发布后维度快照总分为 40。 - [ ] 编写失败测试:模板通过显式 assignment 匹配岗位/部门/用户,不以模板名等于岗位名匹配。 - [ ] 运行测试确认失败。 - [ ] 增加周期维度和模板 assignment/实例化,实现事务边界。 - [ ] 重跑测试确认通过。 ### 任务 6:接入前端完整工作流 **文件:** - 修改:`frontend/src/api/index.js` - 修改:`frontend/src/api/okr.js` - 修改:`frontend/src/views/period/PeriodListView.vue` - 修改:`frontend/src/views/okr/MyOkrView.vue` - 修改:`frontend/src/views/okr/AlignmentView.vue` - 修改:`frontend/src/views/scoring/MyResultView.vue` - 修改:`frontend/src/views/scoring/ScoringListView.vue` - 修改:`frontend/src/views/scoring/ScoringEditView.vue` - 修改:`frontend/src/views/scoring/ScoreAppealView.vue` - 修改:`frontend/src/views/feedback/FeedbackView.vue` - 测试:`frontend/src/__tests__/open-design-page-contract.test.js` - 测试:新增 `frontend/src/__tests__/okr-closed-loop-contract.test.js` - [ ] 编写失败测试:多 O 表单、公司/部门/个人入口、申诉员工视图、员工沟通回复和结构化 readiness 均存在。 - [ ] 运行 `cd frontend && npm test -- open-design-page-contract.test.js okr-closed-loop-contract.test.js`,确认失败。 - [ ] 接入新 API 和基于权限/快照的动作,不保留无后端能力的按钮。 - [ ] 重跑定向测试,确认通过。 ### 任务 7:18 页 Open Design 视觉收口 **文件:** - 修改:`frontend/src/styles/theme.css` - 修改:`frontend/src/styles/components.css` - 修改:`frontend/src/styles/element-plus.css` - 修改:`frontend/src/components/shell/CohereSidebar.vue` - 修改:`frontend/src/components/shell/CohereTopbar.vue` - 修改:18 个 `frontend/src/views/**` 页面。 - 测试:`frontend/src/__tests__/theme-contract.test.js` - 测试:`frontend/src/__tests__/open-design-page-contract.test.js` - [ ] 编写/更新失败契约测试:240px 侧栏、56px 顶栏、品牌色、卡片和全部页面业务区块。 - [ ] 运行主题和页面契约测试确认失败项。 - [ ] 按同一 1280×720 视口逐页对照,删除医疗文案、emoji 业务图标、虚构统计和深浅色嵌套。 - [ ] 验证桌面、平板和手机断点,修复溢出、对齐、字体和点击目标。 - [ ] 重跑主题和页面测试。 ### 任务 8:全链路验证和单 JAR 发布 **文件:** - 修改:`backend/src/test/java/com/emoon/okr/integration/PerformanceLifecycleApiIntegrationTest.java` - 修改:`frontend/src/__tests__/*` - 同步:`frontend/dist` → `backend/src/main/resources/static` - [ ] 用 CEO、主管、员工、HR 完成创建周期到归档的 MockMvc E2E,并断言全部 blocker。 - [ ] 在迁移前数据库副本上启动两次,验证迁移幂等、版本不复用、历史数据不丢失。 - [ ] 运行 `cd frontend && npm test && npm run verify:theme && npm run verify:scoring && npm run build`。 - [ ] 运行 `cd backend && mvn test && mvn clean package`。 - [ ] 同步静态资源并用 `cmp`、JAR 内容和本地浏览器验证 hash 资源。 - [ ] 使用同一视口保存原型与最终 18 页截图,逐页核对视觉和交互差异。