@g1cloud/entity-modeler-next 5.1.5 → 5.1.6
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/dist/core/fkDerived.d.ts +50 -1
- package/dist/core/javaTypes.d.ts +3 -1
- package/dist/core/propagation.d.ts +6 -1
- package/dist/core/scaffoldJava.d.ts +51 -0
- package/dist/entity-modeler-next.css +1 -1
- package/dist/entity-modeler.js +12229 -11837
- package/dist/entity-modeler.umd.cjs +29 -29
- package/dist/i18n/ko.d.ts +10 -4
- package/dist/view/columnResolution.d.ts +30 -0
- package/dist/view/embedSlotCollapse.d.ts +9 -1
- package/dist/view/useAttributeEditing.d.ts +9 -1
- package/package.json +1 -1
package/dist/core/fkDerived.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Association, Attribute, DbColumn, Entity } from './types';
|
|
1
|
+
import { Association, Attribute, DbColumn, Entity, ModelId } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* FK 유래 컬럼 = 물리 컬럼을 보유한 관계 속성(RELATION* + dbAttrs). 형상(dataType/length/scale/
|
|
4
4
|
* physicalName/notNull 등)은 부모 식별자(PK) + 관계 identifying에서 파생된다.
|
|
@@ -17,6 +17,8 @@ import { Association, Attribute, DbColumn, Entity } from './types';
|
|
|
17
17
|
* | 자리 | 술어 | 왜 다른가 |
|
|
18
18
|
* |---|---|---|
|
|
19
19
|
* | `isFkDerivedColumn`(여기) | RELATION* && dbAttrs>0 | 뷰 잠금·형상 해소. `findFkOwningAssociation`이 위임 |
|
|
20
|
+
* | `isJoinColumnOnlyFk`(여기) | RELATION_OWN && 앵커 아님 && 형제가 앵커 | 복합 FK 형제 — **필드를 안 낸다**(아래) |
|
|
21
|
+
* | `isMultiColumnFk`(여기) | RELATION_OWN && dbAttrs>1 | **형상 A** 서브컬럼 표현 대상. 뷰 셋이 공유 |
|
|
20
22
|
* | `attributeOrder.isPhysicalFk` | derivedFrom && dbAttrs>0 | 표시 순서 정렬. **강등 이후** 호출 전제라 `derivedFrom`이 기준(경계 강등된 컬럼은 제자리에 남아야 한다) |
|
|
21
23
|
* | `mermaid.isForeignKey` | RELATION_OWN‖RELATION_REF‖derivedFrom | ER **FK 마커**는 nav(dbAttrs=0)까지 표시 대상이라 컬럼 보유를 안 본다 |
|
|
22
24
|
* | `ddl.ts` FK 제약 방출 | derivedFrom 단독 | 부모 컬럼을 알아야 REFERENCES를 쓸 수 있어 링크가 필수 |
|
|
@@ -27,6 +29,48 @@ import { Association, Attribute, DbColumn, Entity } from './types';
|
|
|
27
29
|
* (`parseMermaid.wireForeignKeyColumns` 주석), 그건 발생원에서 닫았다.
|
|
28
30
|
*/
|
|
29
31
|
export declare function isFkDerivedColumn(attr: Attribute): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* **다중 컬럼 FK**(형상 A) — 관계 하나가 **컬럼 여럿**을 갖는 속성인가.
|
|
34
|
+
*
|
|
35
|
+
* JPA 는 관계당 필드 하나이고 컬럼이 여럿이다(`@ManyToOne` + `@JoinColumns`) ⇒ 「한 속성이 여러 컬럼을
|
|
36
|
+
* 갖는다」는 형상이 **임베드와 같다**. 그래서 뷰 세 곳이 임베드의 서브컬럼 관용구를 이 술어로 함께 탄다:
|
|
37
|
+
* 캔버스 서브행(`EntityNode.hasSubColumns`) · 표시 해소(`columnResolution`) · 편집 슬롯
|
|
38
|
+
* (`useAttributeEditing.hasColumnSlots`).
|
|
39
|
+
*
|
|
40
|
+
* ⚠️**`> 1` 이다** — 단일 컬럼 FK 는 서브컬럼이 없어 대상이 아니다(실측 285/285 가 단일 컬럼 = 전원
|
|
41
|
+
* 무영향). `> 0` 으로 쓰면 FK 전량이 단일 컬럼 편집 블록에서 빠져 나간다.
|
|
42
|
+
* ⚠️`RELATION_REF`(inverse nav)는 컬럼이 0이라 자연히 제외된다.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isMultiColumnFk(attr: Attribute): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 관계 필드를 소유하는 **앵커 속성** 집합 — `end2.attributeRef`(owner, navigable 무관) +
|
|
47
|
+
* `end1.attributeRef`(inverse, navigable일 때만). `scaffoldJava`의 `relByAttr` 키와 **같은 규칙**이며
|
|
48
|
+
* 그쪽이 이 함수로 위임한다(산식 이중화 금지).
|
|
49
|
+
*/
|
|
50
|
+
export declare function fkFieldAnchors(associations: readonly Association[]): Set<ModelId>;
|
|
51
|
+
/**
|
|
52
|
+
* 복합 FK의 **형제 컬럼**인가 — 즉 이 속성이 `@JoinColumns` 컬럼으로만 기여하고 **자기 필드는 내지
|
|
53
|
+
* 않는가**.
|
|
54
|
+
*
|
|
55
|
+
* 배경: 전파(`computeForeignAttributes`)는 부모 PK 멤버마다 속성을 하나씩 만들지만
|
|
56
|
+
* (`parentIdentifiers.map(...)`), JPA는 관계당 **필드 하나**다 — 앵커가 `@ManyToOne` +
|
|
57
|
+
* `@JoinColumns`를 소유하고 형제는 컬럼만 보탠다. ⇒ 형제의 `name`은 **어디에도 방출되지 않는다**.
|
|
58
|
+
*
|
|
59
|
+
* 그래서 이 술어를 쓰는 자리가 셋이다:
|
|
60
|
+
* 1. `scaffoldJava` — 방출 분기(형제는 `@Column`을 내면 같은 컬럼이 두 번 매핑돼 Hibernate가
|
|
61
|
+
* "Repeated column in mapping"으로 부트스트랩에 실패한다).
|
|
62
|
+
* 2. `validation` `CHK-NAME-7` — 형제의 빈 이름은 **필드 미방출을 일으키지 않으므로** error가 아니다
|
|
63
|
+
* (info `CHK-NAME-4`로 강등). 「검증 규칙은 고칠 수 있는 자리를 지목해야 한다」의 적용 —
|
|
64
|
+
* 여기선 *고칠 필요가 없는* 자리다.
|
|
65
|
+
* 3. 편집 뷰 — 이름 칸을 잠그고 앵커를 지목한다(사문 슬롯에 입력을 유도하지 않는다).
|
|
66
|
+
*
|
|
67
|
+
* ⚠️앵커가 **없는** 그룹은 제외한다(false). 그건 컬럼이 통째로 사라지는 별개 결함이고
|
|
68
|
+
* `CHK-JPA-19`·코드젠 `fillIn`이 이미 지목한다 — 여기서 삼키면 무신호가 된다.
|
|
69
|
+
*
|
|
70
|
+
* ★실측(2026-08-27, 프로덕션 v2 29문서): 복합 FK 그룹 **2**(참고 전용 제외 시 1) · 형제 **2**(실효 1) ·
|
|
71
|
+
* `CHK-NAME-7` 21건 중 형제 지목 **0**. 발동은 작지만 유입 경로는 열려 있다(v1 잔재·다중 컬럼 FK 신설).
|
|
72
|
+
*/
|
|
73
|
+
export declare function isJoinColumnOnlyFk(attr: Attribute, entity: Entity, anchors: ReadonlySet<ModelId>): boolean;
|
|
30
74
|
/**
|
|
31
75
|
* FK 유래 컬럼 i의 원본(부모 식별자) 컬럼 — 물리명·타입·길이·스케일이 여기서 파생된다. FK 컬럼 자신의
|
|
32
76
|
* dbAttrs가 비어 있을 때(v1→v2 로드/레거시 데이터, 어댑터가 재전파를 하지 않음) placeholder·캔버스
|
|
@@ -44,3 +88,8 @@ export declare function isFkDerivedColumn(attr: Attribute): boolean;
|
|
|
44
88
|
* 둔 본래 이유)는 그대로다. id가 유일한 문서에서는 두 경로가 같은 속성을 찾아 **결과가 동일하다**.
|
|
45
89
|
*/
|
|
46
90
|
export declare function resolveFkOriginColumn(attr: Attribute, childEntity: Entity | null | undefined, entities: readonly Entity[], associations: readonly Association[], i?: number): DbColumn | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* 부모 식별자 컬럼 평탄화(선언 순서) — 복합 PK 를 한 속성이 담는 **형상 A** 의 슬롯 원본.
|
|
93
|
+
* `scaffoldJava.parentIdColumns` 와 같은 규칙이며 그쪽이 이 함수로 위임한다(산식 이중화 금지).
|
|
94
|
+
*/
|
|
95
|
+
export declare function parentIdColumns(parent: Entity | undefined): DbColumn[];
|
package/dist/core/javaTypes.d.ts
CHANGED
|
@@ -74,7 +74,9 @@ export declare function embedCollectionType(attr: Attribute, associations: Assoc
|
|
|
74
74
|
* 속성 타입 칸 표시 — 모델은 type(자바 타입)·dbAttrs[].dataType(물리 DB 타입)을 분리 보관하므로
|
|
75
75
|
* 뷰 모드별로 맞는 출처를 고른다(결정 2026-06-26):
|
|
76
76
|
* CLASS = 자바 타입 라벨 / PHYSICAL·LOGICAL_PHYSICAL = 물리 DB 타입 / LOGICAL = 숨김.
|
|
77
|
+
* ★**관계 행의 CLASS 타입은 대상 엔티티 클래스**다(`relationTargetName`) — 그 필드의 Java 타입이 곧
|
|
78
|
+
* 그 클래스이기 때문이다. 호출부는 `scaffoldJava.classFields` 가 해소한 값을 넘긴다(뷰가 재기술하지 않음).
|
|
77
79
|
* CustomType 마커는 실제 타입명(customType)을, 임베드 참조 헤더는 임베더블 타입명을 보인다
|
|
78
80
|
* (임베드의 물리 컬럼 타입은 펼침 서브행이 담당). Diagram 노드·Explorer 트리 공용.
|
|
79
81
|
*/
|
|
80
|
-
export declare function attrTypeCell(mode: DisplayMode, attr: Attribute, collectionType?: 'LIST' | 'SET'): string;
|
|
82
|
+
export declare function attrTypeCell(mode: DisplayMode, attr: Attribute, collectionType?: 'LIST' | 'SET', relationTargetName?: string): string;
|
|
@@ -12,8 +12,13 @@ export interface ForeignAttributeSpec {
|
|
|
12
12
|
type: string;
|
|
13
13
|
identifier: boolean;
|
|
14
14
|
notNull: boolean;
|
|
15
|
-
/** 부모 식별자의 컬럼을 미러한 dbAttrs (modelId 없음 — reconcile이 부여) */
|
|
15
|
+
/** 부모 식별자의 컬럼을 미러한 dbAttrs (modelId 없음 — reconcile이 부여). **물리명은 빈값**(상속). */
|
|
16
16
|
dbAttrs: Omit<DbColumn, 'modelId'>[];
|
|
17
|
+
/**
|
|
18
|
+
* 부모 PK 컬럼의 물리명 — **유일화 판정 전용 내부 축**이고 `specToAttribute` 가 영속하지 않는다.
|
|
19
|
+
* 물리명을 비워 상속시키므로(위) 충돌 시 무엇을 기준으로 유일화할지가 spec 안에 남아 있어야 한다.
|
|
20
|
+
*/
|
|
21
|
+
originPhysicalNames?: readonly string[];
|
|
17
22
|
}
|
|
18
23
|
export interface ReconcilePlan {
|
|
19
24
|
/** 신규 생성할 FK 속성 (modelId·dbAttr modelId 부여됨, order 포함) */
|
|
@@ -162,4 +162,55 @@ export declare function mapsIdScalarName(fk: Attribute, assoc: Association, byId
|
|
|
162
162
|
* 단일키 Repository 타입도 쓰고 있어 그쪽도 `Object`가 나가고 있었다.
|
|
163
163
|
*/
|
|
164
164
|
export declare function mapsIdScalarType(fk: Attribute, assoc: Association, byId: Map<ModelId, Entity>, logical: LogicalModel, opts: ScaffoldOptions): string;
|
|
165
|
+
/** 이 엔티티가 내는 Java 필드 한 줄의 역할. */
|
|
166
|
+
export type ClassFieldRole = 'scalar' | 'embed' | 'relation-owner' | 'relation-inverse';
|
|
167
|
+
/** 방출되지 않는 모델 속성의 사유 — `no-anchor` 만 신호 대상(나머지는 정상 스킵). */
|
|
168
|
+
export type ClassFieldOmitReason = 'join-column-only' | 'no-anchor' | 'nav-not-materialized';
|
|
169
|
+
export interface ClassField {
|
|
170
|
+
/** 표시·방출 대상. 합성 스칼라(`synthetic`)는 **모델에 없는 가상 속성**이다. */
|
|
171
|
+
attr: Attribute;
|
|
172
|
+
role: ClassFieldRole;
|
|
173
|
+
/** 모델에 없는 합성 행(@MapsId 스칼라 @Id) — 편집·삭제·재정렬 대상이 아니다. */
|
|
174
|
+
synthetic: boolean;
|
|
175
|
+
/** 이 행을 만든 모델 속성(합성 스칼라면 그 FK, 아니면 `attr` 자신). 행 → 모델 역참조. */
|
|
176
|
+
sourceAttr: Attribute;
|
|
177
|
+
assoc?: Association;
|
|
178
|
+
/** relation-* 의 대상 엔티티 — **CLASS 타입 칸의 출처**(JPA 필드 타입이 곧 이 클래스다). */
|
|
179
|
+
target?: Entity;
|
|
180
|
+
/** relation-inverse 의 컬렉션 래핑(to-many). */
|
|
181
|
+
collection?: 'LIST' | 'SET';
|
|
182
|
+
}
|
|
183
|
+
export interface ClassFieldPlan {
|
|
184
|
+
/** 방출 순서대로의 필드 목록 — **CLASS 뷰의 행 목록이 이것과 같아야 한다**. */
|
|
185
|
+
fields: ClassField[];
|
|
186
|
+
/** 방출되지 않는 모델 속성 + 사유. `no-anchor` 는 컬럼 누락이라 호출부가 신호한다. */
|
|
187
|
+
omitted: {
|
|
188
|
+
attr: Attribute;
|
|
189
|
+
reason: ClassFieldOmitReason;
|
|
190
|
+
}[];
|
|
191
|
+
/** @MapsId 스칼라 필드명 미해소 — 코드젠이 `fillIn` 으로 표면화한다. */
|
|
192
|
+
unresolvedDerivedIds: Attribute[];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* **이 엔티티가 방출하는 Java 필드 목록** — 코드젠·캔버스·탐색기의 단일 출처.
|
|
196
|
+
*
|
|
197
|
+
* 모델 속성과 **1:1이 아니다**. 세 축에서 갈라진다:
|
|
198
|
+
* 1. **@MapsId**: 속성 하나가 **두 필드**를 낸다 — 합성 스칼라 `@Id` + `@MapsId` 연관 필드.
|
|
199
|
+
* (모델이 속성 하나를 유지하는 것은 *모델 결정*[물리명 중복·전파·검증·DDL 무변경]이지 표시 결정이
|
|
200
|
+
* 아니다. 상세=`.claude/docs/MapsIdIdiom-entry_2026-08-26.md` §3.A)
|
|
201
|
+
* 2. **복합 FK 형제**: 앵커가 `@ManyToOne` + `@JoinColumns` 를 소유하고 형제는 컬럼만 보태므로
|
|
202
|
+
* **필드를 내지 않는다**(`fkDerived.isJoinColumnOnlyFk`).
|
|
203
|
+
* 3. **navigable off 인 `RELATION_REF`**: 앵커에 안 잡혀 `emitInverseRelation` 이 호출되지 않는다.
|
|
204
|
+
*
|
|
205
|
+
* ⇒ CLASS 뷰가 모델 속성을 1:1로 그리면 **방출되지 않는 행을 보여주고 방출되는 필드를 감춘다**.
|
|
206
|
+
* 실측(프로덕션 v2 29문서, 2026-08-27): ①+22행 ②−1행 ③−18행 = **41행 어긋남**.
|
|
207
|
+
*
|
|
208
|
+
* ★**타입 해소는 여기 없다** — 소비처마다 답이 다르기 때문이다. 코드젠은 카탈로그·패키지를 타고
|
|
209
|
+
* Java 타입 FQN을 뽑고(`syntheticType` 주입), 뷰는 `javaTypes.attrTypeCell` 로 표시 라벨을 만든다.
|
|
210
|
+
* 이 함수가 소유하는 것은 **행 정체성**(무엇이 몇 줄로 나가는가)이고 그것만 단일 출처다.
|
|
211
|
+
*
|
|
212
|
+
* @param syntheticType 합성 스칼라의 `type` 해소기. 미주입 시 **부모 PK 속성의 `type`을 그대로** 쓴다
|
|
213
|
+
* (모델 값 — 뷰의 표시 라벨엔 그것으로 충분하다).
|
|
214
|
+
*/
|
|
215
|
+
export declare function classFields(entity: Entity, logical: LogicalModel, syntheticType?: (fk: Attribute, assoc: Association) => string): ClassFieldPlan;
|
|
165
216
|
export {};
|