@g1cloud/entity-modeler-next 5.2.1 → 5.2.2

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.
@@ -309,6 +309,55 @@ export type ResolveError = {
309
309
  entity: Handle;
310
310
  keys: string[];
311
311
  }
312
+ /**
313
+ * ── `*-spec-unknown-key` 계열 — add op 의 `spec` 에 그 spec 이 갖지 않는 키 ──
314
+ *
315
+ * ★**patch 계열과 실패 모드가 다르다.** patch 는 통과하면 호스트가 **blind-write** 해 오염을 «만든다».
316
+ * spec 은 반대로 resolver 가 명명된 필드만 골라 담으므로 미지 키가 **조용히 사라진다** — 호출자는
317
+ * `ok` 를 받고 그 값이 반영됐다고 믿는다(무신호 소실). 그래서 둘 다 거부하지만 근거가 갈린다.
318
+ *
319
+ * ★**스키마는 이미 `additionalProperties: false` 로 닫아 두었다** — 이 거부는 새 제약이 아니라
320
+ * **선언된 계약의 집행**이다. 스키마는 LLM 에게 주는 tool 정의일 뿐 게이트가 아니고(호스트
321
+ * symbolic-ops 라우트는 body 를 스키마 검증 없이 resolver 로 넘긴다), 그래서 resolver 가 유일한 게이트다.
322
+ *
323
+ * ★발견 경위(2026-08-29): `entity.add` 에 `serialization`(직렬화 컨테이너)을 주면 `ok:true` 인데 값이
324
+ * 사라졌다. 같은 필드를 `entity.update` 로 주면 `entity-patch-unknown-key` 로 **거부**됐다 — 즉
325
+ * **add 는 삼키고 update 는 거부**하는 비대칭이었다. 어휘를 연 뒤에도(위 `serialization`) 오탈자·
326
+ * 미래 필드가 같은 자리로 사라지므로 계열 자체를 신설한다.
327
+ */
328
+ | {
329
+ code: 'entity-spec-unknown-key';
330
+ opIndex: number;
331
+ handle: Handle;
332
+ keys: string[];
333
+ } | {
334
+ code: 'attribute-spec-unknown-key';
335
+ opIndex: number;
336
+ entity: Handle;
337
+ handle: Handle;
338
+ keys: string[];
339
+ } | {
340
+ code: 'index-spec-unknown-key';
341
+ opIndex: number;
342
+ entity: Handle;
343
+ handle: Handle;
344
+ keys: string[];
345
+ } | {
346
+ code: 'operation-spec-unknown-key';
347
+ opIndex: number;
348
+ entity: Handle;
349
+ handle: Handle;
350
+ keys: string[];
351
+ } | {
352
+ code: 'association-spec-unknown-key';
353
+ opIndex: number;
354
+ handle: AssocHandle;
355
+ keys: string[];
356
+ } | {
357
+ code: 'group-spec-unknown-key';
358
+ opIndex: number;
359
+ keys: string[];
360
+ }
312
361
  /**
313
362
  * entity.add의 논리명이 모델에 이미 있는 엔티티와 충돌. 통과시키면 **도구가 스스로 `CHK-NAME-3`(error)
314
363
  * 상태를 만든다**(CC-5 교훈: 엔진이 검증 error 상태를 생성하지 않는다). 더 나쁜 건 같은 배치의 형제
@@ -455,4 +504,10 @@ export interface ResolverOptions {
455
504
  */
456
505
  embeddableCatalog?: EmbeddableCatalog;
457
506
  }
507
+ export declare const ENTITY_SPEC_KEYS: ReadonlySet<string>;
508
+ export declare const ATTR_SPEC_KEYS: ReadonlySet<string>;
509
+ export declare const INDEX_SPEC_KEYS: ReadonlySet<string>;
510
+ export declare const OPERATION_SPEC_KEYS: ReadonlySet<string>;
511
+ export declare const ASSOC_SPEC_KEYS: ReadonlySet<string>;
512
+ export declare const GROUP_SPEC_KEYS: ReadonlySet<string>;
458
513
  export declare function resolveSymbolicOps(model: LogicalModel, ops: SymbolicOp[], options?: ResolverOptions): ResolveResult;
@@ -1,4 +1,4 @@
1
- import { ClassStereotype, MultiLangText, Multiplicity, OperationVisibility } from '../core/types';
1
+ import { ClassStereotype, Entity, MultiLangText, Multiplicity, OperationVisibility } from '../core/types';
2
2
  /**
3
3
  * 요소 지정 핸들 — modelId 대신 이름/물리명.
4
4
  * 엔티티: 물리명(`table.physicalName`) 우선, 논리명(`name`) 보조 — 논리명은 모델 내 중복 허용(CHK-NAME-3)이라 모호 가능.
@@ -55,6 +55,15 @@ export interface EntitySpec {
55
55
  indexes?: IndexSpec[];
56
56
  /** inline 도메인 메서드 — 배열 순서가 곧 `order`. */
57
57
  operations?: OperationSpec[];
58
+ /**
59
+ * 직렬화 축 — 이 타입이 **소비될 때의 컨테이너**(`stereotype: 'SERIALIZED_TYPE'` 일 때만 의미).
60
+ * 타입을 SoT 로 두는 근거는 `core/types.ts` `Entity.serialization` 주석(요소 타입당 컨테이너가 하나로
61
+ * 고정된다는 실측). 미지정 = 컬렉션이 아닌 단일 값.
62
+ *
63
+ * ★**신규 엔티티는 add 시점에 줘야 한다** — 같은 배치의 `entity.update` 는 갓 만든 엔티티에 닿지 못한다
64
+ * (pending-entity-ref). `useVersion` 과 같은 이유·같은 처방이다.
65
+ */
66
+ serialization?: Entity['serialization'];
58
67
  }
59
68
  /** attribute.add 페이로드 — resolver가 modelId 발급 + dbAttr 골격 조립. */
60
69
  export interface AttrSpec {