@things-factory/headless-twin 10.0.7 โ 10.0.9
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-server/engine/attention-digest.d.ts +52 -0
- package/dist-server/engine/attention-digest.js +76 -0
- package/dist-server/engine/attention-digest.js.map +1 -0
- package/dist-server/engine/board-vocabulary.d.ts +17 -0
- package/dist-server/engine/board-vocabulary.js +63 -0
- package/dist-server/engine/board-vocabulary.js.map +1 -0
- package/dist-server/engine/command-routing.d.ts +33 -0
- package/dist-server/engine/command-routing.js +53 -0
- package/dist-server/engine/command-routing.js.map +1 -0
- package/dist-server/engine/entity-delta.d.ts +13 -6
- package/dist-server/engine/entity-delta.js +38 -12
- package/dist-server/engine/entity-delta.js.map +1 -1
- package/dist-server/engine/index.d.ts +6 -0
- package/dist-server/engine/index.js +10 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/kpi-baseline.d.ts +78 -0
- package/dist-server/engine/kpi-baseline.js +123 -0
- package/dist-server/engine/kpi-baseline.js.map +1 -0
- package/dist-server/engine/kpi-broadcast.d.ts +4 -0
- package/dist-server/engine/kpi-broadcast.js +16 -0
- package/dist-server/engine/kpi-broadcast.js.map +1 -0
- package/dist-server/engine/kpi-query.d.ts +31 -0
- package/dist-server/engine/kpi-query.js +50 -2
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/live-attentions.d.ts +1 -0
- package/dist-server/engine/live-attentions.js +7 -1
- package/dist-server/engine/live-attentions.js.map +1 -1
- package/dist-server/engine/runtime-key.d.ts +15 -0
- package/dist-server/engine/runtime-key.js +64 -0
- package/dist-server/engine/runtime-key.js.map +1 -0
- package/dist-server/engine/state-axes.d.ts +16 -0
- package/dist-server/engine/state-axes.js +54 -0
- package/dist-server/engine/state-axes.js.map +1 -0
- package/dist-server/engine/twin-engine.d.ts +92 -16
- package/dist-server/engine/twin-engine.js +335 -77
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/twin-level.d.ts +23 -0
- package/dist-server/engine/twin-level.js +52 -0
- package/dist-server/engine/twin-level.js.map +1 -0
- package/dist-server/engine/warm-start.d.ts +58 -12
- package/dist-server/engine/warm-start.js +80 -9
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +34 -0
- package/dist-server/service/reference/discovery-result.js +84 -0
- package/dist-server/service/reference/discovery-result.js.map +1 -0
- package/dist-server/service/reference/ingest-space.d.ts +30 -0
- package/dist-server/service/reference/ingest-space.js +63 -0
- package/dist-server/service/reference/ingest-space.js.map +1 -0
- package/dist-server/service/reference/knob-defaults.d.ts +20 -0
- package/dist-server/service/reference/knob-defaults.js +59 -0
- package/dist-server/service/reference/knob-defaults.js.map +1 -0
- package/dist-server/service/reference/reference-live.js +2 -2
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +37 -2
- package/dist-server/service/reference/reference-master.js +55 -5
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +2 -2
- package/dist-server/service/reference/reference-resolver.js +71 -15
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.d.ts +8 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +39 -8
- package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
- package/dist-server/service/twin-control/twin-control-mutation.d.ts +2 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +29 -10
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.js +4 -2
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +6 -2
- package/dist-server/service/twin-journal/twin-journal-query.js +25 -7
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +8 -0
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +23 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.js +9 -0
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-state/twin-state-subscription.js +1 -1
- package/dist-server/service/twin-state/twin-state-subscription.js.map +1 -1
- package/dist-server/service/twin-structure/twin-structure.js +2 -1
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-server/service/twin-target/twin-target-resolver.js +21 -4
- package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/server/engine/attention-digest.ts +102 -0
- package/server/engine/board-vocabulary.ts +61 -0
- package/server/engine/command-routing.ts +67 -0
- package/server/engine/entity-delta.ts +33 -11
- package/server/engine/index.ts +10 -0
- package/server/engine/kpi-baseline.ts +202 -0
- package/server/engine/kpi-broadcast.ts +13 -0
- package/server/engine/kpi-query.ts +81 -3
- package/server/engine/live-attentions.ts +7 -2
- package/server/engine/runtime-key.ts +58 -0
- package/server/engine/state-axes.ts +55 -0
- package/server/engine/twin-engine.ts +350 -77
- package/server/engine/twin-level.ts +48 -0
- package/server/engine/warm-start.ts +130 -16
- package/server/service/reference/discovery-result.ts +95 -0
- package/server/service/reference/ingest-space.ts +70 -0
- package/server/service/reference/knob-defaults.ts +59 -0
- package/server/service/reference/reference-live.ts +2 -2
- package/server/service/reference/reference-master.ts +94 -8
- package/server/service/reference/reference-resolver.ts +80 -16
- package/server/service/twin-attention/twin-attention-query.ts +43 -6
- package/server/service/twin-control/twin-control-mutation.ts +31 -12
- package/server/service/twin-forecast/twin-forecast-query.ts +3 -2
- package/server/service/twin-instance/twin-instance.ts +6 -2
- package/server/service/twin-journal/twin-journal-query.ts +35 -5
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +18 -2
- package/server/service/twin-metrics/twin-metrics-query.ts +1 -1
- package/server/service/twin-space/twin-space-resolver.ts +10 -1
- package/server/service/twin-state/twin-state-subscription.ts +1 -1
- package/server/service/twin-structure/twin-structure.ts +4 -1
- package/server/service/twin-target/twin-target-resolver.ts +22 -4
- package/test/attention-digest.test.ts +135 -0
- package/test/board-vocabulary.test.ts +114 -0
- package/test/capability-mapping.test.ts +4 -4
- package/test/command-routing.test.ts +61 -0
- package/test/discovery-result.test.ts +75 -0
- package/test/entity-delta.test.ts +25 -25
- package/test/ingest-bench.test.ts +3 -3
- package/test/ingest-space.test.ts +50 -0
- package/test/knob-defaults.test.ts +72 -0
- package/test/kpi-baseline-db.test.ts +214 -0
- package/test/kpi-baseline.test.ts +196 -0
- package/test/kpi-query-bench.test.ts +128 -0
- package/test/live-mirror-parity.test.ts +35 -2
- package/test/master-to-twin.test.ts +7 -3
- package/test/mutation-gate.test.ts +108 -0
- package/test/oee-accumulator.test.ts +65 -1
- package/test/registry-key-guard.test.ts +80 -0
- package/test/runtime-key.test.ts +66 -0
- package/test/scale-twin-bench.test.ts +2 -2
- package/test/state-axes.test.ts +74 -0
- package/test/streamline-e2e.test.ts +2 -2
- package/test/structure-revision-db.test.ts +5 -4
- package/test/tenant-registry-db.test.ts +149 -0
- package/test/warm-start-seam.test.ts +140 -0
- package/test/warm-start.test.ts +138 -4
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* ๋
ธ๋ธ ๊ธฐ๋ณธ๊ฐ ์ ์ฉ โ **์์**. "์ ์ค ๊ฐ์ ํ
ํ๋ฆฟ์ด ์ ์ธํ ๊ธฐ๋ณธ๊ฐ์ผ๋ก."
|
|
4
|
+
*
|
|
5
|
+
* โโ ์ ์๋ (2026-08-05) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
6
|
+
* ํ
ํ๋ฆฟ์ ๋
ธ๋ธ๋ง๋ค ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ๋ค(`knobs[].default`). ๊ทธ๋ฐ๋ฐ ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ์ฑ์ฐ๋ ์ผ์ **์์๋๋ง**
|
|
7
|
+
* ํ๊ณ ์์๋ค โ ์๋ฒ๋ ๋ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ทธ๋๋ก `build(p)` ์ ๋๊ธด๋ค. ๊ทธ๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ผ๋ถ๋ง ์ฃผ๊ณ
|
|
8
|
+
* ๋ถ๋ฅด๋ฉด(AIยท์คํฌ๋ฆฝํธยทAPI ํธ์ถ์) ํ
ํ๋ฆฟ ์์์ `Number(p.inboundRate) || 0` ์ด **0** ์ด ๋๊ณ ,
|
|
9
|
+
* ๋ฐ์๋ฅ 0 = ๋์ฐฉ ์์ = **์๋ฌด๊ฒ๋ ํ์ง ์๋ ํธ์**์ด ์กฐ์ฉํ ๋ง๋ค์ด์ง๋ค.
|
|
10
|
+
*
|
|
11
|
+
* ์ค์ ๋ก ๊ทธ ํจ์ ์ ๋ฐ์๋ค: ์ ํต๊ฐ๊ณต ์ฐฝ๊ณ ๋ฅผ ํ๋ผ๋ฏธํฐ ์ผ๋ถ๋ง ์ฃผ๊ณ ๋ง๋ค์๋๋ ์ด๋ฒคํธ๊ฐ 0๊ฑด์ด์๊ณ ,
|
|
12
|
+
* ์ฒ์์๋ ํ
ํ๋ฆฟ์ด ๊นจ์ง ๊ฒ์ผ๋ก ์ค์งํ๋ค. ๊ธฐ๋ณธ๊ฐ์ ์๋ ๊ณณ์ด ๊ณ์ฝ(๋
ธ๋ธ ์คํค๋ง)์ธ๋ฐ ๊ทธ๊ฒ์ ์ ์ฉํ๋
|
|
13
|
+
* ๊ณณ์ด ํ๋ฉด๋ฟ์ด๋ฉด, ํ๋ฉด์ ๊ฑฐ์น์ง ์๋ ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ํจ์ ์ด ๋๋ค.
|
|
14
|
+
*
|
|
15
|
+
* โโ 0 ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฎ์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
16
|
+
* ๋ฐ์๋ฅ `0` ์ "๋์ฐฉ ์์" ์ด๋ผ๋ **๋ป ์๋ ๊ฐ**์ด๋ค. ์๋ ๊ฒ๊ณผ 0 ์ ๋ค๋ฅด๋ค โ falsy ๋ก ํ์ ํด ๋ฎ์ผ๋ฉด
|
|
17
|
+
* "์๊ทน ์์ด ๊ตฌ์กฐ๋ง ๋ณด๊ฒ ๋ค" ๋ ์ ์ธ์ด ์กฐ์ฉํ ๋ค์งํ๋ค. ๊ทธ๋์ **ํค๊ฐ ์์ ๋๋ง** ์ฑ์ด๋ค.
|
|
18
|
+
* `null` ์ ์๋ ๊ฒ์ผ๋ก ๋ณธ๋ค(JSONยทGraphQL ๊ฒฝ๋ก์์ "์ฃผ์ง ์์" ์ด null ๋ก ์ค๋ ์ผ์ด ํํ๋ค).
|
|
19
|
+
*
|
|
20
|
+
* โโ ์ ์ธ ๋ฐ ํ๋ผ๋ฏธํฐ๋ ์๋์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
21
|
+
* ํ
ํ๋ฆฟ์ ๋
ธ๋ธ์ ์๋ ๊ฐ๋ ์ฝ๋๋ค(์: `geo` ๋์ `lat`/`lon` ํด๋ฐฑ). ๋ชจ๋ฅด๋ ํค๋ฅผ ๊ฑท์ด๋ด๋ฉด ๊ทธ ๊ฒฝ๋ก๊ฐ
|
|
22
|
+
* ์กฐ์ฉํ ๋๊ธด๋ค. ๊ทธ๋๋ก ํต๊ณผ์ํจ๋ค.
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.applyKnobDefaults = applyKnobDefaults;
|
|
26
|
+
exports.filledKnobKeys = filledKnobKeys;
|
|
27
|
+
/**
|
|
28
|
+
* ๋น ์ง ๋
ธ๋ธ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด๋ค.
|
|
29
|
+
*
|
|
30
|
+
* @param knobs ํ
ํ๋ฆฟ์ด ์ ์ธํ ๋
ธ๋ธ๋ค(์์ผ๋ฉด ํ๋ผ๋ฏธํฐ๋ฅผ ๊ทธ๋๋ก ๋๋ ค์ค๋ค).
|
|
31
|
+
* @param params ํธ์ถ์๊ฐ ์ค ํ๋ผ๋ฏธํฐ.
|
|
32
|
+
* @returns ์ ๊ฐ์ฒด โ ์
๋ ฅ์ ๋ฐ๊พธ์ง ์๋๋ค(ํธ์ถ์์ ๊ฐ์ฒด๊ฐ ๋ชฐ๋ ๋ณํ๋ฉด ์ถ์ ์ด ์ด๋ ต๋ค).
|
|
33
|
+
*/
|
|
34
|
+
function applyKnobDefaults(knobs, params) {
|
|
35
|
+
const out = { ...(params ?? {}) };
|
|
36
|
+
for (const k of knobs ?? []) {
|
|
37
|
+
if (!k?.key)
|
|
38
|
+
continue;
|
|
39
|
+
if (k.default === undefined)
|
|
40
|
+
continue; // ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ์ง ์์ ๋
ธ๋ธ๋ ์ฑ์ธ ๊ฒ์ด ์๋ค
|
|
41
|
+
const given = out[k.key];
|
|
42
|
+
if (given === undefined || given === null)
|
|
43
|
+
out[k.key] = k.default;
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด ๋
ธ๋ธ ์ด๋ฆ๋ค โ ํธ์ถ์์๊ฒ "๋ฌด์์ ๋ด๊ฐ ์ ํด ์คฌ๋์ง" ์๋ฆด ๋ ์ด๋ค.
|
|
49
|
+
*
|
|
50
|
+
* ์กฐ์ฉํ ์ฑ์ฐ๋ ๊ฒ๋ ์กฐ์ฉํ ๋น์ฐ๋ ๊ฒ๋งํผ ์ํํ๋ค: ์ฌ์ฉ์๊ฐ ์ค ์ ์๋ ๊ฐ์ผ๋ก ํธ์์ด ๋ง๋ค์ด์ก๋๋ฐ
|
|
51
|
+
* ์๋ฌด ๋ง์ด ์์ผ๋ฉด, ๋์ค์ "์ ์ด ์์น์ธ๊ฐ" ๋ฅผ ์๋ฌด๋ ๋ตํ ์ ์๋ค.
|
|
52
|
+
*/
|
|
53
|
+
function filledKnobKeys(knobs, params) {
|
|
54
|
+
const given = params ?? {};
|
|
55
|
+
return (knobs ?? [])
|
|
56
|
+
.filter(k => k?.key && k.default !== undefined && (given[k.key] === undefined || given[k.key] === null))
|
|
57
|
+
.map(k => k.key);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=knob-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knob-defaults.js","sourceRoot":"","sources":["../../../server/service/reference/knob-defaults.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;AAeH,8CASC;AAQD,wCAKC;AA7BD;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,KAA6C,EAAE,MAAkD;IACjI,MAAM,GAAG,GAA4B,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAA;IAC1D,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,EAAE,GAAG;YAAE,SAAQ;QACrB,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,SAAQ,CAAC,4BAA4B;QAClE,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACxB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAA;IACnE,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,KAA6C,EAAE,MAAkD;IAC9H,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAA;IAC1B,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAI,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,GAAI,CAAC,KAAK,IAAI,CAAC,CAAC;SACzG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAI,CAAC,CAAA;AACrB,CAAC","sourcesContent":["/*\n * ๋
ธ๋ธ ๊ธฐ๋ณธ๊ฐ ์ ์ฉ โ **์์**. \"์ ์ค ๊ฐ์ ํ
ํ๋ฆฟ์ด ์ ์ธํ ๊ธฐ๋ณธ๊ฐ์ผ๋ก.\"\n *\n * โโ ์ ์๋ (2026-08-05) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ
ํ๋ฆฟ์ ๋
ธ๋ธ๋ง๋ค ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ๋ค(`knobs[].default`). ๊ทธ๋ฐ๋ฐ ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ์ฑ์ฐ๋ ์ผ์ **์์๋๋ง**\n * ํ๊ณ ์์๋ค โ ์๋ฒ๋ ๋ฐ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ทธ๋๋ก `build(p)` ์ ๋๊ธด๋ค. ๊ทธ๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ผ๋ถ๋ง ์ฃผ๊ณ \n * ๋ถ๋ฅด๋ฉด(AIยท์คํฌ๋ฆฝํธยทAPI ํธ์ถ์) ํ
ํ๋ฆฟ ์์์ `Number(p.inboundRate) || 0` ์ด **0** ์ด ๋๊ณ ,\n * ๋ฐ์๋ฅ 0 = ๋์ฐฉ ์์ = **์๋ฌด๊ฒ๋ ํ์ง ์๋ ํธ์**์ด ์กฐ์ฉํ ๋ง๋ค์ด์ง๋ค.\n *\n * ์ค์ ๋ก ๊ทธ ํจ์ ์ ๋ฐ์๋ค: ์ ํต๊ฐ๊ณต ์ฐฝ๊ณ ๋ฅผ ํ๋ผ๋ฏธํฐ ์ผ๋ถ๋ง ์ฃผ๊ณ ๋ง๋ค์๋๋ ์ด๋ฒคํธ๊ฐ 0๊ฑด์ด์๊ณ ,\n * ์ฒ์์๋ ํ
ํ๋ฆฟ์ด ๊นจ์ง ๊ฒ์ผ๋ก ์ค์งํ๋ค. ๊ธฐ๋ณธ๊ฐ์ ์๋ ๊ณณ์ด ๊ณ์ฝ(๋
ธ๋ธ ์คํค๋ง)์ธ๋ฐ ๊ทธ๊ฒ์ ์ ์ฉํ๋\n * ๊ณณ์ด ํ๋ฉด๋ฟ์ด๋ฉด, ํ๋ฉด์ ๊ฑฐ์น์ง ์๋ ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ํจ์ ์ด ๋๋ค.\n *\n * โโ 0 ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ฎ์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ๋ฐ์๋ฅ `0` ์ \"๋์ฐฉ ์์\" ์ด๋ผ๋ **๋ป ์๋ ๊ฐ**์ด๋ค. ์๋ ๊ฒ๊ณผ 0 ์ ๋ค๋ฅด๋ค โ falsy ๋ก ํ์ ํด ๋ฎ์ผ๋ฉด\n * \"์๊ทน ์์ด ๊ตฌ์กฐ๋ง ๋ณด๊ฒ ๋ค\" ๋ ์ ์ธ์ด ์กฐ์ฉํ ๋ค์งํ๋ค. ๊ทธ๋์ **ํค๊ฐ ์์ ๋๋ง** ์ฑ์ด๋ค.\n * `null` ์ ์๋ ๊ฒ์ผ๋ก ๋ณธ๋ค(JSONยทGraphQL ๊ฒฝ๋ก์์ \"์ฃผ์ง ์์\" ์ด null ๋ก ์ค๋ ์ผ์ด ํํ๋ค).\n *\n * โโ ์ ์ธ ๋ฐ ํ๋ผ๋ฏธํฐ๋ ์๋์ง ์๋๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ
ํ๋ฆฟ์ ๋
ธ๋ธ์ ์๋ ๊ฐ๋ ์ฝ๋๋ค(์: `geo` ๋์ `lat`/`lon` ํด๋ฐฑ). ๋ชจ๋ฅด๋ ํค๋ฅผ ๊ฑท์ด๋ด๋ฉด ๊ทธ ๊ฒฝ๋ก๊ฐ\n * ์กฐ์ฉํ ๋๊ธด๋ค. ๊ทธ๋๋ก ํต๊ณผ์ํจ๋ค.\n */\n\n/** ํ
ํ๋ฆฟ ๋
ธ๋ธ โ ๊ธฐ๋ณธ๊ฐ ์ ์ฉ์ ํ์ํ ๋งํผ๋ง ๋ณธ๋ค. */\nexport interface KnobLike {\n key?: string\n default?: unknown\n}\n\n/**\n * ๋น ์ง ๋
ธ๋ธ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด๋ค.\n *\n * @param knobs ํ
ํ๋ฆฟ์ด ์ ์ธํ ๋
ธ๋ธ๋ค(์์ผ๋ฉด ํ๋ผ๋ฏธํฐ๋ฅผ ๊ทธ๋๋ก ๋๋ ค์ค๋ค).\n * @param params ํธ์ถ์๊ฐ ์ค ํ๋ผ๋ฏธํฐ.\n * @returns ์ ๊ฐ์ฒด โ ์
๋ ฅ์ ๋ฐ๊พธ์ง ์๋๋ค(ํธ์ถ์์ ๊ฐ์ฒด๊ฐ ๋ชฐ๋ ๋ณํ๋ฉด ์ถ์ ์ด ์ด๋ ต๋ค).\n */\nexport function applyKnobDefaults(knobs: readonly KnobLike[] | undefined | null, params: Record<string, unknown> | undefined | null): Record<string, unknown> {\n const out: Record<string, unknown> = { ...(params ?? {}) }\n for (const k of knobs ?? []) {\n if (!k?.key) continue\n if (k.default === undefined) continue // ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ์ง ์์ ๋
ธ๋ธ๋ ์ฑ์ธ ๊ฒ์ด ์๋ค\n const given = out[k.key]\n if (given === undefined || given === null) out[k.key] = k.default\n }\n return out\n}\n\n/**\n * ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด ๋
ธ๋ธ ์ด๋ฆ๋ค โ ํธ์ถ์์๊ฒ \"๋ฌด์์ ๋ด๊ฐ ์ ํด ์คฌ๋์ง\" ์๋ฆด ๋ ์ด๋ค.\n *\n * ์กฐ์ฉํ ์ฑ์ฐ๋ ๊ฒ๋ ์กฐ์ฉํ ๋น์ฐ๋ ๊ฒ๋งํผ ์ํํ๋ค: ์ฌ์ฉ์๊ฐ ์ค ์ ์๋ ๊ฐ์ผ๋ก ํธ์์ด ๋ง๋ค์ด์ก๋๋ฐ\n * ์๋ฌด ๋ง์ด ์์ผ๋ฉด, ๋์ค์ \"์ ์ด ์์น์ธ๊ฐ\" ๋ฅผ ์๋ฌด๋ ๋ตํ ์ ์๋ค.\n */\nexport function filledKnobKeys(knobs: readonly KnobLike[] | undefined | null, params: Record<string, unknown> | undefined | null): string[] {\n const given = params ?? {}\n return (knobs ?? [])\n .filter(k => k?.key && k.default !== undefined && (given[k.key!] === undefined || given[k.key!] === null))\n .map(k => k.key!)\n}\n"]}
|
|
@@ -30,13 +30,13 @@ async function startReferenceLiveFeed(domainId, adapterType, cfg, site, instance
|
|
|
30
30
|
index_js_1.TwinEngine.startLive(instanceId, domainId, det.kind ?? 'wms', await index_js_1.TwinEngine.withSpaceTimeBase(det.board, domainId));
|
|
31
31
|
stopReferenceLiveFeed(instanceId); // ์ฌ๊ธฐ๋ ์ ์ด์ ํผ๋ ์ ๋ฆฌ
|
|
32
32
|
const unsubscribe = adapter.openLiveFeed(cfg, site, (records) => {
|
|
33
|
-
if (!index_js_1.TwinEngine.
|
|
33
|
+
if (!index_js_1.TwinEngine.owns(domainId, instanceId)) {
|
|
34
34
|
stopReferenceLiveFeed(instanceId); // ์ธ์คํด์ค ์ฌ๋ผ์ง๋ฉด ์๊ฐ ์ ์ง(์์ ๋ง)
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
const { accepted } = (0, index_js_1.ingestCanonicalRecords)(records, domainId, new Date().toISOString());
|
|
38
38
|
if (accepted.length)
|
|
39
|
-
index_js_1.TwinEngine.ingestLive(instanceId, accepted);
|
|
39
|
+
index_js_1.TwinEngine.ingestLive(domainId, instanceId, accepted);
|
|
40
40
|
});
|
|
41
41
|
feeds.set(instanceId, unsubscribe);
|
|
42
42
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-live.js","sourceRoot":"","sources":["../../../server/service/reference/reference-live.ts"],"names":[],"mappings":";;AAkBA,wDA4BC;AAGD,sDAMC;AAGD,wDAEC;AA5DD,iEAA+F;AAC/F,oDAAgG;AAEhG;;;;;;GAMG;AAEH,iEAAiE;AACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;AAE3C;;;GAGG;AACI,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,WAAmB,EACnB,GAAqB,EACrB,IAAoB,EACpB,UAAkB;IAElB,MAAM,OAAO,GAAG,IAAA,iCAAU,EAAC,WAAW,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,EAAE,YAAY;QAAE,OAAO,KAAK,CAAA;IAExC,MAAM,GAAG,GAAG,MAAM,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACzD,IAAI,CAAC,GAAG,EAAE,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,gEAAgE,CAAC,CAAA;IAEzH,wFAAwF;IACxF,uDAAuD;IACvD,qBAAU,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,KAAK,EAAE,MAAM,qBAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEtH,qBAAqB,CAAC,UAAU,CAAC,CAAA,CAAC,iBAAiB;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,OAAkB,EAAE,EAAE;QACzE,IAAI,CAAC,qBAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"reference-live.js","sourceRoot":"","sources":["../../../server/service/reference/reference-live.ts"],"names":[],"mappings":";;AAkBA,wDA4BC;AAGD,sDAMC;AAGD,wDAEC;AA5DD,iEAA+F;AAC/F,oDAAgG;AAEhG;;;;;;GAMG;AAEH,iEAAiE;AACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;AAE3C;;;GAGG;AACI,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,WAAmB,EACnB,GAAqB,EACrB,IAAoB,EACpB,UAAkB;IAElB,MAAM,OAAO,GAAG,IAAA,iCAAU,EAAC,WAAW,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,EAAE,YAAY;QAAE,OAAO,KAAK,CAAA;IAExC,MAAM,GAAG,GAAG,MAAM,qBAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACzD,IAAI,CAAC,GAAG,EAAE,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,gEAAgE,CAAC,CAAA;IAEzH,wFAAwF;IACxF,uDAAuD;IACvD,qBAAU,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,KAAK,EAAE,MAAM,qBAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEtH,qBAAqB,CAAC,UAAU,CAAC,CAAA,CAAC,iBAAiB;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,OAAkB,EAAE,EAAE;QACzE,IAAI,CAAC,qBAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC3C,qBAAqB,CAAC,UAAU,CAAC,CAAA,CAAC,uBAAuB;YACzD,OAAM;QACR,CAAC;QACD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,iCAAsB,EAAC,OAA4B,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;QAC7G,IAAI,QAAQ,CAAC,MAAM;YAAE,qBAAU,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IACF,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;IAClC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,8BAA8B;AAC9B,SAAgB,qBAAqB,CAAC,UAAkB;IACtD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,IAAI,CAAC;QAAC,KAAK,EAAE,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACpC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACxB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,oBAAoB;AACpB,SAAgB,sBAAsB;IACpC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;AAC1B,CAAC;AAED,kCAAkC;AAClC,qBAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAA","sourcesContent":["import { getAdapter, type ConnectionConfig, type SiteDescriptor } from './reference-adapter.js'\nimport { TwinEngine, ingestCanonicalRecords, type CanonicalRecord } from '../../engine/index.js'\n\n/*\n * ์ปค๋ฅํฐ ๊ธฐ๋ฐ ๋ผ์ด๋ธ ํผ๋ ๊ฒฐ์ (reference โ live, ยง0 ํ๋ ์ โ realityMode='mirror').\n * ํ๋ฆ: adapter.openLiveFeed(cfg, site, records) โ ingestCanonicalRecords(์ ๊ทโ๋ดํฌ) โ TwinEngine.ingestLive(projector ๋ฏธ๋ฌ).\n * ์ปค๋ฅํฐ๊ฐ \"๋ฒค๋ ์ด๋ฒคํธ โ ์ ๊ท ๋ ์ฝ๋\" ๋งคํ์ ์์ (์ฝ๋)ํ๋ค โ preset ๊ธฐ๋ฐ startLiveFeed(operato-twin, http-get+jsonata)์\n * ๋์นญ์ด๋, ๋งคํ ์์น๋ง ๋ค๋ฅด๋ค. ์ค ์์คํ
์ ํ์ connectionConfig.baseUrl ๊ต์ฒด๋ฟ(์ฝ๋ ๊ฒฝ๋ก ๋์ผ).\n * ์๋ช
์ฃผ๊ธฐ: ์ธ์คํด์ค ์ ์ง(TwinEngine.stop)์ ํ
์ผ๋ก ๋ฌถ์ฌ ํผ๋๋ ํจ๊ป unsubscribe.\n */\n\n/** ํ์ฑ ๋ผ์ด๋ธ ํผ๋ โ instanceId โ unsubscribe(์ด๋ํฐ openLiveFeed ๋ฐํ). */\nconst feeds = new Map<string, () => void>()\n\n/**\n * ์ปค๋ฅํฐ ๋ผ์ด๋ธ ๊ธฐ๋ โ ์ด๋ํฐ openLiveFeed ๋ฅผ ์ธ์คํด์ค์ ๊ฒฐ์ .\n * ๋ฐํ: ๋ผ์ด๋ธ ๊ฒฐ์ ์ฑ๊ณต ์ฌ๋ถ(์ด๋ํฐ๊ฐ openLiveFeed ๋ฏธ์ง์์ด๋ฉด false โ ํธ์ถ์ธก์ด sim ํด๋ฐฑ).\n */\nexport async function startReferenceLiveFeed(\n domainId: string,\n adapterType: string,\n cfg: ConnectionConfig,\n site: SiteDescriptor,\n instanceId: string\n): Promise<boolean> {\n const adapter = getAdapter(adapterType)\n if (!adapter?.openLiveFeed) return false\n\n const det = await TwinEngine.detail(domainId, instanceId)\n if (!det?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board) โ ingest master before live start`)\n\n // mirror ๋ชจ๋ ๊ธฐ๋ โ ์ปค๋ tick ์์ด projector ๊ฐ ์ค ์ด๋ฒคํธ๋ฅผ ๋ฏธ๋ฌ(startLive ๊ฐ realityMode='mirror' ์ค์ ).\n // ์๊ฐ ๊ธฐ์ค์ **๊ณต๊ฐ**์ด ๊ฐ๋๋ค(ํ
๋ํธ ์๋) โ ๊ต๋์ HH:MM ์ ์ด๋ ๊ธฐ์ค์ผ๋ก ์ฝ๋.\n TwinEngine.startLive(instanceId, domainId, det.kind ?? 'wms', await TwinEngine.withSpaceTimeBase(det.board, domainId))\n\n stopReferenceLiveFeed(instanceId) // ์ฌ๊ธฐ๋ ์ ์ด์ ํผ๋ ์ ๋ฆฌ\n const unsubscribe = adapter.openLiveFeed(cfg, site, (records: unknown[]) => {\n if (!TwinEngine.owns(domainId, instanceId)) {\n stopReferenceLiveFeed(instanceId) // ์ธ์คํด์ค ์ฌ๋ผ์ง๋ฉด ์๊ฐ ์ ์ง(์์ ๋ง)\n return\n }\n const { accepted } = ingestCanonicalRecords(records as CanonicalRecord[], domainId, new Date().toISOString())\n if (accepted.length) TwinEngine.ingestLive(domainId, instanceId, accepted)\n })\n feeds.set(instanceId, unsubscribe)\n return true\n}\n\n/** ๋ผ์ด๋ธ ํผ๋ ์ค์ง(unsubscribe). */\nexport function stopReferenceLiveFeed(instanceId: string): boolean {\n const unsub = feeds.get(instanceId)\n if (!unsub) return false\n try { unsub() } catch { /* noop */ }\n feeds.delete(instanceId)\n return true\n}\n\n/** ํ์ฑ ํผ๋ ๋ชฉ๋ก(๊ด์ธก). */\nexport function listReferenceLiveFeeds(): string[] {\n return [...feeds.keys()]\n}\n\n/* ์ธ์คํด์ค ์ ์ง ์ ํผ๋ ์๋ ์ ๋ฆฌ(์๋ช
์ฃผ๊ธฐ ๋์นญ). */\nTwinEngine.onStop(instanceId => stopReferenceLiveFeed(instanceId))\n"]}
|
|
@@ -311,7 +311,14 @@ export interface ReferenceMaster {
|
|
|
311
311
|
* ์์ผ๋ฉด ์ปค๋์ ๋ ๊ฑฐ์(ํ๋์ฝ๋ฉ) ํ๋ฆ์ผ๋ก ๋๋ค. ์ฆ **ํ์ฅ ๋ ์ํผ๋ฅผ ์ ์ด๋ ์ด ์๋ฆฌ์ ์ค๋ฆฌ์ง ์์ผ๋ฉด
|
|
312
312
|
* ์ปค๋์ ๊ทธ๊ฒ์ ๋ณด์ง ๋ชปํ๋ค** โ ์ ์ธ๊ณผ ์คํ์ด ๊ฐ๋ผ์ง๋ ์ง์ ์ด๋ผ ์๋ฆฌ๋ฅผ ์ฐ๋ค.
|
|
313
313
|
*/
|
|
314
|
-
|
|
314
|
+
/**
|
|
315
|
+
* ์์ฐ ์ ์ธ โ `BoardDef.productionSpec` ์ผ๋ก ํต๊ณผํ๋ค(ISA-95 OperationsSegment + BOM).
|
|
316
|
+
*
|
|
317
|
+
* ์์ ์ด๋ฆ์ `mesSpec` ์ด์๋ค. ๋ด๊ธด ๊ฒ์ MES ๋ง์ ๊ฒ์ด ์๋๋ผ "์์ฌ๋ฅผ ์๋นํด ์์ฌ๋ฅผ ์ฐ์ถํ๋
|
|
318
|
+
* ๊ณต์ " ์ด๊ณ , ์ด๋ฆ์ด MES ์๊ธฐ ๋๋ฌธ์ ์ฐฝ๊ณ ํธ์์ ์ด ์๋ฆฌ๋ฅผ ์ธ ์๊ฐ์กฐ์ฐจ ํ์ง ๋ชปํ๋ค(์ ํต๊ฐ๊ณต ์ฐฝ๊ณ ๊ฐ
|
|
319
|
+
* BOM ์ ์ค๋ช
๋ฌธ์์๋ง ์ ์ด ๋ ์ฑ ํคํธ๋ฅผ ๋ชป ๋ง๋๋ ํธ์์ ๋ง๋ ์์ธ). ๊ทผ๊ฑฐ๋ ์ปค๋ ๊ณ์ฝ ์ฃผ์์.
|
|
320
|
+
*/
|
|
321
|
+
productionSpec?: unknown;
|
|
315
322
|
/**
|
|
316
323
|
* ์ฌ๋ โ ์ ์ธํ์ง ์์ผ๋ฉด **์ธ์ ์ ์ฝ์ด ์๋ ํธ์**์ด ๋๋ค(์ค๋น๋ง ์์ผ๋ฉด ์ธ์ ๋ ๋์๊ฐ๋ ๊ณต์ฅ).
|
|
317
324
|
* ๊ณต์ ์ด ์ธ์์ ์๊ตฌํ๋๋ฐ ์ฌ๋์ด ์์ผ๋ฉด ๊ทธ ์์
์ ์์๋์ง ์๋๋ค โ ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ฏ๋ก ๊ทธ๋๋ก ๋๋ค.
|
|
@@ -336,7 +343,7 @@ export interface ReferenceMaster {
|
|
|
336
343
|
export interface IngestedTwin {
|
|
337
344
|
board: any;
|
|
338
345
|
spaceContent: any;
|
|
339
|
-
warnings:
|
|
346
|
+
warnings: IngestWarning[];
|
|
340
347
|
}
|
|
341
348
|
/**
|
|
342
349
|
* ๋ง์คํฐ โ ํธ์ ๊ตฌ์กฐ ๋งคํ(์์). ๋
ธ๋ํ์
์ ์นดํ๋ก๊ทธ๋ก ๊ฒ์ฆ(๋ชจ๋ฅด๋ ํ์
์ warning, ๋ฒ๋ฆฌ์ง ์์ โ ๋ฐ์ ์ฐ์ ).
|
|
@@ -356,4 +363,32 @@ export interface IngestedTwin {
|
|
|
356
363
|
* ๊ทธ๋ ๊ฒ ๋ฐ๊พธ๋ฉด ํ์ ์ด ์กฐ์ฉํ ํ๋ฆฐ๋ค.
|
|
357
364
|
*/
|
|
358
365
|
export declare function utcOffsetOf(timezone?: string, at?: Date): number | undefined;
|
|
366
|
+
/** ์ธ์ ์คํธ๊ฐ ์๋ฆฌ๋ ํ ๊ฐ์ง. */
|
|
367
|
+
export interface IngestWarning {
|
|
368
|
+
/** ์ธ์ด ์ค๋ฆฝ ์ฝ๋. ํ๋ฉด์ `twin.ingest.<code>` ๋ก ๋ ๋ํ๋ค. */
|
|
369
|
+
code: string;
|
|
370
|
+
/** ๋ฌธ์ฅ์ ๋ผ์ธ ๊ฐ. ๋ฒ์ญ์ด ์ด์์ ๋ฐ๊ฟ ์ ์๊ฒ ์ด๋ฆ์ผ๋ก ๋๊ธด๋ค. */
|
|
371
|
+
params?: Record<string, string | number>;
|
|
372
|
+
/** ์์ด canonical ๋ฌธ์ฅ โ ๋ก๊ทธยทํด๋ฐฑ์ฉ. ๋ฒ์ญ์ด ์์ด๋ ์ฝ์ ์ ์์ด์ผ ํ๋ค. */
|
|
373
|
+
message: string;
|
|
374
|
+
}
|
|
375
|
+
/** ์ปค๋ ์นดํ๋ก๊ทธ๊ฐ ๋ชจ๋ฅด๋ ์๋ฆฌ ํ์
โ ๊ทธ ์๋ฆฌ๋ ํ๋ฆ์ ์ฐธ์ฌํ์ง ๋ชปํ ์ ์๋ค. */
|
|
376
|
+
export declare const unknownLocationType: (system: string, type: string, id: string) => IngestWarning;
|
|
377
|
+
/** ์๊ฐ๋ ๋ฌธ์์ด์ ๋ชป ์ฝ์๋ค โ ์๊ฐ ํด์์ด UTC ๋ก ๋จ์ด์ง๋ค(์กฐ์ฉํ ํ์ง ์๊ฐ์ผ๋ก ๊ฐ์ ํ์ง ์๋๋ค). */
|
|
378
|
+
export declare const unknownTimezone: (timezone: string) => IngestWarning;
|
|
379
|
+
/** ์์
์ ์์ ์์์๊ฐยทํ๋ผ๋ฏธํฐ๊ฐ ์๋ค โ ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋๋ค. */
|
|
380
|
+
export declare const operationWithoutDuration: (operation: string) => IngestWarning;
|
|
381
|
+
/** ๋ณผ ์ ์๋ ํํ์ด ์๋ค โ ํ์ฅ์ด ํ๋ฉด์ ๋จ์ง ์๋๋ค. */
|
|
382
|
+
export declare const noViewableRepresentation: () => IngestWarning;
|
|
383
|
+
/** ํฉ์น๋ ๊ณต๊ฐ์ ๊ฐ์ id ์ ๋๋๋งํฌ๊ฐ ์ด๋ฏธ ์๋ค โ ์๋ก ๋ค๋ฅธ ๊ฒ์ด ํ๋๋ก ์ ํ์ ์ ์๋ค. */
|
|
384
|
+
export declare const landmarkIdsMerged: (spaceId: string, ids: readonly string[]) => IngestWarning;
|
|
385
|
+
/** ๋ก๊ทธ ํ ์ค โ ๊ฐ๋ฐ์๊ฐ ์ฝ๋ ๊ฒ์ด๋ฏ๋ก ์์ด canonical ๋ฌธ์ฅ์ ์ด๋ค. */
|
|
386
|
+
export declare const describeWarnings: (warnings: readonly IngestWarning[]) => string;
|
|
387
|
+
/**
|
|
388
|
+
* ์๋ฒ๊ฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด ๋
ธ๋ธ๋ค โ ์ฌ์ฉ์๊ฐ ์ค ์ ์๋ ๊ฐ์ผ๋ก ํธ์์ด ๋ง๋ค์ด์ก์์ ์๋ฆฐ๋ค.
|
|
389
|
+
*
|
|
390
|
+
* ์กฐ์ฉํ ์ฑ์ฐ๋ฉด ๋์ค์ "์ ์ด ์์น์ธ๊ฐ" ๋ฅผ ์๋ฌด๋ ๋ตํ ์ ์๋ค. ๋ง์ ์ผ์ ์๋๋ค(๊ธฐ๋ณธ๊ฐ์ ํ
ํ๋ฆฟ์ด
|
|
391
|
+
* ํ์ ์ ๊ฐ๊ณ ์ ์ธํ ๊ฐ์ด๋ค) โ ๋ค๋ง ๋ฐํ๋ค.
|
|
392
|
+
*/
|
|
393
|
+
export declare const knobDefaultsFilled: (keys: readonly string[]) => IngestWarning;
|
|
359
394
|
export declare function masterToTwin(master: ReferenceMaster, catalog?: any): IngestedTwin;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* ์ขํยทrepresentations ๋ ํธ์ ๊ณต๊ฐ์ธต(๋ณด์/์ถ๊ฐ). ์ค ์์คํ
์ด ์ขํ๋ฅผ ์ ์ฃผ๋ฉด layout ์์ด ์์๋ง ์ธ์ ์คํธ.
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.knobDefaultsFilled = exports.describeWarnings = exports.landmarkIdsMerged = exports.noViewableRepresentation = exports.operationWithoutDuration = exports.unknownTimezone = exports.unknownLocationType = void 0;
|
|
11
12
|
exports.utcOffsetOf = utcOffsetOf;
|
|
12
13
|
exports.masterToTwin = masterToTwin;
|
|
13
14
|
/**
|
|
@@ -45,6 +46,55 @@ function utcOffsetOf(timezone, at = new Date()) {
|
|
|
45
46
|
return undefined; // ์ ์ ์๋ ์ด๋ฆ โ Intl ์ด ๋์ง๋ค
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
/** ์ปค๋ ์นดํ๋ก๊ทธ๊ฐ ๋ชจ๋ฅด๋ ์๋ฆฌ ํ์
โ ๊ทธ ์๋ฆฌ๋ ํ๋ฆ์ ์ฐธ์ฌํ์ง ๋ชปํ ์ ์๋ค. */
|
|
50
|
+
const unknownLocationType = (system, type, id) => ({
|
|
51
|
+
code: 'unknown-location-type',
|
|
52
|
+
params: { system, type, id },
|
|
53
|
+
message: `"${type}" is not a known ${system} location type (${id}) โ the kernel may not include this location in the flow`
|
|
54
|
+
});
|
|
55
|
+
exports.unknownLocationType = unknownLocationType;
|
|
56
|
+
/** ์๊ฐ๋ ๋ฌธ์์ด์ ๋ชป ์ฝ์๋ค โ ์๊ฐ ํด์์ด UTC ๋ก ๋จ์ด์ง๋ค(์กฐ์ฉํ ํ์ง ์๊ฐ์ผ๋ก ๊ฐ์ ํ์ง ์๋๋ค). */
|
|
57
|
+
const unknownTimezone = (timezone) => ({
|
|
58
|
+
code: 'unknown-timezone',
|
|
59
|
+
params: { timezone },
|
|
60
|
+
message: `space timezone "${timezone}" is not a known IANA zone โ the twin will read times as UTC`
|
|
61
|
+
});
|
|
62
|
+
exports.unknownTimezone = unknownTimezone;
|
|
63
|
+
/** ์์
์ ์์ ์์์๊ฐยทํ๋ผ๋ฏธํฐ๊ฐ ์๋ค โ ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋๋ค. */
|
|
64
|
+
const operationWithoutDuration = (operation) => ({
|
|
65
|
+
code: 'operation-without-duration',
|
|
66
|
+
params: { operation },
|
|
67
|
+
message: `operation "${operation}" has no duration or parameters โ kernel defaults will be used`
|
|
68
|
+
});
|
|
69
|
+
exports.operationWithoutDuration = operationWithoutDuration;
|
|
70
|
+
/** ๋ณผ ์ ์๋ ํํ์ด ์๋ค โ ํ์ฅ์ด ํ๋ฉด์ ๋จ์ง ์๋๋ค. */
|
|
71
|
+
const noViewableRepresentation = () => ({
|
|
72
|
+
code: 'no-viewable-representation',
|
|
73
|
+
message: 'the space has no viewable representation (no representations and no geo) โ add one, or provide geo/board'
|
|
74
|
+
});
|
|
75
|
+
exports.noViewableRepresentation = noViewableRepresentation;
|
|
76
|
+
/** ํฉ์น๋ ๊ณต๊ฐ์ ๊ฐ์ id ์ ๋๋๋งํฌ๊ฐ ์ด๋ฏธ ์๋ค โ ์๋ก ๋ค๋ฅธ ๊ฒ์ด ํ๋๋ก ์ ํ์ ์ ์๋ค. */
|
|
77
|
+
const landmarkIdsMerged = (spaceId, ids) => ({
|
|
78
|
+
code: 'landmark-ids-merged',
|
|
79
|
+
params: { spaceId, ids: ids.join(', '), count: ids.length },
|
|
80
|
+
message: `landmark ids already present in space "${spaceId}" โ merged: ${ids.join(', ')}`
|
|
81
|
+
});
|
|
82
|
+
exports.landmarkIdsMerged = landmarkIdsMerged;
|
|
83
|
+
/** ๋ก๊ทธ ํ ์ค โ ๊ฐ๋ฐ์๊ฐ ์ฝ๋ ๊ฒ์ด๋ฏ๋ก ์์ด canonical ๋ฌธ์ฅ์ ์ด๋ค. */
|
|
84
|
+
const describeWarnings = (warnings) => warnings.map(w => `${w.code}: ${w.message}`).join(' | ');
|
|
85
|
+
exports.describeWarnings = describeWarnings;
|
|
86
|
+
/**
|
|
87
|
+
* ์๋ฒ๊ฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด ๋
ธ๋ธ๋ค โ ์ฌ์ฉ์๊ฐ ์ค ์ ์๋ ๊ฐ์ผ๋ก ํธ์์ด ๋ง๋ค์ด์ก์์ ์๋ฆฐ๋ค.
|
|
88
|
+
*
|
|
89
|
+
* ์กฐ์ฉํ ์ฑ์ฐ๋ฉด ๋์ค์ "์ ์ด ์์น์ธ๊ฐ" ๋ฅผ ์๋ฌด๋ ๋ตํ ์ ์๋ค. ๋ง์ ์ผ์ ์๋๋ค(๊ธฐ๋ณธ๊ฐ์ ํ
ํ๋ฆฟ์ด
|
|
90
|
+
* ํ์ ์ ๊ฐ๊ณ ์ ์ธํ ๊ฐ์ด๋ค) โ ๋ค๋ง ๋ฐํ๋ค.
|
|
91
|
+
*/
|
|
92
|
+
const knobDefaultsFilled = (keys) => ({
|
|
93
|
+
code: 'knob-defaults-filled',
|
|
94
|
+
params: { keys: keys.join(', '), count: keys.length },
|
|
95
|
+
message: `values you did not provide were filled from the template defaults: ${keys.join(', ')}`
|
|
96
|
+
});
|
|
97
|
+
exports.knobDefaultsFilled = knobDefaultsFilled;
|
|
48
98
|
function masterToTwin(master, catalog) {
|
|
49
99
|
const warnings = [];
|
|
50
100
|
const known = catalog?.[master.system]?.locationTypes ?? [];
|
|
@@ -52,7 +102,7 @@ function masterToTwin(master, catalog) {
|
|
|
52
102
|
const areaLocs = master.locations.filter(l => l.role === 'area' || l.role === 'both');
|
|
53
103
|
const locations = locationEntries.map(l => {
|
|
54
104
|
if (known.length && !known.includes(l.type))
|
|
55
|
-
warnings.push(
|
|
105
|
+
warnings.push((0, exports.unknownLocationType)(master.system, l.type, l.id));
|
|
56
106
|
// gs1Id(์ ์ ์ ์ฒด์ฑ)๋ฅผ ๋ณด๋ ๋
ธ๋๋ก ํต๊ณผ โ ๊ฒฐํฉ(tag)/์ถ์ ์ด GS1 ๋ก(ยงJ). ๋ก์ปฌ id ๋ ๊ทธ๋๋ก ์ ์ง(name/xref).
|
|
57
107
|
return { id: l.id, type: l.type, capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), parentId: l.parentId, gs1Id: l.gs1Id };
|
|
58
108
|
});
|
|
@@ -79,7 +129,7 @@ function masterToTwin(master, catalog) {
|
|
|
79
129
|
*/
|
|
80
130
|
const utcOffsetMinutes = utcOffsetOf(master.space.timezone);
|
|
81
131
|
if (master.space.timezone && utcOffsetMinutes === undefined) {
|
|
82
|
-
warnings.push(
|
|
132
|
+
warnings.push((0, exports.unknownTimezone)(String(master.space.timezone)));
|
|
83
133
|
}
|
|
84
134
|
/*
|
|
85
135
|
* ์คํผ๋ ์ด์
๋ช
์ธ๋ฅผ board ์ ํต๊ณผ์ํจ๋ค โ ์ปค๋์ด `loadOperations` ๋ก ์๋นํ๋ค(BoardDef ํ์ฅ ํ๋,
|
|
@@ -89,7 +139,7 @@ function masterToTwin(master, catalog) {
|
|
|
89
139
|
if (operations?.length) {
|
|
90
140
|
for (const o of operations) {
|
|
91
141
|
if (!o.duration && !o.parameters?.length)
|
|
92
|
-
warnings.push(
|
|
142
|
+
warnings.push((0, exports.operationWithoutDuration)(o.key));
|
|
93
143
|
}
|
|
94
144
|
}
|
|
95
145
|
/* ์ฌ๋๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๋ฑ๊ธยท๊ต๋ ๊ทธ๋๋ก ์ปค๋๊น์ง ๊ฐ๋ค(๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค). */
|
|
@@ -109,7 +159,7 @@ function masterToTwin(master, catalog) {
|
|
|
109
159
|
const board = {
|
|
110
160
|
locations, equipment, layout, spaceId,
|
|
111
161
|
/* ์์ฐ ์ ์๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค(์ปค๋์ด ๊ทธ๋๋ก ์๋นํ๋ค). */
|
|
112
|
-
...(master.
|
|
162
|
+
...(master.productionSpec ? { productionSpec: master.productionSpec } : {}),
|
|
113
163
|
...(materialDefinitions?.length ? { materialDefinitions } : {}),
|
|
114
164
|
...(master.materialClasses?.length ? { materialClasses: master.materialClasses } : {}),
|
|
115
165
|
...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),
|
|
@@ -135,7 +185,7 @@ function masterToTwin(master, catalog) {
|
|
|
135
185
|
? [{ id: 'r-map', type: 'map', name: '์์ฑ ์ง๋', primary: true, center: { lat: geo.lat, lon: geo.lon }, zoom: 17 }]
|
|
136
186
|
: [];
|
|
137
187
|
if (representations.length === 0) {
|
|
138
|
-
warnings.push(
|
|
188
|
+
warnings.push((0, exports.noViewableRepresentation)());
|
|
139
189
|
}
|
|
140
190
|
const spaceContent = {
|
|
141
191
|
width: master.space.width, depth: master.space.depth, unit: master.space.unit ?? 'm',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-master.js","sourceRoot":"","sources":["../../../server/service/reference/reference-master.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Face2 ๋ง์คํฐ ์ธ์ ์คํธ(ADR-0018 ๋ฐ์ ๋ชจ๋) โ ๋ ํผ๋ฐ์ค ์์คํ
(์ค WMS/YMS/MES ๋๋ ๊ฐ์ ๋ ํผ๋ฐ์ค)์\n * ๋ง์คํฐ๋ฅผ ์ฝ์ด ํธ์ ๊ตฌ์กฐ(BoardDef) + ๊ณต๊ฐ(Space content)์ ์์ฑ. ์๋ฐฐ์ ์ด ์๋๋ผ ์ธ์ ์คํธ๋ก ์ํฐํฐ๊ฐ ํ๋ฅธ๋ค.\n *\n * ๊ท์จ(ADR-0018): ๋๋ฉ์ธ ํ์
(location.type=๋
ธ๋์ฉ)์ ์ปค๋ ์นดํ๋ก๊ทธ ์ดํ๋ฅผ ๊ทธ๋๋ก ๋ฐ์(๋ฐ๋ช
๊ธ์ง).\n * location ์ role ๋ก ๋
ธ๋(์ด์์ )ยทarea(๊ณต๊ฐ์์ญ)ยทboth ๋ฅผ ๊ตฌ๋ถ โ ๋
ธ๋โBoardDef, areaโSpace.areas.\n * ์ขํยทrepresentations ๋ ํธ์ ๊ณต๊ฐ์ธต(๋ณด์/์ถ๊ฐ). ์ค ์์คํ
์ด ์ขํ๋ฅผ ์ ์ฃผ๋ฉด layout ์์ด ์์๋ง ์ธ์ ์คํธ.\n */\n\nimport type { EquipmentLevel, WorkCalendarEntry } from '@operato/twin-kernel'\n\nexport interface RefLocation {\n id: string\n type: string // ๋
ธ๋๋ ์ปค๋ ๋
ธ๋ํ์
(dock/storage/yard-slotโฆ), area ๋ ๊ณต๊ฐ region ํ์
\n name?: string\n role: 'location' | 'area' | 'both'\n parentId?: string\n /** ์ ์ฅ ์ฉ๋ โ ์ด ์๋ฆฌ์ ๋์์ ๋์ผ ์ ์๋ ๋ฌผํ ์. */\n capacity?: number\n /**\n * ๋์ ์ฒ๋ฆฌ ์ โ ์ด ์๋ฆฌ์์ ํ ๋ฒ์ ์งํ๋ ์ ์๋ ์์
์. **์ ์ฅ ์ฉ๋๊ณผ ๋ค๋ฅธ ์ถ**์ด๋ค\n * (์์ฌ๋ฅผ 20๊ฐ ์์ ๋๋ ์ ๋จ ์คํ
์ด์
์ด ํ ๋ฒ์ ํ ๋๋ง ๊น๋๋ค). ๋ฏธ์ง์ =์ ์ฝ ์์.\n */\n parallelism?: number\n /**\n * **ISA-95 ์ค๋น ๊ณ์ธต ๋จ๊ณ** โ `EquipmentLevel` ์ด๊ฑฐ๊ฐ(`ProductionLine`ยท`StorageZone`ยท`WorkCenter`โฆ).\n *\n * `type` ์ ํ์ฅ์ ๋ฑ๋ง(`paint-booth`)์ด๊ณ ์ด๊ฒ์ **ํ์ค์ด ์ ํ ์ญํ **์ด๋ค. ๋์ ๋ค๋ฅธ ์ถ์ด๋ผ ํจ๊ป ๋ ๋ค โ\n * ์ฐ๋ยท์ง๊ณ๋ ํ์ค ์ถ์ผ๋ก, ํ๋ฉด์ ํ์ฅ ๋ฑ๋ง๋ก. ๋ฏธ์ง์ ์ด๋ฉด ๊ทธ ์๋ฆฌ์ ํ์ค ์ญํ ์ ์์ง ๋ชจ๋ฅธ๋ค๋ ๋ป์ด๊ณ ,\n * ์ง์ํด ์ฑ์ฐ์ง ์๋๋ค.\n */\n level?: EquipmentLevel\n footprint?: { x: number; y: number; w: number; h: number } // ์์ผ๋ฉด area ๊ธฐํ + ๋
ธ๋ ์ค์ฌ์ขํ\n gs1Id?: string // ์ ์ GS1 ์ ์ฒด์ฑ(ยงJ) โ ์์น=SGLN. ๊ฒฐํฉ(tag)/์ถ์ canonical id. ๋ฐ์๋ค์ด๊ธฐ ๊ฒฝ๊ณ์ ๋ถ์ฌ(๋ก์ปฌ id=name/xref ๋ก ๋ณด์กด).\n}\n\n/**\n * ์ค๋น ์์ฑ โ **ISA-95 `EquipmentSpecificationProperty`(`OpEquipmentSpecificationPropertyType`) 1:1.**\n * ๊ทธ ํ์
๋ `ID` + `Value`(`ValueString`ยท`DataType`ยท`UnitOfMeasure`) ์ด๋ฏ๋ก ๊ณต์ ๋ชจ์์ ๊ฐ์ ๋ชจ์์ด๋ค.\n *\n * ๋จ์ ์ฝ๋๋ **UN/CEFACT ๊ถ๊ณ 20 ๊ณตํต์ฝ๋**(EPCIS `uom` ๊ณผ ๊ฐ์ ์ฝ๋๊ณ): ์๋๋ `MTS`(metre per\n * second) ๋๋ `KMH`(kilometre per hour). ์ฝ๋๋ฅผ ์ฐ๋ฆฌ๊ฐ ๋ฐ๋ช
ํ์ง ์๋๋ค.\n */\n/**\n * ์์ ์์ฑ โ **์ปค๋ `ResourceProperty` ์ ๊ฐ์ ๋ชจ์**์ด๊ณ , ๊ทธ ๋ชจ์์ ISA-95 ๊ฐ ์ธ ์์์ ๋๊ฐ์ด\n * ์ ์ํ ๊ฒ์ด๋ค(`EquipmentPropertyType` ยท `PersonPropertyType` ยท `PhysicalAssetPropertyType`).\n *\n * ๊ทธ๋์ ์์๋ง๋ค ๋ค๋ฅธ ์์ฑ ํ์
์ ๋์ง ์๋๋ค โ ์์ ์๋ ์ค๋น๋ง ์์ฑ์ ๊ฐ์ก๊ณ (RefEquipmentProperty),\n * ์ธ์ยท์์ฐ์ ๋ถ๋ ์ฌ์ค์ **์ค์ ์๋ฆฌ๊ฐ ์์ด์ ๋ค์ด์ค์ง ๋ชปํ๋ค.**\n */\nexport interface RefResourceProperty {\n id: string\n description?: string\n value?: string\n /** ํ์ค `Value.DataType`. */\n dataType?: string\n /** ํ์ค `Value.UnitOfMeasure` โ UN/CEFACT ๊ณตํต์ฝ๋. ๋ฌผ๋ฆฌ๋์ ๋จ์๊ฐ ์์ผ๋ฉด ์๋น์ฒ๊ฐ ๊ฑฐ์ ํ๋ค. */\n uom?: string\n /** ํ์ ์์ฑ(์ฌ๊ท) โ ํ์ค `<X>PropertyChild`. */\n children?: RefResourceProperty[]\n /** ์ด ๊ฐ์ฒด ์์ฑ์ด ๊ตฌ์ฒดํํ๋ ๋ฑ๊ธ ์์ฑ โ ํ์ค `<X>ClassPropertyID`. */\n classPropertyId?: string\n}\n\n/** ์ ์ด๋ฆ โ ์ค๋น ์ ์ฉ์ด๋ ์์ ์ ๋ณ์นญ(์๋น์ฒ ํธํ). ์ ๊ท ์์ฑ์ `RefResourceProperty`. */\nexport type RefEquipmentProperty = RefResourceProperty\n\n/**\n * ์์ **๋ฑ๊ธ ์ ์** โ ์ปค๋ `ResourceClassDef` ์ ๊ฐ์ ๋ชจ์์ด๊ณ , ๊ทธ ๋ชจ์์ ISA-95 ๊ฐ ์ธ ์์์ ๋๊ฐ์ด\n * ์ ์ํ ๊ฒ์ด๋ค(`PersonnelClassType`ยท`EquipmentClassType`ยท`PhysicalAssetClassType`).\n *\n * ์ ํ์ํ๊ฐ: ์ ์์คํ
์ ๋ฑ๊ธ **์ฒด๊ณ**๋ฅผ ๊ฐ๊ณ ์๋ค(\"6์ถ ์ฉ์ ์๊ฒฉ์\" ๋ \"์ฉ์ ์๊ฒฉ์\" ์ด๊ณ , ๊ทธ๊ฒ์\n * \"์์ฐ์ง\" ์ด๋ค). ๊ทธ ์ฒด๊ณ๊ฐ ๋ค์ด์ฌ ์๋ฆฌ๊ฐ ์์ผ๋ฉด ์๊ตฌ์ ์์์ด **๋ฌธ์์ด์ด ๋๊ฐ์ ๋๋ง** ๋ง์,\n * ํ์ฅ์์๋ ๋๋ ๋ฐฐ์ ์ด ๋ชจ๋ธ์์ ๋งํ๋ค.\n */\nexport interface RefResourceClass {\n id: string\n description?: string\n /** ์์ ๋ฑ๊ธ๋ค โ ํ์ค `<X>ClassBaseID`(๋ณต์ = ๋ค์ค ์์). */\n baseIds?: string[]\n properties?: RefResourceProperty[]\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ(ISO) โ ํ์ค `EffectiveStartDate`/`EffectiveEndDate`. ๋ฐ์ด๋ฉด ์๊ฒฉ์ด ์ฑ๋ฆฝํ์ง ์๋๋ค. */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport interface RefEquipment {\n id: string\n kind: string\n homeLocationId: string\n mtbfMs?: number // ํ๊ท ๊ณ ์ฅ ๊ฐ๊ฒฉ(ํ๋ฅ ์ ๊ณ ์ฅ) โ ์ง์ ์ ์ปค๋์ด breakdown ์๋ฎฌ โ ์ฃผ๋ชฉ(๊ณ ์ฅ) ๋ฐ์\n mttrMs?: number // ํ๊ท ์๋ฆฌ ์๊ฐ\n gs1Id?: string // ์ ์ GS1 ์ ์ฒด์ฑ(ยงJ) โ ์ค๋น=GIAI.\n /**\n * ๊ต๋(๊ฐ๋์๊ฐ) โ ์ด ์๊ฐ๋์๋ง ๋ฐฐ์ ๋๋ค. `startHour <= endHour` ๋ฉด ๊ฐ์ ๋ , ๋์ด๊ฐ๋ฉด ์ผ๊ฐ(22โ6).\n * ๋ฏธ์ง์ =24์๊ฐ ๊ฐ์ฉ. ๊ต๋ ๋ฐ ์์์ ๊ณ ์ฅยท๊ณํ์ ์ง์ **๊ตฌ๋ณ๋๋ ์ด์ **๋ก ์ฐ๋ค(์ํ์ ๋๋ฌ๋๋ค).\n */\n window?: { startHour: number; endHour: number }\n /**\n * ๊ทผ๋ฌด ์บ๋ฆฐ๋ โ ํ์ค `WorkCalendarEntry`(๋ณต์). ์์ผ๋ฉด `window` ๋ณด๋ค ์ด๊ฒ์ ๋ณธ๋ค.\n *\n * ์ถ์ ํ๋ ์์ํฌ `@things-factory/work-shift` ์ `WorkShift`(`fromDate`ยท`fromTime`ยท`toDate`ยท`toTime`)์\n * ๋ง์ถฐ ๋์๋ค โ ๊ทธ ์ํฐํฐ๋ฅผ ๊ต๋์ ์ ๋ณธ์ผ๋ก ๊ฒฐ์ ํ ๋ ์ง์ ๋งคํ์ด ๋๊ฒ. **์์ง ๊ฒฐ์ ํ์ง ์์๋ค**:\n * ๊ทธ ์ํฐํฐ์๋ ์์ ์ฐ๊ฒฐ๊ณผ ๋น๊ทผ๋ฌด(ํด์ผ)๊ฐ ์์ด ํ์ฅ์ด ํจ๊ป ํ์ํ๊ณ , operato-twin ์ ์์กด์ฑ ์ถ๊ฐ๋\n * ์ฑ ์ํคํ
์ฒ ๊ฒฐ์ ์ด๋ค(์ปค๋ฒ๋ฆฌ์ง ยง4-7 ์ ๊ฒฐ์ ์ง์ ์ผ๋ก ๊ธฐ๋ก).\n */\n workCalendar?: WorkCalendarEntry[]\n /**\n * ์ค๋น ์์ฑ(์๋ ๋ฑ) โ ์์ผ๋ฉด **์ด๋์๊ฐ์ ๊ฑฐ๋ฆฌ์์ ๊ณ์ฐํ ์ ์๋ค**(์๋ ์์ด ๊ฑฐ๋ฆฌ๋ง์ผ๋ก๋ ์๊ฐ์ด\n * ์ ๋์จ๋ค). ๊ทธ๋๋ ์ปค๋ ์์๋ก ๋จ์ด์ง๊ณ ๊ทธ ์ฌ์ค์ด `specCoverage()` ์ ๋จ๋๋ค.\n */\n properties?: RefResourceProperty[]\n /** ์ ๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`(๊ต์ ๋ฑ). */\n testSpecificationIds?: string[]\n /**\n * ์ ํจ ๊ธฐ๊ฐ โ **ํ์ค `EffectiveStartDate` / `EffectiveEndDate`**(๊ฐ์ฒด ํ์
์
๋ชจ๋์ ์๋ค).\n *\n * ์์ผ๋ฉด **ํ๊ธฐํ ๊ฒ์ด ์๊ตฌํ ์ด์ ์๋ค**: ๋ฐฐ์ ๋์์ ๋จ๊ณ , ๊ฐ์ฉ ์์ ๋ค์ด๊ฐ๊ณ , ํ๋ฉด์ ๋ฌ๋ค.\n * ๋์
์์ ์ธ ๊ฒ์ ๋ฐ๋๋ก ์ค๋๋ถํฐ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ๊ธฐ๊ฐ ๋ฐ์ด๋ฉด ์ปค๋์ด ๊ทธ ์๊ฐ์ ๋ชจ๋ธ์์\n * ๋นผ๊ณ **์ด์ ๋ฅผ ๋ฌ์ ๋จ๊ธด๋ค**(`effectivity: 'not-yet' | 'expired'`) โ ์กฐ์ฉํ ์ง์ฐ์ง ์๋๋ค.\n */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ๊ณต์ ๋ชจ์ โ ์ปค๋ `OperationParameter`(= ISA-95 `ParameterSpecification`/`ParameterType`) ์ **๊ฐ์ ๋ชจ์**.\n * ์ด๋ฆ์ ๋ฐ๊พธ์ง ์๋๋ค: ์ธ์ ์คํธ ๊ฒฝ๊ณ์์ ์ดํ๊ฐ ๊ฐ๋ฆฌ๋ฉด ๊ทธ ์๋ฆฌ์์ ๋ฐฉ์ธ์ด ์๊ธด๋ค.\n * ID ์ดํ์ ์ ๋ณธ์ ์ปค๋ `OP_PARAM`(ํ์ค์ด ํ๋ผ๋ฏธํฐ ID ๋ฅผ ์ ํ์ง ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ํ ๊ณณ์์ ์ ํ๋ค).\n */\nexport interface RefOperationParameter {\n id: string\n /** ISA-95 `Value.ValueString` โ ํ์ค์ด ๋ฌธ์์ด๋ก ์ฃ๋๋ค. ๊ธฐ๊ฐ ๋ชจ์๋ ISO 8601(`PT8M`). */\n value: string\n /** ISA-95 `Value.UnitOfMeasure`. ๋ฌด์ฐจ์(๋น์จ)์ด๋ฉด ์๋ต. */\n uom?: string\n}\n\n/**\n * ๊ณต์ ์ ์์ฌ ์๊ตฌยท์ฐ์ถ โ **ISA-95 `OperationsSegment.MaterialSpecification`** ๊ณผ ๊ฐ์ ๋ชจ์.\n * ์ธ์ยท์ค๋นยท์์ฐ ๋ช
์ธ์ ๊ฐ์ ์๋ฆฌ์ ์์ด์ผ 4๋ ์์์ด ๋์นญ์ด ๋๋ค(์์ฌ๋ง ๋น ์ ธ ์์๋ค).\n */\nexport interface RefOpMaterialSpecification {\n id?: string\n /** ํ๋ชฉ ๋ฑ๊ธ์ผ๋ก ์๊ตฌ โ ํ์ค `MaterialClassID`. */\n materialClass?: string\n /** ํน์ ํ๋ชฉ์ผ๋ก ์๊ตฌ โ ํ์ค `MaterialDefinitionID`. */\n materialDefinition?: string\n /** ํ์ค `MaterialUse` โ ์ด ๊ณต์ ์์์ ์ฐ์. */\n use: 'consumed' | 'produced' | 'consumable'\n /** ํ์ค `Quantity`. ๋จ์ ๋ฏธ์ง์ ์ด๋ฉด ๊ฐ์. */\n quantity: number\n uom?: string\n}\n\n/** ์์์๊ฐ ๋ณ๋ โ **ํ์ค ๋ฐ ํ์ฅ**(ISA-95 Duration ์ ์ค์นผ๋ผ). ์ปค๋ `DurationVariability` ์ ๋ํ. */\nexport interface RefOperationVariability {\n distribution: 'constant' | 'exponential' | 'uniform' | 'triangular'\n min?: string\n max?: string\n mode?: string\n}\n\n/**\n * ์คํผ๋ ์ด์
๋ช
์ธ โ ISA-95 `OperationsSegment`. ์ปค๋ `OperationDef` ์ ํ๋ ์ด๋ฆ์ด 1:1์ด๋ค.\n *\n * **์ด๊ฒ์ด ์์ผ๋ฉด ์๋ฎฌ๋ ์ด์
์ ์๊ฐ์ ์ฐ๋ฆฌ๊ฐ ์ฝ๋์ ๋ฐ์ ๋ ์์๋ค.** ์ ์์คํ
(๋๋ ๊ฐ์ ๋ ํผ๋ฐ์ค)์ด\n * ๊ณต์ ๋ณ ์์ยท๋ณ๋ยท์์จ์ ๋งํด ์ค์ผ ์์ธก์ด ๊ทธ ํ์ฅ์ ์์ธก์ด ๋๋ค. ์ฃผ์ง ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก\n * ๊ตด๋ฌ๊ฐ๊ณ , **๊ธฐ๋ณธ๊ฐ์ ์ผ๋ค๋ ์ฌ์ค์ ์ปค๋ `specCoverage()` ๊ฐ ๋ฐํ๋ค**(์กฐ์ฉํ ๋์ด๊ฐ์ง ์๋๋ค).\n */\nexport interface RefOperation {\n /** ์์
์ข
๋ฅ ํค โ ์ปค๋ `FlowTask.kind` ์ ๊ฐ์ ๊ฐ์ด์ด์ผ ๋ช
์ธ๊ฐ ๊ทธ ์์
์ ๋ถ๋๋ค. */\n key: string\n label: string\n intent: 'transport' | 'process' | 'dwell'\n locationType?: string\n resourceType?: string\n bizStep?: string\n /** ISA-95 `OperationsSegment.Duration` โ ISO 8601 ๊ธฐ๊ฐ(`PT12M`). */\n duration?: string\n variability?: RefOperationVariability\n parameters?: RefOperationParameter[]\n /**\n * ํ์ ์ธ์ โ ISA-95 `PersonnelSpecification`(`PersonnelClassID` + `Quantity`) 1:1.\n * ์์ผ๋ฉด ์ฌ๋ ์์ด ๋๋ ๊ณต์ ์ด๋ค(์ค๋น๋ง ์ก๋๋ค).\n */\n personnelSpecification?: { personnelClass?: string; quantity: number }[]\n /** ํ์ ๋ฌผ๋ฆฌ ์์ฐ โ ISA-95 `PhysicalAssetSpecification`(๋ฑ๊ธ + ์๋). ๋น ํ๋ ํธ๊ฐ ์์ผ๋ฉด ๋ชป ๋๊ฐ๋ค. */\n physicalAssetSpecification?: { assetClass?: string; quantity: number }[]\n /**\n * ํ์ยท์ฐ์ถ ์์ฌ โ ISA-95 `MaterialSpecification`. **4๋ ์์ ์ค ์์ฌ๋ง ์ด ์๋ฆฌ๊ฐ ์์๋ค** โ\n * ๊ทธ๋์ ๋ถํ์ด ๋จ์ด์ ธ ๋ผ์ธ์ด ์๋ ์ํฉ์ด ์์ธก์ ๋ํ๋์ง ์์๋ค.\n * BOM ์ \"๋ช ๊ฐ\" ๋ ์ฌ๊ธฐ๋ค(ํ๋ชฉ ์ ์์ ์กฐ๋ฆฝ ๊ตฌ์กฐ์๋ ์๋์ด ์๋ค โ 1์ฐจ ์ถ์ฒ ํ์ธ).\n */\n materialSpecification?: RefOpMaterialSpecification[]\n}\n\n/**\n * ์ฌ๋ โ **ISA-95 `Person`.** ์ค๋น์ ๋ณ๊ฐ ์์์ด๋ค(๊ณ ์ฅยท์ค๋นํจ์จ์ด ์๋๋ผ ๋ฑ๊ธยท๊ต๋๋ก ์ฐ๋ค).\n * `personnelClass` ๊ฐ ISA-95 `PersonnelClassID` โ ๊ณต์ ์ ํน์ ์ธ์ด ์๋๋ผ **๋ฑ๊ธ์ผ๋ก** ์ธ์์ ์๊ตฌํ๋ค.\n */\nexport interface RefPerson {\n id: string\n name?: string\n /**\n * ์ํ ๋ฑ๊ธ๋ค โ **ํ์ค `Person.PersonnelClassID`, `maxOccurs=\"unbounded\"`**.\n * ๋ณต์์ธ ๊ฒ์ด ํ์ค์ด๊ณ ๊ทธ๊ฒ์ด ์๊ฒฉ ํํ์ด๋ค: ํ ์ฌ๋์ด ์ฉ์ ์๊ฒฉ๊ณผ ์ง๊ฒ์ฐจ ์๊ฒฉ์ ํจ๊ป ๊ฐ๋๋ค.\n */\n personnelClassIds?: string[]\n /** ๊ต๋ โ ์ค๋น์ ๊ฐ์ ๋ชจ์. ๋ฏธ์ง์ =24์๊ฐ ๊ฐ์ฉ. */\n window?: { startHour: number; endHour: number }\n /** ๊ทผ๋ฌด ์บ๋ฆฐ๋ โ ํ์ค `WorkCalendarEntry`(๋ณต์). 2๊ต๋ยทํด๊ฒยทํด์ผ์ ํจ๊ป ํํํ๋ค. */\n workCalendar?: WorkCalendarEntry[]\n /**\n * ๊ธฐ๋ณธ ์์น โ ํ์ค `Person.OperationalLocation`. ์์ผ๋ฉด \"์ด ๋ผ์ธ์ ๋ช ๋ช
์๋\" ๋ฅผ ๋ฌผ์ ์ ์๋ค.\n * ์ฌ๋์ ์์ง์ด๋ฏ๋ก ์ด ๊ฐ์ **์ถ๋ฐ์ **์ด๊ณ , ์ค์ ์์น๋ ๊ด์ธก(person.status)์ด ๊ฐฑ์ ํ๋ค.\n */\n homeLocationId?: string\n /**\n * ์์ ์์ฑ โ ํ์ค `PersonProperty`. **์๊ฒฉ์ฆยท์๋ จ๋๊ฐ ์ฌ๊ธฐ ๋ค์ด๊ฐ๋ค.**\n *\n * ํ์ค์๋ ์๊ฒฉ(Qualification)์ด๋ผ๋ ๋ณ๋ ์์๊ฐ ์๋ค(`B2MML-Personnel.xsd` ํ์ธ). ์๊ฒฉ์\n * โ ๋ฑ๊ธ ๋ณต์ ์์์ผ๋ก(`personnelClassIds: ['welder-certified','forklift-licensed']`) โก\n * ์ฆ๋น์ ์ด ์์ฑ์ผ๋ก(์๊ฒฉ์ฆ ๋ฒํธยท๋ง๋ฃ์ผ), โข ๊ฒ์ฆ ์ํ์ ํ์ค `TestSpecificationID`(์์ง ๋ฏธ๊ตฌํ).\n */\n properties?: RefResourceProperty[]\n /** ์๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`(์ฐธ์กฐ๋ง; ์ํ ๋ช
์ธยท๊ฒฐ๊ณผ ๋ชจ๋ธ์ ์์ง ์๋ค). */\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ โ ์ฌ๋์๊ฒ๋ **์
์ฌ ์ ยทํด์ฌ ํ**๋ค(์๊ฒฉ ๋ง๋ฃ๋ ๋ฑ๊ธ ์ชฝ ๊ธฐ๊ฐ์ด๋ค: ์ฌ๋์ ๋จ๊ณ ์๊ฒฉ๋ง ๋๊ธด๋ค). */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ๋ฌผ๋ฆฌ ์์ฐ(๋ฐ๋ณต์ฌ์ฉ) โ **ISA-95 `PhysicalAsset`, GS1 `GRAI`.**\n * ํ๋ ํธยท๋ยท์ฉ๊ธฐ์ฒ๋ผ **๋๊ฐ๋ค ๋์์ค๋** ๊ฒ. ๋ฌผ๋ฅ๋จ์(SSCC)์ ๋ค๋ฅด๋ค: SSCC ๋ ๊ทธ ํ๋ ํธ์ ์ค๋ฆฐ ํ๋ฌผ\n * ํ ๋ฉ์ด๋ฆฌ์ด๊ณ , GRAI ๋ ํ๋ ํธ ์์ฒด๋ค(์ค๋์ ์ด ํ๋ฌผ, ๋ด์ผ์ ์ ํ๋ฌผ์ ์ฃ๋๋ค).\n */\nexport interface RefAsset {\n id: string\n name?: string\n /**\n * ์ํ ๋ฑ๊ธ๋ค โ ํ์ค `PhysicalAssetClassID`(๋ณต์). ํ๋ ํธ๊ฐ 'euro-pallet' ์ด๋ฉด์ 'food-grade' ์ผ ์ ์๋ค.\n * ๊ณต์ ์ ์๊ตฌ๋ ๋ฑ๊ธ ํ๋ + ์๋์ด๋ค(ํ์ค `PhysicalAssetSpecification`).\n */\n assetClassIds?: string[]\n /** ๊ธฐ๋ณธ ์์น. */\n homeLocationId?: string\n /** ์ ์ GS1 ์ ์ฒด์ฑ โ ๋ฐ๋ณต์ฌ์ฉ ์์ฐ=GRAI. */\n gs1Id?: string\n /** ์์ ์์ฑ โ ํ์ค `PhysicalAssetProperty`(์ ์ฌ ํ๋ยท๊ท๊ฒฉ ๋ฑ). */\n properties?: RefResourceProperty[]\n /** ์ ๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`. */\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ โ ์์ฐ์์๋ **ํ๊ธฐํ ํ๋ ํธ๊ฐ ํ์์ ๋น ์ง๋ ๊ฒ**์ด๋ค(ํ์ ๋์ ์๊ฐ ๋ถํ์ง ์๊ฒ). */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ํ๋ชฉ ์ ์ โ **ISA-95 `MaterialDefinition`.**\n *\n * ์์ผ๋ฉด ๋กํธ๋ง ๊ด์ธก์ผ๋ก ๋ค์ด์ค๊ณ **ํ๋ชฉ์ด ๋ฌด์์ธ์ง๋ ์๋ฌด ๋ฐ๋ ์๋ค.** ๊ทธ๋์ ๊ฐ์ ๋กํธ๋ฅผ 100๊ฐ๋ก\n * ๋ฐ์๋ \"๋ช kg ์ธ๊ฐ\" ์ ๋ตํ ์ ์๋ค(์ปค๋ `quantityIn` ์ด ํ์ฐ์ ๊ฑฐ๋ถํ๋ ๊ทผ๊ฑฐ).\n *\n * **ํ์ค์ ๋จ์ ํ์ฐ ์์๋ ์๋ค**(1์ฐจ ์ถ์ฒ ์ ์ ํ์ธ) โ ์์ฑ ์ฃผ๋จธ๋๋ฟ์ด๋ค. ๊ทธ๋์ ํ์ฐ ๊ณ์๋\n * ์ปค๋์ด ์ ํ ์์ฑ ์ด๋ฆ(`perBaseUnit`, `uom` ์ด ๋์ ๋จ์)์ผ๋ก `properties` ์ ์ฃ๋๋ค.\n */\nexport interface RefMaterialDefinition {\n /** ํ์ค `ID` โ GTIN(`urn:epc:idpat:sgtin:โฆ`)์ ์ด๋ค(์ ์ฒด์ฑ์ ์ ๋ณธ์ด EPCIS ๋ค). */\n id: string\n name?: string\n /** ์ํ ๋ฑ๊ธ๋ค โ ํ์ค `MaterialClassID`(๋ณต์). */\n materialClassIds?: string[]\n /** ํ๋ชฉ ์์ฑ โ ํ์ค `MaterialDefinitionProperty`. ํ์ฐ ๊ณ์๊ฐ ์ฌ๊ธฐ ๋ค์ด๊ฐ๋ค. */\n properties?: RefResourceProperty[]\n testSpecificationIds?: string[]\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport interface ReferenceMaster {\n source: string\n system: 'wms' | 'yms' | 'mes'\n siteName: string\n /* spaceId ๋ช
์ ์ ๊ทธ ๊ณต๊ฐ์ ์ฐธ์กฐ(์ฌ๋ฌ ํธ์์ด ํ ๊ณต๊ฐ ๊ณต์ , N:1). ์์ผ๋ฉด source ์์ ํ์(1:1). */\n /**\n * ํ์ฅ(๊ณต๊ฐ). **์๊ฐ ๊ธฐ์ค(`timezone`)์ด ์ฌ๊ธฐ ์๋ ์ด์ **: ํ ํ
๋ํธ๊ฐ Rosarito(ํํ์)์ ํ๊ตญ\n * ๊ณต์ฅ์ ํจ๊ป ๊ฐ์ง ์ ์๋ค. ํ
๋ํธ ๋จ์(`Domain.timezone`)๋ก ๋๋ฉด **๋ ์ค ํ๋๋ ๋ฐ๋์ ํ๋ฆฐ๋ค.**\n * ์๊ฐ ๊ธฐ์ค์ **๋ฌผ๋ฆฌ ํ์ฅ์ ์ฑ์ง**์ด๋ฏ๋ก ๊ณต๊ฐ์ด ๊ทธ๊ฒ์ ๊ฐ๋๋ค(๊ณต๊ฐ ์ค์ฌ ์์น).\n *\n * `timezone` ์ IANA ์ด๋ฆ(`'America/Tijuana'`) โ ์คํ์
์ซ์๊ฐ ์๋๋ค. ์ซ์๋ก ๋๋ฉด ์ผ๊ด์ ์ฝ์๊ฐ์\n * ํํํ ์ ์๊ณ , ๋์ค์ ์ ๋ ๊ตฌ๊ฐ์ผ๋ก ์ฎ๊ธธ ๋๋ ์ด๋ฆ์ด ์์ด์ผ ๊ณ์ฐํ ์ ์๋ค.\n */\n space: { spaceId?: string; width: number; depth: number; unit?: string; timezone?: string; geo?: { lat: number; lon: number; rotation?: number }; representations?: any[]; primaryId?: string }\n locations: RefLocation[]\n equipment?: RefEquipment[]\n /** ๊ณต์ ๋ช
์ธ(์์ยท๋ณ๋ยท์์จ) โ ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ตด๋ฌ๊ฐ๋ค(๊ทธ ์ฌ์ค์ specCoverage ๊ฐ ๋ณด๊ณ ). */\n operations?: RefOperation[]\n /**\n * **์์ฐ ์ ์**(๋ ์ํผยท๋ผ์ฐํธยท์์ฌ ๋ฐ์ธ๋ฉ) โ ์ปค๋์ ์ ์-๊ตฌ๋ MES ๋ชจ๋ ์
๊ตฌ.\n *\n * ์์ผ๋ฉด ์ปค๋์ ๋ ๊ฑฐ์(ํ๋์ฝ๋ฉ) ํ๋ฆ์ผ๋ก ๋๋ค. ์ฆ **ํ์ฅ ๋ ์ํผ๋ฅผ ์ ์ด๋ ์ด ์๋ฆฌ์ ์ค๋ฆฌ์ง ์์ผ๋ฉด\n * ์ปค๋์ ๊ทธ๊ฒ์ ๋ณด์ง ๋ชปํ๋ค** โ ์ ์ธ๊ณผ ์คํ์ด ๊ฐ๋ผ์ง๋ ์ง์ ์ด๋ผ ์๋ฆฌ๋ฅผ ์ฐ๋ค.\n */\n mesSpec?: unknown\n /**\n * ์ฌ๋ โ ์ ์ธํ์ง ์์ผ๋ฉด **์ธ์ ์ ์ฝ์ด ์๋ ํธ์**์ด ๋๋ค(์ค๋น๋ง ์์ผ๋ฉด ์ธ์ ๋ ๋์๊ฐ๋ ๊ณต์ฅ).\n * ๊ณต์ ์ด ์ธ์์ ์๊ตฌํ๋๋ฐ ์ฌ๋์ด ์์ผ๋ฉด ๊ทธ ์์
์ ์์๋์ง ์๋๋ค โ ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ฏ๋ก ๊ทธ๋๋ก ๋๋ค.\n */\n persons?: RefPerson[]\n /**\n * ๋ฌผ๋ฆฌ ์์ฐ(๋ฐ๋ณต์ฌ์ฉ) โ ์ ์ธํ์ง ์์ผ๋ฉด ์์ฐ ์ ์ฝ์ด ์๋ ํธ์์ด๋ค.\n * ๊ณต์ ์ด ์์ฐ์ ์๊ตฌํ๋๋ฐ ์์ผ๋ฉด ๊ทธ ์์
์ ์์๋์ง ์๋๋ค โ ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ฏ๋ก ๊ทธ๋๋ก ๋๋ค.\n */\n assets?: RefAsset[]\n /**\n * ๋ฑ๊ธ ์ ์ โ ํ์ค `PersonnelClass`ยท`EquipmentClass`ยท`PhysicalAssetClass`.\n * ์ ์ค์ด๋ ํธ์์ ๋๋ค(์์ ๋ฌธ์์ด ๊ทธ๋๋ก ํ์ ). ์ค์ผ๋ฉด ์์ยท์ ํจ๊ธฐ๊ฐ์ด ์ด์๋๋ค.\n */\n personnelClasses?: RefResourceClass[]\n equipmentClasses?: RefResourceClass[]\n assetClasses?: RefResourceClass[]\n /** ํ๋ชฉ ์ ์ยท๋ฑ๊ธ โ ํ์ค `MaterialDefinition` / `MaterialClass`. ์์ผ๋ฉด ๋จ์ ํ์ฐ์ ํ ์ ์๋ค. */\n materialDefinitions?: RefMaterialDefinition[]\n materialClasses?: RefResourceClass[]\n}\n\nexport interface IngestedTwin {\n board: any // BoardDef(+layout+spaceId) โ ์ปค๋ ์๋น\n spaceContent: any // TwinSpace content โ ๋ทฐ ์๋น\n warnings: string[]\n}\n\n/**\n * ๋ง์คํฐ โ ํธ์ ๊ตฌ์กฐ ๋งคํ(์์). ๋
ธ๋ํ์
์ ์นดํ๋ก๊ทธ๋ก ๊ฒ์ฆ(๋ชจ๋ฅด๋ ํ์
์ warning, ๋ฒ๋ฆฌ์ง ์์ โ ๋ฐ์ ์ฐ์ ).\n * @param catalog DOMAIN_CATALOG (์ปค๋ SSOT). ์์ผ๋ฉด ๊ฒ์ฆ ์๋ต.\n */\n/**\n * IANA ์๊ฐ๋ ์ด๋ฆ โ **๊ทธ ์๊ฐ์** UTC ์คํ์
(๋ถ). ์์กด์ฑ ์์ด `Intl` ๋ก ํผ๋ค.\n *\n * `Intl.DateTimeFormat` ์ `longOffset` ์ `\"GMT-07:00\"` ์ฒ๋ผ ๋์ค๊ณ , ์ด๊ฒ์ **์ผ๊ด์ ์ฝ์๊ฐ์ ๋ฐ์ํ**\n * ๊ฐ์ด๋ค. ๊ทธ๋์ 8์์ `America/Tijuana` ๋ โ420(PDT), 1์์ โ480(PST)์ด ๋๋ค.\n *\n * **ํ๊ณ๋ฅผ ๋ฐํ๋ค**: ์ฌ๊ธฐ์ ๋์ค๋ ๊ฒ์ **ํ ์์ ์** ์คํ์
์ด๋ค. ์ปค๋์ ๊ณ ์ ์คํ์
์ผ๋ก ํ๋ฃจ ์ค ๋ถ์\n * ์ฝ์ผ๋ฏ๋ก, ๋ณด๋๋ฅผ ๋ง๋ ๊ณ์ ๊ณผ ๋ค๋ฅธ ๊ณ์ ์ ๊ธธ๊ฒ ์์ธกํ๋ฉด ํ ์๊ฐ ์ด๊ธ๋๋ค. ํ์ค์ ์ถฉ์คํ ๋ ๋ชจ์ต์\n * ํธ์คํธ๊ฐ ์ ๋ ๊ตฌ๊ฐ(`StartDateTime`/`FinishDateTime`)์ ๊ณ์ฐํด ๋ฃ๋ ๊ฒ์ด๊ณ , ๊ทธ๋ ์ด ํจ์๋ ์ฌ๋ผ์ง๋ค.\n *\n * ๋ชจ๋ฅด๋ ์ด๋ฆ์๋ **0 ์ ๋ตํ์ง ์๋๋ค**(`undefined`) โ 0 ์ \"UTC ๋ผ๊ณ ์ ์ธํ๋ค\" ๋ ๋ป์ด๊ณ , ๋ชจ๋ฅด๋ ๊ฒ์\n * ๊ทธ๋ ๊ฒ ๋ฐ๊พธ๋ฉด ํ์ ์ด ์กฐ์ฉํ ํ๋ฆฐ๋ค.\n */\nexport function utcOffsetOf(timezone?: string, at: Date = new Date()): number | undefined {\n if (!timezone) return undefined\n try {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, timeZoneName: 'longOffset' }).formatToParts(at)\n const name = parts.find(p => p.type === 'timeZoneName')?.value ?? ''\n if (name === 'GMT') return 0 // UTC ๊ณ์ด์ ์คํ์
ํ๊ธฐ๊ฐ ์๋ค\n const m = /^GMT([+-])(\\d{1,2})(?::(\\d{2}))?$/.exec(name)\n if (!m) return undefined\n const sign = m[1] === '-' ? -1 : 1\n return sign * (Number(m[2]) * 60 + Number(m[3] ?? 0))\n } catch {\n return undefined // ์ ์ ์๋ ์ด๋ฆ โ Intl ์ด ๋์ง๋ค\n }\n}\n\nexport function masterToTwin(master: ReferenceMaster, catalog?: any): IngestedTwin {\n const warnings: string[] = []\n const known: string[] = catalog?.[master.system]?.locationTypes ?? []\n\n const locationEntries = master.locations.filter(l => l.role === 'location' || l.role === 'both')\n const areaLocs = master.locations.filter(l => l.role === 'area' || l.role === 'both')\n\n const locations = locationEntries.map(l => {\n if (known.length && !known.includes(l.type)) warnings.push(`unknown ${master.system} location type \"${l.type}\" (${l.id}) โ ์นดํ๋ก๊ทธ์ ์์`)\n // gs1Id(์ ์ ์ ์ฒด์ฑ)๋ฅผ ๋ณด๋ ๋
ธ๋๋ก ํต๊ณผ โ ๊ฒฐํฉ(tag)/์ถ์ ์ด GS1 ๋ก(ยงJ). ๋ก์ปฌ id ๋ ๊ทธ๋๋ก ์ ์ง(name/xref).\n return { id: l.id, type: l.type, capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), parentId: l.parentId, gs1Id: l.gs1Id }\n })\n\n const equipment = (master.equipment ?? []).map(e => ({\n id: e.id, kind: e.kind, homeLocation: e.homeLocationId, mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, gs1Id: e.gs1Id,\n ...(e.window ? { window: e.window } : {}),\n /* ์์ฑ์ ์๋์ง ์๊ณ ํต๊ณผ โ ์ด๋์๊ฐ ์ถ์ ๊ธฐ๊ฐ kind ๋ณ ์๋๋ฅผ ์ฌ๊ธฐ์ ์ฝ๋๋ค(๋จ์ ์ฝ๋ ๊ทธ๋๋ก). */\n ...(e.properties?.length ? { properties: e.properties } : {}), ...(e.workCalendar?.length ? { workCalendar: e.workCalendar } : {}), ...(e.testSpecificationIds?.length ? { testSpecificationIds: e.testSpecificationIds } : {}),\n /* ์ ํจ ๊ธฐ๊ฐ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ํ์ ์ ์ปค๋์ด ์๊ธฐ ์๊ณ๋ก ํ๋ค(ํธ์คํธ๊ฐ ๋ฏธ๋ฆฌ ์๋ฅด์ง ์๋๋ค). */\n ...(e.effectiveStart ? { effectiveStart: e.effectiveStart } : {}), ...(e.effectiveEnd ? { effectiveEnd: e.effectiveEnd } : {})\n }))\n\n // ์ขํ(layout) โ footprint ์ค์ฌ. ์์ผ๋ฉด ์๋ต(coordinate-free ์ ์ง).\n const layout: Record<string, { x: number; y: number }> = {}\n for (const l of locationEntries) if (l.footprint) layout[l.id] = { x: l.footprint.x + l.footprint.w / 2, y: l.footprint.y + l.footprint.h / 2 }\n\n const spaceId = master.space.spaceId ?? `${master.source}-site`\n /*\n * ์๊ฐ ๊ธฐ์ค์ ์ปค๋์ด ์ฝ์ ํํ๋ก ํผ๋ค โ ์ปค๋์ zero-dep ์ด๋ผ ์๊ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค์ด์ง ์๊ณ \n * **๋ถ ์คํ์
**๋ง ๋ฐ๋๋ค(๊ณ์ฝ `BoardDef.utcOffsetMinutes`). ํธ๋ ์ผ์ ํธ์คํธ์ ๋ชซ์ด๋ค.\n *\n * ์ ์ธ์ด ์์ผ๋ฉด **ํ๋๋ฅผ ๋ง๋ค์ง ์๋๋ค** โ ๊ทธ๋ฌ๋ฉด ์ปค๋์ด UTC ๋ก ์ฝ๊ณ , ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ๊ณ์ฝ์ ๋ฐํ์ ธ ์๋ค.\n * ์ฌ๊ธฐ์ 0 ์ ๋ฃ์ผ๋ฉด \"UTC ๋ผ๊ณ ์ ์ธํ๋ค\" ์ \"์ ์ธํ์ง ์์๋ค\" ๊ฐ ๊ตฌ๋ณ๋์ง ์๋๋ค.\n */\n const utcOffsetMinutes = utcOffsetOf(master.space.timezone)\n if (master.space.timezone && utcOffsetMinutes === undefined) {\n warnings.push(`space timezone \"${master.space.timezone}\" is not a known IANA zone โ the twin will read times as UTC`)\n }\n /*\n * ์คํผ๋ ์ด์
๋ช
์ธ๋ฅผ board ์ ํต๊ณผ์ํจ๋ค โ ์ปค๋์ด `loadOperations` ๋ก ์๋นํ๋ค(BoardDef ํ์ฅ ํ๋,\n * ๋ชจ๋ฅด๋ ์ปค๋์ ๋ฌด์). ์ฌ๊ธฐ์ ๊ฐ์ ์๋์ง ์๋๋ค: ๊ธฐ๊ฐ์ ํ์ค ํ๊ธฐ(ISO 8601)๋ก ์ปค๋๊น์ง ๊ทธ๋๋ก ๊ฐ๋ค.\n */\n const operations = master.operations\n if (operations?.length) {\n for (const o of operations) {\n if (!o.duration && !o.parameters?.length) warnings.push(`operation \"${o.key}\" has no duration or parameters โ kernel defaults will be used`)\n }\n }\n /* ์ฌ๋๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๋ฑ๊ธยท๊ต๋ ๊ทธ๋๋ก ์ปค๋๊น์ง ๊ฐ๋ค(๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค). */\n const persons = master.persons?.map(p => ({ id: p.id, personnelClassIds: p.personnelClassIds, ...(p.window ? { window: p.window } : {}), ...(p.workCalendar?.length ? { workCalendar: p.workCalendar } : {}), ...(p.homeLocationId ? { homeLocation: p.homeLocationId } : {}), ...(p.properties?.length ? { properties: p.properties } : {}), ...(p.testSpecificationIds?.length ? { testSpecificationIds: p.testSpecificationIds } : {}), ...(p.effectiveStart ? { effectiveStart: p.effectiveStart } : {}), ...(p.effectiveEnd ? { effectiveEnd: p.effectiveEnd } : {}) }))\n /* ์์ฐ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๋ฑ๊ธยท์๋ฆฌ ๊ทธ๋๋ก ์ปค๋๊น์ง. */\n const assets = master.assets?.map(a => ({ id: a.id, assetClassIds: a.assetClassIds, homeLocation: a.homeLocationId, gs1Id: a.gs1Id, ...(a.properties?.length ? { properties: a.properties } : {}), ...(a.testSpecificationIds?.length ? { testSpecificationIds: a.testSpecificationIds } : {}), ...(a.effectiveStart ? { effectiveStart: a.effectiveStart } : {}), ...(a.effectiveEnd ? { effectiveEnd: a.effectiveEnd } : {}) }))\n /* ํ๋ชฉ ์ ์ยท๋ฑ๊ธ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค(ํ์ฐ ๊ณ์๋ ์ปค๋์ด ์ฝ๋๋ค). */\n const materialDefinitions = master.materialDefinitions?.map(d => ({\n id: d.id,\n ...(d.name ? { description: d.name } : {}),\n ...(d.materialClassIds?.length ? { materialClassIds: d.materialClassIds } : {}),\n ...(d.properties?.length ? { properties: d.properties } : {}),\n ...(d.testSpecificationIds?.length ? { testSpecificationIds: d.testSpecificationIds } : {}),\n ...(d.effectiveStart ? { effectiveStart: d.effectiveStart } : {}),\n ...(d.effectiveEnd ? { effectiveEnd: d.effectiveEnd } : {})\n }))\n const board = {\n locations, equipment, layout, spaceId,\n /* ์์ฐ ์ ์๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค(์ปค๋์ด ๊ทธ๋๋ก ์๋นํ๋ค). */\n ...(master.mesSpec ? { mesSpec: master.mesSpec } : {}),\n ...(materialDefinitions?.length ? { materialDefinitions } : {}),\n ...(master.materialClasses?.length ? { materialClasses: master.materialClasses } : {}),\n ...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),\n ...(operations?.length ? { operations } : {}),\n ...(master.personnelClasses?.length ? { personnelClasses: master.personnelClasses } : {}),\n ...(master.equipmentClasses?.length ? { equipmentClasses: master.equipmentClasses } : {}),\n ...(master.assetClasses?.length ? { assetClasses: master.assetClasses } : {}),\n ...(persons?.length ? { persons } : {}),\n ...(assets?.length ? { assets } : {})\n }\n\n const areas = areaLocs.map(l => ({\n id: l.id, type: l.type, name: l.name ?? l.id, parentId: l.parentId,\n x: l.footprint?.x ?? 0, y: l.footprint?.y ?? 0, w: l.footprint?.w ?? 10, h: l.footprint?.h ?? 10\n }))\n // ์ธ์ ์คํธ ํ์ฅ ๋ฌผ์งํ(space facet #4) โ ํํ์ด ์๊ณ geo ๊ฐ ์์ผ๋ฉด ๊ธฐ๋ณธ map ํํ ํฉ์ฑ.\n // \"์ธ์ ์คํธํ๋ฉด ์์๋ณผ ํ์ฅ(๋ด place)์ด ๋ฌ๋ค\"๋ ๊ณต๊ฐ ์ค์ฌ ์ ์ ๋ณด์ฅ(zero-to-twin): ์ปค๋ฅํฐ/ํ
ํ๋ฆฟ์ด\n // ํํ์ ์ ์ค๋ geo ๋ง ์์ผ๋ฉด ์์ฑ ์ง๋๋ก ์ฐฉ์ง. (area ํด๋ฆฌ๊ณค ๋ฌผ์งํ๋ ์ขํ ํฌ์ ํ์ โ space #3.)\n const geo = master.space.geo\n const givenReps = master.space.representations ?? []\n const representations =\n givenReps.length > 0\n ? givenReps\n : geo\n ? [{ id: 'r-map', type: 'map', name: '์์ฑ ์ง๋', primary: true, center: { lat: geo.lat, lon: geo.lon }, zoom: 17 }]\n : []\n if (representations.length === 0) {\n warnings.push('space has no viewable representation (no representations and no geo) โ add one manually or provide geo/board')\n }\n const spaceContent = {\n width: master.space.width, depth: master.space.depth, unit: master.space.unit ?? 'm',\n geo, representations, primaryId: master.space.primaryId ?? representations[0]?.id,\n areas, landmarks: []\n }\n\n return { board, spaceContent, warnings }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reference-master.js","sourceRoot":"","sources":["../../../server/service/reference/reference-master.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Face2 ๋ง์คํฐ ์ธ์ ์คํธ(ADR-0018 ๋ฐ์ ๋ชจ๋) โ ๋ ํผ๋ฐ์ค ์์คํ
(์ค WMS/YMS/MES ๋๋ ๊ฐ์ ๋ ํผ๋ฐ์ค)์\n * ๋ง์คํฐ๋ฅผ ์ฝ์ด ํธ์ ๊ตฌ์กฐ(BoardDef) + ๊ณต๊ฐ(Space content)์ ์์ฑ. ์๋ฐฐ์ ์ด ์๋๋ผ ์ธ์ ์คํธ๋ก ์ํฐํฐ๊ฐ ํ๋ฅธ๋ค.\n *\n * ๊ท์จ(ADR-0018): ๋๋ฉ์ธ ํ์
(location.type=๋
ธ๋์ฉ)์ ์ปค๋ ์นดํ๋ก๊ทธ ์ดํ๋ฅผ ๊ทธ๋๋ก ๋ฐ์(๋ฐ๋ช
๊ธ์ง).\n * location ์ role ๋ก ๋
ธ๋(์ด์์ )ยทarea(๊ณต๊ฐ์์ญ)ยทboth ๋ฅผ ๊ตฌ๋ถ โ ๋
ธ๋โBoardDef, areaโSpace.areas.\n * ์ขํยทrepresentations ๋ ํธ์ ๊ณต๊ฐ์ธต(๋ณด์/์ถ๊ฐ). ์ค ์์คํ
์ด ์ขํ๋ฅผ ์ ์ฃผ๋ฉด layout ์์ด ์์๋ง ์ธ์ ์คํธ.\n */\n\nimport type { EquipmentLevel, WorkCalendarEntry } from '@operato/twin-kernel'\n\nexport interface RefLocation {\n id: string\n type: string // ๋
ธ๋๋ ์ปค๋ ๋
ธ๋ํ์
(dock/storage/yard-slotโฆ), area ๋ ๊ณต๊ฐ region ํ์
\n name?: string\n role: 'location' | 'area' | 'both'\n parentId?: string\n /** ์ ์ฅ ์ฉ๋ โ ์ด ์๋ฆฌ์ ๋์์ ๋์ผ ์ ์๋ ๋ฌผํ ์. */\n capacity?: number\n /**\n * ๋์ ์ฒ๋ฆฌ ์ โ ์ด ์๋ฆฌ์์ ํ ๋ฒ์ ์งํ๋ ์ ์๋ ์์
์. **์ ์ฅ ์ฉ๋๊ณผ ๋ค๋ฅธ ์ถ**์ด๋ค\n * (์์ฌ๋ฅผ 20๊ฐ ์์ ๋๋ ์ ๋จ ์คํ
์ด์
์ด ํ ๋ฒ์ ํ ๋๋ง ๊น๋๋ค). ๋ฏธ์ง์ =์ ์ฝ ์์.\n */\n parallelism?: number\n /**\n * **ISA-95 ์ค๋น ๊ณ์ธต ๋จ๊ณ** โ `EquipmentLevel` ์ด๊ฑฐ๊ฐ(`ProductionLine`ยท`StorageZone`ยท`WorkCenter`โฆ).\n *\n * `type` ์ ํ์ฅ์ ๋ฑ๋ง(`paint-booth`)์ด๊ณ ์ด๊ฒ์ **ํ์ค์ด ์ ํ ์ญํ **์ด๋ค. ๋์ ๋ค๋ฅธ ์ถ์ด๋ผ ํจ๊ป ๋ ๋ค โ\n * ์ฐ๋ยท์ง๊ณ๋ ํ์ค ์ถ์ผ๋ก, ํ๋ฉด์ ํ์ฅ ๋ฑ๋ง๋ก. ๋ฏธ์ง์ ์ด๋ฉด ๊ทธ ์๋ฆฌ์ ํ์ค ์ญํ ์ ์์ง ๋ชจ๋ฅธ๋ค๋ ๋ป์ด๊ณ ,\n * ์ง์ํด ์ฑ์ฐ์ง ์๋๋ค.\n */\n level?: EquipmentLevel\n footprint?: { x: number; y: number; w: number; h: number } // ์์ผ๋ฉด area ๊ธฐํ + ๋
ธ๋ ์ค์ฌ์ขํ\n gs1Id?: string // ์ ์ GS1 ์ ์ฒด์ฑ(ยงJ) โ ์์น=SGLN. ๊ฒฐํฉ(tag)/์ถ์ canonical id. ๋ฐ์๋ค์ด๊ธฐ ๊ฒฝ๊ณ์ ๋ถ์ฌ(๋ก์ปฌ id=name/xref ๋ก ๋ณด์กด).\n}\n\n/**\n * ์ค๋น ์์ฑ โ **ISA-95 `EquipmentSpecificationProperty`(`OpEquipmentSpecificationPropertyType`) 1:1.**\n * ๊ทธ ํ์
๋ `ID` + `Value`(`ValueString`ยท`DataType`ยท`UnitOfMeasure`) ์ด๋ฏ๋ก ๊ณต์ ๋ชจ์์ ๊ฐ์ ๋ชจ์์ด๋ค.\n *\n * ๋จ์ ์ฝ๋๋ **UN/CEFACT ๊ถ๊ณ 20 ๊ณตํต์ฝ๋**(EPCIS `uom` ๊ณผ ๊ฐ์ ์ฝ๋๊ณ): ์๋๋ `MTS`(metre per\n * second) ๋๋ `KMH`(kilometre per hour). ์ฝ๋๋ฅผ ์ฐ๋ฆฌ๊ฐ ๋ฐ๋ช
ํ์ง ์๋๋ค.\n */\n/**\n * ์์ ์์ฑ โ **์ปค๋ `ResourceProperty` ์ ๊ฐ์ ๋ชจ์**์ด๊ณ , ๊ทธ ๋ชจ์์ ISA-95 ๊ฐ ์ธ ์์์ ๋๊ฐ์ด\n * ์ ์ํ ๊ฒ์ด๋ค(`EquipmentPropertyType` ยท `PersonPropertyType` ยท `PhysicalAssetPropertyType`).\n *\n * ๊ทธ๋์ ์์๋ง๋ค ๋ค๋ฅธ ์์ฑ ํ์
์ ๋์ง ์๋๋ค โ ์์ ์๋ ์ค๋น๋ง ์์ฑ์ ๊ฐ์ก๊ณ (RefEquipmentProperty),\n * ์ธ์ยท์์ฐ์ ๋ถ๋ ์ฌ์ค์ **์ค์ ์๋ฆฌ๊ฐ ์์ด์ ๋ค์ด์ค์ง ๋ชปํ๋ค.**\n */\nexport interface RefResourceProperty {\n id: string\n description?: string\n value?: string\n /** ํ์ค `Value.DataType`. */\n dataType?: string\n /** ํ์ค `Value.UnitOfMeasure` โ UN/CEFACT ๊ณตํต์ฝ๋. ๋ฌผ๋ฆฌ๋์ ๋จ์๊ฐ ์์ผ๋ฉด ์๋น์ฒ๊ฐ ๊ฑฐ์ ํ๋ค. */\n uom?: string\n /** ํ์ ์์ฑ(์ฌ๊ท) โ ํ์ค `<X>PropertyChild`. */\n children?: RefResourceProperty[]\n /** ์ด ๊ฐ์ฒด ์์ฑ์ด ๊ตฌ์ฒดํํ๋ ๋ฑ๊ธ ์์ฑ โ ํ์ค `<X>ClassPropertyID`. */\n classPropertyId?: string\n}\n\n/** ์ ์ด๋ฆ โ ์ค๋น ์ ์ฉ์ด๋ ์์ ์ ๋ณ์นญ(์๋น์ฒ ํธํ). ์ ๊ท ์์ฑ์ `RefResourceProperty`. */\nexport type RefEquipmentProperty = RefResourceProperty\n\n/**\n * ์์ **๋ฑ๊ธ ์ ์** โ ์ปค๋ `ResourceClassDef` ์ ๊ฐ์ ๋ชจ์์ด๊ณ , ๊ทธ ๋ชจ์์ ISA-95 ๊ฐ ์ธ ์์์ ๋๊ฐ์ด\n * ์ ์ํ ๊ฒ์ด๋ค(`PersonnelClassType`ยท`EquipmentClassType`ยท`PhysicalAssetClassType`).\n *\n * ์ ํ์ํ๊ฐ: ์ ์์คํ
์ ๋ฑ๊ธ **์ฒด๊ณ**๋ฅผ ๊ฐ๊ณ ์๋ค(\"6์ถ ์ฉ์ ์๊ฒฉ์\" ๋ \"์ฉ์ ์๊ฒฉ์\" ์ด๊ณ , ๊ทธ๊ฒ์\n * \"์์ฐ์ง\" ์ด๋ค). ๊ทธ ์ฒด๊ณ๊ฐ ๋ค์ด์ฌ ์๋ฆฌ๊ฐ ์์ผ๋ฉด ์๊ตฌ์ ์์์ด **๋ฌธ์์ด์ด ๋๊ฐ์ ๋๋ง** ๋ง์,\n * ํ์ฅ์์๋ ๋๋ ๋ฐฐ์ ์ด ๋ชจ๋ธ์์ ๋งํ๋ค.\n */\nexport interface RefResourceClass {\n id: string\n description?: string\n /** ์์ ๋ฑ๊ธ๋ค โ ํ์ค `<X>ClassBaseID`(๋ณต์ = ๋ค์ค ์์). */\n baseIds?: string[]\n properties?: RefResourceProperty[]\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ(ISO) โ ํ์ค `EffectiveStartDate`/`EffectiveEndDate`. ๋ฐ์ด๋ฉด ์๊ฒฉ์ด ์ฑ๋ฆฝํ์ง ์๋๋ค. */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport interface RefEquipment {\n id: string\n kind: string\n homeLocationId: string\n mtbfMs?: number // ํ๊ท ๊ณ ์ฅ ๊ฐ๊ฒฉ(ํ๋ฅ ์ ๊ณ ์ฅ) โ ์ง์ ์ ์ปค๋์ด breakdown ์๋ฎฌ โ ์ฃผ๋ชฉ(๊ณ ์ฅ) ๋ฐ์\n mttrMs?: number // ํ๊ท ์๋ฆฌ ์๊ฐ\n gs1Id?: string // ์ ์ GS1 ์ ์ฒด์ฑ(ยงJ) โ ์ค๋น=GIAI.\n /**\n * ๊ต๋(๊ฐ๋์๊ฐ) โ ์ด ์๊ฐ๋์๋ง ๋ฐฐ์ ๋๋ค. `startHour <= endHour` ๋ฉด ๊ฐ์ ๋ , ๋์ด๊ฐ๋ฉด ์ผ๊ฐ(22โ6).\n * ๋ฏธ์ง์ =24์๊ฐ ๊ฐ์ฉ. ๊ต๋ ๋ฐ ์์์ ๊ณ ์ฅยท๊ณํ์ ์ง์ **๊ตฌ๋ณ๋๋ ์ด์ **๋ก ์ฐ๋ค(์ํ์ ๋๋ฌ๋๋ค).\n */\n window?: { startHour: number; endHour: number }\n /**\n * ๊ทผ๋ฌด ์บ๋ฆฐ๋ โ ํ์ค `WorkCalendarEntry`(๋ณต์). ์์ผ๋ฉด `window` ๋ณด๋ค ์ด๊ฒ์ ๋ณธ๋ค.\n *\n * ์ถ์ ํ๋ ์์ํฌ `@things-factory/work-shift` ์ `WorkShift`(`fromDate`ยท`fromTime`ยท`toDate`ยท`toTime`)์\n * ๋ง์ถฐ ๋์๋ค โ ๊ทธ ์ํฐํฐ๋ฅผ ๊ต๋์ ์ ๋ณธ์ผ๋ก ๊ฒฐ์ ํ ๋ ์ง์ ๋งคํ์ด ๋๊ฒ. **์์ง ๊ฒฐ์ ํ์ง ์์๋ค**:\n * ๊ทธ ์ํฐํฐ์๋ ์์ ์ฐ๊ฒฐ๊ณผ ๋น๊ทผ๋ฌด(ํด์ผ)๊ฐ ์์ด ํ์ฅ์ด ํจ๊ป ํ์ํ๊ณ , operato-twin ์ ์์กด์ฑ ์ถ๊ฐ๋\n * ์ฑ ์ํคํ
์ฒ ๊ฒฐ์ ์ด๋ค(์ปค๋ฒ๋ฆฌ์ง ยง4-7 ์ ๊ฒฐ์ ์ง์ ์ผ๋ก ๊ธฐ๋ก).\n */\n workCalendar?: WorkCalendarEntry[]\n /**\n * ์ค๋น ์์ฑ(์๋ ๋ฑ) โ ์์ผ๋ฉด **์ด๋์๊ฐ์ ๊ฑฐ๋ฆฌ์์ ๊ณ์ฐํ ์ ์๋ค**(์๋ ์์ด ๊ฑฐ๋ฆฌ๋ง์ผ๋ก๋ ์๊ฐ์ด\n * ์ ๋์จ๋ค). ๊ทธ๋๋ ์ปค๋ ์์๋ก ๋จ์ด์ง๊ณ ๊ทธ ์ฌ์ค์ด `specCoverage()` ์ ๋จ๋๋ค.\n */\n properties?: RefResourceProperty[]\n /** ์ ๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`(๊ต์ ๋ฑ). */\n testSpecificationIds?: string[]\n /**\n * ์ ํจ ๊ธฐ๊ฐ โ **ํ์ค `EffectiveStartDate` / `EffectiveEndDate`**(๊ฐ์ฒด ํ์
์
๋ชจ๋์ ์๋ค).\n *\n * ์์ผ๋ฉด **ํ๊ธฐํ ๊ฒ์ด ์๊ตฌํ ์ด์ ์๋ค**: ๋ฐฐ์ ๋์์ ๋จ๊ณ , ๊ฐ์ฉ ์์ ๋ค์ด๊ฐ๊ณ , ํ๋ฉด์ ๋ฌ๋ค.\n * ๋์
์์ ์ธ ๊ฒ์ ๋ฐ๋๋ก ์ค๋๋ถํฐ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค. ๊ธฐ๊ฐ ๋ฐ์ด๋ฉด ์ปค๋์ด ๊ทธ ์๊ฐ์ ๋ชจ๋ธ์์\n * ๋นผ๊ณ **์ด์ ๋ฅผ ๋ฌ์ ๋จ๊ธด๋ค**(`effectivity: 'not-yet' | 'expired'`) โ ์กฐ์ฉํ ์ง์ฐ์ง ์๋๋ค.\n */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ๊ณต์ ๋ชจ์ โ ์ปค๋ `OperationParameter`(= ISA-95 `ParameterSpecification`/`ParameterType`) ์ **๊ฐ์ ๋ชจ์**.\n * ์ด๋ฆ์ ๋ฐ๊พธ์ง ์๋๋ค: ์ธ์ ์คํธ ๊ฒฝ๊ณ์์ ์ดํ๊ฐ ๊ฐ๋ฆฌ๋ฉด ๊ทธ ์๋ฆฌ์์ ๋ฐฉ์ธ์ด ์๊ธด๋ค.\n * ID ์ดํ์ ์ ๋ณธ์ ์ปค๋ `OP_PARAM`(ํ์ค์ด ํ๋ผ๋ฏธํฐ ID ๋ฅผ ์ ํ์ง ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ํ ๊ณณ์์ ์ ํ๋ค).\n */\nexport interface RefOperationParameter {\n id: string\n /** ISA-95 `Value.ValueString` โ ํ์ค์ด ๋ฌธ์์ด๋ก ์ฃ๋๋ค. ๊ธฐ๊ฐ ๋ชจ์๋ ISO 8601(`PT8M`). */\n value: string\n /** ISA-95 `Value.UnitOfMeasure`. ๋ฌด์ฐจ์(๋น์จ)์ด๋ฉด ์๋ต. */\n uom?: string\n}\n\n/**\n * ๊ณต์ ์ ์์ฌ ์๊ตฌยท์ฐ์ถ โ **ISA-95 `OperationsSegment.MaterialSpecification`** ๊ณผ ๊ฐ์ ๋ชจ์.\n * ์ธ์ยท์ค๋นยท์์ฐ ๋ช
์ธ์ ๊ฐ์ ์๋ฆฌ์ ์์ด์ผ 4๋ ์์์ด ๋์นญ์ด ๋๋ค(์์ฌ๋ง ๋น ์ ธ ์์๋ค).\n */\nexport interface RefOpMaterialSpecification {\n id?: string\n /** ํ๋ชฉ ๋ฑ๊ธ์ผ๋ก ์๊ตฌ โ ํ์ค `MaterialClassID`. */\n materialClass?: string\n /** ํน์ ํ๋ชฉ์ผ๋ก ์๊ตฌ โ ํ์ค `MaterialDefinitionID`. */\n materialDefinition?: string\n /** ํ์ค `MaterialUse` โ ์ด ๊ณต์ ์์์ ์ฐ์. */\n use: 'consumed' | 'produced' | 'consumable'\n /** ํ์ค `Quantity`. ๋จ์ ๋ฏธ์ง์ ์ด๋ฉด ๊ฐ์. */\n quantity: number\n uom?: string\n}\n\n/** ์์์๊ฐ ๋ณ๋ โ **ํ์ค ๋ฐ ํ์ฅ**(ISA-95 Duration ์ ์ค์นผ๋ผ). ์ปค๋ `DurationVariability` ์ ๋ํ. */\nexport interface RefOperationVariability {\n distribution: 'constant' | 'exponential' | 'uniform' | 'triangular'\n min?: string\n max?: string\n mode?: string\n}\n\n/**\n * ์คํผ๋ ์ด์
๋ช
์ธ โ ISA-95 `OperationsSegment`. ์ปค๋ `OperationDef` ์ ํ๋ ์ด๋ฆ์ด 1:1์ด๋ค.\n *\n * **์ด๊ฒ์ด ์์ผ๋ฉด ์๋ฎฌ๋ ์ด์
์ ์๊ฐ์ ์ฐ๋ฆฌ๊ฐ ์ฝ๋์ ๋ฐ์ ๋ ์์๋ค.** ์ ์์คํ
(๋๋ ๊ฐ์ ๋ ํผ๋ฐ์ค)์ด\n * ๊ณต์ ๋ณ ์์ยท๋ณ๋ยท์์จ์ ๋งํด ์ค์ผ ์์ธก์ด ๊ทธ ํ์ฅ์ ์์ธก์ด ๋๋ค. ์ฃผ์ง ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก\n * ๊ตด๋ฌ๊ฐ๊ณ , **๊ธฐ๋ณธ๊ฐ์ ์ผ๋ค๋ ์ฌ์ค์ ์ปค๋ `specCoverage()` ๊ฐ ๋ฐํ๋ค**(์กฐ์ฉํ ๋์ด๊ฐ์ง ์๋๋ค).\n */\nexport interface RefOperation {\n /** ์์
์ข
๋ฅ ํค โ ์ปค๋ `FlowTask.kind` ์ ๊ฐ์ ๊ฐ์ด์ด์ผ ๋ช
์ธ๊ฐ ๊ทธ ์์
์ ๋ถ๋๋ค. */\n key: string\n label: string\n intent: 'transport' | 'process' | 'dwell'\n locationType?: string\n resourceType?: string\n bizStep?: string\n /** ISA-95 `OperationsSegment.Duration` โ ISO 8601 ๊ธฐ๊ฐ(`PT12M`). */\n duration?: string\n variability?: RefOperationVariability\n parameters?: RefOperationParameter[]\n /**\n * ํ์ ์ธ์ โ ISA-95 `PersonnelSpecification`(`PersonnelClassID` + `Quantity`) 1:1.\n * ์์ผ๋ฉด ์ฌ๋ ์์ด ๋๋ ๊ณต์ ์ด๋ค(์ค๋น๋ง ์ก๋๋ค).\n */\n personnelSpecification?: { personnelClass?: string; quantity: number }[]\n /** ํ์ ๋ฌผ๋ฆฌ ์์ฐ โ ISA-95 `PhysicalAssetSpecification`(๋ฑ๊ธ + ์๋). ๋น ํ๋ ํธ๊ฐ ์์ผ๋ฉด ๋ชป ๋๊ฐ๋ค. */\n physicalAssetSpecification?: { assetClass?: string; quantity: number }[]\n /**\n * ํ์ยท์ฐ์ถ ์์ฌ โ ISA-95 `MaterialSpecification`. **4๋ ์์ ์ค ์์ฌ๋ง ์ด ์๋ฆฌ๊ฐ ์์๋ค** โ\n * ๊ทธ๋์ ๋ถํ์ด ๋จ์ด์ ธ ๋ผ์ธ์ด ์๋ ์ํฉ์ด ์์ธก์ ๋ํ๋์ง ์์๋ค.\n * BOM ์ \"๋ช ๊ฐ\" ๋ ์ฌ๊ธฐ๋ค(ํ๋ชฉ ์ ์์ ์กฐ๋ฆฝ ๊ตฌ์กฐ์๋ ์๋์ด ์๋ค โ 1์ฐจ ์ถ์ฒ ํ์ธ).\n */\n materialSpecification?: RefOpMaterialSpecification[]\n}\n\n/**\n * ์ฌ๋ โ **ISA-95 `Person`.** ์ค๋น์ ๋ณ๊ฐ ์์์ด๋ค(๊ณ ์ฅยท์ค๋นํจ์จ์ด ์๋๋ผ ๋ฑ๊ธยท๊ต๋๋ก ์ฐ๋ค).\n * `personnelClass` ๊ฐ ISA-95 `PersonnelClassID` โ ๊ณต์ ์ ํน์ ์ธ์ด ์๋๋ผ **๋ฑ๊ธ์ผ๋ก** ์ธ์์ ์๊ตฌํ๋ค.\n */\nexport interface RefPerson {\n id: string\n name?: string\n /**\n * ์ํ ๋ฑ๊ธ๋ค โ **ํ์ค `Person.PersonnelClassID`, `maxOccurs=\"unbounded\"`**.\n * ๋ณต์์ธ ๊ฒ์ด ํ์ค์ด๊ณ ๊ทธ๊ฒ์ด ์๊ฒฉ ํํ์ด๋ค: ํ ์ฌ๋์ด ์ฉ์ ์๊ฒฉ๊ณผ ์ง๊ฒ์ฐจ ์๊ฒฉ์ ํจ๊ป ๊ฐ๋๋ค.\n */\n personnelClassIds?: string[]\n /** ๊ต๋ โ ์ค๋น์ ๊ฐ์ ๋ชจ์. ๋ฏธ์ง์ =24์๊ฐ ๊ฐ์ฉ. */\n window?: { startHour: number; endHour: number }\n /** ๊ทผ๋ฌด ์บ๋ฆฐ๋ โ ํ์ค `WorkCalendarEntry`(๋ณต์). 2๊ต๋ยทํด๊ฒยทํด์ผ์ ํจ๊ป ํํํ๋ค. */\n workCalendar?: WorkCalendarEntry[]\n /**\n * ๊ธฐ๋ณธ ์์น โ ํ์ค `Person.OperationalLocation`. ์์ผ๋ฉด \"์ด ๋ผ์ธ์ ๋ช ๋ช
์๋\" ๋ฅผ ๋ฌผ์ ์ ์๋ค.\n * ์ฌ๋์ ์์ง์ด๋ฏ๋ก ์ด ๊ฐ์ **์ถ๋ฐ์ **์ด๊ณ , ์ค์ ์์น๋ ๊ด์ธก(person.status)์ด ๊ฐฑ์ ํ๋ค.\n */\n homeLocationId?: string\n /**\n * ์์ ์์ฑ โ ํ์ค `PersonProperty`. **์๊ฒฉ์ฆยท์๋ จ๋๊ฐ ์ฌ๊ธฐ ๋ค์ด๊ฐ๋ค.**\n *\n * ํ์ค์๋ ์๊ฒฉ(Qualification)์ด๋ผ๋ ๋ณ๋ ์์๊ฐ ์๋ค(`B2MML-Personnel.xsd` ํ์ธ). ์๊ฒฉ์\n * โ ๋ฑ๊ธ ๋ณต์ ์์์ผ๋ก(`personnelClassIds: ['welder-certified','forklift-licensed']`) โก\n * ์ฆ๋น์ ์ด ์์ฑ์ผ๋ก(์๊ฒฉ์ฆ ๋ฒํธยท๋ง๋ฃ์ผ), โข ๊ฒ์ฆ ์ํ์ ํ์ค `TestSpecificationID`(์์ง ๋ฏธ๊ตฌํ).\n */\n properties?: RefResourceProperty[]\n /** ์๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`(์ฐธ์กฐ๋ง; ์ํ ๋ช
์ธยท๊ฒฐ๊ณผ ๋ชจ๋ธ์ ์์ง ์๋ค). */\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ โ ์ฌ๋์๊ฒ๋ **์
์ฌ ์ ยทํด์ฌ ํ**๋ค(์๊ฒฉ ๋ง๋ฃ๋ ๋ฑ๊ธ ์ชฝ ๊ธฐ๊ฐ์ด๋ค: ์ฌ๋์ ๋จ๊ณ ์๊ฒฉ๋ง ๋๊ธด๋ค). */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ๋ฌผ๋ฆฌ ์์ฐ(๋ฐ๋ณต์ฌ์ฉ) โ **ISA-95 `PhysicalAsset`, GS1 `GRAI`.**\n * ํ๋ ํธยท๋ยท์ฉ๊ธฐ์ฒ๋ผ **๋๊ฐ๋ค ๋์์ค๋** ๊ฒ. ๋ฌผ๋ฅ๋จ์(SSCC)์ ๋ค๋ฅด๋ค: SSCC ๋ ๊ทธ ํ๋ ํธ์ ์ค๋ฆฐ ํ๋ฌผ\n * ํ ๋ฉ์ด๋ฆฌ์ด๊ณ , GRAI ๋ ํ๋ ํธ ์์ฒด๋ค(์ค๋์ ์ด ํ๋ฌผ, ๋ด์ผ์ ์ ํ๋ฌผ์ ์ฃ๋๋ค).\n */\nexport interface RefAsset {\n id: string\n name?: string\n /**\n * ์ํ ๋ฑ๊ธ๋ค โ ํ์ค `PhysicalAssetClassID`(๋ณต์). ํ๋ ํธ๊ฐ 'euro-pallet' ์ด๋ฉด์ 'food-grade' ์ผ ์ ์๋ค.\n * ๊ณต์ ์ ์๊ตฌ๋ ๋ฑ๊ธ ํ๋ + ์๋์ด๋ค(ํ์ค `PhysicalAssetSpecification`).\n */\n assetClassIds?: string[]\n /** ๊ธฐ๋ณธ ์์น. */\n homeLocationId?: string\n /** ์ ์ GS1 ์ ์ฒด์ฑ โ ๋ฐ๋ณต์ฌ์ฉ ์์ฐ=GRAI. */\n gs1Id?: string\n /** ์์ ์์ฑ โ ํ์ค `PhysicalAssetProperty`(์ ์ฌ ํ๋ยท๊ท๊ฒฉ ๋ฑ). */\n properties?: RefResourceProperty[]\n /** ์ ๊ฒฉ์ ๊ฒ์ฆํ ์ํ ๋ช
์ธ๋ค โ ํ์ค `TestSpecificationID`. */\n testSpecificationIds?: string[]\n /** ์ ํจ ๊ธฐ๊ฐ โ ์์ฐ์์๋ **ํ๊ธฐํ ํ๋ ํธ๊ฐ ํ์์ ๋น ์ง๋ ๊ฒ**์ด๋ค(ํ์ ๋์ ์๊ฐ ๋ถํ์ง ์๊ฒ). */\n effectiveStart?: string\n effectiveEnd?: string\n}\n\n/**\n * ํ๋ชฉ ์ ์ โ **ISA-95 `MaterialDefinition`.**\n *\n * ์์ผ๋ฉด ๋กํธ๋ง ๊ด์ธก์ผ๋ก ๋ค์ด์ค๊ณ **ํ๋ชฉ์ด ๋ฌด์์ธ์ง๋ ์๋ฌด ๋ฐ๋ ์๋ค.** ๊ทธ๋์ ๊ฐ์ ๋กํธ๋ฅผ 100๊ฐ๋ก\n * ๋ฐ์๋ \"๋ช kg ์ธ๊ฐ\" ์ ๋ตํ ์ ์๋ค(์ปค๋ `quantityIn` ์ด ํ์ฐ์ ๊ฑฐ๋ถํ๋ ๊ทผ๊ฑฐ).\n *\n * **ํ์ค์ ๋จ์ ํ์ฐ ์์๋ ์๋ค**(1์ฐจ ์ถ์ฒ ์ ์ ํ์ธ) โ ์์ฑ ์ฃผ๋จธ๋๋ฟ์ด๋ค. ๊ทธ๋์ ํ์ฐ ๊ณ์๋\n * ์ปค๋์ด ์ ํ ์์ฑ ์ด๋ฆ(`perBaseUnit`, `uom` ์ด ๋์ ๋จ์)์ผ๋ก `properties` ์ ์ฃ๋๋ค.\n */\nexport interface RefMaterialDefinition {\n /** ํ์ค `ID` โ GTIN(`urn:epc:idpat:sgtin:โฆ`)์ ์ด๋ค(์ ์ฒด์ฑ์ ์ ๋ณธ์ด EPCIS ๋ค). */\n id: string\n name?: string\n /** ์ํ ๋ฑ๊ธ๋ค โ ํ์ค `MaterialClassID`(๋ณต์). */\n materialClassIds?: string[]\n /** ํ๋ชฉ ์์ฑ โ ํ์ค `MaterialDefinitionProperty`. ํ์ฐ ๊ณ์๊ฐ ์ฌ๊ธฐ ๋ค์ด๊ฐ๋ค. */\n properties?: RefResourceProperty[]\n testSpecificationIds?: string[]\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport interface ReferenceMaster {\n source: string\n system: 'wms' | 'yms' | 'mes'\n siteName: string\n /* spaceId ๋ช
์ ์ ๊ทธ ๊ณต๊ฐ์ ์ฐธ์กฐ(์ฌ๋ฌ ํธ์์ด ํ ๊ณต๊ฐ ๊ณต์ , N:1). ์์ผ๋ฉด source ์์ ํ์(1:1). */\n /**\n * ํ์ฅ(๊ณต๊ฐ). **์๊ฐ ๊ธฐ์ค(`timezone`)์ด ์ฌ๊ธฐ ์๋ ์ด์ **: ํ ํ
๋ํธ๊ฐ Rosarito(ํํ์)์ ํ๊ตญ\n * ๊ณต์ฅ์ ํจ๊ป ๊ฐ์ง ์ ์๋ค. ํ
๋ํธ ๋จ์(`Domain.timezone`)๋ก ๋๋ฉด **๋ ์ค ํ๋๋ ๋ฐ๋์ ํ๋ฆฐ๋ค.**\n * ์๊ฐ ๊ธฐ์ค์ **๋ฌผ๋ฆฌ ํ์ฅ์ ์ฑ์ง**์ด๋ฏ๋ก ๊ณต๊ฐ์ด ๊ทธ๊ฒ์ ๊ฐ๋๋ค(๊ณต๊ฐ ์ค์ฌ ์์น).\n *\n * `timezone` ์ IANA ์ด๋ฆ(`'America/Tijuana'`) โ ์คํ์
์ซ์๊ฐ ์๋๋ค. ์ซ์๋ก ๋๋ฉด ์ผ๊ด์ ์ฝ์๊ฐ์\n * ํํํ ์ ์๊ณ , ๋์ค์ ์ ๋ ๊ตฌ๊ฐ์ผ๋ก ์ฎ๊ธธ ๋๋ ์ด๋ฆ์ด ์์ด์ผ ๊ณ์ฐํ ์ ์๋ค.\n */\n space: { spaceId?: string; width: number; depth: number; unit?: string; timezone?: string; geo?: { lat: number; lon: number; rotation?: number }; representations?: any[]; primaryId?: string }\n locations: RefLocation[]\n equipment?: RefEquipment[]\n /** ๊ณต์ ๋ช
์ธ(์์ยท๋ณ๋ยท์์จ) โ ์์ผ๋ฉด ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ตด๋ฌ๊ฐ๋ค(๊ทธ ์ฌ์ค์ specCoverage ๊ฐ ๋ณด๊ณ ). */\n operations?: RefOperation[]\n /**\n * **์์ฐ ์ ์**(๋ ์ํผยท๋ผ์ฐํธยท์์ฌ ๋ฐ์ธ๋ฉ) โ ์ปค๋์ ์ ์-๊ตฌ๋ MES ๋ชจ๋ ์
๊ตฌ.\n *\n * ์์ผ๋ฉด ์ปค๋์ ๋ ๊ฑฐ์(ํ๋์ฝ๋ฉ) ํ๋ฆ์ผ๋ก ๋๋ค. ์ฆ **ํ์ฅ ๋ ์ํผ๋ฅผ ์ ์ด๋ ์ด ์๋ฆฌ์ ์ค๋ฆฌ์ง ์์ผ๋ฉด\n * ์ปค๋์ ๊ทธ๊ฒ์ ๋ณด์ง ๋ชปํ๋ค** โ ์ ์ธ๊ณผ ์คํ์ด ๊ฐ๋ผ์ง๋ ์ง์ ์ด๋ผ ์๋ฆฌ๋ฅผ ์ฐ๋ค.\n */\n /**\n * ์์ฐ ์ ์ธ โ `BoardDef.productionSpec` ์ผ๋ก ํต๊ณผํ๋ค(ISA-95 OperationsSegment + BOM).\n *\n * ์์ ์ด๋ฆ์ `mesSpec` ์ด์๋ค. ๋ด๊ธด ๊ฒ์ MES ๋ง์ ๊ฒ์ด ์๋๋ผ \"์์ฌ๋ฅผ ์๋นํด ์์ฌ๋ฅผ ์ฐ์ถํ๋\n * ๊ณต์ \" ์ด๊ณ , ์ด๋ฆ์ด MES ์๊ธฐ ๋๋ฌธ์ ์ฐฝ๊ณ ํธ์์ ์ด ์๋ฆฌ๋ฅผ ์ธ ์๊ฐ์กฐ์ฐจ ํ์ง ๋ชปํ๋ค(์ ํต๊ฐ๊ณต ์ฐฝ๊ณ ๊ฐ\n * BOM ์ ์ค๋ช
๋ฌธ์์๋ง ์ ์ด ๋ ์ฑ ํคํธ๋ฅผ ๋ชป ๋ง๋๋ ํธ์์ ๋ง๋ ์์ธ). ๊ทผ๊ฑฐ๋ ์ปค๋ ๊ณ์ฝ ์ฃผ์์.\n */\n productionSpec?: unknown\n /**\n * ์ฌ๋ โ ์ ์ธํ์ง ์์ผ๋ฉด **์ธ์ ์ ์ฝ์ด ์๋ ํธ์**์ด ๋๋ค(์ค๋น๋ง ์์ผ๋ฉด ์ธ์ ๋ ๋์๊ฐ๋ ๊ณต์ฅ).\n * ๊ณต์ ์ด ์ธ์์ ์๊ตฌํ๋๋ฐ ์ฌ๋์ด ์์ผ๋ฉด ๊ทธ ์์
์ ์์๋์ง ์๋๋ค โ ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ฏ๋ก ๊ทธ๋๋ก ๋๋ค.\n */\n persons?: RefPerson[]\n /**\n * ๋ฌผ๋ฆฌ ์์ฐ(๋ฐ๋ณต์ฌ์ฉ) โ ์ ์ธํ์ง ์์ผ๋ฉด ์์ฐ ์ ์ฝ์ด ์๋ ํธ์์ด๋ค.\n * ๊ณต์ ์ด ์์ฐ์ ์๊ตฌํ๋๋ฐ ์์ผ๋ฉด ๊ทธ ์์
์ ์์๋์ง ์๋๋ค โ ๊ทธ๊ฒ์ด ์ฌ์ค์ด๋ฏ๋ก ๊ทธ๋๋ก ๋๋ค.\n */\n assets?: RefAsset[]\n /**\n * ๋ฑ๊ธ ์ ์ โ ํ์ค `PersonnelClass`ยท`EquipmentClass`ยท`PhysicalAssetClass`.\n * ์ ์ค์ด๋ ํธ์์ ๋๋ค(์์ ๋ฌธ์์ด ๊ทธ๋๋ก ํ์ ). ์ค์ผ๋ฉด ์์ยท์ ํจ๊ธฐ๊ฐ์ด ์ด์๋๋ค.\n */\n personnelClasses?: RefResourceClass[]\n equipmentClasses?: RefResourceClass[]\n assetClasses?: RefResourceClass[]\n /** ํ๋ชฉ ์ ์ยท๋ฑ๊ธ โ ํ์ค `MaterialDefinition` / `MaterialClass`. ์์ผ๋ฉด ๋จ์ ํ์ฐ์ ํ ์ ์๋ค. */\n materialDefinitions?: RefMaterialDefinition[]\n materialClasses?: RefResourceClass[]\n}\n\nexport interface IngestedTwin {\n board: any // BoardDef(+layout+spaceId) โ ์ปค๋ ์๋น\n spaceContent: any // TwinSpace content โ ๋ทฐ ์๋น\n warnings: IngestWarning[]\n}\n\n/**\n * ๋ง์คํฐ โ ํธ์ ๊ตฌ์กฐ ๋งคํ(์์). ๋
ธ๋ํ์
์ ์นดํ๋ก๊ทธ๋ก ๊ฒ์ฆ(๋ชจ๋ฅด๋ ํ์
์ warning, ๋ฒ๋ฆฌ์ง ์์ โ ๋ฐ์ ์ฐ์ ).\n * @param catalog DOMAIN_CATALOG (์ปค๋ SSOT). ์์ผ๋ฉด ๊ฒ์ฆ ์๋ต.\n */\n/**\n * IANA ์๊ฐ๋ ์ด๋ฆ โ **๊ทธ ์๊ฐ์** UTC ์คํ์
(๋ถ). ์์กด์ฑ ์์ด `Intl` ๋ก ํผ๋ค.\n *\n * `Intl.DateTimeFormat` ์ `longOffset` ์ `\"GMT-07:00\"` ์ฒ๋ผ ๋์ค๊ณ , ์ด๊ฒ์ **์ผ๊ด์ ์ฝ์๊ฐ์ ๋ฐ์ํ**\n * ๊ฐ์ด๋ค. ๊ทธ๋์ 8์์ `America/Tijuana` ๋ โ420(PDT), 1์์ โ480(PST)์ด ๋๋ค.\n *\n * **ํ๊ณ๋ฅผ ๋ฐํ๋ค**: ์ฌ๊ธฐ์ ๋์ค๋ ๊ฒ์ **ํ ์์ ์** ์คํ์
์ด๋ค. ์ปค๋์ ๊ณ ์ ์คํ์
์ผ๋ก ํ๋ฃจ ์ค ๋ถ์\n * ์ฝ์ผ๋ฏ๋ก, ๋ณด๋๋ฅผ ๋ง๋ ๊ณ์ ๊ณผ ๋ค๋ฅธ ๊ณ์ ์ ๊ธธ๊ฒ ์์ธกํ๋ฉด ํ ์๊ฐ ์ด๊ธ๋๋ค. ํ์ค์ ์ถฉ์คํ ๋ ๋ชจ์ต์\n * ํธ์คํธ๊ฐ ์ ๋ ๊ตฌ๊ฐ(`StartDateTime`/`FinishDateTime`)์ ๊ณ์ฐํด ๋ฃ๋ ๊ฒ์ด๊ณ , ๊ทธ๋ ์ด ํจ์๋ ์ฌ๋ผ์ง๋ค.\n *\n * ๋ชจ๋ฅด๋ ์ด๋ฆ์๋ **0 ์ ๋ตํ์ง ์๋๋ค**(`undefined`) โ 0 ์ \"UTC ๋ผ๊ณ ์ ์ธํ๋ค\" ๋ ๋ป์ด๊ณ , ๋ชจ๋ฅด๋ ๊ฒ์\n * ๊ทธ๋ ๊ฒ ๋ฐ๊พธ๋ฉด ํ์ ์ด ์กฐ์ฉํ ํ๋ฆฐ๋ค.\n */\nexport function utcOffsetOf(timezone?: string, at: Date = new Date()): number | undefined {\n if (!timezone) return undefined\n try {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, timeZoneName: 'longOffset' }).formatToParts(at)\n const name = parts.find(p => p.type === 'timeZoneName')?.value ?? ''\n if (name === 'GMT') return 0 // UTC ๊ณ์ด์ ์คํ์
ํ๊ธฐ๊ฐ ์๋ค\n const m = /^GMT([+-])(\\d{1,2})(?::(\\d{2}))?$/.exec(name)\n if (!m) return undefined\n const sign = m[1] === '-' ? -1 : 1\n return sign * (Number(m[2]) * 60 + Number(m[3] ?? 0))\n } catch {\n return undefined // ์ ์ ์๋ ์ด๋ฆ โ Intl ์ด ๋์ง๋ค\n }\n}\n\n\n/* โโ ์ธ์ ์คํธ ๊ฒฝ๊ณ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ธ์ ์คํธ๋ ๊ตฌ์กฐ์ ๋ฌธ์ ๊ฐ ์์ด๋ ํธ์์ ๋ง๋ค์ด ์ค๋ค(๋ง์ง ์๋ ๊ฒ์ด ์ณ๋ค โ ๋ถ๋ถ์ ์ผ๋ก๋ผ๋ ์ธ์ฐ๊ณ \n * ๊ณ ์ณ ๋๊ฐ๋ ๊ฒ์ด ์ด ์์คํ
์ ๋ฐฉ์์ด๋ค). ๊ทธ๋์ **๊ฒฝ๊ณ ๊ฐ ์ ์ผํ ์ ํธ**์ธ๋ฐ, ๊ทธ ๊ฒฝ๊ณ ๋ฅผ ํ๋ฉด์ด ํ๋๋\n * ๋ณด์ฌ์ฃผ์ง ์๊ณ ์์๋ค: ์ ํต๊ฐ๊ณต ์ฐฝ๊ณ ํ
ํ๋ฆฟ์ ์ปค๋์ด ๋ชจ๋ฅด๋ ์๋ฆฌ ํ์
(`vas-station`)์ผ๋ก ํธ์์\n * ๋ง๋ค๋ฉด์ ๊ฒฝ๊ณ ๋ฅผ ๋์ง๋ง, ์์๋๋ ๊ทธ๊ฒ์ ๋ฒ๋ ธ๊ณ ์ฌ์ฉ์๋ ์๋ฌด ๋ง ์์ด ๋งํ๋ ํธ์์ ๋ฐ์๋ค.\n *\n * ๋ฌธ์ฅ์ด ์๋๋ผ ์ฝ๋๋ก ์ค์ด ๋ณด๋ธ๋ค. ์์ ๊ฒฝ๊ณ ๋ ํ๋ก์ฆ์๊ณ ๊ทธ์ค ํ๋์๋ ํ๊ธ์ด ์์ฌ ์์๋ค\n * (`โ ์นดํ๋ก๊ทธ์ ์์`) โ ๋ค์ฏ ์ธ์ด ํ๋ฉด์ ๊ทธ๋๋ก ๋ด๋ณด๋ด๋ฉด ์ด๋ฒ์ ๊ฑท์ด๋ธ ๋ฌธ์ ๋ฅผ ๋ค์ ๋ง๋ ๋ค.\n * ์ด ํ๋ก์ ํธ๊ฐ ์ด๋ฏธ ์ฐ๋ ๊ท์ฝ๊ณผ ๊ฐ์ ๋ชจ์์ด๋ค: ์ฃผ์ ์ ํธ(kind+params)ยท์ปค๋งจ๋ ๊ฑฐ์ (errorCode+params)ยท\n * ๋ง๋งํจ ํ์ (code+์์ด canonical message).\n *\n * code ์ธ์ด ์ค๋ฆฝ โ ํ๋ฉด์ด `twin.ingest.<code>` ๋ก ์ฌ๋ ๋ง์ ๋ง๋ ๋ค\n * params ๋ฌธ์ฅ์ ๋ผ์ธ ๊ฐ โ ๋ฒ์ญ์ด ์ธ์ด๋ง๋ค ์ด์์ ๋ฐ๊ฟ ์ ์๊ฒ\n * message ์์ด canonical โ ๋ก๊ทธ์ ๋จ๊ณ , ๋ฒ์ญ์ด ์์ ๋ ๊ทธ๋๋ก ๋ณด์ธ๋ค(๋น์นธ๋ณด๋ค ๋ซ๋ค)\n *\n * **์ฌ๊ธฐ ์ฌ๋ ์ด์ **: ์ด ํ์ผ์ด ๊ฒฝ๊ณ ์ ์์ฐ์์ด๊ณ , ํ
์คํธ๊ฐ ์์ค์์ ์ง์ ์ฝ๋ ๋ชจ๋์ด๋ผ\n * ๋ฐํ์ ์๋ import ๋ฅผ ๊ฐ์ง ์ ์๋ค(์ด ์ ์ฅ์์ ๊ท์ฝ โ ๊ทธ๋ฐ ๋ชจ๋์ ์๊ธฐ์๊ฒฐ์ด๋ค).\n * โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */\n/** ์ธ์ ์คํธ๊ฐ ์๋ฆฌ๋ ํ ๊ฐ์ง. */\nexport interface IngestWarning {\n /** ์ธ์ด ์ค๋ฆฝ ์ฝ๋. ํ๋ฉด์ `twin.ingest.<code>` ๋ก ๋ ๋ํ๋ค. */\n code: string\n /** ๋ฌธ์ฅ์ ๋ผ์ธ ๊ฐ. ๋ฒ์ญ์ด ์ด์์ ๋ฐ๊ฟ ์ ์๊ฒ ์ด๋ฆ์ผ๋ก ๋๊ธด๋ค. */\n params?: Record<string, string | number>\n /** ์์ด canonical ๋ฌธ์ฅ โ ๋ก๊ทธยทํด๋ฐฑ์ฉ. ๋ฒ์ญ์ด ์์ด๋ ์ฝ์ ์ ์์ด์ผ ํ๋ค. */\n message: string\n}\n\n/** ์ปค๋ ์นดํ๋ก๊ทธ๊ฐ ๋ชจ๋ฅด๋ ์๋ฆฌ ํ์
โ ๊ทธ ์๋ฆฌ๋ ํ๋ฆ์ ์ฐธ์ฌํ์ง ๋ชปํ ์ ์๋ค. */\nexport const unknownLocationType = (system: string, type: string, id: string): IngestWarning => ({\n code: 'unknown-location-type',\n params: { system, type, id },\n message: `\"${type}\" is not a known ${system} location type (${id}) โ the kernel may not include this location in the flow`\n})\n\n/** ์๊ฐ๋ ๋ฌธ์์ด์ ๋ชป ์ฝ์๋ค โ ์๊ฐ ํด์์ด UTC ๋ก ๋จ์ด์ง๋ค(์กฐ์ฉํ ํ์ง ์๊ฐ์ผ๋ก ๊ฐ์ ํ์ง ์๋๋ค). */\nexport const unknownTimezone = (timezone: string): IngestWarning => ({\n code: 'unknown-timezone',\n params: { timezone },\n message: `space timezone \"${timezone}\" is not a known IANA zone โ the twin will read times as UTC`\n})\n\n/** ์์
์ ์์ ์์์๊ฐยทํ๋ผ๋ฏธํฐ๊ฐ ์๋ค โ ์ปค๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋๋ค. */\nexport const operationWithoutDuration = (operation: string): IngestWarning => ({\n code: 'operation-without-duration',\n params: { operation },\n message: `operation \"${operation}\" has no duration or parameters โ kernel defaults will be used`\n})\n\n/** ๋ณผ ์ ์๋ ํํ์ด ์๋ค โ ํ์ฅ์ด ํ๋ฉด์ ๋จ์ง ์๋๋ค. */\nexport const noViewableRepresentation = (): IngestWarning => ({\n code: 'no-viewable-representation',\n message: 'the space has no viewable representation (no representations and no geo) โ add one, or provide geo/board'\n})\n\n/** ํฉ์น๋ ๊ณต๊ฐ์ ๊ฐ์ id ์ ๋๋๋งํฌ๊ฐ ์ด๋ฏธ ์๋ค โ ์๋ก ๋ค๋ฅธ ๊ฒ์ด ํ๋๋ก ์ ํ์ ์ ์๋ค. */\nexport const landmarkIdsMerged = (spaceId: string, ids: readonly string[]): IngestWarning => ({\n code: 'landmark-ids-merged',\n params: { spaceId, ids: ids.join(', '), count: ids.length },\n message: `landmark ids already present in space \"${spaceId}\" โ merged: ${ids.join(', ')}`\n})\n\n/** ๋ก๊ทธ ํ ์ค โ ๊ฐ๋ฐ์๊ฐ ์ฝ๋ ๊ฒ์ด๋ฏ๋ก ์์ด canonical ๋ฌธ์ฅ์ ์ด๋ค. */\nexport const describeWarnings = (warnings: readonly IngestWarning[]): string =>\n warnings.map(w => `${w.code}: ${w.message}`).join(' | ')\n\n/**\n * ์๋ฒ๊ฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฑ์ด ๋
ธ๋ธ๋ค โ ์ฌ์ฉ์๊ฐ ์ค ์ ์๋ ๊ฐ์ผ๋ก ํธ์์ด ๋ง๋ค์ด์ก์์ ์๋ฆฐ๋ค.\n *\n * ์กฐ์ฉํ ์ฑ์ฐ๋ฉด ๋์ค์ \"์ ์ด ์์น์ธ๊ฐ\" ๋ฅผ ์๋ฌด๋ ๋ตํ ์ ์๋ค. ๋ง์ ์ผ์ ์๋๋ค(๊ธฐ๋ณธ๊ฐ์ ํ
ํ๋ฆฟ์ด\n * ํ์ ์ ๊ฐ๊ณ ์ ์ธํ ๊ฐ์ด๋ค) โ ๋ค๋ง ๋ฐํ๋ค.\n */\nexport const knobDefaultsFilled = (keys: readonly string[]): IngestWarning => ({\n code: 'knob-defaults-filled',\n params: { keys: keys.join(', '), count: keys.length },\n message: `values you did not provide were filled from the template defaults: ${keys.join(', ')}`\n})\n\nexport function masterToTwin(master: ReferenceMaster, catalog?: any): IngestedTwin {\n const warnings: IngestWarning[] = []\n const known: string[] = catalog?.[master.system]?.locationTypes ?? []\n\n const locationEntries = master.locations.filter(l => l.role === 'location' || l.role === 'both')\n const areaLocs = master.locations.filter(l => l.role === 'area' || l.role === 'both')\n\n const locations = locationEntries.map(l => {\n if (known.length && !known.includes(l.type)) warnings.push(unknownLocationType(master.system, l.type, l.id))\n // gs1Id(์ ์ ์ ์ฒด์ฑ)๋ฅผ ๋ณด๋ ๋
ธ๋๋ก ํต๊ณผ โ ๊ฒฐํฉ(tag)/์ถ์ ์ด GS1 ๋ก(ยงJ). ๋ก์ปฌ id ๋ ๊ทธ๋๋ก ์ ์ง(name/xref).\n return { id: l.id, type: l.type, capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), parentId: l.parentId, gs1Id: l.gs1Id }\n })\n\n const equipment = (master.equipment ?? []).map(e => ({\n id: e.id, kind: e.kind, homeLocation: e.homeLocationId, mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, gs1Id: e.gs1Id,\n ...(e.window ? { window: e.window } : {}),\n /* ์์ฑ์ ์๋์ง ์๊ณ ํต๊ณผ โ ์ด๋์๊ฐ ์ถ์ ๊ธฐ๊ฐ kind ๋ณ ์๋๋ฅผ ์ฌ๊ธฐ์ ์ฝ๋๋ค(๋จ์ ์ฝ๋ ๊ทธ๋๋ก). */\n ...(e.properties?.length ? { properties: e.properties } : {}), ...(e.workCalendar?.length ? { workCalendar: e.workCalendar } : {}), ...(e.testSpecificationIds?.length ? { testSpecificationIds: e.testSpecificationIds } : {}),\n /* ์ ํจ ๊ธฐ๊ฐ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ํ์ ์ ์ปค๋์ด ์๊ธฐ ์๊ณ๋ก ํ๋ค(ํธ์คํธ๊ฐ ๋ฏธ๋ฆฌ ์๋ฅด์ง ์๋๋ค). */\n ...(e.effectiveStart ? { effectiveStart: e.effectiveStart } : {}), ...(e.effectiveEnd ? { effectiveEnd: e.effectiveEnd } : {})\n }))\n\n // ์ขํ(layout) โ footprint ์ค์ฌ. ์์ผ๋ฉด ์๋ต(coordinate-free ์ ์ง).\n const layout: Record<string, { x: number; y: number }> = {}\n for (const l of locationEntries) if (l.footprint) layout[l.id] = { x: l.footprint.x + l.footprint.w / 2, y: l.footprint.y + l.footprint.h / 2 }\n\n const spaceId = master.space.spaceId ?? `${master.source}-site`\n /*\n * ์๊ฐ ๊ธฐ์ค์ ์ปค๋์ด ์ฝ์ ํํ๋ก ํผ๋ค โ ์ปค๋์ zero-dep ์ด๋ผ ์๊ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ค์ด์ง ์๊ณ \n * **๋ถ ์คํ์
**๋ง ๋ฐ๋๋ค(๊ณ์ฝ `BoardDef.utcOffsetMinutes`). ํธ๋ ์ผ์ ํธ์คํธ์ ๋ชซ์ด๋ค.\n *\n * ์ ์ธ์ด ์์ผ๋ฉด **ํ๋๋ฅผ ๋ง๋ค์ง ์๋๋ค** โ ๊ทธ๋ฌ๋ฉด ์ปค๋์ด UTC ๋ก ์ฝ๊ณ , ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ๊ณ์ฝ์ ๋ฐํ์ ธ ์๋ค.\n * ์ฌ๊ธฐ์ 0 ์ ๋ฃ์ผ๋ฉด \"UTC ๋ผ๊ณ ์ ์ธํ๋ค\" ์ \"์ ์ธํ์ง ์์๋ค\" ๊ฐ ๊ตฌ๋ณ๋์ง ์๋๋ค.\n */\n const utcOffsetMinutes = utcOffsetOf(master.space.timezone)\n if (master.space.timezone && utcOffsetMinutes === undefined) {\n warnings.push(unknownTimezone(String(master.space.timezone)))\n }\n /*\n * ์คํผ๋ ์ด์
๋ช
์ธ๋ฅผ board ์ ํต๊ณผ์ํจ๋ค โ ์ปค๋์ด `loadOperations` ๋ก ์๋นํ๋ค(BoardDef ํ์ฅ ํ๋,\n * ๋ชจ๋ฅด๋ ์ปค๋์ ๋ฌด์). ์ฌ๊ธฐ์ ๊ฐ์ ์๋์ง ์๋๋ค: ๊ธฐ๊ฐ์ ํ์ค ํ๊ธฐ(ISO 8601)๋ก ์ปค๋๊น์ง ๊ทธ๋๋ก ๊ฐ๋ค.\n */\n const operations = master.operations\n if (operations?.length) {\n for (const o of operations) {\n if (!o.duration && !o.parameters?.length) warnings.push(operationWithoutDuration(o.key))\n }\n }\n /* ์ฌ๋๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๋ฑ๊ธยท๊ต๋ ๊ทธ๋๋ก ์ปค๋๊น์ง ๊ฐ๋ค(๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค). */\n const persons = master.persons?.map(p => ({ id: p.id, personnelClassIds: p.personnelClassIds, ...(p.window ? { window: p.window } : {}), ...(p.workCalendar?.length ? { workCalendar: p.workCalendar } : {}), ...(p.homeLocationId ? { homeLocation: p.homeLocationId } : {}), ...(p.properties?.length ? { properties: p.properties } : {}), ...(p.testSpecificationIds?.length ? { testSpecificationIds: p.testSpecificationIds } : {}), ...(p.effectiveStart ? { effectiveStart: p.effectiveStart } : {}), ...(p.effectiveEnd ? { effectiveEnd: p.effectiveEnd } : {}) }))\n /* ์์ฐ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๋ฑ๊ธยท์๋ฆฌ ๊ทธ๋๋ก ์ปค๋๊น์ง. */\n const assets = master.assets?.map(a => ({ id: a.id, assetClassIds: a.assetClassIds, homeLocation: a.homeLocationId, gs1Id: a.gs1Id, ...(a.properties?.length ? { properties: a.properties } : {}), ...(a.testSpecificationIds?.length ? { testSpecificationIds: a.testSpecificationIds } : {}), ...(a.effectiveStart ? { effectiveStart: a.effectiveStart } : {}), ...(a.effectiveEnd ? { effectiveEnd: a.effectiveEnd } : {}) }))\n /* ํ๋ชฉ ์ ์ยท๋ฑ๊ธ๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค(ํ์ฐ ๊ณ์๋ ์ปค๋์ด ์ฝ๋๋ค). */\n const materialDefinitions = master.materialDefinitions?.map(d => ({\n id: d.id,\n ...(d.name ? { description: d.name } : {}),\n ...(d.materialClassIds?.length ? { materialClassIds: d.materialClassIds } : {}),\n ...(d.properties?.length ? { properties: d.properties } : {}),\n ...(d.testSpecificationIds?.length ? { testSpecificationIds: d.testSpecificationIds } : {}),\n ...(d.effectiveStart ? { effectiveStart: d.effectiveStart } : {}),\n ...(d.effectiveEnd ? { effectiveEnd: d.effectiveEnd } : {})\n }))\n const board = {\n locations, equipment, layout, spaceId,\n /* ์์ฐ ์ ์๋ ์๋์ง ์๊ณ ํต๊ณผ โ ๊ฒฝ๊ณ์์ ์ดํ๋ฅผ ๊ฐ์ง ์๋๋ค(์ปค๋์ด ๊ทธ๋๋ก ์๋นํ๋ค). */\n ...(master.productionSpec ? { productionSpec: master.productionSpec } : {}),\n ...(materialDefinitions?.length ? { materialDefinitions } : {}),\n ...(master.materialClasses?.length ? { materialClasses: master.materialClasses } : {}),\n ...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),\n ...(operations?.length ? { operations } : {}),\n ...(master.personnelClasses?.length ? { personnelClasses: master.personnelClasses } : {}),\n ...(master.equipmentClasses?.length ? { equipmentClasses: master.equipmentClasses } : {}),\n ...(master.assetClasses?.length ? { assetClasses: master.assetClasses } : {}),\n ...(persons?.length ? { persons } : {}),\n ...(assets?.length ? { assets } : {})\n }\n\n const areas = areaLocs.map(l => ({\n id: l.id, type: l.type, name: l.name ?? l.id, parentId: l.parentId,\n x: l.footprint?.x ?? 0, y: l.footprint?.y ?? 0, w: l.footprint?.w ?? 10, h: l.footprint?.h ?? 10\n }))\n // ์ธ์ ์คํธ ํ์ฅ ๋ฌผ์งํ(space facet #4) โ ํํ์ด ์๊ณ geo ๊ฐ ์์ผ๋ฉด ๊ธฐ๋ณธ map ํํ ํฉ์ฑ.\n // \"์ธ์ ์คํธํ๋ฉด ์์๋ณผ ํ์ฅ(๋ด place)์ด ๋ฌ๋ค\"๋ ๊ณต๊ฐ ์ค์ฌ ์ ์ ๋ณด์ฅ(zero-to-twin): ์ปค๋ฅํฐ/ํ
ํ๋ฆฟ์ด\n // ํํ์ ์ ์ค๋ geo ๋ง ์์ผ๋ฉด ์์ฑ ์ง๋๋ก ์ฐฉ์ง. (area ํด๋ฆฌ๊ณค ๋ฌผ์งํ๋ ์ขํ ํฌ์ ํ์ โ space #3.)\n const geo = master.space.geo\n const givenReps = master.space.representations ?? []\n const representations =\n givenReps.length > 0\n ? givenReps\n : geo\n ? [{ id: 'r-map', type: 'map', name: '์์ฑ ์ง๋', primary: true, center: { lat: geo.lat, lon: geo.lon }, zoom: 17 }]\n : []\n if (representations.length === 0) {\n warnings.push(noViewableRepresentation())\n }\n const spaceContent = {\n width: master.space.width, depth: master.space.depth, unit: master.space.unit ?? 'm',\n geo, representations, primaryId: master.space.primaryId ?? representations[0]?.id,\n areas, landmarks: []\n }\n\n return { board, spaceContent, warnings }\n}\n"]}
|
|
@@ -6,7 +6,7 @@ export declare class TwinReferenceResolver {
|
|
|
6
6
|
/** ๋ฑ๋ก๋ ํธ์ ํ
ํ๋ฆฟ(ํ๋ผ๋ฏธํฐํ ์ํคํ์
) ๋ชฉ๋ก โ ๋
ธ๋ธ ์คํค๋ง ํฌํจ(ํด๋ผ์ด์ธํธ ํผ์ฉ). */
|
|
7
7
|
twinTemplates(_context: ResolverContext): Promise<any[]>;
|
|
8
8
|
/** ํ
ํ๋ฆฟ + ๋
ธ๋ธ โ ํฉ์ฑ ๋ง์คํฐ โ ์ธ์ ์คํธ(+๊ธฐ๋+์๋๋ฆฌ์ค). ๋ ํผ๋ฐ์ค import ์ ๊ฐ์ ๊ฒฝ๋ก, ์์ฒ๋ง ํฉ์ฑ. */
|
|
9
|
-
createFromTemplate(templateId: string, params: any, context: ResolverContext, start?: boolean): Promise<any>;
|
|
9
|
+
createFromTemplate(templateId: string, params: any, context: ResolverContext, start?: boolean, spaceId?: string): Promise<any>;
|
|
10
10
|
twinReferences(context: ResolverContext): Promise<any[]>;
|
|
11
11
|
referenceAdapterTypes(): string[];
|
|
12
12
|
/**
|
|
@@ -29,7 +29,7 @@ export declare class TwinReferenceResolver {
|
|
|
29
29
|
* P1 ์ ๋๊ฐ N=1(virtual/๋จ์ผ). start ๋ฉด ๊ฐ ์ธ์คํด์ค ๊ธฐ๋. ๋ผ์ด๋ธ ํผ๋ยทmode ๋ face2-inbound-live ์์ .
|
|
30
30
|
*/
|
|
31
31
|
/** ๋ ํผ๋ฐ์ค๊ฐ ๋
ธ์ถํ๋ ์ฌ์ดํธ/๊ณต์ฅ ๋ฐ๊ฒฌ โ ํธ์ ์์ฑ ์ "์ด๋ ๊ณต์ฅ" ์ ํ์ฉ(ยง2.2). */
|
|
32
|
-
discoverReferenceSites(source: string, context: ResolverContext): Promise<any
|
|
32
|
+
discoverReferenceSites(source: string, context: ResolverContext): Promise<any>;
|
|
33
33
|
/**
|
|
34
34
|
* ํธ์ ์์ฑ โ ๋ ํผ๋ฐ์ค์์ ์ฌ์ดํธ ๋ฐ๊ฒฌ โ (siteIds ์์ผ๋ฉด ๊ทธ ๊ณต์ฅ๋ง) โ fetchMaster โ provision. ์ฌ์ดํธ๋ณ resilient.
|
|
35
35
|
* ์ฌ๋ฌ ๊ณต์ฅ์ ๊ดํ ํ๋ ์์ค๋ siteIds ๋ก "์ด๋ ๊ณต์ฅ"์ ๊ณจ๋ผ ์์ฑ(1:N, ยง2.1ยทยง2.2).
|