@g1cloud/entity-modeler-next 5.0.0-alpha.9 → 5.0.0-beta.10

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.
Files changed (49) hide show
  1. package/dist/agent/resolver.d.ts +46 -0
  2. package/dist/agent/symbolicOp.d.ts +10 -1
  3. package/dist/command/commands.d.ts +15 -6
  4. package/dist/core/associationNav.d.ts +16 -0
  5. package/dist/core/attributeOrder.d.ts +26 -0
  6. package/dist/core/ddl.d.ts +10 -0
  7. package/dist/core/fkDerived.d.ts +17 -0
  8. package/dist/core/inheritedColumns.d.ts +57 -0
  9. package/dist/core/jsonModel.d.ts +23 -0
  10. package/dist/core/mergeDiagram.d.ts +45 -0
  11. package/dist/core/mermaid.d.ts +6 -0
  12. package/dist/core/parseMermaid.d.ts +9 -0
  13. package/dist/core/parseSqlDdl.d.ts +11 -0
  14. package/dist/core/projectSeqDiff.d.ts +41 -0
  15. package/dist/core/propagation.d.ts +22 -0
  16. package/dist/core/quickFix.d.ts +12 -0
  17. package/dist/core/scaffoldJava.d.ts +62 -0
  18. package/dist/core/sharedColumn.d.ts +16 -1
  19. package/dist/core/stereotype.d.ts +2 -0
  20. package/dist/core/text.d.ts +4 -1
  21. package/dist/core/types.d.ts +56 -4
  22. package/dist/core/validation.d.ts +37 -6
  23. package/dist/editor/controller.d.ts +88 -10
  24. package/dist/entity-modeler-next.css +1 -1
  25. package/dist/entity-modeler.js +15808 -11445
  26. package/dist/entity-modeler.umd.cjs +45 -24
  27. package/dist/i18n/en.d.ts +3 -0
  28. package/dist/i18n/index.d.ts +17 -0
  29. package/dist/i18n/ja.d.ts +3 -0
  30. package/dist/i18n/ko.d.ts +373 -0
  31. package/dist/index.d.ts +14 -1
  32. package/dist/view/CommandPalette.vue.d.ts +10 -0
  33. package/dist/view/DiagramCanvas.vue.d.ts +5 -0
  34. package/dist/view/EditModeToggle.vue.d.ts +3 -0
  35. package/dist/view/EditorToolbar.vue.d.ts +2 -0
  36. package/dist/view/EmContextMenu.vue.d.ts +7 -2
  37. package/dist/view/GroupCodeCombobox.vue.d.ts +2 -0
  38. package/dist/view/HistoryPanel.vue.d.ts +3 -0
  39. package/dist/view/OperationSourceEditor.vue.d.ts +2 -0
  40. package/dist/view/{EntityTextPreview.vue.d.ts → ShortcutHelpModal.vue.d.ts} +2 -1
  41. package/dist/view/TextExportModal.vue.d.ts +15 -0
  42. package/dist/view/TextImportModal.vue.d.ts +8 -0
  43. package/dist/view/diffOverlay.d.ts +14 -0
  44. package/dist/view/explorerFilter.d.ts +20 -0
  45. package/dist/view/exportImage.d.ts +14 -0
  46. package/dist/view/opConflictNotice.d.ts +12 -0
  47. package/dist/view/validationDisplay.d.ts +14 -2
  48. package/package.json +1 -1
  49. package/dist/view/exportSvg.d.ts +0 -7
@@ -84,6 +84,28 @@ export type ResolveError = {
84
84
  handle: Handle;
85
85
  matches: ModelId[];
86
86
  }
87
+ /** reorder order 목록의 핸들이 엔티티 내 속성/메서드와 0개 매칭(D7 — 부분 재배치 안 함, 전체 거부). */
88
+ | {
89
+ code: 'reorder-handle-not-found';
90
+ opIndex: number;
91
+ entity: Handle;
92
+ handle: Handle;
93
+ }
94
+ /** reorder order 목록의 핸들이 복수 매칭(모호). */
95
+ | {
96
+ code: 'reorder-handle-ambiguous';
97
+ opIndex: number;
98
+ entity: Handle;
99
+ handle: Handle;
100
+ matches: ModelId[];
101
+ }
102
+ /** reorder order 목록에 같은 요소가 두 번(중복 핸들) — 배열 재배치 모호. */
103
+ | {
104
+ code: 'reorder-handle-duplicate';
105
+ opIndex: number;
106
+ entity: Handle;
107
+ handle: Handle;
108
+ }
87
109
  /**
88
110
  * index.update patch에 `columns` 키 — columnRef(dbAttr modelId)는 사람 핸들로 표현 불가라 패스스루 시
89
111
  * 깨진 인덱스가 된다. 컬럼 변경은 index.remove + index.add(컬럼 핸들 해소 구현)로 유도(거부 권고안).
@@ -129,6 +151,30 @@ export type ResolveError = {
129
151
  entity: Handle;
130
152
  handle: Handle;
131
153
  matches: ModelId[];
154
+ }
155
+ /**
156
+ * attribute.update patch의 평탄 dbAttr 키를 스칼라 단일 컬럼으로 매핑할 수 없음. 스칼라(NORMAL·단일 dbAttr)면
157
+ * `dbAttrs[0]`로 자동 매핑되지만, 모호/불가한 대상은 거부한다: EMBED_PREDEF/다중 dbAttr(어느 컬럼인지 모호 →
158
+ * `embeddableOverrides`), dbAttrs 0개/transient(머지할 컬럼 없음), `sharedColumnRef` 평탄(opaque modelId),
159
+ * flat + dotted-dbAttrs 혼용($set 충돌). 통과 시 논리 노드 blind-write로 orphan 오염이라 거부.
160
+ */
161
+ | {
162
+ code: 'attribute-patch-dbattr-flat-key';
163
+ opIndex: number;
164
+ entity: Handle;
165
+ handle: Handle;
166
+ keys: string[];
167
+ }
168
+ /**
169
+ * attribute.update patch에 Attribute 논리 노드에 실재하지 않는 미지 키 — 통과 시 orphan blind-write.
170
+ * 오탈자/스키마 밖 키를 조용히 흡수하지 않고 명시 거부(자기증식 오염 원천 차단).
171
+ */
172
+ | {
173
+ code: 'attribute-patch-unknown-key';
174
+ opIndex: number;
175
+ entity: Handle;
176
+ handle: Handle;
177
+ keys: string[];
132
178
  };
