Skip to content

Python 更新日志 ​

当前版本 v1.8.52 · PyPI(jeeflow)· 仓库 mldong/jeeflow-python · Releases 版本日期以本仓 git tag 为准;跨语言对齐脉络见 更新记录总览。

1.8.51 — 2026-10-17 ​

audit8 R110+R112。

  • 新增(删除定义守卫):processDefine/remove 删除前校验任何实例存在即拒,批量先整批校验;仓储增 has_instances_by_define_id。
  • 诊断(未知档的边):_follow_edges 落穿时 logging.warning 带 from/to,行为不变。

1.0.0–1.8.4 为四语言同构对齐期(Java / Go / Python / Node 同号演进);1.8.5 起按语言节奏发版,版本号不必同号(Python 全序列无跳号)。

1.8.50 — 2026-10-16 ​

audit8 R91+R77(tag v1.8.50,引擎 commit 0bf4c4d/8f4da2d)。

  • R91 节点级拦截器:interceptor_registry 按名解析+根/节点两级声明,节点档优先、缺名显性报错; 条文=规范 02 §3。
  • R77 提交后腿通道:run_after_commit() 可选通道(登记成功 ⇒ 提交后跑,否则立即跑), 条文=规范 12 §12.3.1。
  • 同批:R80 python 半边 _create_task_with_actors 四条登记腿+四条落库腿补牙。 工具件 flows_resolver.py(R81 原子写)现读确认不进 wheel(pyproject.toml 的 packages.find include=["jeeflow*"] 不收仓根文件)⇒ 该笔零发版可见。

v1.8.52 — 2026-10-31 ​

「退回修改、重提直返」首轮发版(tag v1.8.52=commit 78a2b0e)。条文见 规范 04 引擎操作「退回修改、重提直返」节。

  • 新增:reapplyMode 节点属性与非法值解析期报错、submitType=6 直返建带 _reapplyContext 的申请待办、submitType=5 重提直接回来源节点、_branchCtx 分支归属 与汇合"等齐本轮各根(含该分支还在申请人手里修改)才放行、只放行一次"、保留键入口剥离 与同实例串行化。实现落点:jeeflow/reapply.py + jeeflow/engine.py。
  • 变更:带标记的申请待办在跳转/拒绝/再次退回入口一律先拒(文案对齐 java); 分支归属改为建单后落库(attach_created 写回仓储),此前只改内存对象 ⇒ 下一次请求 从仓储读到的任务没有 _branchCtx、汇合误回落旧判据。
  • 修复(ext 回退契约被新保留键打破):_task_row_to_dict 的控制键集合补两枚保留键, 回退取实例变量副本并合回 _reapplyContext;_merge_exec_into_instance 同挡这两枚 (本栈把任务变量并进执行上下文,不挡就把内部键写进实例变量);内存仓两处 _task_row 补 instanceVariable 投影,与 repository/base.py 的 pi.variable AS instance_variable 同形。

v1.8.49 — 2026-10-16 ​

audit8 R92 行为变更(tag v1.8.49,引擎 commit 4b0bbe0)。

  • 行为变更(执行族返回值):execute_process_task/execute_and_jump_to_end/ execute_and_jump_task/execute_and_jump_to_first_task_node 四法返回 list[ProcessTask] (本次动作产出的任务行),对齐 规范 04 §完成任务 与 java exec.getProcessTaskList();空档出 [] 而非 None。start_* 两法仍返回实例。
  • 实现口径:作用域用 contextvars(_NEW_TASKS + _append_new_task)——本栈建单腿散在十余个 私有方法里,逐个改签名过碎;asyncio 每个 Task 持有自己的 context 拷贝 ⇒ 并发办理互不串味。
  • 门面随动:processTask/execute 六处 inst = await … 的绑定从来没被使用(该动作直接 return None),本轮去掉这条名不副实的绑定 ⇒ 出口形状不变,壳只升 pin。
  • ⚠ 记账:_create_task_with_actors 的四条登记腿目前无判据咬合(该函数自 issues/121 P2 起 零生产调用者),补牙随台账 R80 排。

v1.8.48 — 2026-10-15 ​

issues/232 R64:autoGenTitle 时间戳钉秒 %Y-%m-%d %H:%M:%S(tag v1.8.48,引擎 commit cbdca60)。 条文见 规范 04 autoGenTitle 行(拍 A=秒档;标题专用格式化点,不并 expire_time 腿)。

  • 行为变更(用户可感知):自动生成的标题串从分钟粒度改秒粒度——同分钟内多张单据的标题自此可区分; 前端若对标题格式做正则匹配需同步。

v1.8.47 — 2026-10-12 ​

issues/178 收口:candidatePage 候选映射优先级链+行键归一(tag v1.8.47,引擎 commit ecf4171)。 条文见 规范 06 · 统一门面。

  • 修复(用户可感知):候选人行此前键形恒兜底,宿主 IUserProvider 查得到也不用、realName 等于裸 id。 本版接上 findById→getUser→兜底 的链,行键 id/realName 按优先级回落。
  • 判据:四档 T0 用例+逐处变异红样+字节级还原清洁;复跑 351 格全绿。
  • 传播面:python→fastapi/flask/django,3 张镜像;同批五引擎(go/node/rust/moon)9 张镜像+ moon 一键包全晋升。

v1.8.46 — 2026-10-12 ​

