Skip to content

ADR-003: 连线校验设计

Status

Accepted

Date

2026-03-23

Context

画布编辑器允许用户通过拖拽创建节点间连线。需要防止无效连线(自连接、循环依赖、重复连线),否则数据流引擎会出现死循环或不可预测行为。

校验逻辑需要在两个时机执行:

  1. 拖拽中实时反馈 — Vue Flow 的 isValidConnection 回调,决定是否允许用户将连线放下
  2. 创建时最终校验flowStore.addEdge() 调用前,双重保险

Options Considered

Option A: 在 flowStore 内部直接写校验逻辑

  • Pros: 简单,所有逻辑集中在一个文件
  • Cons: 依赖 Vue Flow 和 Pinia,难以独立测试;校验逻辑与状态管理耦合

Option B: 抽取为纯函数模块

  • Pros: 零依赖,可在任何环境独立测试;输入输出明确(edges 数组 + 新 edge → 校验结果)
  • Cons: 多一个文件

Decision

选择 Option B:校验逻辑抽取为 stores/flowValidation.ts 纯函数模块。

三级校验策略(按检测成本从低到高排列):

  1. 自连接检测source === target,O(1)
  2. 循环检测:BFS 从 target 出发沿现有边正向遍历,检测能否到达 source,O(V+E)
  3. 重复检测:遍历现有边检测相同 source/target/handle 组合,O(E)

导出类型 EdgeValidationResult: { valid: boolean, reason?: 'self-connection' | 'cycle' | 'duplicate' }

Consequences

  • 校验函数无任何框架依赖,可用纯 Vitest 测试覆盖
  • flowStore 通过 validateEdge(edges.value, newEdge) 调用,保持 store 简洁
  • isValidConnection 回调同样委托给 flowStore.validateEdge,避免重复实现
  • 未来若需支持"输入端口单连线"规则(后连接替换先前连线),只需在 validateEdge 中新增一级检测