审批工作流引擎:LifecycleBus 拦截模式——Agent 世界的零侵入事件架构

> EAMX 的审批流不是写在业务代码里的——审批插件通过 LifecycleBus 的 intercept 模式挂载到 equipment:beforeCreatepurchase:beforeSubmit 等业务事件上,实现零侵入的审批门控。本文详解 LifecycleBus 的 emit/intercept 双模式设计,以及如何通过 checkApprovalGate 实现可配置的多级审批。

1. 问题:审批流与业务代码的耦合

传统系统审批的实现方式:

``typescript<br>// 反模式:审批逻辑侵入业务代码<br>async function createEquipment(data) {<br> if (data.value > 100000) {<br> await createApprovalRequest(data);<br> return { status: "pending_approval" };<br> }<br> await insertEquipment(data);<br> return { status: "created" };<br>}<br>``

问题显而易见:

2. EAMX 方案:LifecycleBus 拦截模式

```typescript<br>// equipment 业务代码——完全不涉及审批<br>async function createEquipment(data, ctx) {<br> const result = await db.insert(equipmentsTable).values(data);<br> return { id: result.id, status: "created" };<br>}

// approval 插件——独立于业务代码<br>lifecycleHandler("equipment:beforeCreate", async ({ payload, ctx, abort }) => {<br> if (payload.value > 100000) {<br> const needsApproval = await checkApprovalGate(ctx, {<br> entityType: "Equipment", threshold: 100000,<br> });<br> if (needsApproval) {<br> await createApprovalRequest(ctx, payload);<br> abort("设备价值超过阈值,已提交审批");<br> }<br> }<br>});<br>```

业务代码完全不知道审批的存在。

3. LifecycleBus 双模式对比

| 属性 | emit(观察) | intercept(拦截) |<br>|---|---|---|<br>| 执行方式 | 并行 Promise.allSettled | 串行 for-of |<br>| 失败处理 | 打日志,不中断 | AbortError → 中断主流程 |<br>| 数据修改 | 不能 | ctx.intercept(modified) 修改 payload |<br>| 典型用例 | 通知、日志、缓存失效 | 审批、校验、权限注入 |

4. 完整审批流生命周期

``<br>equipment:beforeCreate<br> ├─ approval 插件检查 → 需要审批?<br> │ ├─ 需要 → 创建审批单 → abort("需要审批")<br> │ └─ 不需要 → 继续<br> ├─ [如果 abort] approval:created 事件 → 通知主管<br> ├─ [主管审批] POST /api/approval/:id/approve<br> │ └─ approval:approved 事件<br> │ └─ equipment 插件监听 → 重新执行 createEquipment<br> └─ [主管拒绝] POST /api/approval/:id/reject<br> └─ approval:rejected 事件 → 通知申请人<br>``

5. 插件注册示例

``typescript<br>export const approvalPlugin: PluginManifest = {<br> id: "approval",<br> name: "审批流",<br> tier: 1,<br> dependencies: ["auth"],<br> permissions: [<br> { action: "approve", subject: "WorkOrder" },<br> { action: "approve", subject: "PurchaseRequest" },<br> ],<br> routePrefix: "/api/approval",<br> createRouter: () => { / CRUD routes / },<br> lifecycleHandlers: {<br> "equipment:beforeCreate": equipmentCreateGate,<br> "purchase:beforeSubmit": purchaseSubmitGate,<br> },<br>};<br>``

17 行注册,零侵入业务代码。

6. 核心文件索引

| 文件 | 行数 | 职责 |<br>|---|---|---|<br>| packages/core/src/lifecycle-bus.ts | 79 | emit/intercept 双模式事件总线 |<br>| packages/core/src/types.ts | — | LifecycleEvent 类型定义 |

下一篇:Tool Registry + MCP Server——AI 的"工具箱"如何按权限动态装配。

作者:白杨,十余年设备资产管理从业经验,EAMX 产品负责人。