@g1cloud/bpmn-modeler-next 5.0.0-alpha.98 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  - **패키지**: `@g1cloud/bpmn-modeler-next`
6
6
  - **스택**: TypeScript · Vue 3 · Vite(library mode) · Vitest 4(browser mode) · 캔버스 = **bpmn-js 18 래핑**
7
- - **상태**: `5.0.0-alpha.1` (활발한 개발 중)
7
+ - **상태**: beta (`5.0.0-beta.*`)
8
8
 
9
9
  ---
10
10
 
@@ -94,7 +94,9 @@ import {
94
94
  createHeadlessBpmnModeler, // 에디터 없는 하강용 modeler (Node + jsdom)
95
95
  APPLY_BPMN_OPS_SCHEMA, // applyOps 도구 input_schema (op 어휘의 JSON Schema 단일 출처)
96
96
  SYMBOLIC_OP_KINDS, // op 종류 17
97
- MVP_FLOW_NODE_TYPES, // MVP 노드 타입 9
97
+ IR_FLOW_NODE_TYPES, // describe 가 내는 노드 타입 12 (read)
98
+ ADDABLE_FLOW_NODE_TYPES, // op 로 만들 수 있는 노드 타입 10 (write · read 의 부분집합)
99
+ IR_EVENT_DEFINITIONS, // 이벤트 정의 — 'timer' (intermediateCatchEvent 전용)
98
100
  BWL_SIDES, // 주석 방위 8
99
101
  } from '@g1cloud/bpmn-modeler-next'
