@g1cloud/entity-modeler-next 5.0.0-alpha.2 → 5.0.0-alpha.21
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 +31 -17
- package/dist/adapter/persisted.d.ts +6 -0
- package/dist/agent/resolver.d.ts +32 -1
- package/dist/agent/symbolicOp.d.ts +47 -0
- package/dist/command/commands.d.ts +15 -3
- package/dist/core/attributeOrder.d.ts +17 -0
- package/dist/core/dbTypes.d.ts +9 -0
- package/dist/core/inheritedColumns.d.ts +57 -0
- package/dist/core/mergeDiagram.d.ts +38 -0
- package/dist/core/mermaid.d.ts +6 -0
- package/dist/core/migrateLegacyMoney.d.ts +8 -0
- package/dist/core/propagation.d.ts +22 -0
- package/dist/core/resolve.d.ts +4 -0
- package/dist/core/sharedColumn.d.ts +16 -1
- package/dist/core/types.d.ts +64 -0
- package/dist/core/validation.d.ts +8 -1
- package/dist/editor/controller.d.ts +53 -1
- package/dist/entity-modeler-next.css +1 -1
- package/dist/entity-modeler.js +11302 -9757
- package/dist/entity-modeler.umd.cjs +17 -15
- package/dist/index.d.ts +6 -1
- package/dist/view/DiagramCanvas.vue.d.ts +2 -0
- package/dist/view/EditModeToggle.vue.d.ts +1 -0
- package/dist/view/EditorToolbar.vue.d.ts +2 -0
- package/dist/view/EntityBasicsSection.vue.d.ts +8 -1
- package/dist/view/EntityIndexSection.vue.d.ts +7 -1
- package/dist/view/EntityNode.vue.d.ts +1 -0
- package/dist/view/EntityOperationsSection.vue.d.ts +7 -1
- package/dist/view/GroupNode.vue.d.ts +1 -0
- package/dist/view/ShortcutHelpModal.vue.d.ts +2 -0
- package/dist/view/{EntityTextPreview.vue.d.ts → TextExportModal.vue.d.ts} +9 -1
- package/dist/view/explorerFilter.d.ts +20 -0
- package/dist/view/exportImage.d.ts +14 -0
- package/dist/view/opConflictNotice.d.ts +12 -0
- package/package.json +1 -1
- package/dist/view/exportSvg.d.ts +0 -7
package/README.md
CHANGED
|
@@ -1,33 +1,47 @@
|
|
|
1
1
|
# entity-modeler-next
|
|
2
2
|
|
|
3
|
-
Vue 3
|
|
4
|
-
|
|
3
|
+
Vue 3 visual entity-modeling / class-diagram editor.
|
|
4
|
+
Distributed as a library package (`@g1cloud/entity-modeler-next`) and embedded in `bluework4-tool` (Nuxt/Vue/Mongo).
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## Stack
|
|
7
7
|
|
|
8
|
-
TypeScript · Vue 3 · **Vue Flow** · Pinia(
|
|
8
|
+
TypeScript · Vue 3 · **Vue Flow** · Pinia (opt-in) · Vite (library mode) · Vitest · views built on `@g1cloud/open-bluesea-core` (BS) components
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @g1cloud/entity-modeler-next
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires the peer dependencies `vue ^3.5.0` and `@g1cloud/open-bluesea-core` (installed by the host).
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { EntityModeler } from '@g1cloud/entity-modeler-next'
|
|
22
|
+
import '@g1cloud/entity-modeler-next/style.css' // required — components render unstyled without it
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Structure
|
|
11
26
|
|
|
12
27
|
```
|
|
13
28
|
src/
|
|
14
|
-
core/
|
|
15
|
-
command/ Command(do/undo)·CommandStack·op/opSync(
|
|
16
|
-
editor/ reactive controller (
|
|
17
|
-
view/ Vue Flow
|
|
18
|
-
adapter/
|
|
19
|
-
agent/
|
|
20
|
-
dev/
|
|
29
|
+
core/ logical/layout types (separated) · resolve (consistency) · routing · autolayout · propagation · validation · type catalogs. Framework-agnostic
|
|
30
|
+
command/ Command (do/undo) · CommandStack · op/opSync (semantic op emit + CAS concurrency)
|
|
31
|
+
editor/ reactive controller (composable wrapping CommandStack, EDITOR inject key)
|
|
32
|
+
view/ Vue Flow components (DiagramCanvas · EntityNode · GroupNode · AssociationEdge · PropertyPanel · ValidationPanel, etc.)
|
|
33
|
+
adapter/ storage-schema mapping (persisted v1/v2 · fromPersisted/toPersisted/toPersistedV2 round-trip)
|
|
34
|
+
agent/ natural-language → op track (symbolicOp · resolver · schema · buildAgentBatch)
|
|
35
|
+
dev/ demo harness (excluded from the library build)
|
|
21
36
|
```
|
|
22
37
|
|
|
23
|
-
|
|
24
|
-
**현재 구조·상태·문서 인덱스의 정본은 루트 `CLAUDE.md`** (저장 스키마 영향은 `docs/M0-schema-impact.md`).
|
|
38
|
+
Core design: **layout references the logical model by `modelId` (one-way)**. The logical model carries no geo/waypoint/style.
|
|
25
39
|
|
|
26
|
-
##
|
|
40
|
+
## Scripts
|
|
27
41
|
|
|
28
42
|
```bash
|
|
29
|
-
pnpm dev #
|
|
43
|
+
pnpm dev # demo harness dev server (src/dev)
|
|
30
44
|
pnpm test # Vitest
|
|
31
45
|
pnpm typecheck # vue-tsc --noEmit
|
|
32
|
-
pnpm build #
|
|
46
|
+
pnpm build # library build (dist/)
|
|
33
47
|
```
|
|
@@ -47,6 +47,10 @@ export interface PAttribute {
|
|
|
47
47
|
identifier: boolean;
|
|
48
48
|
notNull: boolean;
|
|
49
49
|
transient_?: boolean;
|
|
50
|
+
/** Hibernate @NaturalId(자연키/비즈니스 키). 속성 레벨. v1 레거시엔 없는 신규 옵션. */
|
|
51
|
+
naturalId?: boolean;
|
|
52
|
+
/** @NaturalId(mutable=true). undefined/false=불변(Hibernate 기본). */
|
|
53
|
+
naturalIdMutable?: boolean;
|
|
50
54
|
description?: MultiLangText;
|
|
51
55
|
attributeGroup?: string;
|
|
52
56
|
groupCode?: string;
|
|
@@ -129,6 +133,7 @@ export interface PEntity {
|
|
|
129
133
|
geo?: PGeo;
|
|
130
134
|
style?: PStyle;
|
|
131
135
|
collapsed?: boolean;
|
|
136
|
+
locked?: boolean;
|
|
132
137
|
}
|
|
133
138
|
export interface PIndex {
|
|
134
139
|
modelId: string;
|
|
@@ -165,6 +170,7 @@ export interface PGroup {
|
|
|
165
170
|
notes?: PNote[];
|
|
166
171
|
geo?: PGeo;
|
|
167
172
|
style?: PStyle;
|
|
173
|
+
locked?: boolean;
|
|
168
174
|
}
|
|
169
175
|
/**
|
|
170
176
|
* 레거시 NoteModel 직렬화 형태. 연결선은 `ownedConnections`(end1/end2/locations 구조)로 저장되고
|
package/dist/agent/resolver.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogicalModel, ModelId } from '../core/types';
|
|
1
|
+
import { EmbeddableCatalog, LogicalModel, ModelId } from '../core/types';
|
|
2
2
|
import { OpShape } from '../command/op';
|
|
3
3
|
import { AssocHandle, Handle, SymbolicOp } from './symbolicOp';
|
|
4
4
|
/** 해소 실패 — 어느 심볼릭 op(`opIndex`)의 어떤 핸들이 0개/복수 매칭인지. */
|
|
@@ -104,6 +104,31 @@ export type ResolveError = {
|
|
|
104
104
|
code: 'pending-entity-ref';
|
|
105
105
|
opIndex: number;
|
|
106
106
|
handle: Handle;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* embeddableOverrides가 있으나 `type`이 주입된 임베더블 카탈로그의 어떤 엔트리와도 매칭되지 않음
|
|
110
|
+
* (카탈로그 미주입이거나 embeddable 아닌 type). 서브컬럼 오버라이드 silent drop 방지.
|
|
111
|
+
*/
|
|
112
|
+
| {
|
|
113
|
+
code: 'embeddable-type-unresolved';
|
|
114
|
+
opIndex: number;
|
|
115
|
+
entity: Handle;
|
|
116
|
+
handle: Handle;
|
|
117
|
+
}
|
|
118
|
+
/** EMBED_PREDEF SHARED_REF 서브컬럼의 공유 대상 물리명이 소속 엔터티 내 컬럼과 0개 매칭. */
|
|
119
|
+
| {
|
|
120
|
+
code: 'shared-column-target-not-found';
|
|
121
|
+
opIndex: number;
|
|
122
|
+
entity: Handle;
|
|
123
|
+
handle: Handle;
|
|
124
|
+
}
|
|
125
|
+
/** EMBED_PREDEF SHARED_REF 공유 대상 물리명이 복수 컬럼과 매칭(모호). */
|
|
126
|
+
| {
|
|
127
|
+
code: 'shared-column-target-ambiguous';
|
|
128
|
+
opIndex: number;
|
|
129
|
+
entity: Handle;
|
|
130
|
+
handle: Handle;
|
|
131
|
+
matches: ModelId[];
|
|
107
132
|
};
|
|
108
133
|
export type ResolveResult = {
|
|
109
134
|
ok: true;
|
|
@@ -115,6 +140,12 @@ export type ResolveResult = {
|
|
|
115
140
|
export interface ResolverOptions {
|
|
116
141
|
/** modelId 발급기(주입 시 테스트 결정성). 기본 newId. */
|
|
117
142
|
mkId?: () => ModelId;
|
|
143
|
+
/**
|
|
144
|
+
* predefined 임베더블 카탈로그(호스트 주입). `attribute.add`/inline fold의 `spec.type`이 엔트리 `type`과
|
|
145
|
+
* 매칭되면 EMBED_PREDEF(다중 dbAttr)로 확장한다. 미주입(기본 [])이면 확장 없이 NORMAL — 카탈로그 없이는
|
|
146
|
+
* type이 embeddable인지 판정 불가하므로 graceful degrade(현행 동작 유지). 서버 resolve 경로가 주입 책임.
|
|
147
|
+
*/
|
|
148
|
+
embeddableCatalog?: EmbeddableCatalog;
|
|
118
149
|
}
|
|
119
150
|
/**
|
|
120
151
|
* 심볼릭 op 배치를 OpShape 배치로 해소한다.
|
|
@@ -34,6 +34,14 @@ export interface EntitySpec {
|
|
|
34
34
|
stereotype?: ClassStereotype;
|
|
35
35
|
/** 설정 시 `table.physicalName`. */
|
|
36
36
|
physicalName?: string;
|
|
37
|
+
/**
|
|
38
|
+
* JPA `@Version`(낙관적 락) 사용 여부 → `Entity.jpaAttrs.useVersion`. 코드의 `@Version` 필드는 별도 속성으로
|
|
39
|
+
* 모델링하지 않고 이 엔티티 레벨 플래그로 흡수한다(버전 컬럼은 호스트 코드젠 소유). resolver가 true일 때만
|
|
40
|
+
* `jpaAttrs.useVersion:true`를 세팅(false/미설정은 생략 — round-trip diff 방지). *기존* 엔티티에 켤 땐 이 스펙이
|
|
41
|
+
* 아니라 `entity.update` patch의 **dotted key** `{'jpaAttrs.useVersion': true}`를 써야 형제 jpaAttrs 플래그를
|
|
42
|
+
* 통째 $set로 덮어쓰지 않는다(호스트 opInterpreter는 patch를 per-key $set).
|
|
43
|
+
*/
|
|
44
|
+
useVersion?: boolean;
|
|
37
45
|
/** inline 속성 — 배열 순서가 곧 `order`. GroupCodeEnum+groupCode 규칙은 `attribute.add`와 동일하게 강제. */
|
|
38
46
|
attributes?: AttrSpec[];
|
|
39
47
|
/** inline 인덱스 — 컬럼 핸들은 *이 엔티티가 inline으로 만드는* dbAttr 내에서 해소된다(속성 inline 동반 전제). */
|
|
@@ -52,6 +60,12 @@ export interface AttrSpec {
|
|
|
52
60
|
type: string;
|
|
53
61
|
identifier?: boolean;
|
|
54
62
|
notNull?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* JPA `@Transient` — 비영속 속성. true면 `Attribute.transient:true`(속성 레벨 플래그). 컬럼을 만들지 않는
|
|
65
|
+
* 속성이므로 physicalName/dataType 등 컬럼 필드는 함께 주지 않는다(주면 dbAttr가 생성됨). false/미설정은
|
|
66
|
+
* 생략(round-trip diff 방지). *기존* 속성에 켤 땐 `attribute.update` patch `{transient:true}`로도 가능.
|
|
67
|
+
*/
|
|
68
|
+
transient?: boolean;
|
|
55
69
|
/** 설정 시 단일 dbAttr 컬럼 생성(미설정이면 name을 물리명으로). */
|
|
56
70
|
physicalName?: string;
|
|
57
71
|
/** dbAttr 물리 타입(예: 'BIGINT'). physicalName/dataType/length/scale 중 하나라도 있으면 dbAttr 생성. */
|
|
@@ -80,6 +94,39 @@ export interface AttrSpec {
|
|
|
80
94
|
unique?: boolean;
|
|
81
95
|
/** dbAttr 갱신 가능 여부(JPA @Column(updatable=)). */
|
|
82
96
|
updatable?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* predefined 임베더블 서브컬럼 오버라이드 — `type`이 호스트 주입 임베더블 카탈로그 엔트리와 매칭될 때만
|
|
99
|
+
* 의미. resolver가 카탈로그 fields를 그대로 펼친 뒤(EMBED_PREDEF, 다중 dbAttr) 이 배열을 **필드명**으로
|
|
100
|
+
* 매칭해 서브컬럼을 덮어쓴다(JPA `@AttributeOverride` 대응). 미설정 서브컬럼은 카탈로그 기본을 상속한다.
|
|
101
|
+
* 카탈로그 미매칭 type에 이 배열을 주면 resolver가 `embeddable-type-unresolved`로 거부(silent drop 방지).
|
|
102
|
+
*/
|
|
103
|
+
embeddableOverrides?: EmbeddableColumnOverride[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* predefined 임베더블(EMBED_PREDEF)의 개별 서브컬럼 오버라이드. 매칭 키는 카탈로그 필드명
|
|
107
|
+
* (`EmbeddableCatalogField.name`, 예: 'amount'·'currency') — 순서 독립. 미설정 필드는 오버라이드 없음(카탈로그 상속).
|
|
108
|
+
*/
|
|
109
|
+
export interface EmbeddableColumnOverride {
|
|
110
|
+
/** 대상 카탈로그 필드명(EmbeddableCatalogField.name). 예: 'amount', 'currency'. */
|
|
111
|
+
field: string;
|
|
112
|
+
/** 서브컬럼 물리명 오버라이드(@AttributeOverride column name). 미설정 시 카탈로그 기본 컬럼명 상속. */
|
|
113
|
+
physicalName?: string;
|
|
114
|
+
/** 서브컬럼 길이 오버라이드. */
|
|
115
|
+
length?: number;
|
|
116
|
+
/** 서브컬럼 소수 자릿수 오버라이드. */
|
|
117
|
+
scale?: number;
|
|
118
|
+
/** JPA @Column(insertable=). OWN 컬럼에만 저장(SHARED_REF는 타깃 파생). */
|
|
119
|
+
insertable?: boolean;
|
|
120
|
+
/** JPA @Column(updatable=). OWN 컬럼에만 저장(SHARED_REF는 타깃 파생). */
|
|
121
|
+
updatable?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* SHARED_REF — 이 서브컬럼이 자체 물리 컬럼을 갖지 않고 같은 엔터티의 다른 컬럼(**물리명**)을 공유해
|
|
124
|
+
* read-only 투영됨(대표: Money의 currency가 별도 스칼라 통화 컬럼 공유). 설정 시 resolver가 그 물리명을
|
|
125
|
+
* 소속 엔터티 내 기존 컬럼 modelId로 해소해 `DbColumn.sharedColumnRef`로 바인딩하고 physicalName·
|
|
126
|
+
* insertable·updatable은 저장하지 않는다(타깃 파생). 타깃 컬럼은 해소 시점 존재해야 한다(부재=거부).
|
|
127
|
+
* JPA 코드에서 currency 서브컬럼의 `insertable=false && updatable=false`가 이 모드의 시그니처.
|
|
128
|
+
*/
|
|
129
|
+
sharedColumnPhysicalName?: string;
|
|
83
130
|
}
|
|
84
131
|
/** association.add 페이로드 — from/to 엔티티는 resolver가 해소, modelId 발급 + end 조립. */
|
|
85
132
|
export interface AssocSpec {
|
|
@@ -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
|
-
|
|
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. */
|
|
@@ -21,6 +27,8 @@ export declare function resizeEntity(entityId: ModelId, size: {
|
|
|
21
27
|
export declare function setEntitySwatch(entityId: ModelId, token: string | null): Command;
|
|
22
28
|
/** 엔티티 접기/펼치기 (레이아웃만 변경 — 속성/메서드 칸 렌더 게이트) */
|
|
23
29
|
export declare function setEntityCollapsed(entityId: ModelId, collapsed: boolean): Command;
|
|
30
|
+
/** 엔티티 편집 잠금 토글 (레이아웃만 변경 — setEntityCollapsed 동형, LWW) */
|
|
31
|
+
export declare function setEntityLocked(entityId: ModelId, locked: boolean): Command;
|
|
24
32
|
/**
|
|
25
33
|
* 활성 다이어그램 전체 엔티티 접기/펼치기 (D2) — 사전 per-entity collapsed를 캡처한 단일 커맨드.
|
|
26
34
|
* N개 개별 커맨드가 아니라 한 번의 undo로 각 엔티티의 직전 상태를 그대로 복원한다(혼재 상태 보존).
|
|
@@ -28,7 +36,9 @@ export declare function setEntityCollapsed(entityId: ModelId, collapsed: boolean
|
|
|
28
36
|
export declare function setAllEntitiesCollapsed(collapsed: boolean): Command;
|
|
29
37
|
/** 속성 강조 색상 변경 (레이아웃 attributeStyles[attrId]) */
|
|
30
38
|
export declare function setAttributeSwatch(entityId: ModelId, attributeId: ModelId, token: string | null): Command;
|
|
31
|
-
|
|
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;
|
|
32
42
|
/** 그룹 필드 부분 수정 (name·description·packageName·excludeDDLGeneration). 얕은 patch. */
|
|
33
43
|
export declare function updateGroup(groupId: ModelId, patch: Partial<LogicalGroup>): Command;
|
|
34
44
|
/** 그룹 해제(삭제) — 멤버 엔티티는 남고 그룹/박스만 제거 */
|
|
@@ -42,6 +52,8 @@ export declare function resizeGroup(groupId: ModelId, size: {
|
|
|
42
52
|
}): Command;
|
|
43
53
|
/** 그룹 색상 변경 (레이아웃만 변경 — setEntitySwatch와 동형) */
|
|
44
54
|
export declare function setGroupSwatch(groupId: ModelId, token: string | null): Command;
|
|
55
|
+
/** 그룹 편집 잠금 토글 (레이아웃만 변경 — setEntityLocked 거울, LWW) */
|
|
56
|
+
export declare function setGroupLocked(groupId: ModelId, locked: boolean): Command;
|
|
45
57
|
export declare function addAttribute(entityId: ModelId, attribute: Attribute): Command;
|
|
46
58
|
/** 속성 필드 부분 수정 (name·type·dataType·dbAttrs·identifier·notNull 등). 얕은 patch. */
|
|
47
59
|
export declare function updateAttribute(entityId: ModelId, attributeId: ModelId, patch: Partial<Attribute>): Command;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Attribute, Entity } from './types';
|
|
2
|
+
/** 물리 FK 컬럼을 가진 FK 여부 — derivedFrom(관계 파생) + dbAttrs(물리 컬럼) 보유. */
|
|
3
|
+
export declare function isPhysicalFk(a: Attribute): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* 물리 FK 컬럼을 가진 FK를 순수 PK 바로 뒤로 당긴다. `순수 PK → 물리 FK → 나머지` 순으로 재배열하되,
|
|
6
|
+
* FK끼리·나머지끼리의 상대 순서는 원본 order를 보존한다(순서를 새로 추정하지 않음). 순수 PK가 없으면
|
|
7
|
+
* FK를 맨 앞으로. 물리 컬럼 없는 nav 참조(dbAttrs=0)는 추정이라 제외 — 실제로 그런 참조는 어느 엔티티
|
|
8
|
+
* attributes에도 물질화되지 않으므로(유령 앵커 참조) 대상이 되는 일도 없다.
|
|
9
|
+
*
|
|
10
|
+
* ★ order 필드뿐 아니라 **배열 물리 순서 자체**를 재정렬한다. 캔버스 노드(EntityNode)는 attributes를
|
|
11
|
+
* 배열 순서 그대로 렌더하고(order 정렬 미적용), 코드젠·탐색기는 order로 정렬하므로, 둘을 일치시켜야
|
|
12
|
+
* 모든 표시 경로에서 순서가 같다. [[attribute-display-order-array-vs-order-field]]
|
|
13
|
+
*
|
|
14
|
+
* 경계 강등(mergeDiagram)으로 derivedFrom이 제거된 FK는 `isPhysicalFk`가 false라 일반 컬럼으로 제자리에
|
|
15
|
+
* 남는다 — 강등 이후에 호출해야 한다.
|
|
16
|
+
*/
|
|
17
|
+
export declare function reorderForeignAttributes(entities: Entity[]): void;
|
package/dist/core/dbTypes.d.ts
CHANGED
|
@@ -31,6 +31,15 @@ export declare function dbTypeLabel(value: string): string;
|
|
|
31
31
|
* TEXT류(LONGVARCHAR·CLOB·BLOB)·고정 폭 타입(INTEGER·DATE·BOOLEAN 등)은 길이 무의미라 제외.
|
|
32
32
|
*/
|
|
33
33
|
export declare const LENGTH_REQUIRED_DATA_TYPES: ReadonlySet<string>;
|
|
34
|
+
/**
|
|
35
|
+
* scale(소수점 이하 자릿수)이 의미를 갖는 타입 — 정확 수치형(NUMERIC·DECIMAL)뿐이다. 여기서 length는
|
|
36
|
+
* precision(전체 자릿수), scale은 그중 소수부. VARCHAR·CHAR 등 문자/이진 길이 타입과 정수·날짜·불리언
|
|
37
|
+
* 같은 고정 폭 타입엔 scale이 무의미하고, 근사 수치형(FLOAT·REAL·DOUBLE)은 precision만 가질 뿐 scale이 없다.
|
|
38
|
+
*
|
|
39
|
+
* 편집 UI가 이 집합 밖 타입에서 scale 입력을 비활성화하는 어포던스의 단일 출처(타입 메타데이터는 이 카탈로그
|
|
40
|
+
* 소유 — LENGTH_REQUIRED_DATA_TYPES와 대칭). 타입을 이 집합 밖으로 바꾸면 무의미해진 scale은 자동 환원한다.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SCALE_APPLICABLE_DATA_TYPES: ReadonlySet<string>;
|
|
34
43
|
/**
|
|
35
44
|
* dataType 셀렉트 items — 실 컬럼 후보 + 현재값 폴백 합성.
|
|
36
45
|
*
|
|
@@ -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,38 @@
|
|
|
1
|
+
import { Association, AssociationLayout, DiagramLayout, Entity, EntityLayout, GroupLayout, LogicalGroup, LogicalModel, ModelId, Point } 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
|
+
/** 결정적 테스트를 위한 id 생성기 주입(기본 newId). */
|
|
15
|
+
idFactory?: () => ModelId;
|
|
16
|
+
}
|
|
17
|
+
export interface MergeDiagramResult {
|
|
18
|
+
logical: {
|
|
19
|
+
entities: Entity[];
|
|
20
|
+
associations: Association[];
|
|
21
|
+
groups: LogicalGroup[];
|
|
22
|
+
};
|
|
23
|
+
layout: {
|
|
24
|
+
entityLayouts: EntityLayout[];
|
|
25
|
+
associationLayouts: AssociationLayout[];
|
|
26
|
+
groupLayouts: GroupLayout[];
|
|
27
|
+
};
|
|
28
|
+
/** 소스 modelId → 임포트 modelId 매핑(컨트롤러 진입점·후속 배선용). */
|
|
29
|
+
idMap: Map<ModelId, ModelId>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 소스 다이어그램의 선택 서브그래프를 새 id 체계로 재매핑해 반환한다.
|
|
33
|
+
*
|
|
34
|
+
* @param source 소스 다이어그램(로드된 논리 + 레이아웃)
|
|
35
|
+
* @param selectedIds 임포트할 엔티티 modelId 목록(부분 선택 — 전량은 전 엔티티 id 전달)
|
|
36
|
+
* @param opts 경계/충돌/오프셋 정책
|
|
37
|
+
*/
|
|
38
|
+
export declare function mergeDiagram(source: MergeDiagramSource, selectedIds: ModelId[], opts: MergeDiagramOptions): MergeDiagramResult;
|
|
@@ -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,8 @@
|
|
|
1
|
+
import { LogicalModel } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 논리 모델 내 전 레거시 Money 속성을 신규 Money embeddable로 승격한 **새 모델**을 반환(순수).
|
|
4
|
+
* 대상이 없으면 입력 참조를 그대로 반환(no-op). 레이아웃은 논리 modelId만 참조하고 dbAttr을 참조하지
|
|
5
|
+
* 않으므로 무변경 — 호출자(useMigrateEntityDiagram)는 `{ ...state, logical: migrateLegacyMoney(state.logical) }`.
|
|
6
|
+
* amount 슬롯이 레거시 컬럼 modelId를 보존하므로 인덱스(IndexColumn.columnRef) 참조도 안전.
|
|
7
|
+
*/
|
|
8
|
+
export declare function migrateLegacyMoney(logical: LogicalModel): LogicalModel;
|
|
@@ -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;
|
package/dist/core/resolve.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export interface ResolvedEntity {
|
|
|
3
3
|
entity: Entity;
|
|
4
4
|
geo: Geo;
|
|
5
5
|
collapsed: boolean;
|
|
6
|
+
/** 편집 잠금 (layout.locked 통과) — 캔버스 draggable·인스펙터 read-only 게이트 */
|
|
7
|
+
locked: boolean;
|
|
6
8
|
/** 이 엔티티가 속한 그룹(있으면) — 캔버스가 parent 노드로 배치 */
|
|
7
9
|
groupRef?: ModelId;
|
|
8
10
|
/** 헤더 바 색상 등 (레이아웃 style 참조 통과 — swatch 변경 시 computed 무효화) */
|
|
@@ -23,6 +25,8 @@ export interface ResolvedGroup {
|
|
|
23
25
|
geo: Geo;
|
|
24
26
|
/** 그룹 배경 색상 등 (레이아웃 style 참조 통과 — swatch 변경 시 computed 무효화) */
|
|
25
27
|
style?: Style;
|
|
28
|
+
/** 편집 잠금 (layout.locked 통과) — 그룹 draggable·논리수정 게이트 */
|
|
29
|
+
locked: boolean;
|
|
26
30
|
}
|
|
27
31
|
export interface ResolvedNoteConnection {
|
|
28
32
|
noteRef: ModelId;
|
|
@@ -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
|
/**
|
package/dist/core/types.d.ts
CHANGED
|
@@ -103,6 +103,52 @@ export interface GroupCodeCatalogEntry {
|
|
|
103
103
|
codes: GroupCodeValue[];
|
|
104
104
|
}
|
|
105
105
|
export type GroupCodeCatalog = GroupCodeCatalogEntry[];
|
|
106
|
+
/**
|
|
107
|
+
* 슈퍼클래스 카탈로그 — `Entity.superClass`(예: BaseEntity)가 상속시키는 컬럼(감사필드 createdBy/
|
|
108
|
+
* createdAt/updatedBy/updatedAt 등)의 정의. 상속 컬럼은 모델에 물질화되지 않으므로(syncPlaybook §G4
|
|
109
|
+
* 상속필드 의도적 부재) 인덱스 대상으로 참조하려면 이 카탈로그로 파생 투영한다(`inheritedColumns.ts`).
|
|
110
|
+
* EmbeddableCatalog와 동형으로 **호스트가 주입**하며(shared/ 하드코딩 상수, 완전 통합 시 superClassCatalog
|
|
111
|
+
* 엔드포인트) 코어는 소비만 한다. 빈 배열이면 상속 컬럼 투영이 나오지 않는다(inert — 인덱스는 로컬
|
|
112
|
+
* dbAttr만 참조 가능).
|
|
113
|
+
*/
|
|
114
|
+
export interface SuperClassColumnDef {
|
|
115
|
+
/** 논리 필드명 = 합성 modelId(`inherited:<class>:<field>`) 키. 카탈로그 물리명이 바뀌어도 안정(D6). 예: 'createdAt'. */
|
|
116
|
+
field: string;
|
|
117
|
+
/** 물리 컬럼명(@Index columnList 코드젠용). 예: 'created_at'. */
|
|
118
|
+
physicalName: string;
|
|
119
|
+
/** dbTypes 카탈로그 값. 예: 'TIMESTAMP'. */
|
|
120
|
+
dataType: string;
|
|
121
|
+
/** 표시용 논리명(선택). */
|
|
122
|
+
logicalName?: MultiLangText;
|
|
123
|
+
length?: number;
|
|
124
|
+
scale?: number;
|
|
125
|
+
}
|
|
126
|
+
export interface SuperClassDef {
|
|
127
|
+
/** `Entity.superClass`와 매칭되는 클래스명(예: BaseEntity). 카탈로그 내 유일. */
|
|
128
|
+
name: string;
|
|
129
|
+
/**
|
|
130
|
+
* JPA 상속 종류. 초기엔 mapped-superclass만 — @Index(columnList=)가 상속 물리 컬럼을 유효하게
|
|
131
|
+
* 참조하는 전제(상속 컬럼이 자식 테이블에 병합됨). 다른 전략(JOINED 등)은 별도 트랙.
|
|
132
|
+
*/
|
|
133
|
+
kind: 'MAPPED_SUPERCLASS';
|
|
134
|
+
/**
|
|
135
|
+
* base 클래스의 자바 패키지(FQN 구성용). 예: 'net.g1project.ecp.common.domain'.
|
|
136
|
+
* **현재 lib 소비처 없음** — 상속 컬럼 인덱스 모델링은 field/physicalName/dataType만 쓴다.
|
|
137
|
+
* 코드젠이 `import <packageName>.<name>;` + `extends <name>`를 낼 때를 위한 forward 슬롯(호스트 소유).
|
|
138
|
+
* 카탈로그를 base 클래스 단일 SoT로 키우려는 방향(embeddable/javaType 카탈로그 계열)의 provisioning.
|
|
139
|
+
*/
|
|
140
|
+
packageName?: string;
|
|
141
|
+
/**
|
|
142
|
+
* 이 base가 프로젝트 **암묵 default**인지. `Entity.superClass`가 비어 있으면(레거시 관례상
|
|
143
|
+
* 명시 안 함 = 코드젠이 `extends <default>`를 냄) 이 base가 상속 컬럼을 기여한다.
|
|
144
|
+
* 카탈로그 내 최대 하나만 표시(여럿이면 첫 항목). 명시적 `superClass='Object'`는 non-empty라
|
|
145
|
+
* 이 폴백에 걸리지 않고 카탈로그 미스 → 상속 없음(자바 `extends Object` = default 상속 opt-out 트릭).
|
|
146
|
+
*/
|
|
147
|
+
default?: boolean;
|
|
148
|
+
/** 이 슈퍼클래스가 기여하는 컬럼(선언 순서 보존). */
|
|
149
|
+
columns: SuperClassColumnDef[];
|
|
150
|
+
}
|
|
151
|
+
export type SuperClassCatalog = SuperClassDef[];
|
|
106
152
|
export interface DbColumn {
|
|
107
153
|
modelId: ModelId;
|
|
108
154
|
physicalName: string;
|
|
@@ -141,6 +187,17 @@ export interface Attribute {
|
|
|
141
187
|
identifier: boolean;
|
|
142
188
|
notNull: boolean;
|
|
143
189
|
transient?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Hibernate `@NaturalId` — 이 속성이 엔터티의 자연키(비즈니스 키)임을 표시. PK(@Id)와는 별개 개념
|
|
192
|
+
* (자연키는 정의상 대리키가 아닌 도메인 유일 식별자). 프로퍼티 어노테이션이라 컬럼 레벨(unique)이 아니라
|
|
193
|
+
* 속성 레벨. false는 undefined로 환원해 라운드트립 diff 방지. v1 레거시엔 없는 신규 옵션(forward).
|
|
194
|
+
*/
|
|
195
|
+
naturalId?: boolean;
|
|
196
|
+
/**
|
|
197
|
+
* `@NaturalId(mutable = true)` — 자연키 값의 변경 허용. Hibernate 기본은 불변(mutable=false)이므로
|
|
198
|
+
* undefined/false면 불변(어노테이션 인자 생략). naturalId=false일 땐 무의미(직렬화 시 정리).
|
|
199
|
+
*/
|
|
200
|
+
naturalIdMutable?: boolean;
|
|
144
201
|
description?: MultiLangText;
|
|
145
202
|
attributeGroup?: string;
|
|
146
203
|
groupCode?: string;
|
|
@@ -340,6 +397,11 @@ export interface EntityLayout {
|
|
|
340
397
|
entityRef: ModelId;
|
|
341
398
|
geo: Geo;
|
|
342
399
|
collapsed?: boolean;
|
|
400
|
+
/**
|
|
401
|
+
* 편집 잠금 — 이동·크기변경·논리수정·삭제를 차단(뷰 어포던스 계층). 논리 무관·layout LWW.
|
|
402
|
+
* op 인터프리터·undo·replay·복원은 무시한다(간접/시스템 쓰기는 잠금 대상 아님).
|
|
403
|
+
*/
|
|
404
|
+
locked?: boolean;
|
|
343
405
|
displayMode?: DisplayMode;
|
|
344
406
|
/** 엔티티 헤더 바 색상 등 (style.properties.swatch = 토큰명) */
|
|
345
407
|
style?: Style;
|
|
@@ -362,6 +424,8 @@ export interface GroupLayout {
|
|
|
362
424
|
groupRef: ModelId;
|
|
363
425
|
geo: Geo;
|
|
364
426
|
style?: Style;
|
|
427
|
+
/** 편집 잠금 — 그룹 박스 이동·크기변경·그룹 논리수정·삭제 차단(EntityLayout.locked 거울). */
|
|
428
|
+
locked?: boolean;
|
|
365
429
|
/**
|
|
366
430
|
* 그룹 박스에 시각적으로 포함된 노트 멤버십(레거시 `groups[].notes`). 노트는 순수 레이아웃
|
|
367
431
|
* 객체(논리 의미 없음)라 멤버십도 레이아웃에 둔다 — 엔티티 멤버십(LogicalGroup.memberEntityRefs)과 비대칭.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EmbeddableCatalog, LogicalModel, ModelId } from './types';
|
|
1
|
+
import { EmbeddableCatalog, LogicalModel, ModelId, SuperClassCatalog } from './types';
|
|
2
2
|
export declare const PHYSICAL_NAME_MAX_LENGTH = 63;
|
|
3
3
|
/**
|
|
4
4
|
* 물리명이 이식성 권장 한도를 초과하면 경고 메시지, 아니면 null(비차단 — 호출부는 저장을 막지 않는다).
|
|
@@ -43,6 +43,13 @@ export interface ValidationContext {
|
|
|
43
43
|
* 타입 출처. 호스트/dev 주입(reservedWords와 동형 ctx 게이트). 미주입/빈 배열이면 CHK-TYPE-3 skip.
|
|
44
44
|
*/
|
|
45
45
|
embeddableCatalog?: EmbeddableCatalog;
|
|
46
|
+
/**
|
|
47
|
+
* 슈퍼클래스 카탈로그 — CHK-DSN-5(dangling 인덱스 대상)가 인덱스 columnRef의 상속 컬럼(`inherited:`
|
|
48
|
+
* 합성 ref)을 유효한 대상으로 인지하는 화이트리스트 출처. 호스트/dev 주입(embeddableCatalog 동형 ctx
|
|
49
|
+
* 게이트). 미주입/빈 배열이면 상속 컬럼을 인지하지 못하므로, superClass 상속 컬럼을 참조하는 인덱스가
|
|
50
|
+
* dangling으로 오탐될 수 있다 — 카탈로그가 주입돼야 정확 판정(로컬 컬럼만 참조하는 모델은 무영향).
|
|
51
|
+
*/
|
|
52
|
+
superClassCatalog?: SuperClassCatalog;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
55
|
* 설계 품질 검증 — 논리 모델(+선택 컨텍스트)을 받아 이슈 목록을 돌려준다.
|