requireLine() 存在性判断取反,导致已存在的流程线被拒绝、不存在的线反被放行, 线级停发/恢复线上 100% 失败。改为查询为空时拒绝。 - FlowDefAdminService.java:302 补 ! 号(唯一生产代码改动) - FlDefLineOfflineTest 改用真实 FlowDefAdminService(删除业务副本 spy),补非法 GUID/空值/空白/错误学校/trim/在途隔离断言 - FlNewInstancePathTest 新增新实例路径定向测试
11 KiB
FL 后端核心修复执行回执 — Codex
执行日期:2026-10-27(Asia/Shanghai)。范围依据:《FL后端核心修复任务书_Codex_无人值守版.md》。
结论:已核实线级守卫的取反缺陷已作最小修复,测试改为真实调用生产 Service;定向测试 43/43 通过。**待核实(环境阻塞)**真实数据库提交后刷新回读、HTTP 联调及真实 AFTER_COMMIT 行为。本回执不代表整个 FL 终审通过。
1. 基线与范围
- 仓库:
D:/SoftProject/yunhai/flow-center/service。 - 已核实分支
main,HEADa10f2e054c2422ae2dfde82926ae567ad9096093。这是本地仓库基线,不是本次核实过的线上运行版本。 - 已核实开工时
git status --short共 104 项;FlowDefAdminService.java已有修改,FlDefLineOfflineTest.java已存在但未跟踪。均按已有 WIP 保护。 - 开工状态和已跟踪差异见 baseline-status.txt、baseline-tracked.patch;两个目标文件的原始快照也保存在同目录。
- 已读上级
D:/SoftProject/yunhai/AGENTS.md、docs/云海AI代理探索与性能纪律.md、docs/云海项目导航索引.md。入口所指docs/云海平台架构画像_资产与文档基线盘点.md在指定路径不存在,未据此推断环境事实。 - 任务书所列线上验收结论按历史材料记载引用:新实例 152–157 的回调 36/36 对账成功;本轮未重新访问生产或重跑矩阵,也未取得那些报告的独立正文。
2. 本轮代码差异
仅包含三份 Java 文件;以开工 WIP 为基线的独立差异见 task-only.patch。该补丁不是相对 HEAD 的完整发布补丁;应用前应保留原 WIP。
| 文件 | 本轮修改与原因 |
|---|---|
src/main/java/com/yunhai/flowcenter/service/FlowDefAdminService.java:302 |
在存在性查询前补 !,改为缺失时拒绝。保留 null/空白拒绝、trim 和 (schId, flowGuid) 查询范围。生产代码仅改这一处判断。 |
src/test/java/com/yunhai/flowcenter/service/FlDefLineOfflineTest.java |
删除复制业务逻辑的 FlwDefAdminServiceSpy,用已有构造辅助方法创建真实 FlowDefAdminService;补齐停发/恢复非法 GUID、空值、空白、错误学校、trim、发布内容及在途协作隔离断言。 |
src/test/java/com/yunhai/flowcenter/service/FlNewInstancePathTest.java |
增加新实例路径定向测试:真实创建 Service、引擎、任务 Service、激活意图 Service 和监听器串接;repository、人员解析和发布器为 mock。 |
未改 pom、生产配置、前端、FC、Notice、UserBase、网关或 SQL;未新增回填机制,未关闭 D09,未改状态机或事件契约。已有这些路径的差异属于开工 WIP。
3. 真实调用与缺陷捕获证据
先仅替换测试替身,保留错误生产判断,执行原 7 项停发测试:已核实失败 1、错误 1,跳过 0。
lineOfflineDelegatesBulkUpdate:真实存在的g-line被生产requireLine抛错拒绝。unknownLineRejected:不存在的g-nope未抛异常,断言失败。
原始输出见 red-test.log。随后才修复生产判断并补测试。当前测试字段类型是 FlowDefAdminService,由 new FlowDefAdminService(...) 实例化,直接调用其公开 offlineLine / enableLine;被测类和被测方法均未 mock/spy,也没有测试替身里的守卫副本。这一真实失败足以证明重新写反判断会被捕获。
4. 测试结果及实际验证层级
| 范围 | 结果 | 状态与限制 |
|---|---|---|
FlDefLineOfflineTest |
14/14 | 已核实真实管理 Service:已有线双路径通过,分别委托批量更新 1/0;未知 GUID、null、空串、两种空白和错误学校双路径拒绝且不更新;trim;发布版本、内容及在途协作隔离;新发起/预览停发守卫。repository 为 mock。 |
FlNewInstancePathTest |
1/1 | 已核实新实例创建预期办理人的 pending 任务;任务创建事件通过生产监听器/Service 登记本次真实任务成员、定义 ID 和轮次;合法审批记录意图并推进到完成。把定义线标志置为停发后,在途任务仍使用原 defId/version 完成;未查询最新已发布版本替换原版本。 |
FlApplyRecoveryTest#createsWhenAbsentAndStampsIdentity |
1/1 | 已核实新建实例分支、token/轮次、审批中状态与 START 委托。仅执行这个方法。 |
FlAdvanceIntentRecoveryTest |
11/11 | 已核实生产激活结算 Service 的推进/重试/代次保护定向回归。 |
FlStateEventRecoveryTest |
7/7 | 已核实生产事实记录器的事件身份及冻结载荷等断言。 |
CallbackRecoveryDeliveryTest |
9/9 | 已核实生产分发/恢复逻辑和接收契约的内存协作测试;不是线上网络送达验证。 |
| 合计 | 43/43 | Failures 0 / Errors 0 / Skipped 0;Maven BUILD SUCCESS,43.529 秒。 |
完整输出见 targeted-test.log,同目录保存了这六个类的 Surefire XML 和文本报告,避免后续运行覆盖证据。Windows Maven 输出部分中文因原工具链编码显示乱码,测试名、数量及 XML 可复核。
新路径测试直接调用真实业务代码;测试显式驱动同步监听器和后提交入口,并仅初始化 Spring synchronization 以校验激活批次完整性。没有真实事务、Spring AOP、JPA 锁或数据库提交;不能把这个测试描述为真实 AFTER_COMMIT/数据库集成通过。
5. 实际命令
在 service 仓库执行:
git status --short
git branch --show-current
git rev-parse HEAD
git diff --binary
mvn -version
# 生产缺陷仍存在,仅将测试改为调用真实 Service;预期失败,exit=1
mvn -o '-Dmaven.repo.local=D:\SoftProject\yunhai\.m2\repository' '-Dtest=FlDefLineOfflineTest' test
# 修复后定向验证;exit=0
mvn -o '-Dmaven.repo.local=D:\SoftProject\yunhai\.m2\repository' '-Dtest=FlDefLineOfflineTest,FlNewInstancePathTest,FlApplyRecoveryTest#createsWhenAbsentAndStampsIdentity,FlAdvanceIntentRecoveryTest,FlStateEventRecoveryTest,CallbackRecoveryDeliveryTest' test
git diff --check -- src/main/java/com/yunhai/flowcenter/service/FlowDefAdminService.java
git diff --no-index --check docs/evidence/core-fix-20261027/FlDefLineOfflineTest.before.java.txt src/test/java/com/yunhai/flowcenter/service/FlDefLineOfflineTest.java
git apply --reverse --check docs/evidence/core-fix-20261027/task-only.patch
已核实JDK 1.8.0_121、Maven 3.9.16;复用了既有私有依赖本地仓库,离线构建测试可用,没有变更依赖或全局配置。末项只检查补丁,不应用补丁;最终 exit=0,见 patch-check.txt。补丁初次导出为 CRLF 导致检查失败,改为 UTF-8/LF 后通过,Java 源码不受此导出修正影响。
6. 环境阻塞与未处理事项
已核实使用 Get-Command docker、环境变量存在性检查、System.Net.Sockets.TcpClient.ConnectAsync('127.0.0.1', port) 检查本地已知测试入口;证据见 environment.txt:
- Docker 命令不可用,
CI_TEST_DB_URL/SPRING_DATASOURCE_URL未配置。 127.0.0.1:3306与127.0.0.1:13429未连接成功。这仅说明所查入口不可用,不声称全机不存在其他数据库。- 当前
application-test.yml指向本机测试库,FlowEngineIT又要求端口 13429 /fl_d09_20261026;共享FlowTestSupport.cleanDb()含全表删除。未启动此类 IT,未尝试使用开发或生产库替代。
因此以下为待核实(环境阻塞):停发提交后 line_offline=1、恢复提交后 line_offline=0 的数据库刷新/回读;真实仓储批量更新的全版本/学校隔离;真实事务下新实例、任务推进与回调提交链。所需条件是明确隔离、可写且专用的测试数据库及连接参数,后续测试应只创建新测试记录并限定清理范围,禁止直接运行共享清库 helper。
**已核实(静态检查)**仓储 updateLineOffline JPQL 仅更新匹配 schId + flowGuid 的 lineOffline,不更新发布状态、版本、内容或实例。数据库行为仍需上项补证。
未运行 C01 八项、CallbackDispatchIT 七项或完整 CI;本次只有一个管理守卫字符变更,定向回归已覆盖直接影响。历史任务 339、notice.id=78、旧激活意图回填、历史事件补发、重置数据、D14 均不在范围。未发现需要扩展异常语义的已证实新路径缺陷。
7. WorkBuddy 联调说明(准备完成,未执行外部写入)
在获准的隔离测试环境、使用新数据,按以下顺序复验:
- 用本校管理员创建/发布一条测试流程线,先发起新实例并记录 defId/version、任务 ID;确认该任务在
flw_advance_intent.activation_task_ids中有本次激活证明。 POST /api/flow/admin/def/offlineLine,JSON{"flowGuid":"实际测试GUID"}。学校来自登录管理员上下文,不从请求体指定。期望返回受影响行数;读本校该 GUID 全版本flw_def.line_offline应全为 1。- 刷新页面并用
GET /api/flow/admin/def/versions?flowGuid=...回读,仍为停发;新发起和选人预览应提示停发。继续合法办理第 1 步的新实例,在途仍应按原版本推进完成。 POST /api/flow/admin/def/enableLine,同一 JSON。期望受影响行数,刷新/数据库回读全版本line_offline=0;之后新发起使用最高已发布版。- 对照测试前后各版本
status/version/content_json及原实例def_id/def_version应保持不变;空白、不存在 GUID 和另一学校管理员访问应被拒绝且不更新。
路由如有服务 context-path,再加环境配置中的前缀。观察 flw_instance、flw_task、flw_advance_intent 的新记录身份/状态,以及对应新 flw_state_event、flw_callback_log 的稳定 event_id 和投递状态;本次用少量定向新事件,无需重跑六类 36 项矩阵。若出现 D09 无激活证明,先核对是否确为新建实例及其 TASK_CREATED 注册,禁止对旧任务绕过 fail-closed。
8. 交付边界
已交付:最小生产修复、真实调用回归测试、新实例路径测试、实际红/绿日志、可复核代码差异与本回执。未执行历史回填、生产数据库操作、部署或 Git commit/push。数据库与环境联调阻塞不影响已完成代码工作;最终 FL 代码审计仍待前端交付和 WorkBuddy 集成复验后另行安排。