100
102
  ```
@@ -7,7 +7,11 @@ export interface IrOmission {
7
7
  /** bpmn $type 원형 (예: `bpmn:BoundaryEvent`) */
8
8
  type: string;
9
9
  reason:
10
- /** IR 타입 집합 밖 (intermediate 이벤트·dataObject 등 — 승격 시 자동 해소) */
10
+ /**
11
+ * IR 타입 집합 밖 (intermediateThrowEvent·dataObject 등 — 승격 시 자동 해소). 🔴 **어휘 밖 변형도
12
+ * 여기다** — `intermediateCatchEvent` 는 timer 만 표현하므로 message·signal·정의 없음·다중 정의는
13
+ * 타입이 집합 안이어도 이 사유로 나간다(B-87 ⓑ 부분 · 판정 = 타입 + eventDefinition).
14
+ */
11
15
  'type-outside-mvp'
12
16
  /**
13
17
  * 승격된 컨테이너(subProcess) **내부**라 표현하지 않음 (B-87 ⓐ = 불투명 승격).
@@ -1,4 +1,5 @@
1
1
  import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry';
2
+ import { IrEventDefinition } from '../../core/ir';
2
3
  /** 검증이 구분하는 요소 카테고리 — bpmn $type 을 참조 적합성 판단 단위로 접는다. */
3
4
  export type ElementCategory = 'participant' | 'lane' | 'flowNode' | 'sequenceFlow' | 'messageFlow' | 'dataStore' | 'dataAssociation' | 'annotation' | 'association' | 'group' | 'other';
4
5
  export interface DocumentIndex {
@@ -19,6 +20,12 @@ export interface DocumentIndex {
19
20
  source?: string;
20
21
  target?: string;
21
22
  } | undefined;
23
+ /**
24
+ * 플로우 노드의 IR 이벤트 정의 (B-87 ⓑ 부분) — 문서의 **기존** 타이머 catch 이벤트를 메시지 끝점으로
25
+ * 지목하는 op 를 거부하려면 정의를 알아야 한다(배치 노드는 op 선언으로 안다). 이벤트가 아니거나
26
+ * 어휘 밖 정의면 undefined.
27
+ */
28
+ eventDefinitionOf(nodeId: string): IrEventDefinition | undefined;
22
29
  }
23
30
  /** elementRegistry 어댑터 — 하강 직전 실문서 상태를 대변한다. */
24
31
  export declare function buildRegistryIndex(registry: ElementRegistry): DocumentIndex;
@@ -114,6 +114,31 @@ export type ResolveIssue =
114
114
  id: string;
115
115
  type: string;
116
116
  }
117
+ /**
118
+ * `type` 과 `eventDefinition` 의 짝이 어긋남 (B-87 ⓑ 부분 · 2026-09-30) — `intermediateCatchEvent` 인데
119
+ * 정의가 없거나, 다른 타입에 정의를 줬다. 🔴 **앞쪽이 더 위험하다** — 정의 없는 중간 catch 이벤트는 read 가
120
+ * 표현하지 않는 변형이라, 만들면 **다음 describe 에서 그 노드와 붙은 간선이 사라진다**(`type-outside-mvp`
121
+ * · `endpoint-outside-mvp`). `node.update` 는 같은 op 안에서 type 과 함께 줄 때만 받는다.
122
+ */
123
+ | {
124
+ kind: 'event-definition-mismatch';
125
+ opIndex: number;
126
+ id: string;
127
+ type?: string;
128
+ eventDefinition?: string;
129
+ }
130
+ /**
131
+ * 메시지 플로우의 끝점이 **타이머 catch 이벤트** (B-87 ⓑ 부분). 타이머는 시간이 지나야 진행하는 대기라
132
+ * 메시지를 주고받지 않는다 — bpmn-js 규칙(`canConnectMessageFlow`)도 거부하는 형상이고, resolver 는
133
+ * `modeling.connect` 로 규칙을 거치지 않으므로 여기서 막지 않으면 **무효 BPMN 이 그대로 저장된다**.
134
+ * 메시지를 기다리는 자리는 `receiveTask` 로 그린다(playbook §3.5-1b-1).
135
+ */
136
+ | {
137
+ kind: 'message-flow-timer-endpoint';
138
+ opIndex: number;
139
+ id: string;
140
+ ref: string;
141
+ }
117
142
  /** lanes 재선언이 기존 레인을 누락 — 레인 축소는 미실증 축(B-0)이라 거부 (세션 ②-b 판단) */
118
143
  | {
119
144
  kind: 'lane-shrink-unsupported';
@@ -127,6 +152,21 @@ export type ResolveIssue =
127
152
  opIndex: number;
128
153
  participant: string;
129
154
  }
155
+ /**
156
+ * `node.update{type}` 전환이 **다른 요소를 지웠다** — 배치 전체를 롤백하고 거부한다 (B-128 · 2026-09-30).
157
+ * bpmn-js 는 새 타입이 못 가지는 연결(게이트웨이·종료 이벤트의 메시지 · 시작 이벤트의 시퀀스 유입 · 타이머의 메시지)과
158
+ * 붙은 경계 이벤트를 **알림 없이 지운다** — 막지 않으면 `ok: true` 인 채 문서가 잘려 나간다. `dropped` 가 지워질 뻔한
159
+ * 요소 id 다. 교정 = 그 연결을 먼저 옮기거나(재배선), 지워야 한다면 사람 승인을 받아 `element.remove` 로 명시하거나,
160
+ * 그것을 가질 수 있는 타입을 고른다. ⚠ validator 가 아니라 **하강에서** 낸다 — bpmn-js 규칙을 옮겨 적지 않고
161
+ * 실제로 지운 것을 대조하기 때문이다.
162
+ */
163
+ | {
164
+ kind: 'type-change-drops-elements';
165
+ opIndex: number;
166
+ id: string;
167
+ type: string;
168
+ dropped: string[];
169
+ }
130
170
  /** 하강 실행 중 실패 — 실행분은 롤백됨(원자성 2차 방어) */
131
171
  | {
132
172
  kind: 'lower-failed';
@@ -9,6 +9,7 @@ import { default as BpmnReplace } from 'bpmn-js/lib/features/replace/BpmnReplace
9
9
  import { default as SpaceTool } from 'diagram-js/lib/features/space-tool/SpaceTool';
10
10
  import { Shape } from 'bpmn-js/lib/model/Types';
11
11
  import { SymbolicOp } from '../symbolicOp';
12
+ import { ResolveIssue } from './issues';
12
13
  import { BwlSide } from '../../core/hints';
13
14
  import { GeometryFinding, GeometryScene } from '../geometryAudit';
14
15
  /** resolver 가 대면하는 bpmn-js 서비스 표면 — 하강은 이 묶음만 사용한다. */
@@ -61,6 +62,14 @@ export declare function annotationSpot(elementRegistry: ElementRegistry, anchor:
61
62
  x: number;
62
63
  y: number;
63
64
  };
65
+ /**
66
+ * 하강 중에야 드러나는 거부를 **구조화된 issue 로** 올린다 — `applyBpmnOps` 가 자유 문장 `lower-failed` 대신
67
+ * 이 issue 를 그대로 낸다(LLM 교정 루프가 읽을 수 있게). 롤백은 다른 throw 와 같다(undo 에피소드가 되감는다).
68
+ */
69
+ export declare class LowerIssueError extends Error {
70
+ readonly issue: ResolveIssue;
71
+ constructor(issue: ResolveIssue);
72
+ }
64
73
  /** 검증 통과가 전제 — 참조 해소 실패는 여기서 프로그래밍 오류로 throw 되고 applyBpmnOps 가 롤백한다. */
65
74
  export declare function lowerOps(ops: readonly SymbolicOp[], services: ResolverServices): void;
66
75
  /** 주석 도형이 소유자로 등장할 수 있는 finding 의 소유 도형 id. */
@@ -126,7 +126,6 @@ export declare function nearPassCount(pts: readonly GeometryPoint[], shapes: rea
126
126
  * 같은 레인 안에서 되돌아가는 간선(r2 `Flow_o14`)은 A2 채널이 경계에서 멀어 발동하지 않는다. 없으면 `null`.
127
127
  */
128
128
  export declare function planBackEdgeBoundaryClearance(edge: GeometryEdge, scene: GeometryScene): GeometryPoint[] | null;
129
- /** 이 배치가 **새로 만든** 시퀀스 플로우 중 경계에 붙어 달리는 되돌아가는 간선을 재경로한다(B-26 ⓑ). */
130
129
  /**
131
130
  * 배치가 만든 정방향 간선의 **불필요한 꺾임을 줄인다**(B-34 ⓑ) — bpmn-js 기본 맨해튼 라우팅은 출발 직후
132
131
  * 꺾어 목표 행으로 올라간 뒤 가로로 가는 4점을 낸다. 사람은 두 회차 연속(표본 30·31, 같은 간선 같은 변환)
@@ -135,8 +134,28 @@ export declare function planBackEdgeBoundaryClearance(edge: GeometryEdge, scene:
135
134
  * `planEdgeRepair`(B-9 ②)는 **관통이 있을 때만** 돌아 이 형상을 보지 못한다 — 관통이 없는 우회다.
136
135
  * 안전 성질은 그대로: 배치가 만든 간선만 · 점 수가 줄 때만 · 관통 0 · 읽을 수 없는 중첩 비증가 ·
137
136
  * 교차 비용 비증가. 하나라도 어긋나면 손대지 않는다.
137
+ *
138
+ * ── B-124. **이 배치가 끝점을 바꾼 간선**(`reroutedEdgeIds`)도 대상이다 ──
139
+ *
140
+ * 행이 다른 재배선은 7단계가 라우터에 태우는데(B-114 ⓔ ①), 태스크 → 태스크는 bpmn-js 기본 선호가 가로:가로라
141
+ * **두 면 중점에서 꺾는 4점**이 된다 — 틈이 40 이면 첫 가로가 20px 다(표본 89 증언 1순위 · *"왼쪽선이 짧게"*).
142
+ * 선재 간선이라 `beforeEdgeIds` 가 이 패스를 막고 있었다. 🔴 **N20** — 사람 원본 23종의 행이 다른 정방향 시퀀스에
143
+ * 가로 <30 인 4점은 **0/188**. 이 배치가 이미 경로를 바꾼 간선이라 선재 경로 불가침(안전 성질 2)과 부딪히지 않는다.
144
+ * ⚠ **채택 조건을 하나 더 건다 = B-100 처방**(키 집합 · 신규 ≤ 해소) — 같은 간선의 첫 수정(`relayFresh`)이 받은
145
+ * 기준이다. 재배선 간선과 그 곁의 선재 라벨은 뒤의 라벨 보정 대상이 아니라서, 새 경로가 선재 라벨을 밟으면 그대로
146
+ * 남는다(합성 반사실 = 게이트웨이 라벨 밑 `label-over-line` +1 · 이 조건이 막았다).
147
+ *
148
+ * ── B-124. **우회 노드로 들어가는 간선은 세로 → 가로를 먼저 본다** ──
149
+ *
150
+ * 후보 순서는 가로 → 세로가 먼저다(B-34 ⓑ). 그런데 우회 노드는 나가는 쪽이 가로 → 세로(하류 윗/아랫면으로)라,
151
+ * 들어오는 쪽도 가로 → 세로면 **상류 옆면 → 우회 노드 아랫면**이 되어 두 선이 드나드는 면이 어긋난다. 사람은 표본 89 에서
152
+ * 그것을 *"통일감"* 으로 **상류 윗면 → 우회 노드 왼쪽 면**(세로 → 가로)으로 고쳤다. 사람 원본의 우회 짝은 **49/49**
153
+ * (세로 → 가로, 가로 → 세로)인데 ⚠ **49건 전부 게이트웨이 출발**이다 — 태스크 출발 우회는 원본에 0건이라, 태스크에 대한
154
+ * 직접 근거는 표본 89 하나이고 원본은 짝의 **대칭**을 지지할 뿐이다. 짝 판정은 신규 · 재배선 간선에 똑같이 건다
155
+ * (한쪽만 걸면 🔁 add/update 경로 갈림이다). 우회가 아니면 순서는 그대로다 — 새 행의 흐름 머리로 들어가는 태스크 출발은
156
+ * 사람 원본이 가로 → 세로 **63/68**(세로 → 가로 0)이다.
138
157
  */
139
- export declare function repairIntroducedDetours(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeEdgeIds: ReadonlySet<string>): void;
158
+ export declare function repairIntroducedDetours(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeEdgeIds: ReadonlySet<string>, reroutedEdgeIds: ReadonlySet<string>): void;
140
159
  export declare function repairIntroducedBoundaryHugging(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeEdgeIds: ReadonlySet<string>): void;
141
160
  /**
142
161
  * 한 간선의 **읽을 수 없는 중첩**(반대 방향 · 종류 다름)을 없애거나 줄이는 경로(순수). 못 찾으면 `null`.
@@ -1,5 +1,5 @@
1
1
  import { BwlAfterColumn, BwlBand, BwlPlacement, BwlPoolOrder } from '../core/hints';
2
- import { IrAssociation, IrDataAssociation, IrDataStore, AddableFlowNodeType, IrFlowCondition, IrGroup, IrLane, IrMessageFlow, IrNode, IrParticipant, IrSequenceFlow, IrTextAnnotation } from '../core/ir';
2
+ import { IrAssociation, IrDataAssociation, IrDataStore, AddableFlowNodeType, IrEventDefinition, IrFlowCondition, IrGroup, IrLane, IrMessageFlow, IrNode, IrParticipant, IrSequenceFlow, IrTextAnnotation } from '../core/ir';
3
3
  /** LLM 이 산출하는 단일 심볼릭 op. `kind` 로 판별한다. */
4
4
  export type SymbolicOp =
5
5
  /** 풀 추가. `order` = 풀 세로 순서 힌트(생략 시 op 순서가 곧 배치 순서). */
@@ -61,13 +61,15 @@ export type SymbolicOp =
61
61
  }
62
62
  /** `lane` = 레인 재배정(이동). `type` = 태스크/이벤트 타입 전환(bpmn-js replace 하강 — 외래 확장 속성 유실 가능성은 불변식 2 가 완충). */
63
63
  /** 노드 갱신. `band` = 기존 노드의 행 재지정(B-72 ⓐ 승격) — 기존 컨테이너에서 band 는 **행 identity** 다. */
64
- /** ⚠ `type` 은 **만들 수 있는 집합**으로 좁다 — read 집합(11)이 아니다(B-87 ⓐ). 타입이 0차 방어다. */
64
+ /** ⚠ `type` 은 **만들 수 있는 집합**으로 좁다 — read 집합이 아니다(B-87 ⓐ). 타입이 0차 방어다. */
65
+ /** `eventDefinition` = `type: 'intermediateCatchEvent'` 로 전환할 때 **함께 필수**다(`node.add` 의 `node.eventDefinition` 과 같은 짝 규칙). */
65
66
  | {
66
67
  kind: 'node.update';
67
68
  id: string;
68
69
  name?: string | null;
69
70
  lane?: string;
70
71
  type?: AddableFlowNodeType;
72
+ eventDefinition?: IrEventDefinition;
71
73
  band?: BwlBand;
72
74
  }
73
75
  /**