issues/177 收口:候选人属性取数顶层优先·properties.field 嵌套兜底(tag v1.8.46,引擎 commit 91aaba0)。 条文见 规范 08 场景 43「字段权限族」。

  • 修复(用户可感知):设计器把候选人写在嵌套形里,解析层只读顶层 ⇒ 按 UI 配的人读成空。 形状与 issues/163 已立的「顶层优先、嵌套兜底」尺子对齐。
  • 现读更正:本栈的会签条件腿已被 issues/163 轮修掉,本案只剩候选人一处。
  • 判据:两档新格+变异红样;复跑 347 格全绿。
  • 传播面:python→三壳;同批六引擎,9 张镜像+moon 一键包 10/10 晋升。

v1.8.45 — 2026-10-12 ​

issues/176 收口:startAndExecute 自动办理腿 operator 改 flow.auto(tag v1.8.45,引擎 commit 178fd0f)。

  • 变更(用户可感知):一键发起并办理时那条任务的办理人记成系统哨兵,真实发起人不再同时出现在 「我已办」,doneList 可见性回到产品语义。八引擎同批(java/go/node/php/rust/csharp/moon),见各语言页。
  • 判据:跨栈门禁 L2-43 同轮落格;修前红四家族 51/1,唯一红这一格。
  • 传播面:python→三壳;本轮总传播面 8 引擎→13 壳+moon 插件→14 张镜像全晋升。

v1.8.44 — 2026-10-12 ​

issues/145 事务七条债 · python 切片(tag v1.8.44,引擎 commit 5d5e898+0b5fca6)。 条文见 规范 12 · 事务与持久化。

  • 变更:普查里 persist 业务表写腿不在引擎事务内 那一格的 python 腿收口;一次动作一个事务边界, 业务表写腿随动作提交或回滚(异步侧 current_tx_conn 承接连接,a_insert 为 async)。
  • 判据:真库 tier 档+逐处变异对照。
  • 传播面:python→fastapi/flask/django,3 张镜像晋升。

v1.8.43 — 2026-10-11 ​

issues/174 收口:redeploy 原地替换保留 version/state(tag v1.8.43,release commit 75d5a96)。 条文见 规范 08 场景 42。

  • 修复(用户可感知):processDesign/redeploy/processDefine/redeploy 两 action+两条仓储腿此前把 version/state 覆成 1——已办结/已废弃的定义重部署后行状态被打回,按 state 取数的列表与审批记录错乱。
  • 少数边同批:改动落在 java/go/python/node/csharp 五栈(php/rust/moon 与内置 boot2 本就不丢)。
  • 判据:跨栈门禁 L2-41(deploy/redeploy 两 action 此前整族零格);修前红三家族 49/1。
  • 传播面:python→三壳;本轮合计 5 引擎→11 壳→11 张镜像。

v1.8.42 — 2026-10-10 ​

