Skip to content

Feature: 连线系统

一句话目标

用户通过连线构建节点间的数据流向,系统提供方向约束、角色校验、拓扑验证,确保工作流拓扑合理且可执行。

行为约束

约束 1:Handle 方向规则

前置条件: 用户拖拽创建连线 行为: 连线只能从 source handle 连到 target handle;同类型 handle 之间不可相连 后置条件: 非法方向的连线不会被创建

约束 2:连线创建 — 拖拽到 Handle

前置条件: 画布中有两个以上节点 行为: 用户从节点 A 的 source handle 拖拽到节点 B 的 target handle,创建 A → B 连线 后置条件: 连线通过验证后创建并持久化

约束 3:连线创建 — 拖拽到节点体

前置条件: 用户从节点 A 的 source handle 拖拽连线到节点 B 的节点体(非 handle 区域) 行为: 系统自动建立 A(source) → B(target) 的连线,不弹出节点创建菜单 后置条件: 连线通过验证后创建并持久化

约束 4:连线创建 — 拖拽到空白区域

前置条件: 用户从节点 A 的 source handle 拖拽连线到画布空白区域 行为: 在释放位置弹出浮动菜单,用户选择类型后创建新节点并自动建立连线 后置条件: 新节点创建,A → 新节点的连线创建并持久化

约束 5:拓扑验证

前置条件: 用户尝试创建连线 行为: 系统验证三种非法拓扑:自连接(source === target)、循环(会形成有向环)、重复边(相同 source/target/handles) 后置条件: 非法连线不被创建

约束 6:节点连接角色规则

前置条件: 用户尝试创建连线,目标节点为 Image/Video 类型 行为: origin 为 uploaded 的 Image/Video 节点不可作为 target;emptygenerated 可作为 target;文本节点不受 origin 限制 后置条件: 违反角色规则的连线不被创建

角色矩阵:

节点类型origin可作为 source可作为 target
文本任意
图片empty
图片uploaded
图片generated
视频empty
视频uploaded
视频generated

约束 7:连线随节点删除

前置条件: 画布中有节点及其关联连线 行为: 用户删除节点时,所有关联连线同时被移除 后置条件: 节点和关联连线均被删除并持久化

Acceptance Criteria

  • [x] AC-01:自连接(source === target)被阻止
  • [x] AC-02:循环连线被阻止
  • [x] AC-03:重复边被阻止
  • [x] AC-04:删除节点同时移除关联连线
  • [x] AC-05:连线拖到空白区域弹出浮动菜单创建节点
  • [x] AC-06:连线只能从 source handle 连到 target handle
  • [x] AC-07:同类型 handle(source→source 或 target→target)不可相连
  • [x] AC-08:从 source handle 拖拽到目标节点 handle 可创建连线
  • [x] AC-09:从 source handle 拖拽到目标节点体(非 handle)自动建立 source→target 连线,不弹出创建菜单
  • [x] AC-10:origin 为 uploaded 的 Image/Video 节点不可作为 target

BDD Scenarios

gherkin
Feature: 连线系统

  # AC-01
  Scenario: 阻止自连接
    Given 画布中有节点 A
    When 用户从 A 的 source handle 拖拽到 A 的 target handle
    Then 连线不被创建

  # AC-02
  Scenario: 阻止循环连线
    Given 画布中有 A → B 的连线
    When 用户尝试从 B 连到 A
    Then 连线不被创建

  # AC-05
  Scenario: 拖拽到空白区域创建节点和连线
    Given 画布中有节点 A
    When 用户从 A 的 source handle 拖拽到画布空白区域
    Then 在释放位置弹出浮动菜单
    When 选择 "图片" 节点类型
    Then 创建图片节点并自动建立 A → 新节点连线

  # AC-06, AC-07
  Scenario: Handle 方向规则校验
    Given 画布中有节点 A 和节点 B
    When 用户从 A 的 source handle 拖拽到 B 的 target handle
    Then 连线创建成功
    When 用户从 A 的 source handle 拖拽到 B 的 source handle
    Then 连线不被创建

  # AC-08
  Scenario: 拖拽到目标节点 handle 创建连线
    Given 画布中有节点 A 和节点 B
    When 用户从 A 的 source handle 拖拽到 B 的 target handle
    Then A → B 连线创建成功并持久化

  # AC-09
  Scenario: 拖拽到目标节点体创建连线
    Given 画布中有节点 A 和节点 B
    When 用户从 A 的 source handle 拖拽到 B 的节点体
    Then 自动建立 A(source) → B(target) 连线
    And 不弹出节点创建菜单

  # AC-10
  Scenario: Uploaded 节点不可作为 target
    Given 画布中有文本节点 A 和图片节点 B
    And B 的 origin 为 "uploaded"
    When 用户从 A 连线到 B
    Then 连线不被创建

  Scenario: Empty 节点可作为 target
    Given 画布中有文本节点 A 和图片节点 B
    And B 的 origin 为 "empty"
    When 用户从 A 连线到 B
    Then 连线创建成功

TDD 单元测试要点

edge-validation(拓扑验证 + 角色校验,test/unit/flowValidation.test.ts):

  • [x] 自连接返回 { valid: false, reason: 'self-connection' }(AC-01)
  • [x] 存在 A→B 边时,B→A 检测为 cycle(AC-02)
  • [x] 完全相同的 source/target/handles 检测为 duplicate(AC-03)
  • [x] 合法边返回 { valid: true }
  • [x] 同类型 handle 相连返回非法(AC-07)
  • [x] uploaded 图片节点作为 target 返回非法(AC-10)
  • [x] uploaded 视频节点作为 target 返回非法(AC-10)
  • [x] empty / generated 节点作为 target 返回合法(AC-10)
  • [x] 文本节点无论 origin 均可作为 target(AC-10)
  • [x] 旧数据(无 origin 字段)图片节点可作为 target — 向后兼容(AC-10)

Out of Scope

  • ContentOrigin 字段的实现细节(何时设为 uploaded/generated 等)— 属于节点数据模型职责
  • 连线的视觉样式定义(颜色、流光效果参数)— 见 design-system
  • 自定义边组件的具体实现方案 — 属于 feature-dev 阶段
  • 生成时如何处理不兼容上游输入 — 见 data-flow