status: propose created: 2026-08-03
AGENTS.md、memory、本变更四份文档和 code-copilot/rules/automated-testing-standard.md,只验证本轮差异。| 项目 | 计划 |
|---|---|
| 后端 | Java 17、JUnit 5、Mockito;Mapper/Flyway 使用 MySQL 8 临时库 |
| 前端 | Vitest + Node 20.19.0 + Vite production build |
| 流程 | Flowable 用户任务、BPMN parser/writer round-trip、任务并发与回调测试 |
| 消息 | 现有站内消息服务,验证接收人解析和消息记录,不接外部协同渠道 |
| E2E | 版本化脱敏低代码 fixture + 明确的加载器或人工重建步骤 + 合成数据,覆盖绩效核心流程 |
| 当前基线 | 进入 /apply 前按最新工作区统计相关测试类、迁移版本和构建状态 |
| 场景 | 预期 |
|---|---|
| 新 BPMN 子表权限 round-trip | relationCode/fieldCode/readable/writable/requiredOnComplete/allowAdd/allowDelete 无损回显 |
| 历史 BPMN | 主表权限保持现状,未声明子表权限时只读 |
| 自评/上级节点 | 只允许写各自评分字段,快照和公式字段只读 |
| 草稿保存 | 允许空评分,仅执行类型、范围、字段权限和子记录归属校验 |
| 越权主子记录 | 跨主记录行、未知关系、未知字段、新增/删除越权均被服务端拒绝 |
| 历史/已办查看 | 主子表全部只读 |
| 场景 | 预期 |
|---|---|
| 阶段矩阵 | 普通保存只触发 SAVE,草稿不触发集合规则,办理只触发 COMPLETE,发布只做协议静态检查 |
| SUM 精度 | 99.99/100.00/100.01 使用 BigDecimal 得到准确结果 |
| 集合边界 | 空集合、重复明细、全部必填和至少一行按白名单规则返回业务化错误 |
| 条件必填 | 服务端按公式分差要求上级评语;路由/URL/客户端用户/表达式来源不能成为可信必填条件 |
| 结果补充字段 | 申诉要求类型/原因,确认调分要求调整分数,普通确认/驳回不误要求其它结果字段 |
| 服务端公式 | 加权分和父表总分由服务端计算,子表保存后父表聚合刷新 |
| 发布检查 | 公式精度/舍入缺失、依赖失效、公式字段可写配置及集合规则引用损坏均阻断,且不扫描业务记录 |
| 唯一办理入口 | PUT 只能保存草稿;POST 一次携带 COMPLETE 数据和业务结果 |
| 办理并发 | 相同幂等键同摘要幂等命中,不同摘要冲突;已完成任务不能再次保存/办理 |
| 候选状态原子性 | 完整主子表在内存合并、公式重算和校验;校验失败时主表、子表、聚合字段均零写入 |
| 命令阶段恢复 | RESERVED/FORM_SAVED/FLOW_COMPLETED/ACTION_SUCCEEDED/COMPENSATION_PENDING 只能 CAS 前进,不能由客户端回退或跳阶段 |
| 保存后流程失败 | 本地数据已提交但 Flowable 失败时保留 FORM_SAVED,相同命令重试不重复保存并继续办理 |
| Flowable 响应丢失 | 先查任务/历史确认已完成并收敛到 FLOW_COMPLETED,不得第二次办理 |
| 最终响应丢失 | 相同键/摘要返回持久化结果;相同键不同摘要及不同键抢占返回确定冲突 |
| 节点动作 | 业务状态、申诉、日志和消息只由绑定动作执行,Flow Service 不直接重复写状态 |
| 新旧动作互斥 | 节点结果动作与绑定级 APPROVED/REJECTED 回调共存时发布阻断;CANCELED 回调可保留 |
| 动作失败 | Flowable 任务保持已完成,补偿台账为 FAILED,页面可观察 |
| 补偿上下文 | 固定动作编码/发布版本、流程/任务/节点/结果、对象/记录、规范化变量、原幂等键/摘要和 actionLogId;不保存表单/评分正文 |
| 受控重试 | 流程与批量共用 BusinessActionRetryService,对原幂等键、原摘要、原版本和原失败日志 CAS 重试,重复重试不产生第二次逻辑副作用 |
| 自动补偿 | 定时与人工并发只有一方成功;退避和最大次数生效,超限进入人工处理状态 |
APPROVED/REJECTED/CANCELED 回调行为不回退。SUM 与现有聚合公式在空值、精度和舍入上的结果一致。| 场景 | 预期 |
|---|---|
| 可信执行身份 | 预览、手工、Cron 和重试按绑定用户/当前组织实时计算相同数据权限 |
| 权威员工来源 | 按 HARD-GATE 选择的已发布员工对象、系统目录适配器或 HR 对象查询;不得直查原始系统表,停用/主岗位/组织/上级口径准确 |
| 周期上下文 | 月/季/年、时区和正负偏移生成稳定 key/start/end/label,预览、执行和重试保持一致 |
| 身份失效 | 用户停用、组织不可用或权限撤销时失败关闭,零业务写入 |
| 源查询白名单 | 未发布字段、非法操作符、任意 SQL 和超上限查询被拒绝 |
| 稳定分页 | 配置排序自动追加主键;运行中源数据变化不造成同一源记录重复执行 |
| 动作关联查询 | QUERY_RECORDS 按岗位和启用状态加载已发布模板及明细,排序确定且 expect=EXACTLY_ONE;零条/多条明确失败,输出可供 FOREACH 使用 |
| 预览 | 只返回数量和前 N 条脱敏样例,不写运行/目标业务数据 |
| 主子表快照 | 修改源模板后既有任务及明细不变化;单个源记录内主子表失败整体回滚 |
| 并发生成 | 动作日志原子占位;相同员工周期只创建一个目标记录 |
| 最终唯一约束 | 目标对象未发布复合唯一索引时触发器不能启用;数据库约束可阻止竞态重复 |
| 部分失败 | 单条失败不回滚其它记录,运行汇总计数准确 |
| 运行上下文冻结 | run 固定触发器/源查询摘要、period JSON、绑定用户/组织 ID 和动作发布版本;设计态配置变化不影响旧 run 重试,但固定身份的账号状态和当前权限仍实时复核 |
| 失败重试 | 新增 attempt 日志并关联新 run/原 actionLogId,成功项不重放,逻辑幂等键和动作版本保持不变 |
| 分页详情 | 失败明细按 pageNum/pageSize 返回,Long ID 为字符串,错误已脱敏 |
| 场景 | 预期 |
|---|---|
| FIELD 单值/多值 | 用户引用字段可解析单个、集合和逗号分隔用户 ID |
| 非用户字段 | 普通数字/文本字段不可被设计器选作接收人 |
| 空值/非法值 | 默认 FAIL,可显式 SKIP,绝不回退操作人或全员 |
| 兼容规则 | OWNER/CREATOR/USERS/ROLES/DEPTS/ALL 行为不变 |
| 两类消息配置 UI | 触发器和 Business Action 的 SEND_MESSAGE 都能从字段目录选择 FIELD 接收人,不要求高级 JSON |
| 核心流程 | 人工/定时生成 -> 自评草稿/提交 -> 上级评分 -> 确认关闭 |
| 申诉流程 | 员工申诉 -> HR 驳回或调分 -> 关闭,结果和消息一致 |
| 权限 | 员工、上级、HR 三类账号的数据可见和字段可写范围准确 |
| 重复操作 | 重复生成、重复办理、重复回调和补偿重试均无重复业务副作用 |
E2E fixture 必须声明 schemaVersion/fixtureId/namespace。只有测试加载器和命令已经实现时才允许表述为“可导入”;重复加载只 UPSERT 同一 fixture 管理资源,人工同编码冲突失败关闭,清理仅作用于测试命名空间并输出清单。若 HARD-GATE 未授权加载器,则按说明人工配置并明确记录该限制。报表、企微/飞书/钉钉消息不在验收范围。
mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTestsmvn -pl ... -Dtest=... testmvn -pl forge-admin-server -am package -DskipTestssource ~/.nvm/nvm.sh && nvm use v20.19.0 && NODE_OPTIONS=--max-old-space-size=8192 pnpm buildrg -n '\$\{[^}]+\}' forge-server/db/migrationgit diff --check真实命令、测试数量、接口/数据库证据、跳过原因和服务清理统一追加到 execution-log.md。