issues/161 · issues/163(PyPI,引擎 commit 7a5c752)。条文见 规范 06 §4.6 义务 2「求值通道」, 判据=本仓新增 tests/test_decision_nomatch_i161.py + tests/test_countersign_cond_i163.py, 以及 spec_test 会签 07 改回 java 形状。

  • 修复(161):决策节点"没有任何 expr 边为真、也没有默认边"时不再无条件走第一条边——与 java DecisionModel.exec 对齐,抛 decision节点无法确定下一步执行路线(门面出 99999999,msg 与 java demo 同文)。旧形状蒙 edges[0],坏定义/缺变量被静默接受;升级后这类定义会开始报错(任务照常消耗、 实例停在 10,可诊断)。"无 expr 默认边"档保留(默认分支语义)。
  • 修复(163):并行会签的 countersignCompletionCondition(如 #nrOfCompletedInstances>=2) 从此真求值——阈值达成就合并、未完成成员任务行废弃(ABANDONED=99)。门控计数 (nrOfInstances/nrOfActivateInstances/nrOfCompletedInstances,裸名)并进求值原料, 照 rust gate_vars 那一步;ONE_VOTE_VETO 判定顺序不动。同批补"顶层优先、嵌套兜底"读取 properties.field 子对象里的条件(设计器实际落笔处;java/php/csharp/rust/moon 五栈早已读嵌套形)。
  • 用户可感知:按文档/设计器配阈值条件的并行会签,从"永远等满员"变成按阈值放行; 决策边全不真的定义从"蒙着走"变成"报错停住"。
  • 判据:161 三格(两档无命中报错+msg 逐字+对照档正走);163 四格(阈值 2/3 放行+无 cond 对照+ ONE_VOTE_VETO+嵌套读形);变异对照=还原蒙臂 2 红 1 绿、摘嵌套兜底 2 红。T0 tests/(除 jdbc) 343 passed;T1 真库 233 passed / 0 failed。
  • ⚠ 演示种子备注:reset 读数 15 进行中 / 10 已完成 → 18/7——种子三行(define=12)的映射漂移曾被 "蒙臂"装成办结,删蒙臂后如实停住(go/node/rust 同三行本就停住,属既有数据缺陷、另案处理), tests/demo_reset_test.py 期望已按如实值同步。壳侧 fastapi/flask/django 同批补 # 门控变量剥前缀。

v1.8.41 — 2026-10-10 ​

issues/160(PyPI,引擎 commit bca2da9)。条文见 规范 06 §4.6 义务 2「求值通道」, 判据=跨栈门禁 L2-39 档③ + 本仓新增 tests/test_high_light_default_evaluator_i160.py。

  • 修复:宿主没有注册 IExpressionEvaluator 时,两条腿从此共用同一条求值通道。旧形状是运行时 _evaluate_decision 整段跳过求值、靠"取第一条无 expr 的边/无条件取 edges[0]"蒙方向 (amount=500 与 amount=5000 落进同一条支),而门面 highLight 走 eval_expr 拿到 ValueError("ExpressionEvaluator 未配置"),该异常又被模型补全块的裸 except Exception: pass 吞掉 ⇒ 走过的决策边连同其后的整条路径一起丢失,实例照常流转,只有流程图暴露它。
  • 新增:引擎内置默认求值器 jeeflow.default_evaluator——${var} / #var / 裸名变量代入 + >= <= != == > < + 布尔字面量(不含 && / ||;关系运算要求两侧都是数字,非数字操作数判 false, 不拿字典序蒙方向),语义与 rust default_evaluator/csharp DefaultExpressionEvaluator 同形。 宿主注册了 SPI 则宿主优先,且运行时与门面两条腿一起走宿主。
  • 不再静默:highLight 模型补全块的块级 catch 保留(与 java JeeflowFacade:582 同档——坏 content 不该让整条 highLight 报错),但改为落一条带 instanceId / defineId 的 WARNING。 "SPI 未注册"这一档已由内置件变成结构性不可达。
  • 用户可感知:只用引擎、不写求值器的接入方,决策分支从此按表达式真值定支,流程图上走过的分支边 与其后路径正常高亮;已自注册求值器的接入方行为不变(三壳 fastapi/flask/django 即属后者,零改动)。
  • 判据:六格新用例——正反两方向停支/宿主 SPI 优先/内置真值表 17 条(含 python 特有的 "bool 不被当数字吃",True 是 int 实例,归一顺序反了 flag == 1 会自等成 true)/ 坏模型下降级面不变(仍 code=0、边集空、任务行不受影响)且 caplog 真拿到 WARNING。 变异对照(在源码副本逐字还原三处修复)= 3 红 3 绿,红得正是病灶: 走过的边 e3 必须高亮,实得 ['e0','e_apply_1','e2']、amount=500 应走 e4 落在 task3,实得 ['task2']、 必须留 WARNING,实得 []。
  • gate:T0 整个 tests/(除 jdbc)336 passed(同清单改前基线 329 → 改后 335,+6 零回归); T1 tests/jdbc_test.py mysql(160 真库)233 passed / 0 failed。postgres 腿按当前工装跑不通 (⑱ 组无条件发 SELECT @@sql_mode),维持既有豁免口径,不算本轮回归。
  • 发布物自证:wheel 与 sdist 各装进全新 venv(加载点在 site-packages、sys.path 不含仓)跑同一夹具 四档全绿;未注册档另在真库 JDBC 腿与真 HTTP 往返(demo 副本摘掉 SPI)各复跑一遍。

v1.8.40 — 2026-10-10 ​

issues/157(PyPI,引擎 commit d17a10e)。条文见 规范 06 §4.6 义务 2「收录位置」, 判据=跨栈门禁 L2-39 档③。

  • 修复:highLight.historyEdgeNames 不再漏掉"指向活跃节点的那一跳"的边名——_collect_path 此前把 边名当递归实参传,遇活跃目标先 continue ⇒ 那条边永不收录(流程图上通向当前待办的那根线不亮)。 现把收录挪进源节点出边循环、排在活跃判断之前,与 java JeeflowFacade.collectPath:711-718 同位。 与 Go/Node 三家同病灶(普查读数见 issues/157 §6.1),本栈不是孤例。
  • 用户可感知:apply →(活跃)approve、网关分流后进入当前节点那一跳,边名从此会进 historyEdgeNames; 求值为 false 的分支仍整条不收(issues/153 那半不动)。
  • 判据:新增 test_highlight_collects_edge_into_active_node(夹具停在分支上,task2 活跃),断言 e3 收录、 线性腿齐、e4/e5 不收、task3 不进节点集。变异对照(收录挪回下钻之后)该格红 (['e0','e_apply_1','e2'] 缺 e3)而既有 03.5 绿。
  • gate:T0 pytest tests/spec_test.py 227 passed;T1 tests/jdbc_test.py mysql 233 passed / 0 failed(160 真库)。

v1.8.39 — 2026-10-10 ​

issues/154 ④(PyPI,引擎 commit 07b1c6f)。条文见 规范 06 §4.6。

  • 新增:approvalRecord 每行补首列 id(str(t.id))。
  • ①②③ 现读已合规:base.py 的 ORDER BY id ASC、不查实例⇒data: []、ext 空档 {} 无实例变量回落。
  • 判据:视图端点出口用例加了 id 存在/字符串/非空/唯一;变异对照(摘掉那行赋值)当场红、还原复绿。

v1.8.38 — 2026-10-08 ​

issues/152 委托三件收口(PyPI,引擎 commit 427dc9b)。规范条文见 规范 06 §2.5 口径表 与 §4.5「processSurrogate/page 归属不变式」, 判据基线=规范 08 用例 38–41。升级前两处用户可感知的行为变更必读(见下)。

  • 新增:processSurrogate/page 的归属不变式落到引擎自己身上——门面按 §2.5 把归一后的 operator (缺键/空串/全空白 ⇒ demo 缺省 user1)作为 t.operator EQ 下发,形状与本栈 instancePage 一致; 仓储侧补第二层(SQL 侧 AND 1=0、内存侧判不命中),内存仓与 SQL 仓同答案。 此前这条语义全靠集成壳注入 operator(换宿主/直调 SPI 即退化成全库台账,vben5 前端本就不传)。
  • 变更:归属条件的缺失档与空值档同判——绕过门面直调 pageSurrogates 时,t.operator 那条 EQ 值为空或整条没给都返回空页,不再"这条条件不加"放出全库;只收归属列, m_LIKE_* 那套"空值当没填"的可选过滤放行原样不动(与 §2.5 抄送侧同一条尺子)。
  • 修复:写侧授权人三档归一。processSurrogate/save 收到空串/全空白 operator 时不再落进 operator (那种行是死行:getSurrogate 的 WHERE operator = ? 永不命中,台账看得见、待办永不并人); save 缺省档落归一值,update 缺省档保留原授权人不变。
  • 不变:委托查询的作用域优先级(精确优先)与择优顺序(先按 id 取最新一条再交判据裁决) 维持 v1.8.2x 起的既有立法(issues/123 收口形状),与内置 mldong-wf 版方向相反—— 差异与迁移动作已写进 §4.5「与内置版(mldong-wf)的三条方向差异」。
  • ⚠️ 行为变更(用户可感知):① 集成方若曾依赖"processSurrogate/page 不带 operator 返回全库", 升级后该档只返回归一缺省 user1 名下的行;② 直调仓储的调用方若不给归属条件,将拿到空页。 jeeflow-ui 与 vben5 两条前端腿都经门面且各栈已实测零回归。
  • 测试:仓内 T0 五档判据(作用域优先级/停用不自愈/自委托/写侧三档/分页归属两层), 每档配真值档阳性对照;摘掉兜底判据必红。

v1.8.37 — 2026-10-02 ​

  • 新增(issues/115 §3-8):门面第 47 个 action processTask/removeTaskActor(摘单个参与人)。
  • 修复(issues/137 §3-1):门面出口内部异常改固定文案「流程处理失败」+判别式五条,底层原文走日志。
  • 修复(issues/137 §3-6):删除腿收口为**「原值 ∪ trim 值」两形并集**(spi/内存仓/SQL 仓三处同一枚判据)。
  • 修复(issues/137 A §3-4/D/E):实例级 expire_time 补发起腿写点;相对档前缀判非负(_INT_PREFIX 正则不收窄, 在消费点判负);判整数前统一 strip 两端空白(E 档,正则一字不动)。
  • 变更(issues/141 G4):未知节点档记可诊断日志(spec/02 义务 2)。
  • 文档(§3-11):过期注释随批——误配档是八栈一致落穿,本栈不再写成"与 Java 的有意差异"。
  • 测试:pytest 325 passed(T0);tests/jdbc_test.py mysql 真库腿 233 PASS / 0 FAIL(连 160, 含 ⑬ 转办/委托、⑮ 委托台账零残留、⑱ 变量档到期时间落 DATETIME(3))。

v1.8.36 — 2026-09-30 ​

  • 新增(issues/142 A 批):撤掉任务类"参与者为空 ⇒ 兜底挂当前操作人"整条 fallback 腿—— 解析为空时保持空集照常建这一行 DOING(零参与者 ≠ 不建单;"办不动"是可查、可被 transfer/nextNodeOperator 救活的固有形状);顺带补 PARALLEL/SEQUENTIAL/普通建单四处的空集守卫 (会签档空列表零行=黑洞形状)。clazz 配错两档日志分开(配错档不炸流程)。
  • 变更(issues/142 B 批 · spec 06 §2.11):normalize_cc_actors → normalize_actors (逗号拆串收进单点 ⇒ 两形结构上不可能分叉;旧名为同一对象别名);新增标量档 normalize_actor_value 与主键档 require_present_id。五处落点(addCandidate/surrogate、 transfer 三值、nextNodeOperator、updateCcStatus、两仓 addTaskActor)接同一枚。 破坏面:标量 actorIds(如 123)由"报缺参数"变有效参与者; 两仓 add_task_actor(空主键) 改抛 ValueError。
  • 测试:pytest 246 passed / 0 failed(基线 231);真库 tests/jdbc_test.py mysql 223 passed / 0 failed(基线 197;postgres 腿按 issues/118/160 裁定豁免)。

v1.8.35 — 2026-09-29 ​

  • 改造(issues/132):事件类型从字符串套("process_start" 等)迁到整型 A 套 1..9; 旧名以同值成员保留一代(PROCESS_START=1 / PROCESS_FINISH=2 / PROCESS_REJECT=2 / TASK_CREATE=3), 别名不进 list(EventType)。
  • 新增(issues/127):办理抄送腿从门面下沉进引擎(handle_cc_actors 唯一漏斗:先 create_cc_instance 落库 → 逐人 fire CC_CREATE),发起腿 f_ccActors 与手动 createCCInstance 两支同口径;覆盖面收窄到 execute_process_task(jump / reject / 退发起人四档带 tf_ccActors ⇒ 0 支 4、0 行 cc)。下沉的另一收益:with_tx 事务边界现在盖得到 cc 行。
  • 修复(issues/130 遗留分叉):内存扩展仓储写侧归一 enabled(save_surrogate 把 '1' 归成 1), 与 node 同形不对称(update_surrogate 有意不归一,留脏值出口);读侧判据一字未动。
  • 测试:T0 182 passed / 1 failed——唯一红是 tests/demo_reset_test.py,已在 git archive HEAD 副本里复现为发版前也红,与本批无关,立案 issues/141 G5; T1 tests/jdbc_test.py mysql 166/0。四层变异:摘 cc 落库只 fire ⇒ 10 红;摘办理腿 ⇒ 3 红; 判据放宽吃 '1' ⇒ 3 红;把归一搬到读侧 ⇒ 3 红。

v1.8.34 — 2026-09-29 ​

  • 修复(issues/134 · 撤回不校验实例状态):对已办结/非进行中的实例调撤回,改前会被静默改写—— 实例 state 被写成 30 且返回 code=0(症状现场:boot2 生产镜像 code=0 msg='成功',state 20→30)。 聚合根 withdraw 入口加实例态守卫:state != 10(进行中) 一律拒,内部码 20010009,被拒时 实例与任务行零改写、不落库;出口按 issues/121 口径透出 code=99999999 + 逐字文案 「流程实例非进行中,无法撤回」(内部码不进 msg)。任务行层面的既有保护(spec 06 的"20/40 任务行 不改写")原样保留,实例级守卫排在它之前。落点:聚合根 model.py 抛 + facade.py 把 withdraw 上提到任务行循环之前(对齐 java 的 canWithdraw→withdraw→updateInstance 序)。T0 165 passed(基线 159)。
  • 修复(issues/130 · 委托 enabled 脏值默认方向):判据收窄为只认数值 1(isinstance(int) 且非 bool 且 == 1;'1'/1.0/True/2 一律停用);驱动把整数列串化属边界事实, 在仓储读侧 hydrate_enabled()(repository/ext.py::_map_surrogate)还原成数值——不是放宽引擎判据。 内存仓刻意不还原(它没有驱动,脏值就该停用显形);门面写侧 _to_int 归一保留。pytest 168 passed (唯一红是改前即红的 demo_reset_test seed 数,与本案无关)。

v1.8.33 — 2026-09-28 ​

  • 修复(issues/126 案 A):本栈无求值器 ⇒ 新增 jeeflow/engine.py 的 process_time(expr, args) (三档逐字对齐 Java,含"类型不认识落穿"与"解析不出给 None 不落穿"两档细节)+ _apply_expire_time; 五处写点:普通建单 / 串行首位 / 并行全员 / 其它会签档 / 回退新建,外加串行推进位(c325a15 补的第五处)。 jeeflow/build/lib/** 是构建产物副本,未动。
  • 测试 tests/spec_test.py 新增 12 格(同行差值≈2h、变量名档三种值形状、未配三态、解析不出五串、 变量档压过相对档、落穿、并行全员、串行首位与推进位、回退新建两格含"变量源必须用随行不是实例")。 PYTHONIOENCODING=utf-8 .venv/Scripts/python.exe -m pytest tests/spec_test.py -q ⇒ 126 passed; T1 python tests/jdbc_test.py mysql ⇒ 166 passed / 0 failed。
  • 变异对照两层:求值换 datetime.now() ⇒ 新格全红;摘掉第五处 ⇒ 推进那格红; 换回 prev ⇒ 报的是 86400.0s vs want ≈10800s 这种量级差,说明新判据真能分清两个节点。sha256 还原后复跑绿。
  • 跨栈一致性(同批八栈一起发,基准=boot2 内置版 ProcessTaskServiceImpl:213/386/524 三处写):普查发现写点其实是五处,第五处=串行会签推进出的下一位成员(boot2 的推进回调 createCountersignTask(:485,内含 :524 到期写)),各栈这一支普遍绕过本栈建单 helper 直建行,只看建单/回退两支会漏。另一处分叉在落地中被抓出来:回退新建的表达式该取 boot2 的 current=被回退掉的那个节点(:363 current = model.getNode(currentTask.getTaskName()) → :385 ((TaskModel)current).getExpireTime()),而不是落地行所属的 prev;java/php/csharp/rust/node/moon 取 current,go 与 python 头一轮取成了 prev,两栈当时的夹具只给一个节点配表达式 ⇒ 取错也全绿,是比对隔壁栈代码才发现。修完的判据改成双节点不同偏移(落地 1d ∧ 当前 3h ⇒ 断 ≈3h)+反向钉一档「当前未配 ⇒ 必须空」。

v1.8.32 — 2026-09-28 ​

  • 修复(issues/129 案 A,与 Java 1.8.32 同题):门面 12 处 str(args.get("operator", "user1")) 的缺省只在键不存在时生效 ⇒ 显式空串原样穿过;内存仓储四个分页方法用 if operator and ... 真值判据 ⇒ 空串折成"本次不带归属过滤",这正是本栈 demo(MemoryRepository)读出 25 行全库 的成因。现门面集中 ._operator_arg()(trim 后判空回落 user1),内存仓空串/全空白 ⇒ 空页(MemoryRepository 与 MemoryExtRepository 两份同形实现一起兜,同栈两仓结论不同即缺陷),SQL 侧 _build_where 对归属列空值写 AND 1=0。
  • 既有 SPI 保持:operator=None 仍是"不带归属过滤"(与 java"压根没 add 这条条件"同形),只有显式空串是本 issue 的病灶——这一档由测试单独钉住,避免下一轮把 None 也改成空页。issues/114 硬必填未动。
  • 测试(本栈起本机可跑,旧"本机无 Python≥3.10 不跑 T0"的口径作废):uv 装 CPython 3.11 到 G 盘 + 仓内 .venv(pytest / pytest-asyncio / fastapi)。T0 pytest tests --ignore=tests/jdbc_test.py ⇒ 147 passed(基线 144 + 新 3 件:门面三档并排、内存仓空值⇒空页、_build_where 拼串 + 非归属列哨兵);T1 python tests/jdbc_test.py mysql 连 160 真库 ⇒ 166 passed / 0 failed。既有断言零改动。
  • 变异对照三发各自隔离转红:只回退门面 ⇒ 门面件红(空串档应=缺键档 empty=0 absent=1);只摘内存守卫 ⇒ 内存件红;只摘 SQL 兜底 ⇒ 拼串件红;三文件按 sha256 还原。
  • 线上复验:160 demo 部署 v1.8.32 后四出口空串档 = 4 / 5 / 1 / 2(修前 25 / 46 / 24 / 9)。
  • 发版核验:干净环境 pip/uv install jeeflow==1.8.32 装得到且落地文件含归一化 helper;CI Release(build+twine→PyPI 轮询→安装侧断言)绿。

v1.8.31 — 2026-09-24 ​

  • 变更(issues/124 变量出口立法,对齐 Java v1.8.30 基准):processInstance/detail 出口 variables 更名为 ext(inst.variables or {},键形态与列表行一致),variable / instanceVariable 原串退出门面出口;唯一出口 = ext(实例侧)+ instanceExt(任务行侧),空变量出 {};持久层 variable 列不动。
  • 新增 processTask/detail 顶层 taskFormData(tf_ 前缀过滤);demo _inst_vo / _task_vo 同步摘 variable 键。
  • 测试 py_compile 过;本机无 Python ≥3.10 不跑 T0,行为实证在集成镜像层 gate(i18n gate 126/0 + contract_runner 改读 ext 后 13 栈绿);PyPI 回拉 1.8.31 200。

v1.8.30 — 2026-09-23 ​

  • 修复(委托判据取行顺序,对齐 Java 参考实现):get_surrogate 改为「各作用域先按主键 id 取最新一条,再交四判据裁决」——SQL 仓 _query_newest_surrogate 撤掉 AND enabled = 1 AND surrogate <> ? 与时间窗谓词,只留 WHERE operator = ? [AND 作用域] ORDER BY id DESC LIMIT 1;内存仓 _newest_surrogate 同形(只择优不过滤)⇒ 双仓同答案。四判据唯一本体在 model.ProcessSurrogate.is_effective(enabled 只认整数 1 / 代理人非空且非本人 / 窗口覆盖判定时刻,起止 NULL = 该侧不限、判定时刻为空不比窗),surrogate_is_effective 委托给它,判据不留第二份。同层内判否不回落更旧那条;精确作用域判否(含池空)后仍看全流程作用域最新一条。旧顺序等价于「历史上留过一条窗内委托就永久生效」,用户随后停用 / 挪窗外 / 改自委托都判不动它。
  • 修复(出口文案统一):退回上一步两格对外 msg 删 20010007: / 20010008: 码前缀,改 Java 逐字中文文案;两码是引擎内部码、严禁进对外 msg(对外恒 code=99999999)。
  • 测试 T0(本机无 ≥3.10 解释器,改在 160 临时 python:3.11-slim --rm 容器跑):pytest(除 jdbc_test)144 passed(改前同口径 138,+5 用例);-k "newest or parity or surrogate" 33 passed;真库 tests/jdbc_test.py mysql 支路 166 passed / 0 failed(测毕自清零残留)。新增用例:test_surrogate_newest_{out_of_window,disabled,dirty_enabled,self_delegation}_beats_older_effective_one + 正向对照 test_surrogate_newest_effective_applies_and_keeps_original;夹具 tests/surrparity.py 自证改为独立重算新旧两种顺序(旧夹具的「停用/自委托行 id 更大仍取生效最大」两条期望与条款直接矛盾,按新语义反转,非放宽断言)。
  • 变异对照 两仓换回旧形状 ⇒ pytest 5 failed / 139 passed(红=4 格判据 + 1 格双仓对拍,正向仍绿)、真库 159 passed / 7 failed。未测:postgres 版 jdbc_test(本机无 ≥3.10 解释器 + 该库不碰),SQL 侧形状与 mysql 同构。
  • 跨栈验证 13 个集成栈候选镜像门禁对拍:委托判据格 L2-17 全绿(13/13,fastapi / flask / django 三栈同判),13 栈逐格 0 分叉;L2-18 13 栈同形同错=门禁夹具支间未清场,非引擎缺陷。

v1.8.29 — 2026-09-22 ​

09-22 夜发版轮(issues/120 时钟基座 + issues/121 P1/P2 血缘回退)Python 侧代次;tag v1.8.29(19:25),bump commit 7bbb88a。

  • 新增(121 P1):建单写 parentTaskId 与行级 isFirstTaskNode,门面读时行上值优先(81eb3f9); 引擎控制键不算「任务变量非空」,P1 不打断 ext 回退实例变量(b3601e6)。
  • 变更(121 P2):退回上一步改血缘版——复活血缘前驱行、参与者取该行办结人(3514514); submitType 3/6 口径拆开(bab826d)。
  • 修复(issues/116 批次 D):委托 processName 改取流程模型 name(契约 06 §4.5 条款 1.1,28bde7c); 条款 1.1 判空改「先 trim」并收敛单点解析 + 三条建单路径独立用例 + 1.4 乱序夹具(5d6abe6); 门面 enabled 空串按脏值落 0(对齐条款 5 写侧新措辞,4ab0bef)。
  • 本机 T0 口径:该仓在本机跑不了 pytest(PATH 上 3.8.5 不满足 list[int] | None 等 PEP 585/604 语法, 3.9 未装 pytest)⇒ 本代次行为实证落在镜像层 gate(fastapi/flask/django 三栈 runner.py), 台账里记的是"未在本机测"而不是"绿"。

v1.8.28 — 2026-09-10 ​

  • 修复 裸装 import 即炸:repository/mysql.py 顶层 import aiomysql(可选依赖)随包 __init__ 无条件执行,干净环境 pip install jeeflow 后首行 import jeeflow 即 ModuleNotFoundError(PyPI 1.8.27 起全部命中,README 快速开始裸装不可用)。改 if TYPE_CHECKING 惰性引用对齐 postgres.py 先例(aiomysql 在文件内仅类型标注,from __future__ import annotations 下运行时零引用)。
  • 测试 新增 tests/test_bare_import.py:子进程 sys.modules 置 None 模拟裸装,断言核心入口与双适配器类照常可导入;全量 107 passed。

v1.8.27 — 2026-09-09 ​

  • 修复 五语言 SQL 仓聚合水合:find_instance_by_id 此前只查 wf_process_instance 单表不装任务,门面 processInstance/detail 的 tasks/activeTaskList 恒空(gate26 L2-12 门禁真根因,非会签语义)。二次查 wf_process_task(复用 _find_tasks_by_state:id ASC + actorIds 批查,事务内经 _tx_conn_var 复用连接)水合任务副本,语义对齐 Java findTasksByInstanceId / PHP PdoProcessRepository / C# FindTasksInternalAsync(聚合水合口径)。update_instance 级联仅按 task.id 幂等 UPDATE(无 INSERT / 不改 actor),水合后 withdraw 回写与 Java 同构。memory 仓本就水合(基线正确,未动);引擎核心会签语义未动。
  • 测试 T0 新增「SQL 仓 detail 任务列表非空」用例(tests/jdbc_test.py ⑫ 段,mysql/postgres 双库:水合非空 + actorIds + detail tasks/activeTaskList 非空);既有 spec 软拒绝用例续 PASS(核心语义不动);全绿。
  • 集成栈 mldong-fastapi-jeeflow / mldong-flask-jeeflow pin → 1.8.27 随 P3 收口(base+1,进行中)。

v1.8.26 — 2026-09-04 ​

  • 修复 pro 真验回归:stats_define_group 返回映射 r[4] 越界且列错位 → 4 列对齐 r[0]–r[3](key/label/count/avgDurationSeconds),define 维出真分组。

v1.8.25 — 2026-09-04 ​

  • 新增 stats 三 action(processInstance/stats/overview|trend|group)落地。
  • 修复 stats 契约对齐 A–E 验收。
  • 修复 事件监听器异常兜底(P2,一个监听器异常不打断其余)。

v1.8.24 — 2026-09-03 ​

  • 新增 CC_CREATE 抄送知会事件(六语言统一缺口 Python 栈):EventType.CC_CREATE 字符串枚举 + ProcessEvent.ccActorId 直传 + 公开 fire_event + facade 两路(start 事务内)逐抄送人 fire;纯增量(无监听器零副作用)。
  • 验证 T0 83/83 + T1 真 MySQL 45/45。

v1.8.23 — 2026-09-01 ​

  • 修复(引擎侧根因):createTask 任务行落库之后 fire TASK_CREATE 事件——此前「从不 fire」,新待办 TODO 事件整类缺失,messagePage 恒空;新待办 / 分支节点 / 退回重办 / 会签各子任务逐任务触发,对齐 Java CreateTaskHandler 时机。

v1.8.22 — 2026-08-31 ​

  • 修复:execute 不再覆盖实例 u_*——以 start 注入的发起人 u_* 为底、仅并入非 u_* 键(helper _merge_exec_into_instance)。实例 u_realName 恒为发起人,对齐 Java 基准。

v1.8.21 — 2026-08-30 ​

  • 修复 批量入参契约:删除/启停类 action 统一走 _id_list——{ids} 数组优先、单 {id} 兼容,空值 / 含非法值一律 99999999,不再静默成功;processDefine/remove 批量补齐(Python 独有的第二处缺口 批量下沉当时只给了 upAndDown)。

v1.8.20 — 2026-08-24 ​

  • 修复 会签一票否决条件化 + merged 废弃残留任务(五语言对齐内置引擎);串行会签无 Python 变更(实现本就正确)。

v1.8.19 — 2026-08-23 ​

  • 修复–82 门面字段级契约批次(五语言)Python 部分:processSurrogate 补 update / detail、candidatePage 行键归一、listByType 补 processDefineState、id 精度守卫(_to_int,float64 超 2^53 显性报错)、委托修复、submitType 门面行为 + 抄送空 actors → 99999999 测试。

v1.8.18 — 2026-08-16 ​

  • 修复:FormFieldAssigneeHandler.findFieldValue 增加 f_ 前缀优先匹配(对齐 Java 1.8.11)。

v1.8.17 — 2026-08-15 ​

  • 修复:facade 分页补齐 pageNum / pageSize / recordCount / pageCount / total 五键。

v1.8.16 — 2026-08-13 ​

  • 修复(五语言同批):processTask/detail 的 taskModel 补全 ext / form 字段,用于字段权限下发。

v1.8.15 — 2026-08-09 ​

  • 变更(CI)为 CI 发布流水线做准备;无引擎行为变更。

v1.8.14 — 2026-08-09 ​

  • 变更(CI)test job 移除、aliyun mirror;无引擎行为变更。

v1.8.13 — 2026-08-09 ​

  • 新增:register_persist_meta 注册助手,集成方一行调用同步字典项与实例。
  • 变更 流程定义声明 postInterceptors 但注册表无实例时,发起 / 办理改为显式报错(原为静默跳过)。

v1.8.12 — 2026-08-08 ​

  • 改进 updateDefine / save / deploy 的 content 字段支持 string 与 JSON 对象双形态(四语言同批)。
  • 测试 回归护栏——redeploy 后 version 不变(实现本就正确)。

v1.8.11 — 2026-08-06 ​

  • 修复:processDesign/page id 字符串化;upAndDown 兼容 {ids, opType} 批量。
  • 修复:会签任务 performType 落库(三端对齐 Java);撤回状态改为 Withdraw(30) 而非 Reject(45);发起时抄送 f_ccActors 创建抄送。

v1.8.10 / v1.8.9 — 2026-08-05 ​

  • 无本语言行为变更(版本对齐)。

v1.8.8 — 2026-08-05 ​

  • 新增:nodeProgress 成员 name 经 UserProvider SPI 解析 realName,未注册或查不到时回退空串。

v1.8.7 — 2026-08-05 ​

  • 修复:performType 增加字符串兼容('ALL' / 'COUNTERSIGN')。

v1.8.6 — 2026-08-05 ​

  • 修复:persist ext 仓库漏导入 _user_str,JdbcProcessExtRepository 读路径 NameError。
  • 新增:highLight 新增 nodeProgress——会签节点成员进度、普通节点历史与进行中状态。

v1.8.5 — 2026-08-05 ​

  • 修复 E9:审计用户列防御 BIGINT——createUser/updateUser 读回 str 归一化(NULL 保持 None)。
  • 修复 E10:persist 两处 ? 占位符残留,统一走方言占位符。

v1.8.4 — 2026-08-05 ​

  • 新增:流程定义级 postInterceptors 声明与拦截器注册表,未声明的流程不触发,与 Java 语义一致。
  • 新增 三门下沉:processDesign/listByType、processInstance/bizData、updateDefine 顶层 JSON 兼容、remove / upAndDown 批量。
  • 修复:performType 解析容错;persist 连接契约与 MySQL 方言占位符。

v1.8.3 — 2026-08-04 ​

  • 无本语言行为变更(版本对齐;– 为 Java 侧随版,三门于 1.8.4 对齐)。

v1.8.2 — 2026-08-04 ​

  • 修复:SYNC 字段权限语义同步(办理入口过滤,上游只读不可绕过)。

v1.8.1 — 2026-08-04 ​

  • 修复:SYNC 字段权限键兼容前端 PERMISSION_f_ 约定。

v1.8.0 — 2026-08-04 ​

  • 新增:persistMode 双模式(ARCHIVE / SYNC 同步演进)闭环——任务节点级字段权限、状态字段写入、tf_ 去前缀、幂等节点级、子表递归、MetaTableWriter.update。

v1.7.0 — 2026-08-04 ​

  • 新增:元数据驱动的动态写入 / 读取规范(jeeflow.persist)。

v1.6.6 — 2026-08-04 ​

  • 修复:persist 表结构探测 schema 限定。

v1.6.5 — 2026-08-04 ​

  • 新增:persist 主键生成支持。

v1.6.4 — 2026-08-04 ​

  • 改进:persist 默认列匹配宽松化(驼峰 ↔ 下划线归一)。

v1.6.3 — 2026-08-04 ​

  • 改进:persist 用户列默认取 operator;同执行链重复触发防护。

v1.6.2 — 2026-08-04 ​

  • 新增:业务数据通用入库 jeeflow.persist + PersistPostInterceptor。

v1.6.1 / v1.6.0 — 2026-08-04 ​

  • 新增(四语言同构):表单数据契约、IOrgUserProvider SPI、7 个内置参与者处理器、candidatePage 双源、assign 增加 operator 参数。

v1.5.1 — 2026-08-03 ​

  • 新增:processDesign/redeploy、updateDefine、update + is_deployed 同步。

v1.5.0 — 2026-08-02 ​

  • 修复(issues 05/06/07 修复集):详情 jsonObject、highLight 决策节点表达式过滤、design/detail jsonObject 补齐。

v1.4.0 — 2026-08-02 ​

  • 新增:引擎元数据能力——枚举字典 + SPI 实现清单。

v1.3.0 — 2026-08-02 ​

  • 新增 page_cc_instances 分页 SPI + ccList 补齐;add_task_actor 去重追加语义。

v1.2.0 / v1.1.0 — 2026-08-02 ​

  • 新增 视图端点补齐 + IUserSearchProvider;管理扩展三表 + IProcessExtRepository + 统一门面(四语言同构)。

v1.0.0 — 2026-08-01 ​

  • 引擎核心四语言同构实现(Python):5 张核心表、启动/执行/驳回/跳转/退回发起人/会签/抄送/委托、4 SPI、MySQL / PostgreSQL,发布到 PyPI。

jeeflow · 轻量级多语言工作流引擎