@operato/twin-kernel 0.7.45 → 0.7.47
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/contract.d.ts +13 -1
- package/dist/mes-kernel.d.ts +17 -0
- package/dist/mes-kernel.js +97 -9
- package/dist-cjs/index.cjs +59 -10
- package/package.json +1 -1
package/dist/contract.d.ts
CHANGED
|
@@ -2180,7 +2180,19 @@ export interface TwinModelDef {
|
|
|
2180
2180
|
export interface ProductionSpec {
|
|
2181
2181
|
/** 무엇이 있고 어떻게 흐르나 — `DomainDefinition`(자기 타입, zero-dep). */
|
|
2182
2182
|
definition: import('./domain-definition.ts').DomainDefinition;
|
|
2183
|
-
/**
|
|
2183
|
+
/**
|
|
2184
|
+
* 자재 키 → **그 자재의 클래스 식별자를 정하는 값.**
|
|
2185
|
+
*
|
|
2186
|
+
* 두 모양을 받는다. `companyPrefix` 가 있으면 값은 GS1 item reference 이고 클래스는
|
|
2187
|
+
* `urn:epc:idpat:sgtin:<prefix>.<ref>.*` 로 조립된다. 프리픽스가 없으면 값은 **이미 완성된 클래스
|
|
2188
|
+
* URI** 이고(CBV 2.0 §8.3.4 `.../class/ObjClassid`) 커널은 그것을 그대로 쓴다 — 조립하면 값을 망친다.
|
|
2189
|
+
*
|
|
2190
|
+
* ── 같은 자재를 가리키는 이름은 하나다 ──────────────────────────────────────
|
|
2191
|
+
* 공정 명세의 `materialSpecification.materialDefinition` 도 **이 값에서 나온 클래스 식별자**여야 한다.
|
|
2192
|
+
* 두 자리가 같은 자재를 다른 이름으로 부르면, 커널은 그것이 같은 자재인지 알 길이 없다 — 같은 산출을
|
|
2193
|
+
* 두 번 만드는 것을 막는 기동 검사가 그때 조용히 열린다(§`assertNoDoubleProduction`). 옮길 수 없는
|
|
2194
|
+
* 식별자는 기동에서 말한다.
|
|
2195
|
+
*/
|
|
2184
2196
|
binding?: Record<string, string>;
|
|
2185
2197
|
companyPrefix?: string;
|
|
2186
2198
|
/** 쓸 레시피 키(미지정 시 첫 레시피) — 직렬 생산 경로(MES)만 쓴다. */
|
package/dist/mes-kernel.d.ts
CHANGED
|
@@ -107,7 +107,24 @@ export declare class MesKernel extends FlowEngine {
|
|
|
107
107
|
*/
|
|
108
108
|
private recipeDef;
|
|
109
109
|
/** 자재 키 → 구체 gtin 클래스(idpat). 구체 식별은 바인딩+prefix 로 인스턴스가 주입. */
|
|
110
|
+
/**
|
|
111
|
+
* 자재 키 → **품목 클래스 식별자.** 선언된 스킴이 모양을 정한다.
|
|
112
|
+
*
|
|
113
|
+
* ── 두 길 (2026-08-21) ─────────────────────────────────────────────────────
|
|
114
|
+
* **프리픽스가 있으면** `binding[key]` 를 품번(itemRef)으로 보고 SGTIN 을 조립한다(예전 거동).
|
|
115
|
+
* **없으면** `binding[key]` 가 **이미 완성된 클래스 식별자**다 — 커넥터가 선언된 도메인 아래에서
|
|
116
|
+
* 만든 CBV 형식(`https://<도메인>/class/<id>`)이고, 조립하면 그 값을 망친다.
|
|
117
|
+
*
|
|
118
|
+
* 실 연동에서 이것이 드러났다: 커넥터가 `binding` 에 완성된 URI 를 실었는데 커널이 그것을 품번으로
|
|
119
|
+
* 보고 프리픽스와 이어 붙이려 했다. 선언이 권위이므로 선언된 모양을 그대로 쓴다.
|
|
120
|
+
*/
|
|
110
121
|
private classOf;
|
|
122
|
+
/**
|
|
123
|
+
* 자재 키 + 일련번호 → **개체 식별자.**
|
|
124
|
+
*
|
|
125
|
+
* 프리픽스가 있으면 SGTIN(직렬), 없으면 선언된 이름공간 아래 CBV §8.2.4 `.../obj/<Objid>`.
|
|
126
|
+
* `Objid` 는 경로 성분 하나여야 하므로 구분자를 넣지 않는다 — 자재 키와 일련번호를 `-` 로 잇는다.
|
|
127
|
+
*/
|
|
111
128
|
private serialOf;
|
|
112
129
|
/**
|
|
113
130
|
* 이 공정이 **만든다고 선언한 품목** — 표준 `OpMaterialSpecification` `MaterialUse='produced'`.
|
package/dist/mes-kernel.js
CHANGED
|
@@ -49,9 +49,27 @@ export class MesKernel extends FlowEngine {
|
|
|
49
49
|
* 계약에서 `binding`·`companyPrefix` 는 선택이다 — 유통가공(비직렬 클래스+수량)은 자재 명세에
|
|
50
50
|
* gtin 을 직접 적으므로 필요 없다. 그래서 **필요한 경로에서만** 요구하고, 없으면 기동을 막는다.
|
|
51
51
|
*/
|
|
52
|
-
if (productionSpec?.definition?.recipes?.length
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
if (productionSpec?.definition?.recipes?.length) {
|
|
53
|
+
/*
|
|
54
|
+
* ── 프리픽스가 없는 현장도 세운다 (2026-08-21) ──────────────────────────
|
|
55
|
+
* 예전에는 `companyPrefix` 가 없으면 무조건 거절했다. 그래서 **GS1 회사 프리픽스가 없는 실
|
|
56
|
+
* 시스템이 기동조차 못 했다** — 첫 실 연동(F&B MES)이 정확히 그 자리에서 막혔다.
|
|
57
|
+
*
|
|
58
|
+
* 표준은 GS1 키만 인정하지 않는다. 선언된 도메인 아래의 클래스 식별자
|
|
59
|
+
* (CBV 2.0 §8.3.4 `.../class/<id>`)도 정합이고 소유 권한자는 그 도메인의 주인이다
|
|
60
|
+
* (EPCIS 2.0 §6.4). 그러면 프리픽스를 요구할 근거가 없다.
|
|
61
|
+
*
|
|
62
|
+
* 두 길을 섞지 않는다: 프리픽스가 있으면 SGTIN, 없고 이름공간이 있으면 도메인 기반.
|
|
63
|
+
* 둘 다 없으면 자재 키를 식별자로 옮길 방법이 없으므로 그때만 거절한다.
|
|
64
|
+
*/
|
|
65
|
+
const hasPrefix = !!productionSpec.companyPrefix;
|
|
66
|
+
const hasNamespace = !!productionSpec.identity?.namespaces?.length;
|
|
67
|
+
if (!productionSpec.binding || !(hasPrefix || hasNamespace)) {
|
|
68
|
+
throw new Error('recipe-driven production needs `binding`, and either `companyPrefix` (GS1 keys) or ' +
|
|
69
|
+
'`identity.namespaces` (domain-based identifiers — CBV 2.0 §8.3.4 `.../class/<id>`, assigned by the ' +
|
|
70
|
+
'owner of that internet domain). The definition does not know identifiers, so material keys cannot ' +
|
|
71
|
+
'be resolved without one of the two. The kernel does not invent a company prefix.');
|
|
72
|
+
}
|
|
55
73
|
}
|
|
56
74
|
/* 겹침 검사는 **바인딩 검증 뒤**다 — 검사 자체가 자재 키를 식별자로 옮겨 견주기 때문이다. */
|
|
57
75
|
if (productionSpec?.definition?.operations) {
|
|
@@ -71,9 +89,25 @@ export class MesKernel extends FlowEngine {
|
|
|
71
89
|
* 모든 계산이 거짓이 된다).
|
|
72
90
|
*/
|
|
73
91
|
assertNoDoubleProduction(ops) {
|
|
74
|
-
|
|
92
|
+
/*
|
|
93
|
+
* ── 두 어휘를 문자열로 견주지 않는다 (2026-08-21) ──────────────────────────
|
|
94
|
+
* 예전에는 `classOf(레시피 산출)` 과 `materialSpecification.materialDefinition` 을 **문자열로** 견주었다.
|
|
95
|
+
* 그 둘은 서로 다른 층의 이름이고(§`materialKeyOfClass`), 우연히 같은 커넥터에서는 맞았다.
|
|
96
|
+
* 커넥터가 둘을 다르게 실으면 — 공정 명세는 클래스 URI, `binding` 은 품번 — 이 검사가 **조용히
|
|
97
|
+
* 아무것도 잡지 못한다.** 같은 산출을 두 번 만드는 것을 막으려고 둔 검사인데, 바로 그때 열린다.
|
|
98
|
+
*
|
|
99
|
+
* 그래서 양쪽을 **자재 키**로 옮겨 놓고 견준다. 옮길 수 없는 식별자는 그 자리에서 말한다 —
|
|
100
|
+
* 런타임이 이미 같은 규칙으로 멈추므로(§`materialKeyOfClass`), 기동에서 말하는 편이 낫다.
|
|
101
|
+
*/
|
|
102
|
+
const finals = new Set((this.productionSpec?.definition?.recipes ?? []).flatMap(r => (r.outputs ?? []).map(o => o.material)));
|
|
103
|
+
/*
|
|
104
|
+
* 레시피가 없으면 겹칠 것이 없다 — 그리고 그때는 `binding` 도 없다(유통가공은 산출을 자재 명세로만
|
|
105
|
+
* 말한다). 옮기기를 시도하면 없는 통로를 지나려 하므로 여기서 끝낸다.
|
|
106
|
+
*/
|
|
107
|
+
if (!finals.size)
|
|
108
|
+
return;
|
|
75
109
|
const bad = ops
|
|
76
|
-
.filter(o => (o.materialSpecification ?? []).some(m => m.use === 'produced' && m.materialDefinition && finals.has(m.materialDefinition)))
|
|
110
|
+
.filter(o => (o.materialSpecification ?? []).some(m => m.use === 'produced' && m.materialDefinition && finals.has(this.materialKeyOfClass(m.materialDefinition, o.key))))
|
|
77
111
|
.map(o => o.key);
|
|
78
112
|
if (!bad.length)
|
|
79
113
|
return;
|
|
@@ -106,7 +140,27 @@ export class MesKernel extends FlowEngine {
|
|
|
106
140
|
* 아니라 **하나를 고르는** 것이므로 규칙이 갈리지 않는다.
|
|
107
141
|
*/
|
|
108
142
|
identityDeclaration() {
|
|
109
|
-
|
|
143
|
+
/*
|
|
144
|
+
* ── 가리지 않고 **합친다** (2026-08-21) ────────────────────────────────────
|
|
145
|
+
* 예전에는 생산 선언이 있으면 모델 선언을 **가렸다**(`?? super`). 그래서 생산 선언이 프리픽스만
|
|
146
|
+
* 말하고 이름공간은 모델에만 있는 현장에서, 커널이 모델의 이름공간을 보지 못해 작업지시 식별자를
|
|
147
|
+
* 만들 수 없었다 — 시험이 그것을 잡았다.
|
|
148
|
+
*
|
|
149
|
+
* 두 선언은 경쟁이 아니라 같은 사실의 두 자리다(생산 선언은 먼저 생긴 자리다). 항목별로 있는 것을
|
|
150
|
+
* 쓴다: 생산 선언이 말한 것이 이기고, 말하지 않은 것은 모델에서 온다.
|
|
151
|
+
*/
|
|
152
|
+
const own = this.productionSpec?.identity;
|
|
153
|
+
const model = super.identityDeclaration();
|
|
154
|
+
if (!own)
|
|
155
|
+
return model;
|
|
156
|
+
if (!model)
|
|
157
|
+
return own;
|
|
158
|
+
return {
|
|
159
|
+
namespaces: own.namespaces?.length ? own.namespaces : model.namespaces,
|
|
160
|
+
documentTypes: { ...model.documentTypes, ...own.documentTypes },
|
|
161
|
+
...(own.companyPrefix ?? model.companyPrefix ? { companyPrefix: own.companyPrefix ?? model.companyPrefix } : {}),
|
|
162
|
+
...(own.issuedClaim ?? model.issuedClaim ? { issuedClaim: own.issuedClaim ?? model.issuedClaim } : {})
|
|
163
|
+
};
|
|
110
164
|
}
|
|
111
165
|
identityGroundingView() {
|
|
112
166
|
return identityGroundingOf(this.productionSpec);
|
|
@@ -264,11 +318,44 @@ export class MesKernel extends FlowEngine {
|
|
|
264
318
|
return d.recipes[0];
|
|
265
319
|
}
|
|
266
320
|
/** 자재 키 → 구체 gtin 클래스(idpat). 구체 식별은 바인딩+prefix 로 인스턴스가 주입. */
|
|
321
|
+
/**
|
|
322
|
+
* 자재 키 → **품목 클래스 식별자.** 선언된 스킴이 모양을 정한다.
|
|
323
|
+
*
|
|
324
|
+
* ── 두 길 (2026-08-21) ─────────────────────────────────────────────────────
|
|
325
|
+
* **프리픽스가 있으면** `binding[key]` 를 품번(itemRef)으로 보고 SGTIN 을 조립한다(예전 거동).
|
|
326
|
+
* **없으면** `binding[key]` 가 **이미 완성된 클래스 식별자**다 — 커넥터가 선언된 도메인 아래에서
|
|
327
|
+
* 만든 CBV 형식(`https://<도메인>/class/<id>`)이고, 조립하면 그 값을 망친다.
|
|
328
|
+
*
|
|
329
|
+
* 실 연동에서 이것이 드러났다: 커넥터가 `binding` 에 완성된 URI 를 실었는데 커널이 그것을 품번으로
|
|
330
|
+
* 보고 프리픽스와 이어 붙이려 했다. 선언이 권위이므로 선언된 모양을 그대로 쓴다.
|
|
331
|
+
*/
|
|
267
332
|
classOf(materialKey) {
|
|
268
|
-
|
|
333
|
+
const spec = this.productionSpec;
|
|
334
|
+
const bound = spec.binding[materialKey];
|
|
335
|
+
if (spec.companyPrefix)
|
|
336
|
+
return sgtinClass(spec.companyPrefix, bound);
|
|
337
|
+
if (!bound) {
|
|
338
|
+
throw new Error(`material '${materialKey}' has no binding — the model must say which item this key names. ` +
|
|
339
|
+
'The kernel does not invent an identifier for it.');
|
|
340
|
+
}
|
|
341
|
+
/* 이미 완성된 식별자다. 모양이 표준에 맞는지는 판정기가 답한다(§classIdentifierViolation). */
|
|
342
|
+
return bound;
|
|
269
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* 자재 키 + 일련번호 → **개체 식별자.**
|
|
346
|
+
*
|
|
347
|
+
* 프리픽스가 있으면 SGTIN(직렬), 없으면 선언된 이름공간 아래 CBV §8.2.4 `.../obj/<Objid>`.
|
|
348
|
+
* `Objid` 는 경로 성분 하나여야 하므로 구분자를 넣지 않는다 — 자재 키와 일련번호를 `-` 로 잇는다.
|
|
349
|
+
*/
|
|
270
350
|
serialOf(materialKey, serial) {
|
|
271
|
-
|
|
351
|
+
const spec = this.productionSpec;
|
|
352
|
+
if (spec.companyPrefix)
|
|
353
|
+
return sgtinUri(spec.companyPrefix, spec.binding[materialKey], serial);
|
|
354
|
+
const uri = this.declaredObjectId(`${materialKey}-${serial}`);
|
|
355
|
+
if (uri)
|
|
356
|
+
return uri;
|
|
357
|
+
throw new Error(`cannot name an instance of '${materialKey}': the model declares neither \`companyPrefix\` (GS1 keys) nor a ` +
|
|
358
|
+
'usable `identity.namespaces` entry (CBV 2.0 §8.2.4 `.../obj/<id>`). The kernel does not invent one.');
|
|
272
359
|
}
|
|
273
360
|
/**
|
|
274
361
|
* 이 공정이 **만든다고 선언한 품목** — 표준 `OpMaterialSpecification` `MaterialUse='produced'`.
|
|
@@ -424,7 +511,8 @@ export class MesKernel extends FlowEngine {
|
|
|
424
511
|
* 번호라고 말해 주지 않는다.
|
|
425
512
|
*/
|
|
426
513
|
workOrderId(serial) {
|
|
427
|
-
|
|
514
|
+
/* 선언을 읽는 곳은 하나다(§`FlowEngine.identityDeclaration`) — 직접 읽으면 모델 자리를 놓친다. */
|
|
515
|
+
const identity = this.identityDeclaration();
|
|
428
516
|
for (const ns of identity?.namespaces ?? []) {
|
|
429
517
|
const uri = bizTransactionUri(ns, serial);
|
|
430
518
|
if (uri)
|
package/dist-cjs/index.cjs
CHANGED
|
@@ -6643,10 +6643,14 @@ var MesKernel = class extends FlowEngine {
|
|
|
6643
6643
|
if (productionSpec?.definition?.operations) {
|
|
6644
6644
|
this.loadOperations(productionSpec.definition.operations);
|
|
6645
6645
|
}
|
|
6646
|
-
if (productionSpec?.definition?.recipes?.length
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
)
|
|
6646
|
+
if (productionSpec?.definition?.recipes?.length) {
|
|
6647
|
+
const hasPrefix = !!productionSpec.companyPrefix;
|
|
6648
|
+
const hasNamespace = !!productionSpec.identity?.namespaces?.length;
|
|
6649
|
+
if (!productionSpec.binding || !(hasPrefix || hasNamespace)) {
|
|
6650
|
+
throw new Error(
|
|
6651
|
+
"recipe-driven production needs `binding`, and either `companyPrefix` (GS1 keys) or `identity.namespaces` (domain-based identifiers \u2014 CBV 2.0 \xA78.3.4 `.../class/<id>`, assigned by the owner of that internet domain). The definition does not know identifiers, so material keys cannot be resolved without one of the two. The kernel does not invent a company prefix."
|
|
6652
|
+
);
|
|
6653
|
+
}
|
|
6650
6654
|
}
|
|
6651
6655
|
if (productionSpec?.definition?.operations) {
|
|
6652
6656
|
this.assertNoDoubleProduction(productionSpec.definition.operations);
|
|
@@ -6665,8 +6669,13 @@ var MesKernel = class extends FlowEngine {
|
|
|
6665
6669
|
* 모든 계산이 거짓이 된다).
|
|
6666
6670
|
*/
|
|
6667
6671
|
assertNoDoubleProduction(ops) {
|
|
6668
|
-
const finals = new Set((this.productionSpec?.definition?.recipes ?? []).flatMap((r) => (r.outputs ?? []).map((o) =>
|
|
6669
|
-
|
|
6672
|
+
const finals = new Set((this.productionSpec?.definition?.recipes ?? []).flatMap((r) => (r.outputs ?? []).map((o) => o.material)));
|
|
6673
|
+
if (!finals.size) return;
|
|
6674
|
+
const bad2 = ops.filter(
|
|
6675
|
+
(o) => (o.materialSpecification ?? []).some(
|
|
6676
|
+
(m) => m.use === "produced" && m.materialDefinition && finals.has(this.materialKeyOfClass(m.materialDefinition, o.key))
|
|
6677
|
+
)
|
|
6678
|
+
).map((o) => o.key);
|
|
6670
6679
|
if (!bad2.length) return;
|
|
6671
6680
|
throw new Error(
|
|
6672
6681
|
`MES recipe already produces its output \u2014 operations [${bad2.join(", ")}] must not also declare that same material as materialSpecification use:'produced' (that would create the same output twice). Declare intermediate outputs freely; the final output belongs to the recipe.`
|
|
@@ -6697,7 +6706,16 @@ var MesKernel = class extends FlowEngine {
|
|
|
6697
6706
|
* 아니라 **하나를 고르는** 것이므로 규칙이 갈리지 않는다.
|
|
6698
6707
|
*/
|
|
6699
6708
|
identityDeclaration() {
|
|
6700
|
-
|
|
6709
|
+
const own = this.productionSpec?.identity;
|
|
6710
|
+
const model = super.identityDeclaration();
|
|
6711
|
+
if (!own) return model;
|
|
6712
|
+
if (!model) return own;
|
|
6713
|
+
return {
|
|
6714
|
+
namespaces: own.namespaces?.length ? own.namespaces : model.namespaces,
|
|
6715
|
+
documentTypes: { ...model.documentTypes, ...own.documentTypes },
|
|
6716
|
+
...own.companyPrefix ?? model.companyPrefix ? { companyPrefix: own.companyPrefix ?? model.companyPrefix } : {},
|
|
6717
|
+
...own.issuedClaim ?? model.issuedClaim ? { issuedClaim: own.issuedClaim ?? model.issuedClaim } : {}
|
|
6718
|
+
};
|
|
6701
6719
|
}
|
|
6702
6720
|
identityGroundingView() {
|
|
6703
6721
|
return identityGroundingOf(this.productionSpec);
|
|
@@ -6846,11 +6864,42 @@ var MesKernel = class extends FlowEngine {
|
|
|
6846
6864
|
return d.recipes[0];
|
|
6847
6865
|
}
|
|
6848
6866
|
/** 자재 키 → 구체 gtin 클래스(idpat). 구체 식별은 바인딩+prefix 로 인스턴스가 주입. */
|
|
6867
|
+
/**
|
|
6868
|
+
* 자재 키 → **품목 클래스 식별자.** 선언된 스킴이 모양을 정한다.
|
|
6869
|
+
*
|
|
6870
|
+
* ── 두 길 (2026-08-21) ─────────────────────────────────────────────────────
|
|
6871
|
+
* **프리픽스가 있으면** `binding[key]` 를 품번(itemRef)으로 보고 SGTIN 을 조립한다(예전 거동).
|
|
6872
|
+
* **없으면** `binding[key]` 가 **이미 완성된 클래스 식별자**다 — 커넥터가 선언된 도메인 아래에서
|
|
6873
|
+
* 만든 CBV 형식(`https://<도메인>/class/<id>`)이고, 조립하면 그 값을 망친다.
|
|
6874
|
+
*
|
|
6875
|
+
* 실 연동에서 이것이 드러났다: 커넥터가 `binding` 에 완성된 URI 를 실었는데 커널이 그것을 품번으로
|
|
6876
|
+
* 보고 프리픽스와 이어 붙이려 했다. 선언이 권위이므로 선언된 모양을 그대로 쓴다.
|
|
6877
|
+
*/
|
|
6849
6878
|
classOf(materialKey) {
|
|
6850
|
-
|
|
6879
|
+
const spec = this.productionSpec;
|
|
6880
|
+
const bound = spec.binding[materialKey];
|
|
6881
|
+
if (spec.companyPrefix) return sgtinClass(spec.companyPrefix, bound);
|
|
6882
|
+
if (!bound) {
|
|
6883
|
+
throw new Error(
|
|
6884
|
+
`material '${materialKey}' has no binding \u2014 the model must say which item this key names. The kernel does not invent an identifier for it.`
|
|
6885
|
+
);
|
|
6886
|
+
}
|
|
6887
|
+
return bound;
|
|
6851
6888
|
}
|
|
6889
|
+
/**
|
|
6890
|
+
* 자재 키 + 일련번호 → **개체 식별자.**
|
|
6891
|
+
*
|
|
6892
|
+
* 프리픽스가 있으면 SGTIN(직렬), 없으면 선언된 이름공간 아래 CBV §8.2.4 `.../obj/<Objid>`.
|
|
6893
|
+
* `Objid` 는 경로 성분 하나여야 하므로 구분자를 넣지 않는다 — 자재 키와 일련번호를 `-` 로 잇는다.
|
|
6894
|
+
*/
|
|
6852
6895
|
serialOf(materialKey, serial) {
|
|
6853
|
-
|
|
6896
|
+
const spec = this.productionSpec;
|
|
6897
|
+
if (spec.companyPrefix) return sgtinUri(spec.companyPrefix, spec.binding[materialKey], serial);
|
|
6898
|
+
const uri = this.declaredObjectId(`${materialKey}-${serial}`);
|
|
6899
|
+
if (uri) return uri;
|
|
6900
|
+
throw new Error(
|
|
6901
|
+
`cannot name an instance of '${materialKey}': the model declares neither \`companyPrefix\` (GS1 keys) nor a usable \`identity.namespaces\` entry (CBV 2.0 \xA78.2.4 \`.../obj/<id>\`). The kernel does not invent one.`
|
|
6902
|
+
);
|
|
6854
6903
|
}
|
|
6855
6904
|
/**
|
|
6856
6905
|
* 이 공정이 **만든다고 선언한 품목** — 표준 `OpMaterialSpecification` `MaterialUse='produced'`.
|
|
@@ -6991,7 +7040,7 @@ var MesKernel = class extends FlowEngine {
|
|
|
6991
7040
|
* 번호라고 말해 주지 않는다.
|
|
6992
7041
|
*/
|
|
6993
7042
|
workOrderId(serial) {
|
|
6994
|
-
const identity = this.
|
|
7043
|
+
const identity = this.identityDeclaration();
|
|
6995
7044
|
for (const ns of identity?.namespaces ?? []) {
|
|
6996
7045
|
const uri = bizTransactionUri(ns, serial);
|
|
6997
7046
|
if (uri) return uri;
|
package/package.json
CHANGED