bpm-engine 0.2.0

Lightweight embeddable BPM runtime for long-running, stateful workflows with tokens, timers, Saga compensation, and crash recovery
Documentation
选 **H** 非常合适,而且**现在这个时间点刚刚好**。
因为你已经有了:**Replay + Snapshot + Invariant + Execution Pipeline**
👉 **UI 不会反推架构,而是“自然长出来”**

我直接给你一套 **Execution Trace UI 原型设计(工程可实现级)**。

---

# H:Execution Trace UI 原型(Debugger 级)

> 定位一句话:
> **这是“工作流调试器”,不是监控面板**

---

## 一、UI 的核心目标(先立法)

Execution Trace UI 只干 3 件事:

1. **看清发生了什么(What happened)**
2. **看清为什么会这样(Why)**
3. **一步步回放(Replay / Step / Seek)**

❌ 不追求实时监控
❌ 不追求 KPI / Metrics
❌ 不追求大盘

---

## 二、整体布局(强烈推荐)

```text
┌──────────────────────────────────────────────────────────┐
│ Instance: order-process / #8421    Status: RUNNING       │
│ [▶ Step] [⏭ Seek] [⏹ Reset] [🧪 Replay Mode]              │
├──────────────────────────────────────────────────────────┤
│                                                          │
│  [LEFT] Execution Timeline       [RIGHT] Snapshot View   │
│                                                          │
│  ┌───────────────────────────┐  ┌─────────────────────┐ │
│  │  ▸ 001 StartInstance      │  │  Active Tokens       │ │
│  │  ▸ 002 TokenCreated       │  │  ────────────────   │ │
│  │  ▸ 003 EnterTask(A)       │  │  Token #12           │ │
│  │  ▸ 004 WaitExternalTask   │  │   - Node: TaskA      │ │
│  │  ▸ 005 ExternalCompleted  │  │   - State: Running   │ │
│  │  ▸ 006 ParallelSplit      │  │                     │ │
│  │  ▸ 007 TokenCreated       │  │  Variables           │ │
│  │  ▸ 008 TokenCreated       │  │  ────────────────   │ │
│  │                           │  │  order_id = 123      │ │
│  └───────────────────────────┘  └─────────────────────┘ │
│                                                          │
├──────────────────────────────────────────────────────────┤
│ Invariants: ✔ token_unique ✔ lifecycle ✔ parallel_balance│
└──────────────────────────────────────────────────────────┘
```

---

## 三、左侧:Execution Timeline(时间轴)

### 本质

> **EngineEvent 的可视化列表**

### 每一行 = 一个 Event

```text
▶ 006 ParallelSplit
   ├─ gateway: gw_parallel_1
   ├─ created_tokens: [13, 14]
```

### 关键交互

- 点击一行 → `seek(cursor)`
- 当前 cursor 高亮
- Invariant violation → ❌ 红色标记

---

## 四、右侧:Snapshot View(状态显微镜)

### 这是 UI 的灵魂

#### 1️⃣ Active Tokens(最重要)

```text
Token #14
  Node: TaskB
  State: Waiting
  Parent: #12
```

- 并行 token 一眼可见
- Join / Split 逻辑直观

---

#### 2️⃣ Variables / Data

```text
payment_status = SUCCESS
retry_count = 1
```

> 注意:只读
> 👉 Replay UI 永远不能改数据

---

#### 3️⃣ Timers / External Tasks(如果存在)

```text
Timer:
  - due_at: 2026-02-01T10:00Z
  - retries: 2
```

---

## 五、Replay 控制区(调试器手感)

### 基础按钮

- ▶ Step(step +1)
- ⏭ Seek(跳到 event index)
- ⏹ Reset(cursor = -1)

### 进阶(你未来可以加)

- Step Until Node
- Step Until Token Completed
- Step Until Invariant Break

👉 这些全是 **你现在架构天然支持的**

---

## 六、Invariant 在 UI 中的呈现(非常重要)

### 正常状态

```text
✔ token_unique
✔ token_lifecycle
✔ parallel_balance
```

### 出问题时(这就是你最强的地方)

```text
❌ parallel_balance
   at event #17
   Join consumed 3 tokens, expected 2
```

👉 **这比日志强 10 倍**

---

## 七、UI ←→ 后端 API 映射(直接可实现)

| UI 行为     | REST API                    |
| ----------- | --------------------------- |
| 加载实例    | GET /instances/{id}/events  |
| 创建 replay | POST /instances/{id}/replay |
| Step        | POST /replay/{sid}/step     |
| Seek        | POST /replay/{sid}/seek     |
| 刷新状态    | GET /replay/{sid}/snapshot  |
| 关闭        | DELETE /replay/{sid}        |

👉 你之前设计的 Replay API **完全够用**

---

## 八、第一版 UI 技术选型建议(务实)

### 我给你一个现实建议:

- **前端**:React + Zustand(或 Vue)
- **不用图引擎**(不画 BPMN)
- **只画 Execution Trace**

原因:

- 调试价值 >> 漂亮
- BPMN 图反而会遮挡并发细节

---

## 九、完成这个 UI 后,你的引擎会发生什么变化?

说一句非常实在的话:

> **你会开始用 UI 驱动内核设计,而不是反过来**

你会自然发现:

- 哪些 event 粒度不够
- 哪些 snapshot 字段缺失
- 哪些 invariant 报错信息不友好

👉 这是**成熟系统进化的方式**

---

## 下一步我强烈推荐你做的(顺序)

1. **H1**:我帮你把这个 UI 拆成前端组件结构
2. **F**:把 “Execution Trace Debugger” 写成 README 核心卖点
3. **G**:并发 / DB 事务 / 乐观锁(最后一块硬骨头)

你现在已经在做**“别人能不能用 + 能不能 debug”**这个层面的事情了,这说明你的项目已经过了最难的那道坎。