133
179
  export type ResolveResult = {
134
180
  ok: true;
@@ -226,10 +226,15 @@ export type SymbolicOp = {
226
226
  entity: Handle;
227
227
  attribute: Handle;
228
228
  patch: Record<string, unknown>;
229
+ embeddableOverrides?: EmbeddableColumnOverride[];
229
230
  } | {
230
231
  kind: 'attribute.remove';
231
232
  entity: Handle;
232
233
  attribute: Handle;
234
+ } | {
235
+ kind: 'attribute.reorder';
236
+ entity: Handle;
237
+ order: Handle[];
233
238
  } | {
234
239
  kind: 'association.add';
235
240
  spec: AssocSpec;
@@ -271,6 +276,10 @@ export type SymbolicOp = {
271
276
  kind: 'operation.remove';
272
277
  entity: Handle;
273
278
  operation: Handle;
279
+ } | {
280
+ kind: 'operation.reorder';
281
+ entity: Handle;
282
+ operations: Handle[];
274
283
  } | {
275
284
  kind: 'group.add';
276
285
  spec: GroupSpec;
@@ -279,5 +288,5 @@ export type SymbolicOp = {
279
288
  * v1이 다루는 심볼릭 op 종류의 닫힌 집합(단일 출처). resolver·JSON Schema(`schema.ts`)가 공유한다.
280
289
  * 아래 컴파일타임 단언이 이 튜플과 `SymbolicOp['kind']`의 일치를 강제 — 한쪽만 늘리면 타입 에러.
281
290
  */
282
- export declare const SYMBOLIC_OP_KINDS: readonly ["entity.add", "entity.update", "entity.remove", "attribute.add", "attribute.update", "attribute.remove", "association.add", "association.remove", "association.update", "associationEnd.update", "index.add", "index.update", "index.remove", "operation.add", "operation.update", "operation.remove", "group.add"];
291
+ export declare const SYMBOLIC_OP_KINDS: readonly ["entity.add", "entity.update", "entity.remove", "attribute.add", "attribute.update", "attribute.remove", "association.add", "association.remove", "association.update", "associationEnd.update", "index.add", "index.update", "index.remove", "operation.add", "operation.update", "operation.remove", "attribute.reorder", "operation.reorder", "group.add"];
283
292
  export type SymbolicOpKind = (typeof SYMBOLIC_OP_KINDS)[number];
@@ -1,6 +1,12 @@
1
- import { Association, AssociationEnd, AssociationLayout, Attribute, Entity, EntityIndex, Geo, LogicalGroup, ModelId, Note, Operation, Point } from '../core/types';
1
+ import { Association, AssociationEnd, AssociationLayout, Attribute, Entity, EntityIndex, EntityLayout, Geo, GroupLayout, LogicalGroup, ModelId, Note, Operation, Point } from '../core/types';
2
2
  import { Command } from './types';
3
- export declare function addEntity(entity: Entity, geo: Geo): Command;
3
+ /**
4
+ * geo 외 EntityLayout 부가 필드(collapsed·displayMode·style·attributeStyles 등).
5
+ * import 등 레이아웃 스타일까지 복제하는 경로에서 전달. entityRef·geo는 별도 인자라 제외.
6
+ * locked는 뷰 어포던스라 호출자가 필요 시만 포함(import는 드롭).
7
+ */
8
+ export type EntityLayoutExtras = Partial<Omit<EntityLayout, 'entityRef' | 'geo'>>;
9
+ export declare function addEntity(entity: Entity, geo: Geo, extras?: EntityLayoutExtras): Command;
4
10
  /** 엔티티 삭제 — 참조 관계·레이아웃·그룹 멤버십까지 cascade. memento로 위치 보존 복원. */
5
11
  export declare function removeEntity(entityId: ModelId): Command;
6
12
  /** 엔티티 필드 부분 수정 (name·stereotype·package·table·jpaAttrs·description 등). 얕은 patch. */
@@ -30,7 +36,9 @@ export declare function setEntityLocked(entityId: ModelId, locked: boolean): Com
30
36
  export declare function setAllEntitiesCollapsed(collapsed: boolean): Command;
31
37
  /** 속성 강조 색상 변경 (레이아웃 attributeStyles[attrId]) */
32
38
  export declare function setAttributeSwatch(entityId: ModelId, attributeId: ModelId, token: string | null): Command;
33
- export declare function addGroup(group: LogicalGroup, geo: Geo): Command;
39
+ /** geo GroupLayout 부가 필드(style ). entityLayout의 EntityLayoutExtras 거울. */
40
+ export type GroupLayoutExtras = Partial<Omit<GroupLayout, 'groupRef' | 'geo' | 'memberNoteRefs'>>;
41
+ export declare function addGroup(group: LogicalGroup, geo: Geo, extras?: GroupLayoutExtras): Command;
34
42
  /** 그룹 필드 부분 수정 (name·description·packageName·excludeDDLGeneration). 얕은 patch. */
35
43
  export declare function updateGroup(groupId: ModelId, patch: Partial<LogicalGroup>): Command;
36
44
  /** 그룹 해제(삭제) — 멤버 엔티티는 남고 그룹/박스만 제거 */
@@ -52,10 +60,11 @@ export declare function updateAttribute(entityId: ModelId, attributeId: ModelId,
52
60
  export declare function removeAttribute(entityId: ModelId, attributeId: ModelId): Command;
53
61
  /**
54
62
  * 속성 재정렬 — 대상(attrIds)을 현재 표시 순서를 유지한 채 toIndex로 이동.
55
- * 표시 순서 = attributes 배열 순서가 SoT이므로 배열을 splice 이동하고, 저장·range선택이
56
- * 의존하는 order 필드를 0..n-1로 전체 재인덱싱한다(중간 삭제로 생긴 기존 갭도 함께 치유).
57
- * toIndex = 대상을 모두 제거한 뒤의 배열(rest) 기준 삽입 위치.
63
+ * 표시 순서 SoT는 `order` 필드다(S1 이후 뷰가 order sort). 배열도 splice 함께 맞춰 두 표현을
64
+ * 일관 유지하고(캔버스 노드가 배열도 참조하는 전환기 안전), order 필드를 0..n-1로 전체 재인덱싱한다
65
+ * (중간 삭제로 생긴 기존 갭도 함께 치유). toIndex = 대상을 모두 제거한 뒤의 배열(rest) 기준 삽입 위치.
58
66
  * invert는 변경 전 배열 스냅샷(order 포함 얕은 복사)으로 통째 복원 → 재인덱싱 손실 없이 원자 원복.
67
+ * emit은 order 패치(S3, orderPatchEmission) — 배열 $set 아님.
59
68
  */
60
69
  export declare function reorderAttributes(entityId: ModelId, attrIds: ModelId[], toIndex: number): Command;
61
70
  export declare function addOperation(entityId: ModelId, operation: Operation): Command;
@@ -0,0 +1,16 @@
1
+ import { Multiplicity } from './types';
2
+ /** end2 multiplicity가 컬렉션(0..* / 1..*)인가 — 코드젠의 @OneToMany vs @OneToOne 분기와 동일 기준. */
3
+ export declare function isCollectionMultiplicity(m: Multiplicity): boolean;
4
+ /**
5
+ * 다중성 표시 기호(0..1 / 1 / 0..* / 1..*) — 영속용 enum(`*_INSTANCE(S)`)의 단일 표시 SoT.
6
+ * 기호는 언어 무관 UML 표기라 i18n 대상이 아니다. 캔버스 관계선 라벨·인스펙터 select·mermaid
7
+ * 라벨이 모두 이 함수로 위임한다(과거 multSymbol/multHuman으로 중복 정의되던 것 통합).
8
+ */
9
+ export declare function multiplicityLabel(m: Multiplicity): string;
10
+ /**
11
+ * inverse nav 기본 이름: 자식 엔티티명(camel). 컬렉션이면 복수형.
12
+ * 예: Order→OrderItem 컬렉션 → `orderItems`, 단일 → `orderItem`.
13
+ */
14
+ export declare function defaultInverseNavName(childEntityName: string, isCollection: boolean): string;
15
+ /** 엔티티 내 속성명 유일화 — 충돌 시 숫자 suffix(addEmbedAssociation 필드명 패턴과 동형). */
16
+ export declare function uniqueAttributeName(base: string, existing: ReadonlySet<string>): string;
@@ -0,0 +1,26 @@
1
+ import { Attribute, Entity } from './types';
2
+ /**
3
+ * 다음 표시 순서 값 = 현재 최대 `order` + 1(비어 있으면 0). 표시 순서가 `order` 필드 단일 SoT이므로
4
+ * add-side는 반드시 이 값을 써야 order가 항상 distinct하다. 배열 `.length`를 쓰면
5
+ * `removeAttribute`/`removeOperation`가 재인덱싱하지 않아(splice만) 남은 order와 length가 충돌할 수
6
+ * 있다(order [0,2] + length 2 → 신규 order 2 = 중복). [[attribute-display-order-array-vs-order-field]]
7
+ */
8
+ export declare function nextOrder(items: readonly {
9
+ order: number;
10
+ }[]): number;
11
+ /** 물리 FK 컬럼을 가진 FK 여부 — derivedFrom(관계 파생) + dbAttrs(물리 컬럼) 보유. */
12
+ export declare function isPhysicalFk(a: Attribute): boolean;
13
+ /**
14
+ * 물리 FK 컬럼을 가진 FK를 순수 PK 바로 뒤로 당긴다. `순수 PK → 물리 FK → 나머지` 순으로 재배열하되,
15
+ * FK끼리·나머지끼리의 상대 순서는 원본 order를 보존한다(순서를 새로 추정하지 않음). 순수 PK가 없으면
16
+ * FK를 맨 앞으로. 물리 컬럼 없는 nav 참조(dbAttrs=0)는 추정이라 제외 — 실제로 그런 참조는 어느 엔티티
17
+ * attributes에도 물질화되지 않으므로(유령 앵커 참조) 대상이 되는 일도 없다.
18
+ *
19
+ * ★ order 필드뿐 아니라 **배열 물리 순서 자체**를 재정렬한다. 캔버스 노드(EntityNode)는 attributes를
20
+ * 배열 순서 그대로 렌더하고(order 정렬 미적용), 코드젠·탐색기는 order로 정렬하므로, 둘을 일치시켜야
21
+ * 모든 표시 경로에서 순서가 같다. [[attribute-display-order-array-vs-order-field]]
22
+ *
23
+ * 경계 강등(mergeDiagram)으로 derivedFrom이 제거된 FK는 `isPhysicalFk`가 false라 일반 컬럼으로 제자리에
24
+ * 남는다 — 강등 이후에 호출해야 한다.
25
+ */
26
+ export declare function reorderForeignAttributes(entities: Entity[]): void;
@@ -0,0 +1,10 @@
1
+ import { EmbeddableCatalog, LogicalModel } from './types';
2
+ export type SqlDialect = 'postgres';
3
+ export interface DdlContext {
4
+ /** EMBED_PREDEF 서브컬럼의 카탈로그 기본 물리명 해석용(validateModel과 동형 주입). */
5
+ embeddableCatalog?: EmbeddableCatalog;
6
+ }
7
+ /** 표시 모드 → 기본 DDL 방언. 현재는 PG 단일. */
8
+ export declare function defaultSqlDialect(): SqlDialect;
9
+ /** 논리 모델을 지정 방언의 SQL DDL로 직렬화. */
10
+ export declare function entityModelToDdl(logical: LogicalModel, _dialect?: SqlDialect, ctx?: DdlContext): string;
@@ -0,0 +1,17 @@
1
+ import { Association, Attribute, DbColumn, Entity } from './types';
2
+ /**
3
+ * FK 유래 컬럼 = 물리 컬럼을 보유한 관계 속성(RELATION* + dbAttrs). 형상(dataType/length/scale/
4
+ * physicalName/notNull 등)은 부모 식별자(PK) + 관계 identifying에서 파생된다.
5
+ * derivedFrom이 아니라 이 불변식을 쓰는 이유: derivedFrom은 세션 중 live propagation으로 만든 FK에만
6
+ * 붙고 어댑터가 로드 시 복원하지 않아(영속 데이터엔 0건) 로드된 다이어그램에선 FK 판정에서 통째로 누락된다.
7
+ * RELATION_REF(inverse nav, dbAttrs=0)는 물리 컬럼이 없어 제외.
8
+ */
9
+ export declare function isFkDerivedColumn(attr: Attribute): boolean;
10
+ /**
11
+ * FK 유래 컬럼 i의 원본(부모 식별자) 컬럼 — 물리명·타입·길이·스케일이 여기서 파생된다. FK 컬럼 자신의
12
+ * dbAttrs가 비어 있을 때(v1→v2 로드/레거시 데이터, 어댑터가 재전파를 하지 않음) placeholder·캔버스
13
+ * 표시에 쓴다(레거시 getForeignDatabaseAttributePlaceholder 동형). 1순위 derivedFrom.sourceAttributeRef
14
+ * (전파가 심은 권위), 2순위 관계 역참조로 부모 식별자 컬럼(derivedFrom 부재하는 레거시 v1 로드 FK 폴백).
15
+ * 못 찾으면 undefined.
16
+ */
17
+ export declare function resolveFkOriginColumn(attr: Attribute, childEntity: Entity | null | undefined, entities: readonly Entity[], associations: readonly Association[], i?: number): DbColumn | undefined;
@@ -0,0 +1,57 @@
1
+ import { Entity, ModelId, MultiLangText, SuperClassCatalog } from './types';
2
+ /**
3
+ * 상속 컬럼 참조 네임스페이스 접두사. 합성 modelId 형식 = `inherited:<BaseClass>:<field>`.
4
+ * 실제 modelId는 crypto.randomUUID()(하이픈 UUID, 콜론 없음)라 이 접두사 공간과 disjoint —
5
+ * IndexColumn.columnRef가 로컬 dbAttr modelId(UUID)와 상속 컬럼(합성)을 단일 ModelId 형태로
6
+ * 균일하게 담을 수 있다(D2 = 2a 합성 stable modelId, IndexColumn 유니온화 회피).
7
+ */
8
+ export declare const INHERITED_REF_PREFIX = "inherited:";
9
+ /** `inherited:<baseClass>:<field>` 합성 modelId 생성. */
10
+ export declare function makeInheritedColumnRef(baseClass: string, field: string): ModelId;
11
+ /** ref가 상속 컬럼 합성 modelId인지. UUID(로컬 dbAttr)면 false. */
12
+ export declare function isInheritedColumnRef(ref: string): boolean;
13
+ /**
14
+ * 합성 modelId를 `{baseClass, field}`로 분해. 상속 ref가 아니거나 형식이 깨졌으면 null.
15
+ * baseClass/field는 자바 식별자라 콜론을 포함하지 않으므로 접두사 뒤 **첫 콜론**으로 분할한다.
16
+ */
17
+ export declare function parseInheritedColumnRef(ref: string): {
18
+ baseClass: string;
19
+ field: string;
20
+ } | null;
21
+ /**
22
+ * 파생(비저장) 상속 컬럼 — `Entity.superClass`가 카탈로그로 기여하는 컬럼을 인덱스 대상으로 참조
23
+ * 가능하게 하는 투영 결과. `entity.attributes`에 넣지 않는다(G4 보존). 뷰 picker·라벨, codegen,
24
+ * 검증이 온디맨드로 이 함수를 호출해 소비한다.
25
+ */
26
+ export interface InheritedColumn {
27
+ /** 합성 modelId(`inherited:<baseClass>:<field>`) — IndexColumn.columnRef가 참조하는 값. */
28
+ modelId: ModelId;
29
+ /** 기여한 슈퍼클래스명(= 카탈로그 name = Entity.superClass). */
30
+ baseClass: string;
31
+ /** 논리 필드명(합성 id 키, D6). */
32
+ field: string;
33
+ /** 물리 컬럼명(@Index columnList 코드젠·라벨용). */
34
+ physicalName: string;
35
+ /** dbTypes 카탈로그 값. */
36
+ dataType: string;
37
+ logicalName?: MultiLangText;
38
+ length?: number;
39
+ scale?: number;
40
+ }
41
+ /**
42
+ * 엔티티의 `superClass`를 카탈로그로 해소해 상속 컬럼을 투영한다(파생·비저장).
43
+ *
44
+ * - `entity.superClass`가 **비어 있으면** 카탈로그의 **default base**(`SuperClassDef.default`)로 폴백한다.
45
+ * 레거시 관례상 superClass 미명시 = 코드젠 암묵 default(`extends BaseEntity`)라, 빈 값은 default 상속으로
46
+ * 해석해야 상속 컬럼이 점등된다. default가 지정 안 된 카탈로그면 빈 값은 여전히 빈 배열(opt-in 보존).
47
+ * - 명시적 `superClass='Object'`(자바 `extends Object` = default 상속 opt-out 트릭)는 non-empty라
48
+ * default 폴백에 안 걸리고 카탈로그 미스 → 빈 배열. opt-out이 자연 보존된다.
49
+ * - D7 스킵: `stereotype === 'JPA_EMBEDDABLE'`(임베더블은 엔티티 상속 안 함), 엔티티 자신이
50
+ * 카탈로그 base(= 상속의 원천)면 스킵(자기 자신에게 투영하는 순환 방지).
51
+ * - 각 투영 컬럼에 합성 modelId(§4.3)를 부여한다.
52
+ * - 초기엔 1단 투영만(대부분 BaseEntity 단일 단계). base가 또 다른 base를 상속하는 다단 체인은
53
+ * 카탈로그가 상위 참조를 표현하도록 확장한 뒤 재귀 활성(범위 밖).
54
+ *
55
+ * 카탈로그가 비어 있거나 매칭 base가 없으면 빈 배열(inert 게이트 — groupCodeCatalog 동일 관례).
56
+ */
57
+ export declare function projectInheritedColumns(entity: Entity, catalog: SuperClassCatalog): InheritedColumn[];
@@ -0,0 +1,23 @@
1
+ import { DiagramLayout, LogicalModel } from './types';
2
+ import { MergeDiagramSource } from './mergeDiagram';
3
+ export declare const DIAGRAM_JSON_FORMAT = "entity-modeler-diagram";
4
+ export declare const DIAGRAM_JSON_VERSION = 1;
5
+ export interface DiagramJsonEnvelope {
6
+ format: typeof DIAGRAM_JSON_FORMAT;
7
+ version: number;
8
+ logical: LogicalModel;
9
+ layout: DiagramLayout;
10
+ }
11
+ /** 파싱 실패(잘못된 JSON·봉투·골격) — 호출부가 사용자에게 사유를 표시할 수 있도록 message에 이유를 담는다. */
12
+ export declare class InvalidDiagramJsonError extends Error {
13
+ constructor(reason: string);
14
+ }
15
+ /** 현재 다이어그램(논리 + 레이아웃)을 이식 가능한 JSON 백업 문자열로 직렬화(pretty). */
16
+ export declare function diagramToJson(logical: LogicalModel, layout: DiagramLayout): string;
17
+ /**
18
+ * JSON 백업 문자열 → 임포트 소스(논리 + 레이아웃). 봉투·모델 골격을 검증하고, 실패 시
19
+ * `InvalidDiagramJsonError`를 던진다. 레이아웃 서브배열이 없으면 빈 배열로 관용 보정한다
20
+ * (논리 전용 JSON도 수용 — importEntities 폴백 geo가 배치). 참조 무결성(dangling)은 mergeDiagram이
21
+ * 관용 처리하므로 여기서 강제하지 않는다.
22
+ */
23
+ export declare function parseDiagramJson(text: string): MergeDiagramSource;
@@ -0,0 +1,45 @@
1
+ import { Association, AssociationLayout, DiagramLayout, Entity, EntityLayout, GroupLayout, LogicalGroup, LogicalModel, ModelId, Point, Style } from './types';
2
+ export interface MergeDiagramSource {
3
+ logical: LogicalModel;
4
+ /** 소스 다이어그램 레이아웃 — 임포트 서브그래프의 좌표/스타일을 함께 옮긴다. */
5
+ layout: DiagramLayout;
6
+ }
7
+ export interface MergeDiagramOptions {
8
+ /** depth-1 관련 엔티티(경계 관계의 반대편)를 선택집합에 함께 끌어와 관계를 유지(D3 옵션 토글). */
9
+ includeRelated?: boolean;
10
+ /** 병합 대상(타깃) 논리 모델 — 이름/테이블 물리명 충돌 감지에 사용(D7). */
11
+ existing: LogicalModel;
12
+ /** 임포트 서브그래프 좌표에 더할 오프셋(D8 — 빈 영역 배치는 호출자가 계산해 전달). */
13
+ offset?: Point;
14
+ /**
15
+ * 이름/물리명 충돌 시 붙일 접미사(D7). 기본 `_imported`(타 모듈 import).
16
+ * 같은 문서 클립보드 붙여넣기는 `_copy`가 자연스럽다(단일 paste와 일관).
17
+ */
18
+ collisionSuffix?: string;
19
+ /** 결정적 테스트를 위한 id 생성기 주입(기본 newId). */
20
+ idFactory?: () => ModelId;
21
+ }
22
+ export interface MergeDiagramResult {
23
+ logical: {
24
+ entities: Entity[];
25
+ associations: Association[];
26
+ groups: LogicalGroup[];
27
+ };
28
+ layout: {
29
+ entityLayouts: EntityLayout[];
30
+ associationLayouts: AssociationLayout[];
31
+ groupLayouts: GroupLayout[];
32
+ };
33
+ /** 소스 modelId → 임포트 modelId 매핑(컨트롤러 진입점·후속 배선용). */
34
+ idMap: Map<ModelId, ModelId>;
35
+ }
36
+ /**
37
+ * 소스 다이어그램의 선택 서브그래프를 새 id 체계로 재매핑해 반환한다.
38
+ *
39
+ * @param source 소스 다이어그램(로드된 논리 + 레이아웃)
40
+ * @param selectedIds 임포트할 엔티티 modelId 목록(부분 선택 — 전량은 전 엔티티 id 전달)
41
+ * @param opts 경계/충돌/오프셋 정책
42
+ */
43
+ export declare function mergeDiagram(source: MergeDiagramSource, selectedIds: ModelId[], opts: MergeDiagramOptions): MergeDiagramResult;
44
+ /** 스타일 맵의 키(속성/연산 modelId) remap — 강등돼 사라진 키는 드롭. */
45
+ export declare function remapStyleKeys(styles: Record<ModelId, Style>, get: (old: ModelId) => ModelId | undefined): Record<ModelId, Style>;
@@ -0,0 +1,6 @@
1
+ import { DisplayMode, LogicalModel } from './types';
2
+ export type MermaidDialect = 'er' | 'class';
3
+ /** 표시 모드 → 기본 Mermaid 방언. CLASS만 클래스 다이어그램, 나머지(논리·물리·논리·물리)는 ER. */
4
+ export declare function defaultMermaidDialect(mode: DisplayMode): MermaidDialect;
5
+ /** 논리 모델을 지정 방언의 Mermaid 소스로 직렬화. */
6
+ export declare function entityModelToMermaid(logical: LogicalModel, dialect: MermaidDialect): string;
@@ -0,0 +1,9 @@
1
+ import { LogicalModel } from './types';
2
+ import { MergeDiagramSource } from './mergeDiagram';
3
+ /** Mermaid ER 소스를 논리 모델로 파싱(순수). 좌표/그룹/노트는 없음(리버스 임포트는 논리 전용). */
4
+ export declare function parseMermaidEr(text: string): LogicalModel;
5
+ /**
6
+ * Mermaid ER 텍스트 → 임포트 소스(논리 + auto-layout 레이아웃). `controller.importEntities`가 그대로 소비한다.
7
+ * 좌표가 없으므로 packEntityBoxes(높이 인지)로 겹침 없는 격자를 생성한다.
8
+ */
9
+ export declare function mermaidErToImportSource(text: string): MergeDiagramSource;
@@ -0,0 +1,11 @@
1
+ import { LogicalModel } from './types';
2
+ import { MergeDiagramSource } from './mergeDiagram';
3
+ export interface ParseSqlDdlResult {
4
+ logical: LogicalModel;
5
+ /** best-effort 파싱에서 건너뛴 statement·해석 못한 부분(부분 성공 가시화). */
6
+ warnings: string[];
7
+ }
8
+ /** SQL DDL을 논리 모델로 파싱(순수·best-effort). warnings에 건너뛴 부분 보고. */
9
+ export declare function parseSqlDdl(text: string): ParseSqlDdlResult;
10
+ /** SQL DDL → 임포트 소스(논리 + auto-layout). controller.importEntities가 그대로 소비. */
11
+ export declare function sqlDdlToImportSource(text: string): MergeDiagramSource;
@@ -0,0 +1,41 @@
1
+ import { ModelId } from './types';
2
+ import { FieldAuditRecord } from './projectFieldAudit';
3
+ import { ActionFieldChange, ActionSubject } from './projectActionLog';
4
+ /** 한 대상의 구간 net 결과 — verb + net 필드 변경(최초 old→최종 new). */
5
+ export interface SeqDiffEntry {
6
+ subject: ActionSubject;
7
+ /** added=구간 내 생성되어 B에 존재 / removed=A에 존재했고 구간 내 삭제 / modified=양쪽 존재+내용 변경. */
8
+ verb: 'added' | 'modified' | 'removed';
9
+ /** net 필드 변경. added=최종값(요약), removed=빈 배열(tombstone), modified=old→new(수렴分 제외). */
10
+ fields: ActionFieldChange[];
11
+ }
12
+ export interface SeqDiff {
13
+ fromSeq: number;
14
+ /** 실효 상한 — 옵션 미지정 시 스트림 최신 seq(레코드 없으면 fromSeq). */
15
+ toSeq: number;
16
+ /** subject 최초 등장 순(결정적). */
17
+ entries: SeqDiffEntry[];
18
+ }
19
+ /**
20
+ * op 이력 스트림을 구간 `(fromSeq, toSeq]`의 subject별 net diff로 투영한다.
21
+ *
22
+ * @param records seq 정렬 이력 레코드(전체 스트림 — old 파생 정확성을 위해 구간 밖 레코드도 포함해 전달).
23
+ * @param range fromSeq(비포함)·toSeq(포함, 생략=최신). D1: 투영기는 일반형, UI는 "과거↔현재"부터.
24
+ */
25
+ export declare function projectSeqDiff(records: readonly FieldAuditRecord[], range: {
26
+ fromSeq: number;
27
+ toSeq?: number;
28
+ }): SeqDiff;
29
+ /** 캔버스 오버레이 마크 — 엔티티 노드 단위(removed 대상은 캔버스에 없어 패널 전용, D3). */
30
+ export interface DiffMark {
31
+ verb: 'added' | 'modified';
32
+ /** 구간 내 추가/변경된 속성 행(하이라이트 대상). 삭제 속성은 행이 없어 제외. */
33
+ changedAttributeIds: Set<ModelId>;
34
+ /** 구간 내 추가/변경된 연산 행. */
35
+ changedOperationIds: Set<ModelId>;
36
+ }
37
+ /**
38
+ * SeqDiff → 캔버스 마크 맵. 엔티티 subject는 자기 verb로, 자식(속성/연산/인덱스) 변경은 부모 엔티티를
39
+ * modified로 승격(이미 added면 유지)한다. 연관/그룹은 S3 스코프 밖(엔티티 오버레이 전용).
40
+ */
41
+ export declare function buildDiffMarks(diff: SeqDiff): Map<ModelId, DiffMark>;
@@ -47,3 +47,25 @@ export declare function reconcileForeignAttributes(logical: LogicalModel, childE
47
47
  * self-association은 비식별이라 자식 식별자를 바꾸지 않아 더 전파되지 않는다(자연 종료).
48
48
  */
49
49
  export declare function planPropagation(logical: LogicalModel, changedEntityId: ModelId, idFactory?: IdFactory): Map<ModelId, ReconcilePlan>;
50
+ /**
51
+ * 주어진 속성이 "연관관계가 관리하는 FK 컬럼"이면 그 소유 연관관계를 돌려준다(아니면 undefined).
52
+ *
53
+ * 논리 모델러 계보(ERwin/ER-Studio/PowerDesigner)에서 FK 컬럼은 관계가 migrate한 파생 속성이라
54
+ * 관계가 소유한다 — 컬럼을 직접 지우는 게 아니라 관계를 삭제/변경해 제거해야 한다. 이 판별로
55
+ * FK 속성의 직접 삭제를 차단(어포던스+가드)하고 사용자를 관계 삭제 경로로 유도한다.
56
+ *
57
+ * FK 컬럼 불변식(RELATION* + 물리 컬럼 보유, EntityNode.keyMarks와 동형)으로 먼저 게이트해, 관계의
58
+ * 부모측 end가 가리키는 PK(비-RELATION) 오탐을 배제한다. 그다음 두 신호로 소유 관계를 찾는다:
59
+ *
60
+ * 1순위 `derivedFrom.associationRef` — 전파가 심은 권위 신호. v2 네이티브 doc에 보존되고 어댑터
61
+ * hydration이 복원한다. GUI·sync 스킬·에이전트 어느 경로로 만들어졌든 FK 자신에 붙어 있어,
62
+ * 관계 end의 `attributeRef`가 stale해도(자기참조 재생성·sync가 링크를 다르게 심은 경우 등) 정확하다.
63
+ * 2순위 관계 end의 `attributeRef` 역참조 — `derivedFrom`이 없는 경우(레거시 v1 로드 FK 등)의 폴백.
64
+ * 방향 규약은 end2=자식이지만 드문 로드 형태가 end1에 실을 수 있어 양 end를 모두 검사한다.
65
+ *
66
+ * (초기엔 attributeRef만 신뢰했으나, sync 스킬로 만든 자기참조 FK가 `derivedFrom`은 정확한데
67
+ * end2.attributeRef는 옛 FK id를 가리키는 실사례로 derivedFrom을 1순위로 승격.)
68
+ *
69
+ * `derivedFrom`이 이미 삭제된 관계를 가리키거나(고아) 둘 다 매칭 없으면 undefined → 직접 삭제(정리) 허용.
70
+ */
71
+ export declare function findFkOwningAssociation(logical: LogicalModel, entityId: ModelId, attributeId: ModelId): Association | undefined;
@@ -0,0 +1,12 @@
1
+ import { JpaCascadeType, LogicalModel, ModelId } from './types';
2
+ import { ValidationIssue } from './validation';
3
+ export interface QuickFixPlan {
4
+ ruleId: string;
5
+ /** 현재는 association end의 cascade 재설정 한 종류(중복 제거). 확장 시 kind 분기 추가. */
6
+ kind: 'setEndCascades';
7
+ assocRef: ModelId;
8
+ which: 'end1' | 'end2';
9
+ cascades: JpaCascadeType[];
10
+ }
11
+ /** 이슈에 적용 가능한 결정적 quick-fix가 있으면 계획을, 없으면 null(순수·부수효과 없음). */
12
+ export declare function resolveQuickFix(issue: ValidationIssue, model: LogicalModel): QuickFixPlan | null;
@@ -0,0 +1,62 @@
1
+ import { LogicalModel, ModelId, SuperClassCatalog, EmbeddableCatalog } from './types';
2
+ import { JavaTypeDef } from './javaTypes';
3
+ export interface ScaffoldOptions {
4
+ /** 저장값→소스 타입 역해소 카탈로그. 미주입 시 lib 내장 `JAVA_TYPES` 폴백(호스트 javaTypeCatalog 미러). */
5
+ javaTypeCatalog?: readonly JavaTypeDef[];
6
+ /** 임베더블 타입 해소용(EMBED_PREDEF 필드 타입·클래스명). 미주입 시 모델 type 폴백 + fillIn. */
7
+ embeddableCatalog?: EmbeddableCatalog;
8
+ /**
9
+ * `extends <superClass>` + 상속 컬럼 인덱스 해소용. 핸드오프 O3 — `SuperClassDef.packageName`이
10
+ * "코드젠 forward 슬롯"으로 예약돼 있고 이 emitter가 그 첫 소비처다. 미주입 시 상속 컬럼/extends 미방출.
11
+ */
12
+ superClassCatalog?: SuperClassCatalog;
13
+ /**
14
+ * 패키지 조합 설정(레거시 codegen 이식 — 프로젝트/모듈 설정 + 그룹 조합). 모델 엔티티엔 packageName 이
15
+ * 없고(모델링 도구 특성), 코드젠이 `{basePackage}.{그룹 packageName}.{layerSuffix}` 로 조합한다.
16
+ * - `basePackage`: 모듈 base(호스트 `srcGenConfig.bizModuleConfigs[moduleId].basePackage`, 예 `net.g1project.ecp.sales.order`).
17
+ * - `layerSuffix`: DDD 레이어 접미(기본 `command.domain` — 실물 골든 관례). 그룹 packageName 이 base 마지막
18
+ * 세그먼트와 중복돼도 정상(대형 모듈은 base 안에 order/claim 서브패키지 존재). 그룹 미소속/무 packageName 이면
19
+ * 그룹 세그먼트 생략. 미주입 시 placeholder 폴백(reconcile 몫).
20
+ */
21
+ packageConfig?: {
22
+ basePackage: string;
23
+ layerSuffix?: string;
24
+ };
25
+ /**
26
+ * GroupCodeEnum 속성의 enum 클래스가 사는 패키지(레거시 codegen 컨벤션 = const 프로젝트 basePackage +
27
+ * `.code`, 예 `net.g1project.ecp.common.code`). 주입 시 `@Enumerated` 필드에 `{pkg}.{groupCode}` import 를
28
+ * 방출한다. 미주입 시 import 생략 + fillIn(패키지 확인). 호스트가 srcGenConfig.constProjectConfig 에서 도출.
29
+ */
30
+ groupCodeEnumPackage?: string;
31
+ /**
32
+ * Lombok 방출 모드(기본 `true` — 모델러 사용 프로젝트가 사실상 전부 Lombok). true면 **필드 단위**
33
+ * `@Getter`(스칼라·단일 임베드·owner 관계, 대형 엔티티 SalesOrch류 관례) + 클래스 `@NoArgsConstructor
34
+ * (access = AccessLevel.PROTECTED)`를 방출하고 수동 getter·protected 생성자를 생략한다. **컬렉션 관계**
35
+ * getter는 @Getter가 raw 컬렉션을 반환해 애그리거트 보호가 깨지므로 예외 — 수동 `Collections.unmodifiable…`
36
+ * 유지(@Getter 미부착). **@Version**은 JPA 관리 내부 필드라 getter 제외(실측 37/38 무 getter).
37
+ * `{Entity}PK`는 필드 @Getter만, equals/hashCode·생성자는 수동. `false` = 수동 전량(생성기/코퍼스 패리티,
38
+ * 바이트 골든 앵커 모드 — @Version getter 포함).
39
+ */
40
+ lombok?: boolean;
41
+ }
42
+ export interface ScaffoldedEntity {
43
+ modelId: ModelId;
44
+ /** `{ClassName}.java` */
45
+ fileName: string;
46
+ /** 조합·결정된 패키지(소비자 UI의 패키지 트리 그룹핑용). placeholder 폴백 시 `com.example`. */
47
+ packageName: string;
48
+ /** 컴파일 가능 최소 골격 자바 소스(`// TODO [손채움]` 포함). */
49
+ source: string;
50
+ /** 사람이 채울 지점 목록(라벨) — reconcile 보고용. */
51
+ fillIns: string[];
52
+ /** 신규 엔티티 경로에서만 write(기존엔 재추가 금지, §4.4) — reconcile 판단. */
53
+ repository?: {
54
+ fileName: string;
55
+ source: string;
56
+ };
57
+ }
58
+ /**
59
+ * 대상 엔티티들을 JPA 자바 소스로 렌더한다. `logical`은 참조 폐포(FK 대상 등) 해소를 위해 전체를 받고,
60
+ * `targetIds`가 실제 산출(파일 생성) 스코프다. 스코프 밖 엔티티는 읽기(폐포)에만 쓰이고 산출되지 않는다.
61
+ */
62
+ export declare function scaffoldEntityJava(logical: LogicalModel, targetIds: readonly ModelId[], opts?: ScaffoldOptions): ScaffoldedEntity[];
@@ -1,4 +1,4 @@
1
- import { DbColumn, ModelId } from './types';
1
+ import { DbColumn, Entity, ModelId } from './types';
2
2
  /** SHARED_REF 컬럼의 파생 투영값. insertable/updatable는 정의상 항상 false. */
3
3
  export interface ResolvedSharedColumn {
4
4
  /** 타깃 컬럼의 물리명(이 컬럼이 read-only로 투영되는 실제 물리 컬럼). */
@@ -6,9 +6,24 @@ export interface ResolvedSharedColumn {
6
6
  insertable: false;
7
7
  updatable: false;
8
8
  }
9
+ /**
10
+ * SHARED_REF 후보·해석의 **컬럼 스코프 엔터티** — "임베드 평탄화 후 같은 물리 테이블에 들어가는
11
+ * 컬럼을 가진 엔터티들". 일반 엔터티는 자기 자신뿐이지만, JPA_EMBEDDABLE 엔터티는 @Embedded로 owner
12
+ * 테이블에 평탄화되므로 owner 엔터티(자기를 EMBED_OWN 표시속성으로 임베드한 엔터티)의 컬럼도 같은
13
+ * 테이블 스코프다 → embeddable 안의 Money.currency가 owner의 통화 writer 컬럼을 SHARED_REF로 공유할 수
14
+ * 있다(BNKR_SALES 실측: OrderAmount·CancellationAmtDetail 등 수많은 embeddable이 owner의 단일 통화
15
+ * 컬럼을 공유하는 지배적 패턴). owner 판별 = `embedded.embeddableRef === 이 엔터티 modelId`인 EMBED_OWN
16
+ * 표시속성 보유(adapter가 owner에 push, diagramAdapter.ts:428). 다중 owner(재사용, 결정 B-1)면 합집합 —
17
+ * 실효 물리명이 같으면 각 usage의 @AttributeOverride가 정상 emit되고 어긋나면 dangling으로 표면화된다.
18
+ * 일반 엔터티엔 [self]만 반환 → 기존 동작 무회귀.
19
+ */
20
+ export declare function sharedColumnScopeEntities(entity: Entity, entities: readonly Entity[]): Entity[];
21
+ /** 스코프 엔터티들의 전 컬럼 평탄화 — 해석 인덱스(`indexColumnsByModelId`) 입력. */
22
+ export declare function collectSharedColumns(entity: Entity, entities: readonly Entity[]): DbColumn[];
9
23
  /**
10
24
  * 같은 엔터티의 컬럼들을 modelId로 인덱싱 — picker 후보 해석·SHARED_REF 타깃 조회 공용 인덱스.
11
25
  * EMBED 펼친 dbAttrs를 포함한 전 컬럼을 평탄화하므로 SHARED_REF 타깃이 임베드 내부여도 조회된다.
26
+ * (embeddable→owner 크로스 스코프가 필요하면 `collectSharedColumns`로 입력을 넓혀 넘긴다.)
12
27
  */
13
28
  export declare function indexColumnsByModelId(columns: readonly DbColumn[]): Map<ModelId, DbColumn>;
14
29
  /**
@@ -0,0 +1,2 @@
1
+ import { ClassStereotype } from './types';
2
+ export declare function stereotypeLabel(s: ClassStereotype): string;
@@ -3,6 +3,9 @@ import { DisplayMode, LogicalModel } from './types';
3
3
  * 표시 모드별 라벨(평문) — Diagram Explorer 트리/캡션 공용.
4
4
  * EntityNode의 labelSegs와 동일 의미 규칙: '논리'는 업무 논리명이며 없으면 '(논리명)'
5
5
  * 플레이스홀더(코드명으로 폴백하지 않음), '물리'는 physicalName, CLASS만 코드명.
6
+ *
7
+ * `logicalFallback`은 논리명 미입력 시 표시할 플레이스홀더(UI 크롬). 뷰는 로케일 문자열
8
+ * (`em.node.logicalMissing`)을 주입하고, 미주입 시 ko 기본값으로 폴백(codegen/테스트 무회귀).
6
9
  */
7
- export declare function displayLabel(mode: DisplayMode, code: string, logical: string | undefined, physical: string | undefined): string;
10
+ export declare function displayLabel(mode: DisplayMode, code: string, logical: string | undefined, physical: string | undefined, logicalFallback?: string): string;
8
11
  export declare function entityModelToText(logical: LogicalModel): string;