2026-07-13-enterprise-okr-closed-loop.md 11 KB

企业 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.javaScoreAppealService.javaFeedbackService.java:考评人快照、申诉修正和沟通闭环。
  • 修改 backend/src/main/java/com/emoon/okr/controller/*dto/*:显式请求/响应契约。
  • 修改 frontend/src/api/*stores/workspace.jsrouter/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 的真实 startDatedueDate,且日期必须位于周期范围内。

  • [ ] 编写失败前端测试:团队成员卡片导航至 /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/distbackend/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 页截图,逐页核对视觉和交互差异。