# jnpf-flow-engine — JNPF 独立流程引擎(自有源码重建工程) JNPF 独立流程引擎 `jnpf-workflow-admin` 的**自有源码**版本。由黑盒发行 jar (`jnpf-workflow-admin-1.0.0-RELEASE.jar`,无源码)反编译还原(2026-07-17,任务 B), 实现"引擎侧 bug 可修、Flowable 版本可升"。 ## 这是什么 黑盒引擎 = **官方 Flowable 7.0.1 + 极少量 JNPF 定制**。反编译确认定制仅 42 个自有类: | 层 | 类 | 说明 | |---|---|---| | 启动 | `JnpfFlowableApplication` | 标准 `@SpringBootApplication` | | REST 控制器 | `admin/controller/{Definition,Instance,Task}Controller` | `/api/Flow/*` 共 27 端点 | | 响应/异常 | `admin/result/Result`、`admin/handle/GlobalExceptionHandler` | 统一 `{success,code,msg,data}` 包装 | | 服务实现 | `flowable/service/{Definition,Instance,Task}ServiceImpl` | 调 Flowable 引擎 API | | 拓扑工具 | `flowable/util/FlowableUtil`、`flowable/cmd/JumpCmd` | BPMN 图推导 + 自定义节点跳转命令 | | 契约模型 | `common/model/fo/*`(14 个)、`common/model/vo/*`(9 个) | 请求/响应对象 | | 契约接口 | `common/service/I{Definition,Instance,Task}Service` | | | 枚举/异常/工具 | `common/exception/{ResultCode,BizException}`、`common/util/FlowUtil` | | | **Liquibase 补丁** | `liquibase/snapshot/JdbcDatabaseSnapshot` | **达梦 DM8 表快照适配**,仅 `jdbc:dm` 连接串生效 | `liquibase/snapshot/JdbcDatabaseSnapshot` 是官方 liquibase-core 4.27.0 同名类的 JNPF 补丁版 (覆盖 classpath 里的官方类):给达梦 DM8 增加 `queryDM()` 表清单查询 + `escapeForLike/getTables` 分支。现交付库是 PostgreSQL 用不到此路径,但**逐行保真保留**以维持 100% 等价(切达梦库零改动)。 本工程用官方 4.27.0 源码为底、仅打这 3 处 DM 补丁(见文件内 `JNPF 补丁` 注释)。 ## HTTP 契约(不可变) `/api/Flow/*` 27 端点与黑盒 jar **契约兼容**,调用方 = jnpf-flowable 的 `FlowAbleUrl`(唯一调用方)。 兼容边界(见验证):`success`/`code`/`data` 三字段逐字节一致;**唯一例外**是 move 系列参数校验的 多字段错误 `msg` 拼接顺序(Bean Validation 对约束违反集合的遍历序未定义、跨编译不保证稳定), 但调用方只判 `success`/`code`、不解析该 `msg`,故不影响契约。关键约束: - `Result.success` 是 **Boolean**(调用方判 `Boolean.FALSE.equals(getSuccess())`) - `Result.code` 是 **String**(成功 = `"200"`,勿写数字) - 引擎**不校验 token**(无 Sa-Token filter),调用方透传 Authorization 头但引擎忽略——勿加鉴权 ## 构建 独立 Spring Boot 3.3.2 / JDK 21 工程,**不挂主仓父 POM**(主仓是 Spring Cloud/JDK 8 体系,不同源)。 ```bash mvn -f jnpf-flow-engine/pom.xml clean package -DskipTests # 产物:jnpf-flow-engine/target/jnpf-workflow-admin-1.0.0-RELEASE.jar ``` 依赖版本与黑盒 jar 逐项对齐(Spring Boot 3.3.2、Flowable 7.0.1、knife4j 4.5.0、hutool 5.8.27、 postgresql 42.6.2、五家数据库驱动 + protobuf)。构建产物依赖清单与黑盒 jar 仅差 3 项: 2 个 JNPF 定制 jar(已展开为本工程源码)+ lombok(compile-only,正确排除)。 ## 部署(容器) 镜像工程在 `docker/flow-engine/`。`prepare-context.sh` 取源优先级: 1. `FLOWAPI_JAR` 环境变量显式指定 2. **本工程 `jnpf-flow-engine/target/` 的构建产物**(默认) 3. 黑盒原件 `~/Infra/jnpf/flowApi/`(回滚锚点) ```bash mvn -f jnpf-flow-engine/pom.xml clean package -DskipTests docker compose build jnpf-flow-engine && docker compose up -d jnpf-flow-engine ``` 回滚到黑盒(必须显式,脚本不再自动降级): `FLOWAPI_JAR=~/Infra/jnpf/flowApi/jnpf-workflow-admin-1.0.0-RELEASE.jar ./docker/flow-engine/prepare-context.sh`。 ## 回归测试 `test/` 下两个脚本固化了 A/B 验证,改引擎后重跑即可: - `test/contract-smoke.sh [base]`:27 端点错误码/空数据断言;新旧引擎各跑一遍 diff = 契约字节对比 - `test/lifecycle.sh [base] [tag]`:deploy→start→next→complete→back(JumpCmd)→historic→delete 全生命周期, 抽 taskKey/code/name 骨架 A/B diff(覆盖状态机写路径) ## 验证(2026-07-17 已过) - 27 项契约响应 A/B 对比:26 逐字节一致;唯一差异 = move 校验多字段错误 `msg` 拼接顺序 (Bean Validation 约束集合遍历序未定义、跨编译不保证;调用方只判 success/code 不解析 msg,非契约) - 完整生命周期 A/B(deploy→start→next→complete→back(JumpCmd 节点跳转)→historic→delete) 语义骨架逐行一致 - 自建镜像容器 healthy,全栈 16 容器启动,jnpf-flowable 日志无"流程引擎异常" ## 许可 JNPF 商业授权客户对自有部署做等价重建属维护行为;**产物不外发/不开源**。