@things-factory/headless-twin 10.0.19 โ†’ 10.1.0

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.
Files changed (327) hide show
  1. package/dist-server/engine/canonical-ingest.d.ts +10 -1
  2. package/dist-server/engine/canonical-ingest.js +110 -33
  3. package/dist-server/engine/canonical-ingest.js.map +1 -1
  4. package/dist-server/engine/event-time.d.ts +25 -0
  5. package/dist-server/engine/event-time.js +98 -0
  6. package/dist-server/engine/event-time.js.map +1 -0
  7. package/dist-server/engine/index.d.ts +2 -0
  8. package/dist-server/engine/index.js +23 -0
  9. package/dist-server/engine/index.js.map +1 -1
  10. package/dist-server/engine/ingest-dedupe.d.ts +18 -6
  11. package/dist-server/engine/ingest-dedupe.js +201 -15
  12. package/dist-server/engine/ingest-dedupe.js.map +1 -1
  13. package/dist-server/engine/ingest-health.d.ts +60 -1
  14. package/dist-server/engine/ingest-health.js +43 -8
  15. package/dist-server/engine/ingest-health.js.map +1 -1
  16. package/dist-server/engine/kpi-fold.d.ts +19 -0
  17. package/dist-server/engine/kpi-fold.js +4 -1
  18. package/dist-server/engine/kpi-fold.js.map +1 -1
  19. package/dist-server/engine/kpi-query.js +23 -3
  20. package/dist-server/engine/kpi-query.js.map +1 -1
  21. package/dist-server/engine/oee-accumulator.d.ts +35 -2
  22. package/dist-server/engine/oee-accumulator.js +56 -4
  23. package/dist-server/engine/oee-accumulator.js.map +1 -1
  24. package/dist-server/engine/twin-engine.d.ts +72 -3
  25. package/dist-server/engine/twin-engine.js +118 -5
  26. package/dist-server/engine/twin-engine.js.map +1 -1
  27. package/dist-server/index.js +21 -0
  28. package/dist-server/index.js.map +1 -1
  29. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.d.ts +5 -0
  30. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js +66 -0
  31. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js.map +1 -0
  32. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.d.ts +5 -0
  33. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js +79 -0
  34. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js.map +1 -0
  35. package/dist-server/migrations/index.js +5 -1
  36. package/dist-server/migrations/index.js.map +1 -1
  37. package/dist-server/routes.js +12 -20
  38. package/dist-server/routes.js.map +1 -1
  39. package/dist-server/service/actuation/actuation-advisor.d.ts +60 -0
  40. package/dist-server/service/actuation/actuation-advisor.js +53 -0
  41. package/dist-server/service/actuation/actuation-advisor.js.map +1 -0
  42. package/dist-server/service/actuation/actuation-outcome.d.ts +52 -0
  43. package/dist-server/service/actuation/actuation-outcome.js +34 -0
  44. package/dist-server/service/actuation/actuation-outcome.js.map +1 -0
  45. package/dist-server/service/actuation/actuation-rule-resolver.d.ts +19 -0
  46. package/dist-server/service/actuation/actuation-rule-resolver.js +161 -0
  47. package/dist-server/service/actuation/actuation-rule-resolver.js.map +1 -0
  48. package/dist-server/service/actuation/actuation-rule.d.ts +55 -0
  49. package/dist-server/service/actuation/actuation-rule.js +130 -0
  50. package/dist-server/service/actuation/actuation-rule.js.map +1 -0
  51. package/dist-server/service/actuation/approval-gateway.d.ts +20 -0
  52. package/dist-server/service/actuation/approval-gateway.js +14 -0
  53. package/dist-server/service/actuation/approval-gateway.js.map +1 -0
  54. package/dist-server/service/actuation/catch-up-effects.d.ts +16 -0
  55. package/dist-server/service/actuation/catch-up-effects.js +120 -0
  56. package/dist-server/service/actuation/catch-up-effects.js.map +1 -0
  57. package/dist-server/service/actuation/command-dispatcher.d.ts +206 -8
  58. package/dist-server/service/actuation/command-dispatcher.js +191 -14
  59. package/dist-server/service/actuation/command-dispatcher.js.map +1 -1
  60. package/dist-server/service/actuation/command-store.d.ts +10 -2
  61. package/dist-server/service/actuation/command-store.js +168 -5
  62. package/dist-server/service/actuation/command-store.js.map +1 -1
  63. package/dist-server/service/actuation/dispatch-after-approval.d.ts +11 -0
  64. package/dist-server/service/actuation/dispatch-after-approval.js +73 -0
  65. package/dist-server/service/actuation/dispatch-after-approval.js.map +1 -0
  66. package/dist-server/service/actuation/effect-match.d.ts +53 -0
  67. package/dist-server/service/actuation/effect-match.js +65 -0
  68. package/dist-server/service/actuation/effect-match.js.map +1 -0
  69. package/dist-server/service/actuation/index.d.ts +21 -2
  70. package/dist-server/service/actuation/index.js +21 -2
  71. package/dist-server/service/actuation/index.js.map +1 -1
  72. package/dist-server/service/actuation/retry-plan.d.ts +63 -0
  73. package/dist-server/service/actuation/retry-plan.js +99 -0
  74. package/dist-server/service/actuation/retry-plan.js.map +1 -0
  75. package/dist-server/service/actuation/rule-evaluate.d.ts +127 -0
  76. package/dist-server/service/actuation/rule-evaluate.js +205 -0
  77. package/dist-server/service/actuation/rule-evaluate.js.map +1 -0
  78. package/dist-server/service/actuation/rule-loop.d.ts +5 -0
  79. package/dist-server/service/actuation/rule-loop.js +156 -0
  80. package/dist-server/service/actuation/rule-loop.js.map +1 -0
  81. package/dist-server/service/actuation/rule-runner.d.ts +52 -0
  82. package/dist-server/service/actuation/rule-runner.js +135 -0
  83. package/dist-server/service/actuation/rule-runner.js.map +1 -0
  84. package/dist-server/service/actuation/rule-wiring.d.ts +24 -0
  85. package/dist-server/service/actuation/rule-wiring.js +80 -0
  86. package/dist-server/service/actuation/rule-wiring.js.map +1 -0
  87. package/dist-server/service/actuation/settle-effects.d.ts +21 -0
  88. package/dist-server/service/actuation/settle-effects.js +101 -0
  89. package/dist-server/service/actuation/settle-effects.js.map +1 -0
  90. package/dist-server/service/actuation/sweep-dispatch.d.ts +37 -0
  91. package/dist-server/service/actuation/sweep-dispatch.js +125 -0
  92. package/dist-server/service/actuation/sweep-dispatch.js.map +1 -0
  93. package/dist-server/service/actuation/twin-command-resolver.d.ts +120 -0
  94. package/dist-server/service/actuation/twin-command-resolver.js +406 -0
  95. package/dist-server/service/actuation/twin-command-resolver.js.map +1 -0
  96. package/dist-server/service/actuation/twin-command.d.ts +81 -0
  97. package/dist-server/service/actuation/twin-command.js +60 -0
  98. package/dist-server/service/actuation/twin-command.js.map +1 -1
  99. package/dist-server/service/actuation/twin-now.d.ts +41 -0
  100. package/dist-server/service/actuation/twin-now.js +65 -0
  101. package/dist-server/service/actuation/twin-now.js.map +1 -0
  102. package/dist-server/service/index.d.ts +5 -2
  103. package/dist-server/service/index.js +8 -0
  104. package/dist-server/service/index.js.map +1 -1
  105. package/dist-server/service/reference/actuation-routing.d.ts +60 -0
  106. package/dist-server/service/reference/actuation-routing.js +126 -0
  107. package/dist-server/service/reference/actuation-routing.js.map +1 -0
  108. package/dist-server/service/reference/actuation-target.d.ts +65 -0
  109. package/dist-server/service/reference/actuation-target.js +94 -0
  110. package/dist-server/service/reference/actuation-target.js.map +1 -0
  111. package/dist-server/service/reference/connection-portability-resolver.d.ts +29 -0
  112. package/dist-server/service/reference/connection-portability-resolver.js +181 -0
  113. package/dist-server/service/reference/connection-portability-resolver.js.map +1 -0
  114. package/dist-server/service/reference/connection-portability.d.ts +138 -0
  115. package/dist-server/service/reference/connection-portability.js +230 -0
  116. package/dist-server/service/reference/connection-portability.js.map +1 -0
  117. package/dist-server/service/reference/fill-cadence.d.ts +17 -0
  118. package/dist-server/service/reference/fill-cadence.js +31 -0
  119. package/dist-server/service/reference/fill-cadence.js.map +1 -0
  120. package/dist-server/service/reference/fill-dedupe.d.ts +16 -0
  121. package/dist-server/service/reference/fill-dedupe.js +63 -0
  122. package/dist-server/service/reference/fill-dedupe.js.map +1 -0
  123. package/dist-server/service/reference/fill-loop.d.ts +35 -0
  124. package/dist-server/service/reference/fill-loop.js +187 -0
  125. package/dist-server/service/reference/fill-loop.js.map +1 -0
  126. package/dist-server/service/reference/fill-span.d.ts +10 -0
  127. package/dist-server/service/reference/fill-span.js +37 -0
  128. package/dist-server/service/reference/fill-span.js.map +1 -0
  129. package/dist-server/service/reference/hook-contract.d.ts +88 -4
  130. package/dist-server/service/reference/hook-contract.js +105 -4
  131. package/dist-server/service/reference/hook-contract.js.map +1 -1
  132. package/dist-server/service/reference/hook-rejected.d.ts +25 -0
  133. package/dist-server/service/reference/hook-rejected.js +48 -0
  134. package/dist-server/service/reference/hook-rejected.js.map +1 -0
  135. package/dist-server/service/reference/index.d.ts +4 -1
  136. package/dist-server/service/reference/index.js +5 -1
  137. package/dist-server/service/reference/index.js.map +1 -1
  138. package/dist-server/service/reference/live-cadence.d.ts +68 -0
  139. package/dist-server/service/reference/live-cadence.js +44 -0
  140. package/dist-server/service/reference/live-cadence.js.map +1 -0
  141. package/dist-server/service/reference/live-feed-lease.d.ts +15 -0
  142. package/dist-server/service/reference/live-feed-lease.js +56 -0
  143. package/dist-server/service/reference/live-feed-lease.js.map +1 -0
  144. package/dist-server/service/reference/live-ingest.d.ts +21 -0
  145. package/dist-server/service/reference/live-ingest.js +66 -0
  146. package/dist-server/service/reference/live-ingest.js.map +1 -0
  147. package/dist-server/service/reference/reference-adapter.d.ts +291 -2
  148. package/dist-server/service/reference/reference-adapter.js +19 -1
  149. package/dist-server/service/reference/reference-adapter.js.map +1 -1
  150. package/dist-server/service/reference/reference-fill-run.d.ts +50 -0
  151. package/dist-server/service/reference/reference-fill-run.js +142 -0
  152. package/dist-server/service/reference/reference-fill-run.js.map +1 -0
  153. package/dist-server/service/reference/reference-fill.d.ts +90 -0
  154. package/dist-server/service/reference/reference-fill.js +141 -0
  155. package/dist-server/service/reference/reference-fill.js.map +1 -0
  156. package/dist-server/service/reference/reference-hook.d.ts +22 -0
  157. package/dist-server/service/reference/reference-hook.js +135 -55
  158. package/dist-server/service/reference/reference-hook.js.map +1 -1
  159. package/dist-server/service/reference/reference-link-groups.d.ts +10 -0
  160. package/dist-server/service/reference/reference-link-groups.js +15 -0
  161. package/dist-server/service/reference/reference-link-groups.js.map +1 -0
  162. package/dist-server/service/reference/reference-links.d.ts +14 -0
  163. package/dist-server/service/reference/reference-links.js +73 -0
  164. package/dist-server/service/reference/reference-links.js.map +1 -0
  165. package/dist-server/service/reference/reference-live.d.ts +1 -0
  166. package/dist-server/service/reference/reference-live.js +32 -6
  167. package/dist-server/service/reference/reference-live.js.map +1 -1
  168. package/dist-server/service/reference/reference-master.d.ts +56 -2
  169. package/dist-server/service/reference/reference-master.js +33 -3
  170. package/dist-server/service/reference/reference-master.js.map +1 -1
  171. package/dist-server/service/reference/reference-resolver.d.ts +27 -0
  172. package/dist-server/service/reference/reference-resolver.js +79 -1
  173. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  174. package/dist-server/service/twin-event/twin-event-keys.d.ts +31 -3
  175. package/dist-server/service/twin-event/twin-event-keys.js +36 -4
  176. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  177. package/dist-server/service/twin-event/twin-event.d.ts +1 -0
  178. package/dist-server/service/twin-event/twin-event.js +11 -2
  179. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  180. package/dist-server/service/twin-model/choose-recipe.d.ts +15 -0
  181. package/dist-server/service/twin-model/choose-recipe.js +33 -0
  182. package/dist-server/service/twin-model/choose-recipe.js.map +1 -0
  183. package/dist-server/service/twin-model/external-resolver.d.ts +76 -0
  184. package/dist-server/service/twin-model/external-resolver.js +109 -0
  185. package/dist-server/service/twin-model/external-resolver.js.map +1 -0
  186. package/dist-server/service/twin-model/project-structure.js +16 -3
  187. package/dist-server/service/twin-model/project-structure.js.map +1 -1
  188. package/dist-server/service/twin-model/twin-equipment.d.ts +17 -0
  189. package/dist-server/service/twin-model/twin-equipment.js +10 -0
  190. package/dist-server/service/twin-model/twin-equipment.js.map +1 -1
  191. package/dist-server/service/twin-model/twin-lineage-query.js +75 -1
  192. package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
  193. package/dist-server/service/twin-model/twin-model-item-query.js +94 -5
  194. package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
  195. package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
  196. package/dist-server/service/twin-space/twin-space.d.ts +29 -0
  197. package/dist-server/service/twin-space/twin-space.js +13 -0
  198. package/dist-server/service/twin-space/twin-space.js.map +1 -1
  199. package/dist-server/service/twin-subject/event-subjects.d.ts +3 -1
  200. package/dist-server/service/twin-subject/event-subjects.js +8 -1
  201. package/dist-server/service/twin-subject/event-subjects.js.map +1 -1
  202. package/dist-shared/entity-delta.js +1 -1
  203. package/dist-shared/entity-delta.js.map +1 -1
  204. package/package.json +7 -7
  205. package/server/engine/canonical-ingest.ts +119 -33
  206. package/server/engine/event-time.ts +96 -0
  207. package/server/engine/index.ts +20 -0
  208. package/server/engine/ingest-dedupe.ts +203 -27
  209. package/server/engine/ingest-health.ts +91 -6
  210. package/server/engine/kpi-fold.ts +24 -1
  211. package/server/engine/kpi-query.ts +23 -4
  212. package/server/engine/oee-accumulator.ts +80 -8
  213. package/server/engine/twin-engine.ts +119 -5
  214. package/server/index.ts +23 -0
  215. package/server/migrations/1786600000000-RenameOperatoMesAdapterType.ts +66 -0
  216. package/server/migrations/1786700000000-AddDispatchRetryColumns.ts +82 -0
  217. package/server/migrations/index.ts +5 -1
  218. package/server/routes.ts +12 -24
  219. package/server/service/actuation/actuation-advisor.ts +124 -0
  220. package/server/service/actuation/actuation-outcome.ts +97 -0
  221. package/server/service/actuation/actuation-rule-resolver.ts +147 -0
  222. package/server/service/actuation/actuation-rule.ts +139 -0
  223. package/server/service/actuation/approval-gateway.ts +44 -0
  224. package/server/service/actuation/catch-up-effects.ts +152 -0
  225. package/server/service/actuation/command-dispatcher.ts +401 -20
  226. package/server/service/actuation/command-store.ts +182 -8
  227. package/server/service/actuation/dispatch-after-approval.ts +71 -0
  228. package/server/service/actuation/effect-match.ts +124 -0
  229. package/server/service/actuation/index.ts +21 -2
  230. package/server/service/actuation/retry-plan.ts +145 -0
  231. package/server/service/actuation/rule-evaluate.ts +352 -0
  232. package/server/service/actuation/rule-loop.ts +160 -0
  233. package/server/service/actuation/rule-runner.ts +216 -0
  234. package/server/service/actuation/rule-wiring.ts +84 -0
  235. package/server/service/actuation/settle-effects.ts +115 -0
  236. package/server/service/actuation/sweep-dispatch.ts +179 -0
  237. package/server/service/actuation/twin-command-resolver.ts +387 -0
  238. package/server/service/actuation/twin-command.ts +128 -1
  239. package/server/service/actuation/twin-now.ts +97 -0
  240. package/server/service/index.ts +9 -1
  241. package/server/service/reference/actuation-routing.ts +165 -0
  242. package/server/service/reference/actuation-target.ts +163 -0
  243. package/server/service/reference/connection-portability-resolver.ts +171 -0
  244. package/server/service/reference/connection-portability.ts +285 -0
  245. package/server/service/reference/fill-cadence.ts +29 -0
  246. package/server/service/reference/fill-dedupe.ts +66 -0
  247. package/server/service/reference/fill-loop.ts +153 -0
  248. package/server/service/reference/fill-span.ts +31 -0
  249. package/server/service/reference/hook-contract.ts +185 -5
  250. package/server/service/reference/hook-rejected.ts +53 -0
  251. package/server/service/reference/index.ts +5 -1
  252. package/server/service/reference/live-cadence.ts +129 -0
  253. package/server/service/reference/live-feed-lease.ts +56 -0
  254. package/server/service/reference/live-ingest.ts +94 -0
  255. package/server/service/reference/reference-adapter.ts +327 -5
  256. package/server/service/reference/reference-fill-run.ts +165 -0
  257. package/server/service/reference/reference-fill.ts +223 -0
  258. package/server/service/reference/reference-hook.ts +162 -56
  259. package/server/service/reference/reference-link-groups.ts +21 -0
  260. package/server/service/reference/reference-links.ts +77 -0
  261. package/server/service/reference/reference-live.ts +30 -5
  262. package/server/service/reference/reference-master.ts +90 -5
  263. package/server/service/reference/reference-resolver.ts +77 -2
  264. package/server/service/twin-event/twin-event-keys.ts +37 -4
  265. package/server/service/twin-event/twin-event.ts +18 -1
  266. package/server/service/twin-model/choose-recipe.ts +31 -0
  267. package/server/service/twin-model/external-resolver.ts +161 -0
  268. package/server/service/twin-model/project-structure.ts +16 -3
  269. package/server/service/twin-model/twin-equipment.ts +22 -0
  270. package/server/service/twin-model/twin-lineage-query.ts +82 -1
  271. package/server/service/twin-model/twin-model-item-query.ts +95 -4
  272. package/server/service/twin-model/twin-model-tree-query.ts +1 -1
  273. package/server/service/twin-space/twin-space.ts +39 -0
  274. package/server/service/twin-subject/event-subjects.ts +8 -1
  275. package/shared/entity-delta.ts +1 -1
  276. package/test/ack-shape-alignment.test.ts +97 -0
  277. package/test/actuation-approval-door.test.ts +421 -0
  278. package/test/actuation-dispatch.test.ts +16 -3
  279. package/test/actuation-effect.test.ts +162 -0
  280. package/test/actuation-outcome.test.ts +152 -0
  281. package/test/actuation-rule-runner.test.ts +281 -0
  282. package/test/actuation-rule.test.ts +266 -0
  283. package/test/actuation-seam.test.ts +249 -0
  284. package/test/actuation-settle.test.ts +164 -0
  285. package/test/actuation-target.test.ts +145 -0
  286. package/test/canonical-ingest-vocabularies.test.ts +49 -2
  287. package/test/capability-mapping.test.ts +1 -1
  288. package/test/choose-recipe.test.ts +117 -0
  289. package/test/command-store-writes-columns.test.ts +126 -0
  290. package/test/connection-portability-doors.test.ts +87 -0
  291. package/test/connector-capability-declaration.test.ts +54 -4
  292. package/test/declaration-reaches-model.test.ts +43 -0
  293. package/test/dedupe-transformation.test.ts +112 -0
  294. package/test/entity-delta.test.ts +1 -1
  295. package/test/event-subjects.test.ts +2 -1
  296. package/test/external-resolver.test.ts +171 -0
  297. package/test/fill-dedupe.test.ts +59 -0
  298. package/test/fill-loop.test.ts +35 -0
  299. package/test/first-envelope.test.ts +153 -0
  300. package/test/fold-shift-dst.test.ts +110 -0
  301. package/test/home-in-area.test.ts +90 -0
  302. package/test/hook-rejected-shape.test.ts +86 -0
  303. package/test/hook-response-sum.test.ts +193 -0
  304. package/test/hook-sequence.test.ts +1 -1
  305. package/test/ingest-dedupe.test.ts +56 -0
  306. package/test/ingest-expected-quiet.test.ts +111 -0
  307. package/test/ingest-idempotent.test.ts +79 -0
  308. package/test/ingest-reconcile-four-ways.test.ts +97 -0
  309. package/test/ingest-rules-header.test.ts +100 -0
  310. package/test/ingest-window-rolls-unobserved.test.ts +72 -0
  311. package/test/intake-mapping-parity.test.ts +175 -0
  312. package/test/live-cadence.test.ts +170 -0
  313. package/test/live-feed-lease.test.ts +63 -0
  314. package/test/live-mirror-parity.test.ts +1 -1
  315. package/test/oee-accumulator.test.ts +3 -3
  316. package/test/oee-site-calendar.test.ts +146 -0
  317. package/test/order-and-transaction-split.test.ts +107 -0
  318. package/test/reference-fill.test.ts +235 -0
  319. package/test/reference-hook.test.ts +1 -1
  320. package/test/reference-links.test.ts +56 -0
  321. package/test/retry-plan.test.ts +139 -0
  322. package/test/sweep-dispatch.test.ts +191 -0
  323. package/test/twin-event-keys.test.ts +20 -6
  324. package/test/twin-model-item-db.test.ts +6 -6
  325. package/test/twin-model-tree-db.test.ts +6 -6
  326. package/tsconfig.shared.tsbuildinfo +1 -1
  327. package/tsconfig.tsbuildinfo +1 -1
@@ -131,6 +131,20 @@ export interface RefTestSpecification {
131
131
  export interface RefEquipment {
132
132
  id: string;
133
133
  kind: string;
134
+ /**
135
+ * ์†ํ•œ **๋“ฑ๊ธ‰๋“ค** โ€” ๊ณ„์•ฝ ์„ ์–ธ์˜ `equipment[].equipmentClassIds` ๋กœ ๊ทธ๋Œ€๋กœ ๊ฐ„๋‹ค.
136
+ *
137
+ * โ”€โ”€ ์™œ ๋น ์ ธ ์žˆ์—ˆ๋‚˜ (2026-09-04) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
138
+ * ์ปค๋„์— ์ด ์ถ•์„ ์—ฌ๋Š” ๋‚  ๋ชจ๋ธยท์ƒํƒœยท์ €๋„ยท๋ฏธ๋Ÿฌ๊นŒ์ง€ ๋ฐฐ์„ ํ–ˆ๋Š”๋ฐ **์ ‘์ˆ˜๋ฉด์ด ๋น ์กŒ๋‹ค.** ์‚ฌ๋žŒ๊ณผ ์ž์‚ฐ์€
139
+ * ๋ฐ›๋Š”๋ฐ(`personnelClassIds`ยท`assetClassIds`) ์„ค๋น„๋งŒ ์—†์—ˆ๋‹ค.
140
+ *
141
+ * ๊ทธ๋ž˜์„œ ์›๋ณธ์ด ์„ค๋น„ 22๋Œ€์— ๋“ฑ๊ธ‰์„ ๋‹ค ์ฑ„์›Œ ๋ณด๋ƒˆ๋Š”๋ฐ **๋ฌธํ„ฑ์—์„œ ๋ฒ„๋ ค์กŒ๋‹ค** โ€” ๊ฑฐ์ ˆ๋„ ๊ฒฝ๊ณ ๋„ ์—†์ด.
142
+ * ๋“ฑ๊ธ‰ ๋ชฉ๋ก์€ ์„œ๊ณ  ์†Œ์†์€ ์•„๋ฌด๋„ ์—†์–ด์„œ, ํ™”๋ฉด์—์„œ ๋“ฑ๊ธ‰์„ ๊ณจ๋ผ๋„ ์„ค๋น„๊ฐ€ ์•ˆ ๋‚˜์™”๋‹ค.
143
+ *
144
+ * ์†Œ์†์€ ์ด ์„ ์–ธ๊ณผ `kind` ๋ฅผ ํ•ฉ์นœ ๊ฒƒ์ด๋‹ค(ยง`equipmentClassMembership`) โ€” ํŒ์ •ํ•˜๋Š” ์ชฝ์ด ๊ทธ ํ•จ์ˆ˜๋ฅผ
145
+ * ์ง€๋‚œ๋‹ค.
146
+ */
147
+ equipmentClassIds?: string[];
134
148
  /** ์‚ฌ๋žŒ์ด ๋ถ€๋ฅด๋Š” ์ด๋ฆ„ โ€” ์—†์œผ๋ฉด ํ™”๋ฉด์ด id ๋ฅผ ๋ณด์ธ๋‹ค(id ๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋ฒ ๋ผ์ง€ ์•Š๋Š”๋‹ค). */
135
149
  name?: string;
136
150
  /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */
@@ -266,6 +280,33 @@ export interface RefPerson {
266
280
  name?: string;
267
281
  /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */
268
282
  testResults?: RefTestResult[];
283
+ /**
284
+ * **์ด ์‚ฌ๋žŒ์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์ปค๋„ ์„ ์–ธ์˜ `personnel[].identity` ๋กœ ๊ฐ„๋‹ค.
285
+ *
286
+ * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๋ ˆ์ธ์ด ๋ฌผ์Œ, 2026-09-05) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
287
+ * ์„ค๋น„์—์„œ ์ด ์ž๋ฆฌ๋ฅผ ๋งŒ๋“  ์ด์œ ๊ฐ€ ์‚ฌ๋žŒ์—๊ฒŒ๋„ ๊ทธ๋Œ€๋กœ ๊ฑธ๋ฆฐ๋‹ค: **์ง€์—ญ ์ด๋ฆ„์€ ๊ทธ ํ˜„์žฅ ์•ˆ์—์„œ๋งŒ
288
+ * ๊ณ ์œ ํ•˜๋‹ค.** ์ธ๋ฒ„ํ„ฐ `001` ์ด ๋‘ ๋ฐœ์ „์†Œ์— ์žˆ์–ด์„œ ํ•จ๊ป˜ ์ง‘๊ณ„ํ•˜๋‹ˆ ํ•œ์ชฝ ๋ฐœ์ „๋Ÿ‰์ด ์‚ฌ๋ผ์กŒ๋‹ค.
289
+ * `E-1001` ๋„ ๋‹ค๋ฅธ ๊ณต์žฅ์— ์žˆ์„ ์ˆ˜ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ํ˜„์žฅ์„ ํ•จ๊ป˜ ๋ณด๋Š” ์ˆœ๊ฐ„ ๊ฐ™์€ ์ผ์ด ๋‚œ๋‹ค.
290
+ *
291
+ * โ”€โ”€ **์—ฌ๊ธฐ์— ๊ฐœ์ธ์ •๋ณด๋ฅผ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค** โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
292
+ * ์„ค๋น„์™€ ์‚ฌ๋žŒ์ด ๊ฐˆ๋ฆฌ๋Š” ์ž๋ฆฌ๊ฐ€ ์ด๊ฒƒ์ด๋‹ค. ์„ค๋น„์˜ ์ •์ฒด์„ฑ์€ ํ•˜๋“œ์›จ์–ด ์ผ๋ จ๋ฒˆํ˜ธ์ด๊ณ  ์•„๋ฌด์—๊ฒŒ๋„ ํ•ด๊ฐ€
293
+ * ์—†๋‹ค. ์‚ฌ๋žŒ์˜ ใ€Œ์ „์—ญ์—์„œ ๊ณ ์œ ํ•œ ๊ฐ’ใ€์€ ์‚ฌ์›๋ฒˆํ˜ธยท์ถœ์ž…์นด๋“œยท์ฃผ๋ฏผ๋“ฑ๋ก์ฒ˜๋Ÿผ **๊ทธ ์‚ฌ๋žŒ์— ๊ด€ํ•œ ์‚ฌ์‹ค**
294
+ * ์ด๊ณ , ์ €๋„์€ ๋˜ํ’€์ด ์ฝํžˆ๊ณ  ๋ฏธ๋Ÿฌ๋กœ ๋ณต์ œ๋˜๊ณ  ๊ตฌ๋…์œผ๋กœ ๋ฐฉ์†ก๋œ๋‹ค โ€” ํ•œ ๋ฒˆ ๋“ค์–ด๊ฐ€๋ฉด ์ง€์›Œ์ง€์ง€ ์•Š๋Š”๋‹ค.
295
+ *
296
+ * ๊ทธ๋ž˜์„œ ์ด ์นธ์ด ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ **ํ˜„์žฅ์„ ์•ž์— ๋ถ™์—ฌ ์ „์—ญ์—์„œ ๊ณ ์œ ํ•ด์ง„ ์ด๋ฆ„**์ด๋‹ค. ๊ทธ ์ด์ƒ์ด ์•„๋‹ˆ๋‹ค.
297
+ *
298
+ * ```
299
+ * ๋งž๋‹ค urn:hatiolab:mes-line-a:obj:E-1001 (ยง`objectUri` ๊ฐ€ ๋งŒ๋“ ๋‹ค)
300
+ * https://hatiotrailer.com/twin/obj/E-1001
301
+ * ์•„๋‹ˆ๋‹ค ์นด๋“œ๋ฒˆํ˜ธ ยท ์‚ฌ์›๋ฒˆํ˜ธ ์›๋ฌธ ยท ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ ยท ์ƒ์ฒด ์‹๋ณ„์ž
302
+ * ```
303
+ *
304
+ * ใ€Œ์ด ์‚ฌ๋žŒ์ด ๋ˆ„๊ตฌ์ธ๊ฐ€ใ€๋Š” ์ธ์‚ฌ ์‹œ์Šคํ…œ์ด ๋‹ตํ•  ๋ฌผ์Œ์ด๊ณ  ํŠธ์œˆ์˜ ๋ฌผ์Œ์ด ์•„๋‹ˆ๋‹ค. ํŠธ์œˆ์€ **๊ฐ™์€
305
+ * ์‚ฌ๋žŒ์ธ์ง€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ธ์ง€**๋งŒ ์•Œ๋ฉด ๋œ๋‹ค โ€” ๊ทธ ์ผ์— ๊ฐœ์ธ์ •๋ณด๋Š” ํ•„์š” ์—†๋‹ค.
306
+ *
307
+ * ๊ฐ’์ด ์—†์œผ๋ฉด ๋น„์šด๋‹ค. ์ง€๊ธˆ ์›๋ณธ์ด ๊ทธ๋Ÿฐ ๊ฐ’์„ ์ฃผ์ง€ ์•Š์œผ๋ฏ€๋กœ ๋‹น๋ถ„๊ฐ„ ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค.
308
+ */
309
+ identity?: string;
269
310
  /**
270
311
  * ์†ํ•œ ๋“ฑ๊ธ‰๋“ค โ€” **ํ‘œ์ค€ `Person.PersonnelClassID`, `maxOccurs="unbounded"`**.
271
312
  * ๋ณต์ˆ˜์ธ ๊ฒƒ์ด ํ‘œ์ค€์ด๊ณ  ๊ทธ๊ฒƒ์ด ์ž๊ฒฉ ํ‘œํ˜„์ด๋‹ค: ํ•œ ์‚ฌ๋žŒ์ด ์šฉ์ ‘ ์ž๊ฒฉ๊ณผ ์ง€๊ฒŒ์ฐจ ์ž๊ฒฉ์„ ํ•จ๊ป˜ ๊ฐ–๋Š”๋‹ค.
@@ -314,8 +355,21 @@ export interface RefAsset {
314
355
  assetClassIds?: string[];
315
356
  /** ๊ธฐ๋ณธ ์œ„์น˜. */
316
357
  homeLocationId?: string;
317
- /** ์ •์‹ GS1 ์ •์ฒด์„ฑ โ€” ๋ฐ˜๋ณต์‚ฌ์šฉ ์ž์‚ฐ=GRAI. */
318
- gs1Id?: string;
358
+ /**
359
+ * **์ด ์ž์‚ฐ์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์„ค๋น„์™€ ๊ฐ™์€ ์ด๋ฆ„์ด๋‹ค(ยง`RefEquipment.identity`).
360
+ *
361
+ * โ”€โ”€ ์™œ ์ด๋ฆ„์„ ๋ฐ”๊ฟจ๋‚˜ (2026-09-04) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
362
+ * `gs1Id` ์˜€๋‹ค. ์„ค๋น„์—์„œ ๊ทธ ์ด๋ฆ„์„ ๋ฐ”๊พผ ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์—๋„ ๊ทธ๋Œ€๋กœ ์ ์šฉ๋œ๋‹ค โ€” **GS1 ํ‚ค๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด
363
+ * ์ •์ƒ์ด๋‹ค.** ์ž์‚ฐ์˜ ์‹ค์ธก ๊ฐ’๋„ ์ œ์กฐ๋ฒˆํ˜ธยท์‚ฌ๋‚ด ๊ด€๋ฆฌ๋ฒˆํ˜ธ์ด๊ณ , GS1 ์„ ์š”๊ตฌํ•˜๋Š” ์ด๋ฆ„์„ ๋‘๋ฉด ๊ทธ๊ฒƒ์„
364
+ * ์ฑ„์šฐ๋Š” ์ชฝ์ด ์—†๋Š” ํ‚ค๋ฅผ ์ง€์–ด๋‚ด๊ฑฐ๋‚˜ ์นธ์„ ๋น„์›Œ ๋‘”๋‹ค.
365
+ *
366
+ * ๊ทธ๋ฆฌ๊ณ  ๋งˆ์Šคํ„ฐ๋Š” ์ด๋ฏธ `identity` ๋กœ ๋‚ธ๋‹ค(์„ค๋น„ยท์ž์‚ฐ ๋‘˜ ๋‹ค). ์ด ์ž๋ฆฌ๋งŒ ๋‹ค๋ฅธ ์ด๋ฆ„์ด๋ผ **์›๋ณธ์ด
367
+ * ์ฑ„์šฐ๋Š” ์ˆœ๊ฐ„ ์กฐ์šฉํžˆ ์‚ฌ๋ผ์กŒ๋‹ค.** ์ง€๊ธˆ ์ž์‚ฐ 26๋Œ€๊ฐ€ ๋‹ค ๋น„์–ด ์žˆ์–ด ๋ฒ„๋ ค์ง€๋Š” ๊ฐ’์€ ์—†์—ˆ๋‹ค โ€”
368
+ * ์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๋ ˆ์ธ์ด ๊ทธ๊ฒƒ์„ ์žฌ์„œ ใ€Œ๋ˆ„๊ฐ€ ์ฑ„์šฐ๋Š” ์ˆœ๊ฐ„ใ€์ด๋ผ๊ณ  ์งš์—ˆ๋‹ค.
369
+ *
370
+ * ์ž๋ฆฌ ์ชฝ(`RefLocation.gs1Id`)์€ ๊ทธ๋Œ€๋กœ๋‹ค โ€” ๊ฑฐ๊ธฐ๋Š” ์‹ค์ œ๋กœ SGLN ์ด ์˜จ๋‹ค.
371
+ */
372
+ identity?: string;
319
373
  /** ์ž์› ์†์„ฑ โ€” ํ‘œ์ค€ `PhysicalAssetProperty`(์ ์žฌ ํ•œ๋„ยท๊ทœ๊ฒฉ ๋“ฑ). */
320
374
  properties?: RefResourceProperty[];
321
375
  /** ์ ๊ฒฉ์„ ๊ฒ€์ฆํ•œ ์‹œํ—˜ ๋ช…์„ธ๋“ค โ€” ํ‘œ์ค€ `TestSpecificationID`. */
@@ -235,9 +235,26 @@ function masterToTwin(master, catalog) {
235
235
  */
236
236
  return { id: l.id, type: l.type, ...(l.name ? { name: l.name } : {}), ...(l.description ? { description: l.description } : {}), capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), ...(l.properties?.length ? { properties: l.properties } : {}), parentId: l.parentId, ...(l.upstreamId ? { upstreamId: l.upstreamId } : {}), gs1Id: l.gs1Id };
237
237
  });
238
+ /*
239
+ * โ”€โ”€ ์„ค๋น„๊ฐ€ ๊ตฌ์—ญ์— ์„œ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค (2026-09-06) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
240
+ * ๋งˆ์Šคํ„ฐ๋Š” ์ž๋ฆฌ์™€ ๊ตฌ์—ญ์„ **ํ•œ ๋ชฉ๋ก**์— ๋‹ด๊ณ  `role` ๋กœ ๊ฐ€๋ฅธ๋‹ค(ยง`locationEntries` ยท `areaLocs`).
241
+ * ๊ทธ๋ž˜์„œ ์„ค๋น„์˜ `homeLocationId` ๊ฐ€ ๊ตฌ์—ญ์„ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค โ€” ์‹ค์ œ๋กœ `EQ-CAM-SHOWER-01` ์ด
242
+ * `LINE-CAM`(๊ตฌ์—ญ)์— ์„œ ์žˆ๊ณ , ๊ทธ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค(์—์–ด์ƒค์›Œ๋Š” ๋ผ์ธ ์ „์ฒด์— ๋”ธ๋ฆฐ๋‹ค).
243
+ *
244
+ * ๊ณ„์•ฝ์ด ๊ทธ ๊ตฌ๋ถ„์„ ์œ„ํ•ด `homeLocationKind` ๋ฅผ ๋‘์—ˆ๋Š”๋ฐ(`HomeKind = 'location' | 'area'`)
245
+ * **์•„๋ฌด๋„ ์•ˆ ์ฑ„์šฐ๊ณ  ์žˆ์—ˆ๋‹ค.** ๊ทธ๋ž˜์„œ ์ธ์ œ์ŠคํŠธ๊ฐ€ ๊ทธ ์ฐธ์กฐ๋ฅผ ใ€Œ๋Š์–ด์กŒ๋‹คใ€๊ณ  ๊ฒฝ๊ณ ํ–ˆ๋‹ค.
246
+ *
247
+ * ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๋งˆ์Šคํ„ฐ๊ฐ€ ์ด๋ฏธ `role` ๋กœ ๋งํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์„ ์ฝ๋Š”๋‹ค.
248
+ */
249
+ const areaIds = new Set(master.locations.filter(l => l.role === 'area').map(l => l.id));
238
250
  const equipment = (master.equipment ?? []).map(e => ({
239
251
  id: e.id, kind: e.kind, ...(e.name ? { name: e.name } : {}), ...(e.description ? { description: e.description } : {}), ...(e.testResults?.length ? { testResults: e.testResults } : {}),
240
- homeLocation: e.homeLocationId, mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, ...(e.identity ? { identity: e.identity } : {}),
252
+ /* ๋“ฑ๊ธ‰ ์†Œ์† โ€” ์‚ฌ๋žŒยท์ž์‚ฐ๊ณผ ๊ฐ™์€ ์ž๋ฆฌ. ๋น ๋œจ๋ฆฌ๋ฉด ์›๋ณธ์ด ์ฑ„์šด ๋“ฑ๊ธ‰์ด ๋ฌธํ„ฑ์—์„œ ์กฐ์šฉํžˆ ๋ฒ„๋ ค์ง„๋‹ค. */
253
+ ...(e.equipmentClassIds?.length ? { equipmentClassIds: e.equipmentClassIds } : {}),
254
+ homeLocation: e.homeLocationId,
255
+ /* ์ž๋ฆฌ๋ฉด ์•ˆ ์ ๋Š”๋‹ค โ€” ๊ณ„์•ฝ์˜ ๊ธฐ๋ณธ๊ฐ’์ด `location` ์ด๊ณ , ์—†๋Š” ์นธ์„ ๋งŒ๋“ค๋ฉด ํ™”๋ฉด์ด ๊ทธ๊ฒƒ์„ ๊ทธ๋ฆฐ๋‹ค. */
256
+ ...(e.homeLocationId && areaIds.has(e.homeLocationId) ? { homeLocationKind: 'area' } : {}),
257
+ mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, ...(e.identity ? { identity: e.identity } : {}),
241
258
  ...(e.window ? { window: e.window } : {}),
242
259
  /* ์†์„ฑ์€ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ์ด๋™์‹œ๊ฐ„ ์ถ”์ •๊ธฐ๊ฐ€ kind ๋ณ„ ์†๋„๋ฅผ ์—ฌ๊ธฐ์„œ ์ฝ๋Š”๋‹ค(๋‹จ์œ„ ์ฝ”๋“œ ๊ทธ๋Œ€๋กœ). */
243
260
  ...(e.properties?.length ? { properties: e.properties } : {}), ...(e.workCalendar?.length ? { workCalendar: e.workCalendar } : {}), ...(e.testSpecificationIds?.length ? { testSpecificationIds: e.testSpecificationIds } : {}),
@@ -261,6 +278,18 @@ function masterToTwin(master, catalog) {
261
278
  if (master.space.timezone && utcOffsetMinutes === undefined) {
262
279
  warnings.push((0, exports.unknownTimezone)(String(master.space.timezone)));
263
280
  }
281
+ /*
282
+ * โ”€โ”€ ์ด๋ฆ„๋„ ํ•จ๊ป˜ ์‹ฃ๋Š”๋‹ค (2026-09-07) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
283
+ * ์œ„์—์„œ ํ‘ผ ์˜คํ”„์…‹์€ **์ด ์ˆœ๊ฐ„์˜** ๊ฐ’์ด๊ณ , ์ด ๋ชจ๋ธ์€ ์ €์žฅ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ์ˆ˜๋Š” ๋งˆ์Šคํ„ฐ๋ฅผ ๋ฐ›์€ ๋‚ ์˜
284
+ * ๊ณ„์ ˆ๋กœ ๊ตณ๋Š”๋‹ค โ€” `America/Tijuana`(PST โˆ’480 / PDT โˆ’420)๊ฐ€ ์ž๋ฃŒ์— ์žˆ๊ณ , ์ง€๋‚œ ๊ตฌ๊ฐ„์„ ๊ต๋Œ€๋ณ„๋กœ ์ ‘์œผ๋ฉด
285
+ * ๊ทธ ์•ˆ์˜ ์ „ํ™˜์ด ์‚ฌ์‹ค์„ ํ•œ ์‹œ๊ฐ„ ๋ฐ€์–ด **๋‹ค๋ฅธ ๊ต๋Œ€๋กœ** ์„ธ๊ฒŒ ํ•œ๋‹ค. ์˜ค๋ฅ˜๋Š” ๋‚˜์ง€ ์•Š๋Š”๋‹ค.
286
+ *
287
+ * ์ด๋ฆ„์ด ํ•จ๊ป˜ ์žˆ์œผ๋ฉด ์†Œ๋น„์ฒ˜๊ฐ€ ์ˆœ๊ฐ„๋งˆ๋‹ค ๋‹ค์‹œ ํ’€ ์ˆ˜ ์žˆ๋‹ค(ยง`shiftContext`). ์ปค๋„์€ ์ด ๊ฐ’์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
288
+ *
289
+ * ์˜คํ”„์…‹์ด ์•ˆ ํ’€๋ฆฐ ์ด๋ฆ„์€ ์‹ฃ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ทธ ๊ฒฝ์šฐ๋Š” ์œ„์—์„œ ๊ฒฝ๊ณ ๋กœ ๋งํ–ˆ๊ณ , ํ’€๋ฆฌ์ง€ ์•Š๋Š” ์ด๋ฆ„์„ ์‹ค์–ด
290
+ * ๋‘๋ฉด ์†Œ๋น„์ฒ˜๊ฐ€ ๊ทธ๊ฒƒ์„ ๋ฏฟ๊ณ  ๋งค๋ฒˆ ์‹คํŒจํ•œ๋‹ค.
291
+ */
292
+ const timezone = utcOffsetMinutes !== undefined ? master.space.timezone : undefined;
264
293
  /*
265
294
  * ์˜คํผ๋ ˆ์ด์…˜ ๋ช…์„ธ๋ฅผ model ์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค โ€” ์ปค๋„์ด `loadOperations` ๋กœ ์†Œ๋น„ํ•œ๋‹ค(TwinModelDef ํ™•์žฅ ํ•„๋“œ,
266
295
  * ๋ชจ๋ฅด๋Š” ์ปค๋„์€ ๋ฌด์‹œ). ์—ฌ๊ธฐ์„œ ๊ฐ’์„ ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค: ๊ธฐ๊ฐ„์€ ํ‘œ์ค€ ํ‘œ๊ธฐ(ISO 8601)๋กœ ์ปค๋„๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ๊ฐ„๋‹ค.
@@ -273,9 +302,9 @@ function masterToTwin(master, catalog) {
273
302
  }
274
303
  }
275
304
  /* ์‚ฌ๋žŒ๋„ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ๋“ฑ๊ธ‰ยท๊ต๋Œ€ ๊ทธ๋Œ€๋กœ ์ปค๋„๊นŒ์ง€ ๊ฐ„๋‹ค(๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค). */
276
- const persons = master.persons?.map(p => ({ id: p.id, ...(p.name ? { name: p.name } : {}), ...(p.testResults?.length ? { testResults: p.testResults } : {}), 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 } : {}) }));
305
+ const persons = master.persons?.map(p => ({ id: p.id, ...(p.name ? { name: p.name } : {}), ...(p.testResults?.length ? { testResults: p.testResults } : {}), personnelClassIds: p.personnelClassIds, ...(p.identity ? { identity: p.identity } : {}), ...(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 } : {}) }));
277
306
  /* ์ž์‚ฐ๋„ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ๋“ฑ๊ธ‰ยท์ž๋ฆฌ ๊ทธ๋Œ€๋กœ ์ปค๋„๊นŒ์ง€. */
278
- const assets = master.assets?.map(a => ({ id: a.id, ...(a.name ? { name: a.name } : {}), ...(a.testResults?.length ? { testResults: a.testResults } : {}), 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 } : {}) }));
307
+ const assets = master.assets?.map(a => ({ id: a.id, ...(a.name ? { name: a.name } : {}), ...(a.testResults?.length ? { testResults: a.testResults } : {}), assetClassIds: a.assetClassIds, homeLocation: a.homeLocationId, ...(a.identity ? { identity: a.identity } : {}), ...(a.properties?.length ? { properties: a.properties } : {}), ...(a.testSpecificationIds?.length ? { testSpecificationIds: a.testSpecificationIds } : {}), ...(a.effectiveStart ? { effectiveStart: a.effectiveStart } : {}), ...(a.effectiveEnd ? { effectiveEnd: a.effectiveEnd } : {}) }));
279
308
  /* ํ’ˆ๋ชฉ ์ •์˜ยท๋“ฑ๊ธ‰๋„ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค(ํ™˜์‚ฐ ๊ณ„์ˆ˜๋Š” ์ปค๋„์ด ์ฝ๋Š”๋‹ค). */
280
309
  const materialDefinitions = master.materialDefinitions?.map(d => ({
281
310
  id: d.id,
@@ -320,6 +349,7 @@ function masterToTwin(master, catalog) {
320
349
  ...(materialDefinitions?.length ? { materialDefinitions } : {}),
321
350
  ...(materialClasses?.length ? { materialClasses } : {}),
322
351
  ...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),
352
+ ...(timezone ? { timezone } : {}),
323
353
  ...(operations?.length ? { operations } : {}),
324
354
  ...(testSpecifications?.length ? { testSpecifications } : {}),
325
355
  ...(personnelClasses?.length ? { personnelClasses } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"reference-master.js","sourceRoot":"","sources":["../../../server/service/reference/reference-master.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAwfH,kCAaC;AAsFD,sDAKC;AA0GD,oCA+JC;AASD,wCAQC;AAnZD;;;GAGG;AACH;;;;;;;;;;;;GAYG;AACH,SAAgB,WAAW,CAAC,QAAiB,EAAE,KAAW,IAAI,IAAI,EAAE;IAClE,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACpH,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,EAAE,KAAK,IAAI,EAAE,CAAA;QACpE,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,CAAC,CAAA,CAAC,qBAAqB;QAClD,MAAM,CAAC,GAAG,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxD,IAAI,CAAC,CAAC;YAAE,OAAO,SAAS,CAAA;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAClC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA,CAAC,4BAA4B;IAC/C,CAAC;AACH,CAAC;AA+BD;;;;;;;;;;;GAWG;AACI,MAAM,yBAAyB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAiB,EAAE,CAAC,CAAC;IACjG,IAAI,EAAE,8BAA8B;IACpC,MAAM,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE;IAChC,OAAO,EACL,IAAI,WAAW,kDAAkD,OAAO,sEAAsE;QAC9I,wGAAwG;CAC3G,CAAC,CAAA;AANW,QAAA,yBAAyB,6BAMpC;AAEF;;;;;;;;GAQG;AACI,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,EAAU,EAAiB,EAAE,CAAC,CAAC;IAC/F,IAAI,EAAE,uBAAuB;IAC7B,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;IAC5B;;;;;;;;;OASG;IACH,OAAO,EACL,IAAI,IAAI,6BAA6B,MAAM,KAAK,EAAE,oEAAoE;QACtH,2GAA2G;QAC3G,gEAAgE;CACnE,CAAC,CAAA;AAjBW,QAAA,mBAAmB,uBAiB9B;AAEF;;;;;;GAMG;AACH,SAAgB,qBAAqB,CAAC,cAAuB;IAC3D,MAAM,IAAI,GAAI,cAAsB,EAAE,UAAU,EAAE,aAAa,CAAA;IAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAA;IACtH,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACvC,CAAC;AAED,mEAAmE;AAC5D,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAiB,EAAE,CAAC,CAAC;IACnE,IAAI,EAAE,kBAAkB;IACxB,MAAM,EAAE,EAAE,QAAQ,EAAE;IACpB,OAAO,EAAE,mBAAmB,QAAQ,8DAA8D;CACnG,CAAC,CAAA;AAJW,QAAA,eAAe,mBAI1B;AAEF,4CAA4C;AACrC,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAiB,EAAE,CAAC,CAAC;IAC7E,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,EAAE,SAAS,EAAE;IACrB,OAAO,EAAE,cAAc,SAAS,gEAAgE;CACjG,CAAC,CAAA;AAJW,QAAA,wBAAwB,4BAInC;AAEF,sCAAsC;AAC/B,MAAM,wBAAwB,GAAG,GAAkB,EAAE,CAAC,CAAC;IAC5D,IAAI,EAAE,4BAA4B;IAClC,OAAO,EAAE,0GAA0G;CACpH,CAAC,CAAA;AAHW,QAAA,wBAAwB,4BAGnC;AAEF;;;;;;GAMG;AACI,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAE,GAAW,EAAiB,EAAE,CAAC,CAAC;IACjF,IAAI,EAAE,sBAAsB;IAC5B,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IACtB,OAAO,EAAE,GAAG,KAAK,kDAAkD,GAAG,6BAA6B;CACpG,CAAC,CAAA;AAJW,QAAA,mBAAmB,uBAI9B;AAEF;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAiB,EAAE,CAAC,CAAC;IAClE,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,EAAE,MAAM,EAAE;IAClB,OAAO,EAAE,gCAAgC,MAAM,6EAA6E;CAC7H,CAAC,CAAA;AAJW,QAAA,gBAAgB,oBAI3B;AAEF;;;;;;GAMG;AACI,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,KAAoI,EAAiB,EAAE,CAAC,CAAC;IACrM,IAAI,EAAE,mBAAmB;IACzB,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE;IACzB,OAAO,EACL,wDAAwD,GAAG,MAAM;QACjE,IAAI,KAAK,CAAC,cAAc,kBAAkB,KAAK,CAAC,gBAAgB,gBAAgB;QAChF,IAAI,KAAK,CAAC,gBAAgB,gBAAgB,KAAK,CAAC,cAAc,gBAAgB,KAAK,CAAC,aAAa,WAAW;CAC/G,CAAC,CAAA;AAPW,QAAA,gBAAgB,oBAO3B;AAEF;;;;;;;;;GASG;AACI,MAAM,wBAAwB,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAE,MAAyB,EAAE,KAAa,EAAiB,EAAE,CAAC,CAAC;IACrI,IAAI,EAAE,4BAA4B;IAClC,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE;IAC7D,OAAO,EAAE,GAAG,KAAK,IAAI,KAAK,8CAA8C,QAAQ,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,0DAA0D;CAClK,CAAC,CAAA;AAJW,QAAA,wBAAwB,4BAInC;AAGF,iDAAiD;AAC1C,MAAM,gBAAgB,GAAG,CAAC,QAAkC,EAAU,EAAE,CAC7E,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAD7C,QAAA,gBAAgB,oBAC6B;AAE1D;;;;;GAKG;AACI,MAAM,kBAAkB,GAAG,CAAC,IAAuB,EAAiB,EAAE,CAAC,CAAC;IAC7E,IAAI,EAAE,sBAAsB;IAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE;IACrD,OAAO,EAAE,sEAAsE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;CACjG,CAAC,CAAA;AAJW,QAAA,kBAAkB,sBAI7B;AAEF;;;;;GAKG;AACI,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAE,KAAa,EAAiB,EAAE,CAAC,CAAC;IAClF,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;IACtB,OAAO,EAAE,GAAG,KAAK,4EAA4E,GAAG,yDAAyD;CAC1J,CAAC,CAAA;AAJW,QAAA,oBAAoB,wBAI/B;AAEF,SAAgB,YAAY,CAAC,MAAuB,EAAE,OAAa;IACjE,oEAAoE;IACpE,MAAM,QAAQ,GAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9D;;;OAGG;IACH,MAAM,KAAK,GAAa,qBAAqB,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,IAAI,EAAE,CAAA;IAErH,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;IAChG,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;IAErF,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACxC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAA,2BAAmB,EAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5G,gFAAgF;QAChF;;;;WAIG;QACH;;;;WAIG;QACH,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IACza,CAAC,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnD,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvL,YAAY,EAAE,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnH,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,8DAA8D;QAC9D,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/N,4DAA4D;QAC5D,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/H,CAAC,CAAC,CAAA;IAEH,yDAAyD;IACzD,MAAM,MAAM,GAA6C,EAAE,CAAA;IAC3D,KAAK,MAAM,CAAC,IAAI,eAAe;QAAE,IAAI,CAAC,CAAC,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAA;IAE/I,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,OAAO,CAAA;IAC/D;;;;;;OAMG;IACH,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC3D,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC5D,QAAQ,CAAC,IAAI,CAAC,IAAA,uBAAe,EAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC/D,CAAC;IACD;;;OAGG;IACH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;IACpC,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAA,gCAAwB,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IACD,yDAAyD;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACppB,qCAAqC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACzgB,4DAA4D;IAC5D,MAAM,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChE,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,sEAAsE;QACtE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,CAAC,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC,CAAC,CAAA;IACH;;;;;;;;;OASG;IACH,MAAM,MAAM,GAAG,CAAC,IAAyB,EAAE,EAAE,CAC3C,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACvG;;;;OAIG;IACH,MAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACvF,GAAG,IAAI;QACP,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC,CAAC,CAAA;IACH,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACxD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IAChD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IAEtD,MAAM,KAAK,GAAG;QACZ,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO;QACrC,uDAAuD;QACvD,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,uDAAuD;QACvD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAA;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzH,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE;KACjG,CAAC,CAAC,CAAA;IACH,+DAA+D;IAC/D,oEAAoE;IACpE,qEAAqE;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAA;IAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,CAAA;IACpD;;;;;;;;;;OAUG;IACH,MAAM,eAAe,GACnB,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,GAAG;YACH,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YACjG,CAAC,CAAC,EAAE,CAAA;IACV,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,IAAA,gCAAwB,GAAE,CAAC,CAAA;IAC3C,CAAC;IACD,MAAM,YAAY,GAAG;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG;QACpF,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE;QACjF,KAAK;KACN,CAAA;IAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAA;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,KAAmB,EACnB,MAA8C;IAE9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAA;IACpD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,CAAA;IACzD,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AAClD,CAAC","sourcesContent":["/*\n * Face2 ๋งˆ์Šคํ„ฐ ์ธ์ œ์ŠคํŠธ(ADR-0018 ๋ฐ˜์˜ ๋ชจ๋“œ) โ€” ๋ ˆํผ๋Ÿฐ์Šค ์‹œ์Šคํ…œ(์‹ค WMS/YMS/MES ๋˜๋Š” ๊ฐ€์ƒ ๋ ˆํผ๋Ÿฐ์Šค)์˜\n * ๋งˆ์Šคํ„ฐ๋ฅผ ์ฝ์–ด ํŠธ์œˆ ๊ตฌ์กฐ(TwinModelDef) + ๊ณต๊ฐ„(Space content)์„ ์ƒ์„ฑ. ์†๋ฐฐ์„ ์ด ์•„๋‹ˆ๋ผ ์ธ์ œ์ŠคํŠธ๋กœ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ๋ฅธ๋‹ค.\n *\n * ๊ทœ์œจ(ADR-0018): ๋„๋ฉ”์ธ ํƒ€์ž…(location.type=๋…ธ๋“œ์šฉ)์€ ์ปค๋„ ์นดํƒˆ๋กœ๊ทธ ์–ดํœ˜๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜์˜(๋ฐœ๋ช… ๊ธˆ์ง€).\n * location ์€ role ๋กœ ๋…ธ๋“œ(์šด์˜์ )ยทarea(๊ณต๊ฐ„์˜์—ญ)ยทboth ๋ฅผ ๊ตฌ๋ถ„ โ€” ๋…ธ๋“œโ†’TwinModelDef, areaโ†’Space.areas.\n * ์ขŒํ‘œยทrepresentations ๋Š” ํŠธ์œˆ ๊ณต๊ฐ„์ธต(๋ณด์™„/์ถ”๊ฐ€). ์‹ค ์‹œ์Šคํ…œ์ด ์ขŒํ‘œ๋ฅผ ์•ˆ ์ฃผ๋ฉด layout ์—†์ด ์œ„์ƒ๋งŒ ์ธ์ œ์ŠคํŠธ.\n */\n\nimport type { DomainSystem, EquipmentLevel, TestSpecificationCriterion, WorkCalendarEntry } from '@operato/ops-contract'\n\nexport interface RefLocation {\n id: string\n type: string // ๋…ธ๋“œ๋Š” ์ปค๋„ ๋…ธ๋“œํƒ€์ž…(dock/storage/yard-slotโ€ฆ), area ๋Š” ๊ณต๊ฐ„ region ํƒ€์ž…\n name?: string\n description?: string\n role: 'location' | 'area' | 'both'\n parentId?: string\n /**\n * **์ „๊ธฐ์ ์œผ๋กœ ์–ด๋””์„œ ๋ฐ›๋Š”๊ฐ€** โ€” ์ด ์ž๋ฆฌ์— ์ „๊ธฐ๋ฅผ ์ฃผ๋Š” ์ƒ๋ฅ˜ ์ž๋ฆฌ(์ปค๋„ ๊ณ„์•ฝ์˜ `upstreamId`).\n *\n * `parentId`(๊ณต๊ฐ„ ํฌํ•จ)์™€ ๋”ฐ๋กœ ๋‘๋Š” ์ด์œ ๋Š” ์ปค๋„ ๊ณ„์•ฝ์— ์ ํ˜€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋น ๋œจ๋ฆฌ๋ฉด ๋งˆ์Šคํ„ฐ๊ฐ€ ๋งํ•œ ๊ณ„ํ†ต์ด\n * ๋ชจ๋ธ๊นŒ์ง€ ์˜ค์ง€ ๋ชปํ•˜๊ณ , ๋ฟŒ๋ฆฌ ๊ณ„๋Ÿ‰ ํŒ์ •์ด ๋ถ„๊ธฐ ๊ณ„๋Ÿ‰๊ธฐ๊นŒ์ง€ ๋ฟŒ๋ฆฌ๋กœ ์„ธ์–ด **๋ถ€ํ•˜๊ฐ€ ๋‘ ๋ฐฐ๋กœ** ๋ณด์ธ๋‹ค.\n */\n upstreamId?: 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 /**\n * ์ž๋ฆฌ์˜ **์—ด๋ฆฐ ์†์„ฑ** โ€” ํ‘œ์ค€ `OperationalLocationProperty`(์„ค๋น„ยท์‚ฌ๋žŒยท์ž์‚ฐ๊ณผ ๊ฐ™์€ ๋ชจ์–‘).\n *\n * ๋ฌด์—‡์ด ์—ฌ๊ธฐ ์‹ค๋ฆฌ๋‚˜: **์ž๋ฆฌ์˜ ๋ฌผ๋ฆฌ๋Ÿ‰**์ด๋‹ค. ์—๋„ˆ์ง€์˜ ๊ณ„์•ฝ์ „๋ ฅ(`contract.kW`)์ด ์ฒซ ์‚ฌ๋ก€๋‹ค โ€”\n * ๊ทธ ๊ฐ’์ด ์•‰์„ ์ž๋ฆฌ๊ฐ€ ์—†์–ด์„œ EMS ์ปค๋„์€ ๊ณ„์•ฝ ๋Œ€๋น„ ํŒ์ •์„ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค(์ž๋ฆฌ๊ฐ€ ์—†์œผ๋ฉด ์‚ฌ์‹ค์ด\n * ๋“ค์–ด์˜ค์ง€ ๋ชปํ•œ๋‹ค). ์ปค๋„์€ ์ž๊ธฐ๊ฐ€ **์ฝ๋Š”** ์†์„ฑ id ๋งŒ ์„ ์–ธํ•˜๊ณ (`EMS_PROPERTY`) ๋‚˜๋จธ์ง€๋Š” ๋‚˜๋ฅธ๋‹ค.\n */\n properties?: RefResourceProperty[]\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\n/**\n * ๊ฒ€์‚ฌ ๋ช…์„ธ โ€” **์ž์›์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ**(ISA-95 `TestSpecification`).\n *\n * ํ‘œ์ค€ ํ•„๋“œ๋Š” ์…‹๋งŒ ๋‹ด๋Š”๋‹ค(`ID`ยท`Description`ยท`Version`) โ€” ์žฌ๋Š” ์†์„ฑ๊ณผ ํ•ฉ๊ฒฉ ๊ธฐ์ค€์€ ์•„์ง 1์ฐจ ์ถœ์ฒ˜์™€\n * ๋Œ€์กฐํ•˜์ง€ ์•Š์•˜๋‹ค(์ปค๋„ ๊ณ„์•ฝ์˜ ๋จธ๋ฆฌ๋ง์ด ๊ทธ ์‚ฌ์‹ค์„ ์ ์–ด ๋‘์—ˆ๋‹ค).\n */\n/**\n * ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” **\"์ด ๊ฐœ์ฒด๊ฐ€ ๊ทธ ์‹œํ—˜์„ ํ†ต๊ณผํ–ˆ๋‹ค\"** ๋Š” ๊ธฐ๋ก(ISA-95 ๊ฒฐ๊ณผ).\n *\n * ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ๋Š” ๊ณณ์€ ํŠธ์œˆ์ด ์•„๋‹ˆ๋‹ค(์ธ์‚ฌยท์ •๋น„ ์‹œ์Šคํ…œ์ด ๊ธฐ๋กํ•œ๋‹ค) โ€” ๊ทธ๋ž˜์„œ ๊ด€์ธก์ด๋ฉด์„œ **์„ ์–ธ ๊ฒฝ๋กœ๋กœ** ์˜จ๋‹ค.\n * ์ปค๋„์€ ์ด ๊ฐ’์ด ์žˆ์„ ๋•Œ๋งŒ ์ž๊ฒฉ์„ ํŒ์ •ํ•œ๋‹ค: ์—†์œผ๋ฉด ์ œ์•ฝ์ด ์•„๋‹ˆ๊ณ (๋ผ์ธ์ด ๊ตถ์ง€ ์•Š๋Š”๋‹ค), ์žˆ์œผ๋ฉด ๋งŒ๋ฃŒยท\n * ๋ถˆํ•ฉ๊ฒฉ์ด ๋ฐฐ์ •์„ ๋ง‰๋Š”๋‹ค.\n */\nexport interface RefTestResult {\n specId: string\n result: 'pass' | 'fail'\n at?: string\n /** ์—†์œผ๋ฉด ๋ฌด๊ธฐํ•œ โ€” ์ง์ž‘์œผ๋กœ ๊ธฐํ•œ์„ ๋งŒ๋“ค๋ฉด ๋ฉ€์ฉกํ•œ ์ž๊ฒฉ์ž๊ฐ€ ์˜ค๋ฅ˜ ์—†์ด ์‚ฌ๋ผ์ง„๋‹ค. */\n expiresAt?: string\n}\n\nexport interface RefTestSpecification {\n id: string\n /** ํ‘œ์‹œ๋ช… โ€” i18n ํ‚ค์ผ ์ˆ˜ ์žˆ๋‹ค. ์ฝ๋Š” ์–ดํœ˜๋ฅผ ํ•˜๋‚˜๋กœ ๋งž์ถ”๋ ค๊ณ  ์ธ์ œ์ŠคํŠธ๊ฐ€ `name` ์œผ๋กœ ์˜ฎ๊ธด๋‹ค. */\n description?: string\n version?: string\n /**\n * ํŒ์ • ๊ธฐ์ค€๋“ค โ€” ์ปค๋„ ๊ณ„์•ฝ์˜ `TestSpecification.criteria` ๋ฅผ ๊ทธ๋Œ€๋กœ ๋‚˜๋ฅธ๋‹ค.\n *\n * **๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค.** ์ปค๋„ ํƒ€์ž…์„ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฏ€๋กœ `limit.{minimum,maximum,uom}` ยท\n * `expression` ยท `evaluatedPropertyId` ๊ฐ€ ์›๋ณธ์—์„œ ์ปค๋„๊นŒ์ง€ ํ•œ ์ด๋ฆ„์œผ๋กœ ๊ฐ„๋‹ค.\n *\n * ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๋ช…์„ธ๋Š” ์„ฑ๋ฆฝํ•œ๋‹ค(์ด๋ฆ„๋งŒ์œผ๋กœ ใ€Œ๋ฌด์—‡์œผ๋กœ ๊ฒ€์ฆํ–ˆ๋‚˜ใ€์— ๋‹ตํ•œ๋‹ค). ์„ ์–ธํ•˜๋ฉด **ํŒ์ •์—\n * ๊ทผ๊ฑฐ๊ฐ€ ์žˆ๋Š”์ง€**๋ฅผ ๋ฌผ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค โ€” ์ปค๋„์˜ `criterionSaysNothing` ์ด ๊ทธ๊ฒƒ์„ ์„ผ๋‹ค.\n */\n criteria?: TestSpecificationCriterion[]\n}\n\nexport interface RefEquipment {\n id: string\n kind: string\n /** ์‚ฌ๋žŒ์ด ๋ถ€๋ฅด๋Š” ์ด๋ฆ„ โ€” ์—†์œผ๋ฉด ํ™”๋ฉด์ด id ๋ฅผ ๋ณด์ธ๋‹ค(id ๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋ฒ ๋ผ์ง€ ์•Š๋Š”๋‹ค). */\n name?: string\n /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\n description?: string\n homeLocationId: string\n mtbfMs?: number // ํ‰๊ท  ๊ณ ์žฅ ๊ฐ„๊ฒฉ(ํ™•๋ฅ ์  ๊ณ ์žฅ) โ€” ์ง€์ • ์‹œ ์ปค๋„์ด breakdown ์‹œ๋ฎฌ โ†’ ์ฃผ๋ชฉ(๊ณ ์žฅ) ๋ฐœ์ƒ\n mttrMs?: number // ํ‰๊ท  ์ˆ˜๋ฆฌ ์‹œ๊ฐ„\n /**\n * **์ด ์„ค๋น„์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์ปค๋„ ์„ ์–ธ์˜ `equipment[].identity` ๋กœ ๊ทธ๋Œ€๋กœ ๊ฐ„๋‹ค.\n *\n * ์˜ˆ์ „ ์ด๋ฆ„์€ `gs1Id` ์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ **GS1 ํ‚ค๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค** โ€” ์‹ค์ธกํ•œ ๊ฐ’์€ ์ธ๋ฒ„ํ„ฐ์˜\n * ํ•˜๋“œ์›จ์–ด ์‹๋ณ„์ž(`ES100000007d8d061d-1`)์ด๊ณ , ์›๋ณธ์ด GIAI ๋ฅผ ์ฃผ๋ฉด ๊ทธ๊ฒƒ๋„ ์—ฌ๊ธฐ ๋“ค์–ด์˜จ๋‹ค.\n * ์ด๋ฆ„์ด ํ•œ ์ข…๋ฅ˜๋งŒ ๊ฐ€๋ฆฌํ‚ค๋ฉด ๋‹ค๋ฅธ ์ข…๋ฅ˜๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ ๊ทธ ์ž๋ฆฌ๋ฅผ ๋ชป ์“ด๋‹ค.\n *\n * ์ž๋ฆฌ(`RefLocation.gs1Id`)๋Š” ๊ทธ๋Œ€๋กœ๋‹ค โ€” ๊ทธ์ชฝ์€ ์‹ค์ œ๋กœ SGLN ์ด ์˜จ๋‹ค.\n */\n identity?: string\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 /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\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 /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\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\n/**\n * **์ด ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•** โ€” ํŠธ์œˆ์ด ์ž๊ธฐ ์›๋ณธ์„ ๊ธฐ์–ตํ•˜๋Š” ์ž๋ฆฌ.\n *\n * ํŠธ์œˆ์€ ์›๋ณธ์„ ๋น„์ถœ ๋ฟ์ด๋ฏ€๋กœ(ADR-0028), ์›๋ณธ์ด ๋‹ฌ๋ผ์ง€๋ฉด **๋‹ค์‹œ ์ฝ์–ด์•ผ** ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ง€๊ธˆ๊นŒ์ง€\n * ํŠธ์œˆ์€ \"๋‚ด๊ฐ€ ๋ฌด์—‡์—์„œ ๋‚˜์™”๋‚˜\" ๋ฅผ ๋‚จ๊ธฐ์ง€ ์•Š์•˜๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๋กœ ๋“ค์–ด์˜จ ํŠธ์œˆ์€ `TwinReference` ํ–‰์ด\n * ์žˆ์—ˆ์ง€๋งŒ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์„ธ์šด ํŠธ์œˆ์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†์—ˆ๊ณ , ๊ทธ๋ž˜์„œ **๋‹ค์‹œ ์ฝ์„ ๋Œ€์ƒ์ด ์—†๋Š” ํŠธ์œˆ**์ด\n * ๋งŒ๋“ค์–ด์กŒ๋‹ค. ์›๋ณธ์„ ์žƒ์€ ํŠธ์œˆ์€ ์ฒซ๋‚ ์˜ ๋ชจ์Šต์— ์˜์›ํžˆ ๋จธ๋ฌธ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์›์ฒœ์ด ๋ฌด์—‡์ด๋“  ์—ฌ๊ธฐ ํ•œ ์ž๋ฆฌ์— ๋‚จ๊ธด๋‹ค. ๋‹ค์‹œ ์ฝ๊ธฐ๋Š” ์ด ๊ฐ’ ํ•˜๋‚˜๋งŒ ๋ณด๋ฉด ๋œ๋‹ค.\n */\nexport type MasterOrigin =\n /**\n * ๋“ฑ๋ก๋œ ๋ ˆํผ๋Ÿฐ์Šค(์–ด๋Œ‘ํ„ฐ)์—์„œ ์™”๋‹ค โ€” ๋‹ค์‹œ ์ฝ๊ธฐ = ๊ทธ ์–ด๋Œ‘ํ„ฐ๋กœ ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜จ๋‹ค.\n *\n * `source` ๋Š” **๋ ˆํผ๋Ÿฐ์Šค ๋“ฑ๋ก ์ด๋ฆ„**์ด๊ณ  ๊ทธ ์ฐธ์กฐ๊ฐ€ ๋ณด๊ณ ํ•˜๋Š” ์‚ฌ์ดํŠธ ์ „๋ถ€์— ๊ฐ™๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋А ์‚ฌ์ดํŠธ์—์„œ\n * ์˜จ ํŠธ์œˆ์ธ์ง€๋Š” `siteId` ๊ฐ€ ์žˆ์–ด์•ผ ์•ˆ๋‹ค โ€” ์—†์œผ๋ฉด ๋‹ค์‹œ ์ฝ๊ธฐ๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ ์ฐพ์ง€ ๋ชปํ•œ๋‹ค(2026-08-18 ์‹ค์ธก:\n * ์‚ฌ์ดํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ์ฐธ์กฐ์—์„œ ์˜จ ํŠธ์œˆ์€ ์žฌ๋™๊ธฐ๊ฐ€ ์ „๋ถ€ ๊ฑฐ์ ˆ๋๋‹ค. ์ฐธ์กฐ ์ด๋ฆ„์„ ์‚ฌ์ดํŠธ๋ณ„ ๋งˆ์Šคํ„ฐ์˜\n * `source`(=์ธ์Šคํ„ด์Šค id)์™€ ๋น„๊ตํ•˜๊ณ  ์žˆ์—ˆ๋‹ค โ€” ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋น„๊ตํ•œ ๊ฒƒ์ด๋‹ค).\n */\n | { kind: 'reference'; source: string; siteId?: string; spaceId?: string }\n /**\n * ํ…œํ”Œ๋ฆฟ + ๋…ธ๋ธŒ๋กœ ํ•ฉ์„ฑํ–ˆ๋‹ค โ€” ๋‹ค์‹œ ์ฝ๊ธฐ = ๊ฐ™์€ ๋…ธ๋ธŒ๋กœ ๋‹ค์‹œ ์ง“๋Š”๋‹ค(ํ•ฉ์„ฑ์€ ๊ฒฐ์ •์ ์ด๋‹ค).\n *\n * `spaceId` ๋Š” **๋งŒ๋“ค ๋•Œ ๊ณ ๋ฅธ ํ˜„์žฅ**์ด๋‹ค(ํ•ฉ์ณ ๋„ฃ๊ธฐ). ๊ธฐ์–ตํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์‹œ ์ฝ์„ ๋•Œ ํŠธ์œˆ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ž๊ธฐ\n * ํ˜„์žฅ์„ ๋– ๋‚œ๋‹ค โ€” ํ…œํ”Œ๋ฆฟ์ด ๋‚ธ ๊ธฐ๋ณธ ๊ณต๊ฐ„์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ทธ ํ˜„์žฅ์˜ ๊ฐ’(์š”๊ธˆ ๋“ฑ)๋„ ํ•จ๊ป˜\n * ์žƒ๋Š”๋‹ค(2026-08-18 ์‹ค์ธก: ํ•œ ํ˜„์žฅ์— ํ•ฉ์ณ ๋‘” EMS ํŠธ์œˆ ์—ฌ๋Ÿ์ด ์žฌ๋™๊ธฐ ๋’ค ๊ฐ์ž ๊ณต๊ฐ„์œผ๋กœ ํฉ์–ด์กŒ๋‹ค).\n */\n | { kind: 'template'; templateId: string; params: Record<string, unknown>; spaceId?: string }\n\nexport interface ReferenceMaster {\n source: string\n /**\n * ์–ด๋А ์ข…๋ฅ˜์˜ ํŠธ์œˆ์ธ๊ฐ€ โ€” **์ปค๋„ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ์ •๋ณธ**์ด๋‹ค(`DomainSystem`).\n *\n * ์˜ˆ์ „์—๋Š” `'wms' | 'yms' | 'mes'` ๋ฅผ ์—ฌ๊ธฐ ์ ์–ด ๋’€๋‹ค. ์ปค๋„์— ์ข…๋ฅ˜๊ฐ€ ํ•˜๋‚˜ ๋Š˜ ๋•Œ(์—๋„ˆ์ง€) ์ด ์ค„์ด\n * ํ•จ๊ป˜ ์›€์ง์—ฌ์•ผ ํ•˜๋Š”๋ฐ, ์†์œผ๋กœ ์ ํžŒ ๋ชฉ๋ก์€ ๊ทธ๊ฒƒ์„ ์•Œ๋ ค ์ฃผ์ง€ ์•Š๋Š”๋‹ค โ€” ์–ดํœ˜์˜ ์ง‘์€ ํ•œ ๊ณณ์ด์–ด์•ผ ํ•œ๋‹ค.\n */\n system: DomainSystem\n siteName: string\n /** ๊ฒ€์‚ฌ ๋ช…์„ธ โ€” ์ž์›ยท๋“ฑ๊ธ‰์˜ `testSpecificationIds` ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ. */\n testSpecifications?: RefTestSpecification[]\n /**\n * ์ด ๋งˆ์Šคํ„ฐ๊ฐ€ ์–ด๋””์„œ ๋‚˜์™”๋‚˜ โ€” **๋‹ค์‹œ ์ฝ๊ธฐ์˜ ์œ ์ผํ•œ ๊ทผ๊ฑฐ.** ์—†์œผ๋ฉด ๊ทธ ํŠธ์œˆ์€ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์—†๊ณ ,\n * ์กฐํšŒ ํ™”๋ฉด์ด ๊ทธ ์‚ฌ์‹ค์„ ๊ทธ๋Œ€๋กœ ๋งํ•œ๋‹ค(์—†๋Š” ๊ฒƒ์„ ์žˆ๋Š” ์ฒ™ํ•˜์ง€ ์•Š๋Š”๋‹ค).\n */\n origin?: MasterOrigin\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 * ์ƒ์‚ฐ ์„ ์–ธ โ€” `TwinModelDef.productionSpec` ์œผ๋กœ ํ†ต๊ณผํ•œ๋‹ค(ISA-95 OperationsSegment + BOM).\n *\n * ์˜ˆ์ „ ์ด๋ฆ„์€ `mesSpec` ์ด์—ˆ๋‹ค. ๋‹ด๊ธด ๊ฒƒ์€ MES ๋งŒ์˜ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ \"์ž์žฌ๋ฅผ ์†Œ๋น„ํ•ด ์ž์žฌ๋ฅผ ์‚ฐ์ถœํ•˜๋Š”\n * ๊ณต์ •\" ์ด๊ณ , ์ด๋ฆ„์ด MES ์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ฐฝ๊ณ  ํŠธ์œˆ์€ ์ด ์ž๋ฆฌ๋ฅผ ์“ธ ์ƒ๊ฐ์กฐ์ฐจ ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค(์œ ํ†ต๊ฐ€๊ณต ์ฐฝ๊ณ ๊ฐ€\n * BOM ์„ ์„ค๋ช… ๋ฌธ์„œ์—๋งŒ ์ ์–ด ๋‘” ์ฑ„ ํ‚คํŠธ๋ฅผ ๋ชป ๋งŒ๋“œ๋Š” ํŠธ์œˆ์„ ๋งŒ๋“  ์›์ธ). ๊ทผ๊ฑฐ๋Š” ์ปค๋„ ๊ณ„์•ฝ ์ฃผ์„์—.\n */\n productionSpec?: unknown\n /**\n * **์ด ์›๋ณธ์ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“œ๋Š” ์ด๋ฆ„๊ณต๊ฐ„** โ€” `TwinModelDef.identity` ๋กœ ํ†ต๊ณผํ•œ๋‹ค.\n *\n * **์„ ์–ธ์ด ์—†์œผ๋ฉด ์ปค๋„์ด ๊ฑฐ์ ˆํ•œ๋‹ค** (0.7.45~). ์˜ˆ์ „์—๋Š” ์ƒ์ˆ˜ ํ”„๋ฆฌํ”ฝ์Šค๋กœ ํŒ”๋ ˆํŠธยทํŠธ๋ ˆ์ผ๋Ÿฌยท๋ฌธ์„œ๋ฅผ\n * ๋งŒ๋“ค์—ˆ๋Š”๋ฐ(`0614141` โ€” GS1 ์ด ๊ทœ๊ฒฉ ์˜ˆ์ œ๋กœ ์“ฐ๋‹ค ๋ฒ„๋ฆฐ ๊ฐ’์ด๊ณ  `06โ€ฆ` ์€ ์‹ค ๋ฐฐ์ • ๋Œ€์—ญ์ด๋‹ค), ๊ทธ ๊ฐ’์€\n * ์ €๋„์— ์˜์›ํžˆ ๋‚จ์œผ๋ฉด์„œ ์ง€์–ด๋‚ธ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•ด ์ฃผ๋Š” ๋ฐ๊ฐ€ ์—†์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋„์ด ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์›๋ณธ์ด ์ž๊ธฐ ๋„๋ฉ”์ธ์„ ๋งํ•˜๋ฉด ๊ทธ ์•„๋ž˜์—์„œ ๋งŒ๋“ ๋‹ค โ€” ๊ทธ๊ฒƒ์ด ํ‘œ์ค€ ์ •ํ•ฉ์ด๋‹ค(CBV 2.0 ยง8.2.4ยทยง8.5.5,\n * ใ€Œ๊ทธ ์ธํ„ฐ๋„ท ๋„๋ฉ”์ธ ์†Œ์œ ์ž๊ฐ€ ๋ฐฐ์ •ํ•œ๋‹คใ€). GS1 ํ‚ค๋ฅผ ์“ฐ๋ ค๋ฉด `documentTypes` + `companyPrefix` ์ด๊ณ ,\n * ๊ทธ๋•Œ **์ž๋ฆฌ ์ˆ˜๊ฐ€ ๋งž์•„์•ผ ํ•œ๋‹ค**(SGTIN ์€ ํ”„๋ฆฌํ”ฝ์Šค + ํ’ˆ๋ชฉ์ฐธ์กฐ = 13์ž๋ฆฌ, GS1 TDS).\n *\n * ์ •์ฒด์„ฑ์€ ์ƒ์‚ฐ๊ณผ ๋ฌด๊ด€ํ•˜๋ฏ€๋กœ `productionSpec` ์ด ์•„๋‹ˆ๋ผ **๋ชจ๋ธ**์ด ๊ฐ–๋Š”๋‹ค โ€” ์ฐฝ๊ณ ยท์•ผ๋“œ๋Š” ์•„๋ฌด๊ฒƒ๋„\n * ์ƒ์‚ฐํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ํŒ”๋ ˆํŠธยทํŠธ๋ ˆ์ผ๋Ÿฌ๋ฅผ ์‹๋ณ„ํ•œ๋‹ค.\n */\n identity?: 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 * ์ปค๋„ฅํ„ฐ๊ฐ€ **์˜ฎ๊ธฐ๋Š” ๋™์•ˆ ์•Œ๊ฒŒ ๋œ ๊ฒƒ.** ์™ธ๋ถ€ ์‹œ์Šคํ…œ์˜ ๊ฐ’์„ ์šฐ๋ฆฌ ์–ดํœ˜๋กœ ๋ชป ์˜ฎ๊ฒจ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค๋ฉด\n * ์—ฌ๊ธฐ์— ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด `masterToTwin` ์˜ ๊ฒฝ๊ณ ์™€ ํ•œ ์ค„๊ธฐ๋กœ ํ•ฉ์ณ์ ธ ํ™”๋ฉด๊นŒ์ง€ ๊ฐ„๋‹ค.\n *\n * ์ด ์ž๋ฆฌ๊ฐ€ ์—†๋˜ ๋™์•ˆ ์ปค๋„ฅํ„ฐ๋Š” ํ•  ๋ง์ด ์žˆ์–ด๋„ **๋งํ•  ๊ณณ์ด ์—†์—ˆ๋‹ค.** ๊ทธ๋ž˜์„œ ๋„ํฌ๋ฅผ ๋ž™์œผ๋กœ ๋ฐ”๊ฟ”\n * ๋†“๊ณ ๋„ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์„ฑ๊ณตํ–ˆ๋‹ค. ์˜ฎ๊ธฐ๋Š” ์‚ฌ๋žŒ๋งŒ ์•„๋Š” ์‚ฌ์‹ค์€ ์˜ฎ๊ธฐ๋Š” ์ž๋ฆฌ์—์„œ ์‹ค์–ด์•ผ ํ•œ๋‹ค.\n */\n warnings?: IngestWarning[]\n /**\n * **์›๋ณธ์ด ๊ฐ€์ง„ ์ˆ˜** โ€” ์˜ฎ๊ธด ์ˆ˜์˜ ๋ถ„๋ชจ๋‹ค.\n *\n * ์ดํ‰์€ ๋„์ฐฉํ•œ ๋ชจ๋ธ๋งŒ ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ใ€Œ๋ ˆ์‹œํ”ผ 1,261ใ€๊นŒ์ง€๋งŒ ๋งํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ๋žŒ์ด ๋ฌป๋Š” ๊ฒƒ์€\n * ใ€Œ๊ทธ๊ฒŒ ์ „๋ถ€์ธ๊ฐ€ใ€๋‹ค โ€” ์›๋ณธ์— 1,408๊ฐœ๊ฐ€ ์žˆ์—ˆ๊ณ  147๊ฐœ๋ฅผ ์˜ฎ๊ธฐ์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ๊ทธ ์‚ฌ์‹ค์ด ์ดํ‰์˜ ์ฒซ ์ค„์—\n * ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ’ˆ๋ชฉ 2,789 ์™€ ์ž์žฌ 1,789 ์˜ ์ฐจ์ด๋ฅผ ํ™”๋ฉด์—์„œ ์ฝ์–ด ๋‚ด์ง€ ๋ชปํ•ด ์ง์ ‘\n * ๋ฌผ์—ˆ๋‹ค(2026-08-22).\n *\n * ๋ถ„๋ชจ๋ฅผ ์•„๋Š” ๊ฒƒ์€ **์ปค๋„ฅํ„ฐ๋ฟ์ด๋‹ค.** ๊ทธ๋ž˜์„œ ์ปค๋„ฅํ„ฐ๊ฐ€ ์‹ค์–ด ๋ณด๋‚ธ๋‹ค. ๋ณด๋‚ด์ง€ ์•Š์œผ๋ฉด ์ดํ‰์€ ๋ถ„๋ชจ ์—†์ด\n * ์˜ฎ๊ธด ์ˆ˜๋งŒ ๋งํ•œ๋‹ค โ€” **์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์—ด์‡ ๋Š” ์ดํ‰์ด ์„ธ๋Š” ์ด๋ฆ„๊ณผ ๊ฐ™๋‹ค(`recipes`ยท`materials`ยท`totalInputs`ยทโ€ฆ). ๊ฐ’์€ **์›๋ณธ์„ ๋๊นŒ์ง€ ์ฝ์–ด์„œ\n * ์„ผ ๊ฒƒ**์ด์–ด์•ผ ํ•œ๋‹ค. ์ž˜๋ฆฐ ์ฝ๊ธฐ์˜ ์ˆ˜๋ฅผ ์—ฌ๊ธฐ ๋‹ด์œผ๋ฉด ใ€Œ์ „๋ถ€ ์˜ฎ๊ฒผ๋‹คใ€๋Š” ๊ฑฐ์ง“์ด ๋œ๋‹ค.\n */\n originCounts?: Record<string, number>\n}\n\nexport interface IngestedTwin {\n model: any // TwinModelDef(+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/**\n * **์‹œ๊ฐ์„ ๋ชจ๋ฅด๋Š” ์ฑ„ ์‹œ๊ฐ์œผ๋กœ ํŒ์ •ํ•˜๋ ค ํ•œ๋‹ค** โ€” ๋ฐœ์ „ ํ˜•์ƒ์€ ํ•˜๋ฃจ์˜ ์‹œ๊ฐ์„ ์ฝ๋Š”๋ฐ ์ด ํŠธ์œˆ์˜ ๊ณต๊ฐ„์ด\n * ์‹œ๊ฐ„๋Œ€๋ฅผ ๋งํ•˜์ง€ ์•Š์•˜๋‹ค.\n *\n * โ”€โ”€ ์™œ ๊ฒฝ๊ณ ์ธ๊ฐ€ (2026-08-18) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„์€ ์‹œ๊ฐ„๋Œ€๋ฅผ ๋ชจ๋ฅด๋ฉด UTC ๋กœ ์ฝ๋Š”๋‹ค(๊ณ„์•ฝ์— ๋ฐํ˜€ ๋‘” ๊ทœ์œจ โ€” ๋ชจ๋ฅด๋Š” ๊ฐ’์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค). ๊ทธ๋Ÿฐ๋ฐ ๋ฐœ์ „\n * ํ˜•์ƒ์€ **์‹œ๊ฐ๋ณ„ ๋น„์œจ**์ด๋ผ, ์‹œ๊ฐ„๋Œ€๊ฐ€ ์—†์œผ๋ฉด ํ˜„์žฅ ์ •์˜ค๊ฐ€ ์•„๋‹ˆ๋ผ UTC ์ •์˜ค์— ํ”ผํฌ๊ฐ€ ์„ ๋‹ค(KST ํ˜„์žฅ์ด๋ฉด\n * ๋ฐค 9์‹œ). ๊ฐ’์ด ๊ทธ๋Ÿด๋“ฏํ•˜๊ฒŒ ๋‚˜์˜ค๋ฏ€๋กœ ์•„๋ฌด๋„ ์•Œ์•„์ฑ„์ง€ ๋ชปํ•œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์‹œ๊ฐ„๋Œ€๋ฅผ **์ง€์–ด๋‚ด์ง€ ์•Š๊ณ **(์„œ๋ฒ„ ๋กœ์ปฌ์ด๋‚˜ ์ž„์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๊ทธ ํŠธ์œˆ์˜ ๋ชจ๋“  ์‹œ๊ฐ ํŒ์ •์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ \n * ๊ทธ ๊ฐ€์ • ์œ„์— ์„ ๋‹ค) ๋Œ€์‹  **๊ทธ ์กฐํ•ฉ์„ ๋งํ•œ๋‹ค** โ€” ๊ณต๊ฐ„์— ์‹œ๊ฐ„๋Œ€๋ฅผ ์„ ์–ธํ•˜๋ฉด ์‚ฌ๋ผ์ง€๋Š” ๊ฒฝ๊ณ ๋‹ค.\n */\nexport const generationWithoutTimeZone = (spaceId: string, equipmentId: string): IngestWarning => ({\n code: 'generation-without-time-zone',\n params: { spaceId, equipmentId },\n message:\n `\"${equipmentId}\" declares a daily generation shape but space \"${spaceId}\" declares no time zone โ€” the hourly fractions will be read in UTC, ` +\n 'so the generation peak will not land at local noon. Declare the space time zone (we do not guess one).'\n})\n\n/**\n * ์•„๋ฌด๋„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ์ž๋ฆฌ ํƒ€์ž… โ€” ๊ทธ ์ž๋ฆฌ๋Š” ํ๋ฆ„์— ์ฐธ์—ฌํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค.\n *\n * **๋ฌป๋Š” ์ƒ๋Œ€๋ฅผ ๊ณ ์ณค๋‹ค (2026-08-20).** ์˜ˆ์ „์—๋Š” ๋‚ด์žฅ ์นดํƒˆ๋กœ๊ทธ์—๊ฒŒ๋งŒ ๋ฌผ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์›๋ณธ์ด ์ž๊ธฐ\n * `DomainDefinition.locationTypes` ๋ฅผ ํ•จ๊ป˜ ๋ณด๋‚ด๋ฉด **๊ทธ ์„ ์–ธ์ด ์ •๋ณธ**์ด๋‹ค โ€” ์นดํƒˆ๋กœ๊ทธ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š”\n * ๋„๋ฉ”์ธ๋“ค์˜ ๊ธฐ๋ณธ ์–ดํœ˜์ผ ๋ฟ์ด๋‹ค. ๋ฌผ์„ ์ƒ๋Œ€๊ฐ€ ํ‹€๋ ธ์œผ๋‹ˆ, ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ•œ ์›๋ณธ์€ ์ •์ƒ์ ์ธ ํƒ€์ž…๋งˆ๋‹ค\n * ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›์•˜๋‹ค(F&B ๋ผ์ธ์„ ๋ถ™์ด๋ฉด ์ž๋ฆฌ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ). ์†Œ์Œ์ด ๋˜๋ฉด ์‚ฌ๋žŒ์€ ๊ฒฝ๊ณ ๋ฅผ ์ฝ์ง€ ์•Š๊ฒŒ ๋˜๊ณ , ๊ทธ๋•Œ\n * ์ง„์งœ ๊ฒฝ๊ณ ๋„ ํ•จ๊ป˜ ์ฃฝ๋Š”๋‹ค.\n */\nexport const unknownLocationType = (system: string, type: string, id: string): IngestWarning => ({\n code: 'unknown-location-type',\n params: { system, type, id },\n /*\n * โ”€โ”€ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€ ๋งํ•œ๋‹ค (2026-08-25) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „ ๋ฌธ์žฅ์€ ใ€Œํ๋ฆ„์— ์ฐธ์—ฌํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹คใ€์˜€๋‹ค. ๋ฌผ๊ฑด์ด ํ๋ฅด๋Š” ๋„๋ฉ”์ธ์—์„œ๋Š” ๋งž๋Š” ๋ง์ธ๋ฐ,\n * ์—๋„ˆ์ง€ ํŠธ์œˆ์—๋Š” ํ๋ฆ„์ด ์—†์–ด์„œ ๊ทธ ๋ฌธ์žฅ์ด ์•„๋ฌด๊ฒƒ๋„ ์•Œ๋ ค ์ฃผ์ง€ ์•Š์•˜๋‹ค(์‹ค์ œ๋กœ ํƒœ์–‘๊ด‘ ๋ฐœ์ „์†Œ๋ฅผ\n * ๋ถ™์ด๋ฉด์„œ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›์€ ์‚ฌ๋žŒ์ด ใ€Œ์ด ๊ฒฝ๊ณ ๊ฐ€ ๋œป์ด ์žˆ๋Š”๊ฐ€ใ€๋ฅผ ๋˜๋ฌผ์—ˆ๋‹ค).\n *\n * ์ข…๋ฅ˜๋ฅผ ๋ชจ๋ฅด๋ฉด ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๋Š” ์ผ์€ ํ•˜๋‚˜๋‹ค: **๊ทธ ์ž๋ฆฌ์— ๋Šฅ๋ ฅ์ด ๋ถ™์ง€ ์•Š๋Š”๋‹ค.** ๋Šฅ๋ ฅ์ด ์—†์œผ๋ฉด\n * ์ƒํƒœ ํ•„๋“œ๋„ ์—†๊ณ , ๋กค์—…์—๋„ ๋“ค์–ด๊ฐ€์ง€ ์•Š๊ณ , ์ €์ž‘๋ฉด ํŒ”๋ ˆํŠธ์—๋„ ์„œ์ง€ ์•Š๋Š”๋‹ค. ๋„๋ฉ”์ธ์„ ๊ฐ€๋ฆฌ์ง€ ์•Š๊ณ \n * ์ฐธ์ธ ๋ฌธ์žฅ์ด๋ฏ€๋กœ ์ด๊ฒƒ์„ ์ ๋Š”๋‹ค.\n */\n message:\n `\"${type}\" is declared nowhere for ${system} (${id}) โ€” neither in the master's own locationTypes nor in the built-in ` +\n `catalog. A location whose type is unknown gets no capabilities, so it carries no state, joins no rollup, ` +\n `and (in domains that move things) may be left out of the flow.`\n})\n\n/**\n * ์›๋ณธ์ด ํ•จ๊ป˜ ๋ณด๋‚ธ ์ž๋ฆฌ ํƒ€์ž… ์„ ์–ธ โ€” ์žˆ์œผ๋ฉด **์ด๊ฒƒ์ด ์ •๋ณธ**์ด๋‹ค.\n *\n * ์ปค๋„ ๊ณ„์•ฝ์˜ `DomainDefinition.locationTypes` ๋Š” `{ key, label, โ€ฆ }` ๋ชฉ๋ก์ด๋‹ค. ์ฝ์„ ์ˆ˜ ์—†๋Š” ๋ชจ์–‘์ด๋ฉด\n * `undefined` ๋ฅผ ๋Œ๋ ค **์นดํƒˆ๋กœ๊ทธ๋กœ ๋–จ์–ด์ง„๋‹ค** โ€” ๋นˆ ๋ฐฐ์—ด์„ ๋Œ๋ ค์ฃผ๋ฉด ใ€Œ์•„๋ฌด ํƒ€์ž…๋„ ์„ ์–ธ๋˜์ง€ ์•Š์•˜๋‹คใ€๊ฐ€\n * ๋˜์–ด ๋ชจ๋“  ์ž๋ฆฌ๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›๋Š”๋‹ค(์—†๋Š” ๊ฒƒ๊ณผ ๋ชป ์ฝ์€ ๊ฒƒ์€ ๋‹ค๋ฅด๋‹ค).\n */\nexport function declaredLocationTypes(productionSpec: unknown): string[] | undefined {\n const list = (productionSpec as any)?.definition?.locationTypes\n if (!Array.isArray(list) || !list.length) return undefined\n const keys = list.map((t: any) => (typeof t === 'string' ? t : t?.key)).filter((k: any) => typeof k === 'string' && k)\n return keys.length ? keys : undefined\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/**\n * ๊ตฌ์กฐ ํˆฌ์˜์—์„œ **๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ์„ ๋ชป ์ฐพ์•˜๋‹ค.**\n *\n * ์˜ˆ์ „์—๋Š” ์ด๋Ÿฐ ์ฐธ์กฐ๊ฐ€ model JSON ์•ˆ์˜ ๋งจ ๋ฌธ์ž์—ด์ด๋ผ ํ™”๋ฉด๋งŒ ๊ฒฝ๊ณ ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜จ\n * ๋ฐ์ดํ„ฐ๋Š” ์•„๋ฌด๋„ ์•ˆ ๋ดค๋‹ค. ์ด์ œ ํ–‰์œผ๋กœ ํ’€๋ฉด์„œ **์ธ์ œ์ŠคํŠธ๊ฐ€ ์ง์ ‘ ์•ˆ๋‹ค** โ€” ๊ทธ๋Ÿฌ๋‹ˆ ์ธ์ œ์ŠคํŠธ๊ฐ€ ๋งํ•œ๋‹ค.\n * ๋ง‰์ง€๋Š” ์•Š๋Š”๋‹ค(ํŠธ์œˆ์€ model ๋กœ ์ด๋ฏธ ๋™์ž‘ํ•œ๋‹ค). ๋‹ค๋งŒ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค.\n */\nexport const unresolvedReference = (field: string, ref: string): IngestWarning => ({\n code: 'unresolved-reference',\n params: { field, ref },\n message: `${field} points at something that is not in this twin (${ref}) โ€” the link was left empty`\n})\n\n/**\n * ๊ตฌ์กฐ ํˆฌ์˜ ์ž์ฒด๊ฐ€ ์‹คํŒจํ–ˆ๋‹ค โ€” ์กฐํšŒ๋Š” ๋ชป ํ•˜์ง€๋งŒ **ํŠธ์œˆ์€ ๋™์ž‘ํ•œ๋‹ค**(์ปค๋„์€ model ๋ฅผ ์ด๋ฏธ ๋ฐ›์•˜๋‹ค).\n * ํ–‰์€ ์›๋ณธ์—์„œ ๋‹ค์‹œ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ธ์ œ์ŠคํŠธ๋ฅผ ์‹คํŒจ๋กœ ๋งŒ๋“ค์ง€ ์•Š๋˜, ์นจ๋ฌตํ•˜์ง€๋„ ์•Š๋Š”๋‹ค.\n */\nexport const projectionFailed = (reason: string): IngestWarning => ({\n code: 'projection-failed',\n params: { reason },\n message: `structure projection failed (${reason}) โ€” the twin runs, but model inspection will be stale until the next ingest`\n})\n\n/**\n * **๋™์ž‘ ์ค‘์— ๊ณต์žฅ์„ ์ „ํ™˜ํ–ˆ๋‹ค** โ€” ๋ฏธ๋Ÿฌ๋Š” ๋ฉˆ์ถ”์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ฌด์—‡์ด ์‚ฌ๋ผ์กŒ๋Š”์ง€ ์—ฌ๊ธฐ์„œ ๋งํ•œ๋‹ค.\n *\n * ๋ฉˆ์ท„๋‹ค ์„ธ์šฐ๋Š” ๊ตฌ์กฐ ์ „ํ™˜์ด๋ผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ \"๋‹ค์‹œ ์„ธ์› ๋‹ค\" ๋Š” ๊ฒƒ์„ ์•ˆ๋‹ค. ๋ฏธ๋Ÿฌ๋Š” ๊ทธ ๋งˆ๋””๊ฐ€ ์—†์–ด์„œ\n * ์ž๋ฆฌ ํ•˜๋‚˜ยท์„ค๋น„ ํ•œ ๋Œ€๊ฐ€ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์—†์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค โ€” ์ž๋ฆฌ๊ฐ€ ์ˆ˜์ฒœ์ธ ํ˜„์žฅ์—์„œ ํ™”๋ฉด์˜ ์ˆ˜๋ฅผ ์„ธ์–ด\n * ๋ˆˆ์น˜์ฑ„๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†๋‹ค. ๋Š˜์–ด๋‚œ ๊ฒƒ๋„ ํ•จ๊ป˜ ๋งํ•œ๋‹ค(๋ฌด์—‡์ด ๋ฐ˜์˜๋˜์—ˆ๋‚˜๊ฐ€ ๊ณง ์ธ์ œ์ŠคํŠธ์˜ ๋‹ต์ด๋‹ค).\n */\nexport const structureAdopted = (rev: number, shift: { locationsAdded: number; locationsDropped: number; equipmentDropped: number; personsDropped: number; assetsDropped: number }): IngestWarning => ({\n code: 'structure-adopted',\n params: { rev, ...shift },\n message:\n `the running mirror adopted a new structure (revision ${rev}) โ€” ` +\n `+${shift.locationsAdded} location(s), -${shift.locationsDropped} location(s), ` +\n `-${shift.equipmentDropped} equipment, -${shift.personsDropped} person(s), -${shift.assetsDropped} asset(s)`\n})\n\n/**\n * ์ปค๋„ฅํ„ฐ๊ฐ€ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์˜ ๊ฐ’์„ **์šฐ๋ฆฌ ์–ดํœ˜๋กœ ์˜ฎ๊ธฐ์ง€ ๋ชปํ•ด ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค.**\n *\n * ์˜ˆ: Oracle WMS ๊ฐ€ ์šฐ๋ฆฌ ํ‘œ์— ์—†๋Š” `locn_type` ์„ ์ฃผ๋ฉด ๊ทธ ์ž๋ฆฌ๋Š” `storage` ๊ฐ€ ๋œ๋‹ค โ€” ๋„ํฌ๊ฐ€ ๋ž™์œผ๋กœ\n * ๋ชจ๋ธ๋ง๋˜๋Š” ๊ฒƒ์ด๋‹ค. ์ธ์ œ์ŠคํŠธ๋ฅผ ํ†ต์งธ๋กœ ์‹คํŒจ์‹œํ‚ฌ ์ผ์€ ์•„๋‹ˆ์ง€๋งŒ(๋กœ์ผ€์ด์…˜ ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ํ˜„์žฅ ์ „์ฒด๊ฐ€\n * ์•ˆ ๋“ค์–ด์˜ค๋Š” ํŽธ์ด ๋” ๋‚˜์˜๋‹ค), **์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋„˜์–ด๊ฐ€๋ฉด ์•ˆ ๋œ๋‹ค.** ํŠธ์œˆ์ด ์‹ค๋ฌผ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ƒ๊ฒผ๋Š”๋ฐ\n * ์•„๋ฌด๋„ ๊ทธ ์‚ฌ์‹ค์„ ๋ชจ๋ฅธ ์ฑ„ ๊ทธ ์œ„์—์„œ ํ๋ฆ„์„ ๋…ผํ•˜๊ฒŒ ๋œ๋‹ค.\n *\n * ๊ฐ’์„ ๋‚˜์—ดํ•˜๋Š” ์ด์œ : \"3๊ฑด\" ๋งŒ์œผ๋กœ๋Š” ์ปค๋„ฅํ„ฐ ๋งคํ•‘์— ๋ฌด์—‡์„ ๋”ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.\n */\nexport const connectorMappingFallback = (field: string, fallback: string, values: readonly string[], count: number): IngestWarning => ({\n code: 'connector-mapping-fallback',\n params: { field, fallback, values: values.join(', '), count },\n message: `${count} ${field} value(s) had no mapping and fell back to \"${fallback}\" (${values.join(', ')}) โ€” the twin's shape differs from the source system here`\n})\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\n/**\n * ์ด ํ˜„์žฅ์˜ ์„ค๋น„๋ฅผ ๋…ธ๋ธŒ ๊ฐ’์œผ๋กœ ์ฑ„์› ๋‹ค โ€” **์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์—๋„ˆ์ง€ ํŠธ์œˆ์˜ ๋ถ€ํ•˜๋ฅผ ์ด์›ƒ ์„ค๋น„ id ๋กœ ์„ ์–ธํ•  ๋•Œ ์“ด๋‹ค. ๋ช‡ ๊ฐœ๋ฅผ ๊ฐ€์ ธ์™”๋Š”์ง€ ๋งํ•ด ์ฃผ์ง€ ์•Š์œผ๋ฉด, ์‚ฌ์šฉ์ž๋Š”\n * ์ž๊ธฐ๊ฐ€ ๊ณ ๋ฅด์ง€ ์•Š์€ ์„ค๋น„๋“ค์ด ๋ถ€ํ•˜๋กœ ์žกํžŒ ๊ฒƒ์„ ๋‚˜์ค‘์— ํ™”๋ฉด์—์„œ์•ผ ์•Œ๊ฒŒ ๋œ๋‹ค.\n */\nexport const siteEquipmentAdopted = (key: string, count: number): IngestWarning => ({\n code: 'site-equipment-adopted',\n params: { key, count },\n message: `${count} piece(s) of equipment already on this site were adopted as loads (knob \"${key}\") โ€” set their coefficients before trusting the numbers`\n})\n\nexport function masterToTwin(master: ReferenceMaster, catalog?: any): IngestedTwin {\n /* ์ปค๋„ฅํ„ฐ๊ฐ€ ์˜ฎ๊ธฐ๋ฉฐ ์•Œ๊ฒŒ ๋œ ๊ฒƒ์„ ๋จผ์ € ์‹ฃ๋Š”๋‹ค โ€” ์›์ธ์ด ์•ž์— ์˜ค๋Š” ํŽธ์ด ์ฝ๊ธฐ ์‰ฝ๋‹ค(๋Œ€์ฒด๊ฐ€ ๋จผ์ €, ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ๋’ค). */\n const warnings: IngestWarning[] = [...(master.warnings ?? [])]\n /*\n * ์›๋ณธ์ด ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ–ˆ์œผ๋ฉด **๊ทธ๊ฒƒ์— ๋Œ€์กฐํ•œ๋‹ค.** ๋‚ด์žฅ ์นดํƒˆ๋กœ๊ทธ๋Š” ๊ทธ ์„ ์–ธ์ด ์—†์„ ๋•Œ์˜ ๊ธฐ๋ณธ์ด๋‹ค โ€”\n * ์ƒ๋Œ€๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š์œผ๋ฉด, ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ•œ ์›๋ณธ์ด ์ •์ƒ์ ์ธ ์ž๋ฆฌ๋งˆ๋‹ค ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›๋Š”๋‹ค.\n */\n const known: string[] = declaredLocationTypes(master.productionSpec) ?? 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 /*\n * **์ด๋ฆ„์„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค.** ์—ฌ๊ธฐ์„œ ๋ฒ„๋ฆฌ๊ณ  ์žˆ์—ˆ๋‹ค โ€” ๊ทธ๋ž˜์„œ ๋ชจ๋ธ์—๋„, ํˆฌ์˜ํ•œ ํ–‰์—๋„ ์ด๋ฆ„์ด ์—†๊ณ \n * ํ™”๋ฉด์€ ์ž๋ฆฌ id ๋ฅผ ๊ทธ๋Œ€๋กœ ์ฐ์—ˆ๋‹ค(`cut-station`). ๋ชฉ๋กยทํ‘œยท๊ด€๊ณ„ ๊ทธ๋ฆผ์—์„œ ๊ฐ™์€ ๊ฒฐํ•จ์ด ๋”ฐ๋กœ\n * ๋ณด์˜€๋˜ ์ด์œ ๊ฐ€ ์ด ํ•œ ์ค„์ด๋‹ค. ์ด๋ฆ„ ์—†๋Š” ์›๋ณธ์€ ์ด๋ฆ„ ์—†์ด ํ†ต๊ณผํ•œ๋‹ค(id ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).\n */\n /*\n * **์†์„ฑ๋„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค** โ€” ์„ค๋น„์™€ ๊ฐ™์€ ๊ทœ์œจ(์†๋Œ€์ง€ ์•Š๊ณ  ๋‚˜๋ฅธ๋‹ค). ์—ฌ๊ธฐ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฆฌ์— ์‹ค์€ ๊ฐ’์ด\n * ์ปค๋„์— ๋‹ฟ์ง€ ์•Š๋Š”๋‹ค: ์—๋„ˆ์ง€์˜ ๊ณ„์•ฝ์ „๋ ฅ(`contract.kW`)์ด ๊ทธ ๊ฒฝ๋กœ์ด๊ณ , ํ†ต๊ณผํ•˜์ง€ ์•Š์œผ๋ฉด ์ปค๋„์ด\n * ๊ณ„์•ฝ์„ ๋ชจ๋ฅด๋Š” ์ฑ„๋กœ ์„œ์„œ **ํŒ์ •์„ ์•„์˜ˆ ํ•˜์ง€ ์•Š๋Š”๋‹ค**(์˜ค๋ฅ˜ ์—†์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ ).\n */\n return { id: l.id, type: l.type, ...(l.name ? { name: l.name } : {}), ...(l.description ? { description: l.description } : {}), capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), ...(l.properties?.length ? { properties: l.properties } : {}), parentId: l.parentId, ...(l.upstreamId ? { upstreamId: l.upstreamId } : {}), gs1Id: l.gs1Id }\n })\n\n const equipment = (master.equipment ?? []).map(e => ({\n id: e.id, kind: e.kind, ...(e.name ? { name: e.name } : {}), ...(e.description ? { description: e.description } : {}), ...(e.testResults?.length ? { testResults: e.testResults } : {}),\n homeLocation: e.homeLocationId, mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, ...(e.identity ? { identity: e.identity } : {}),\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 * **๋ถ„ ์˜คํ”„์…‹**๋งŒ ๋ฐ›๋Š”๋‹ค(๊ณ„์•ฝ `TwinModelDef.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 * ์˜คํผ๋ ˆ์ด์…˜ ๋ช…์„ธ๋ฅผ model ์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค โ€” ์ปค๋„์ด `loadOperations` ๋กœ ์†Œ๋น„ํ•œ๋‹ค(TwinModelDef ํ™•์žฅ ํ•„๋“œ,\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, ...(p.name ? { name: p.name } : {}), ...(p.testResults?.length ? { testResults: p.testResults } : {}), 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, ...(a.name ? { name: a.name } : {}), ...(a.testResults?.length ? { testResults: a.testResults } : {}), 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 /* ์ด๋ฆ„์€ ์ด๋ฆ„ ์ž๋ฆฌ์— โ€” ์˜ˆ์ „์—๋Š” `name` ์„ `description` ์œผ๋กœ ์˜ฎ๊ฒจ ๋‹ด์•˜๋‹ค(์–ดํœ˜๊ฐ€ ๋’ค์ง‘ํ˜€ ์žˆ์—ˆ๋‹ค). */\n ...(d.name ? { name: 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 /*\n * **๋“ฑ๊ธ‰์˜ ํ‘œ์‹œ๋ช…์€ `name` ์ด๋‹ค.**\n *\n * ํ‘œ์ค€ ๋งˆ์Šคํ„ฐ๋Š” ๋“ฑ๊ธ‰์˜ ํ‘œ์‹œ๋ช…์„ `description` ์— ๋‹ด๋Š”๋‹ค(`RefResourceClass.description` = i18n ํ‚ค).\n * ๊ทธ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋ชจ๋ธ์— ์‹ค์œผ๋ฉด ํ™”๋ฉด์˜ \"์„ค๋ช…\" ์—ด์— ์ด๋ฆ„์ด ์•‰๋Š”๋‹ค โ€” ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ด๋ฆ„์ธ๋ฐ ๋จธ๋ฆฌ๊ธ€์€\n * ์„ค๋ช…์ด๋ผ, ๊ฐ™์€ ๊ฒƒ์„ ์ถ•๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๋ถ€๋ฅด๊ฒŒ ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ **๋ฌธ ํ•˜๋‚˜์—์„œ ์–ดํœ˜๋ฅผ ๋งž์ถ˜๋‹ค**: ํ‘œ์‹œ๋ช…์€ ์–ด๋А ์ถ•์ด๋“  `name`. ์›๋ž˜์˜ `description` ์€\n * ๋‚จ๊ฒจ ๋‘์ง€ ์•Š๋Š”๋‹ค โ€” ๋‘ ์ž๋ฆฌ์— ๊ฐ™์€ ๊ฐ’์ด ์žˆ์œผ๋ฉด ์–ด๋А ๊ฒƒ์ด ์ •๋ณธ์ธ์ง€ ๋‹ค์‹œ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.\n */\n const asName = (list?: RefResourceClass[]) =>\n list?.map(({ description, ...rest }) => ({ ...rest, ...(description ? { name: description } : {}) }))\n /*\n * ๊ฒ€์‚ฌ ๋ช…์„ธ๋„ **ํ‘œ์‹œ๋ช…์€ `name`** ์ด๋‹ค โ€” ๋“ฑ๊ธ‰๊ณผ ๊ฐ™์€ ๊ทœ์น™์„ ์“ด๋‹ค(์–ดํœ˜๋ฅผ ํ•˜๋‚˜๋กœ). ํ‘œ์ค€ ๋งˆ์Šคํ„ฐ๋Š”\n * ํ‘œ์‹œ๋ช…์„ `description` ์— ๋‹ด์œผ๋ฏ€๋กœ ๋ฌธ ํ•˜๋‚˜์—์„œ ์˜ฎ๊ธด๋‹ค. ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ํ™”๋ฉด์˜ \"์„ค๋ช…\" ์—ด์— ์ด๋ฆ„์ด\n * ์•‰์•„ ์ถ•๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๊ฐ™์€ ๊ฒƒ์„ ๋ถ€๋ฅด๊ฒŒ ๋œ๋‹ค(๋“ฑ๊ธ‰์—์„œ ์ด๋ฏธ ๊ฒช์—ˆ๋‹ค).\n */\n const testSpecifications = master.testSpecifications?.map(({ description, ...rest }) => ({\n ...rest,\n ...(description ? { name: description } : {})\n }))\n const personnelClasses = asName(master.personnelClasses)\n const equipmentClasses = asName(master.equipmentClasses)\n const assetClasses = asName(master.assetClasses)\n const materialClasses = asName(master.materialClasses)\n\n const model = {\n locations, equipment, layout, spaceId,\n /* ์ƒ์‚ฐ ์ •์˜๋„ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๊ทธ๋Œ€๋กœ ์†Œ๋น„ํ•œ๋‹ค). */\n ...(master.productionSpec ? { productionSpec: master.productionSpec } : {}),\n /* ์ •์ฒด์„ฑ ์„ ์–ธ๋„ ๊ทธ๋Œ€๋กœ ํ†ต๊ณผํ•œ๋‹ค โ€” ์—†์œผ๋ฉด ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๋ ˆ๊ฑฐ์‹œ ์ƒ์ˆ˜๋กœ ๋–จ์–ด์ง„๋‹ค). */\n ...(master.identity ? { identity: master.identity } : {}),\n ...(materialDefinitions?.length ? { materialDefinitions } : {}),\n ...(materialClasses?.length ? { materialClasses } : {}),\n ...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),\n ...(operations?.length ? { operations } : {}),\n ...(testSpecifications?.length ? { testSpecifications } : {}),\n ...(personnelClasses?.length ? { personnelClasses } : {}),\n ...(equipmentClasses?.length ? { equipmentClasses } : {}),\n ...(assetClasses?.length ? { 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, ...(l.upstreamId ? { upstreamId: l.upstreamId } : {}),\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 /*\n * โ”€โ”€ ์ด๋ฆ„์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค (2026-08-26) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์—ฌ๊ธฐ๊ฐ€ ํ•ฉ์„ฑํ•œ ํ‘œํ˜„์— `name: '์œ„์„ฑ ์ง€๋„'` ๋ฅผ ๋„ฃ๊ณ  ์žˆ์—ˆ๋‹ค. ์ด ์ธต์€ ์–ธ์–ด ์ค‘๋ฆฝ์ด์–ด์•ผ ํ•˜๋Š”๋ฐ ํ•œ๊ตญ์–ด๊ฐ€\n * ๊ทธ๋Œ€๋กœ ์ €์žฅ๋๋‹ค.\n *\n * ๋‚ฑ๋ง ์—ด์‡ (`twin.representation.map` ๊ฐ™์€ ๊ฒƒ)๋ฅผ ๋„ฃ๋Š” ๊ธธ๋„ ์žˆ๋Š”๋ฐ ํƒํ•˜์ง€ ์•Š์•˜๋‹ค. **ํ‘œํ˜„์˜ ์ด๋ฆ„์€\n * ์‚ฌ๋žŒ์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ฐ’**์ด๊ณ , ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ฐ’ ์•ˆ์— ์—ด์‡ ๊ฐ€ ๋“ค์–ด ์žˆ์œผ๋ฉด ์‚ฌ๋žŒ์ด ํ•œ ๋ฒˆ ๊ณ ์น˜๋Š” ์ˆœ๊ฐ„\n * ๊ทธ ์ž๋ฆฌ๋งŒ ์—ด์‡ ๊ฐ€ ์•„๋‹ˆ๊ฒŒ ๋˜์–ด ๊ทœ์น™์ด ๋‘˜์ด ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด๋ฆ„์„ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค. ํ™”๋ฉด์ด ์ข…๋ฅ˜(`map`)๋กœ ๋ถ€๋ฅด๊ณ , ์‚ฌ๋žŒ์ด ๋ถ™์ด๋ฉด ๊ทธ๋•Œ๋ถ€ํ„ฐ ๊ทธ ์ด๋ฆ„์ด๋‹ค.\n */\n const representations =\n givenReps.length > 0\n ? givenReps\n : geo\n ? [{ id: 'r-map', type: 'map', 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\n }\n\n return { model, spaceContent, warnings }\n}\n\n/**\n * ๋‹ค์‹œ ์ฝ์„ ์‚ฌ์ดํŠธ๋ฅผ ๊ณ ๋ฅธ๋‹ค โ€” **๊ธฐ์–ตํ•ด ๋‘” ์‚ฌ์ดํŠธ ํ•˜๋‚˜๋งŒ**.\n *\n * ๋ชป ์ฐพ์œผ๋ฉด **์ฒซ ์‚ฌ์ดํŠธ๋กœ ๋•Œ์šฐ์ง€ ์•Š๋Š”๋‹ค**: ๋‹ค๋ฅธ ํ˜„์žฅ์˜ ๊ตฌ์กฐ๋ฅผ ์ด ํŠธ์œˆ์— ๋ฎ์–ด์“ฐ๋Š” ์ผ์ด๊ณ , ๊ทธ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€\n * ์•„๋‹ˆ๋ผ **์˜ค๋ฅ˜ ์—†์ด ํ‹€๋ฆฐ ๊ณต์žฅ**์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. ๊ธฐ์–ต์ด ์—†๋Š” ์˜› ํŠธ์œˆ์€ `undefined` ๋ฅผ ๋Œ๋ ค์ฃผ๊ณ , ๋ถ€๋ฅด๋Š” ์ชฝ์ด\n * ๋งˆ์Šคํ„ฐ์˜ ์ •์ฒด(`source` = ์ธ์Šคํ„ด์Šค id)๋กœ ์ฐพ๋Š” ๊ธธ์„ ํƒํ•œ๋‹ค.\n */\nexport function pickOriginSite<T extends { siteId: string }>(\n sites: readonly T[],\n origin: { siteId?: string } | undefined | null\n): { site?: T; reason?: 'no-remembered-site' | 'site-gone' } {\n const wanted = String(origin?.siteId ?? '').trim()\n if (!wanted) return { reason: 'no-remembered-site' }\n const site = sites.find(s => String(s.siteId) === wanted)\n return site ? { site } : { reason: 'site-gone' }\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 * ๋งˆ์Šคํ„ฐ๋ฅผ ์ฝ์–ด ํŠธ์œˆ ๊ตฌ์กฐ(TwinModelDef) + ๊ณต๊ฐ„(Space content)์„ ์ƒ์„ฑ. ์†๋ฐฐ์„ ์ด ์•„๋‹ˆ๋ผ ์ธ์ œ์ŠคํŠธ๋กœ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ๋ฅธ๋‹ค.\n *\n * ๊ทœ์œจ(ADR-0018): ๋„๋ฉ”์ธ ํƒ€์ž…(location.type=๋…ธ๋“œ์šฉ)์€ ์ปค๋„ ์นดํƒˆ๋กœ๊ทธ ์–ดํœ˜๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜์˜(๋ฐœ๋ช… ๊ธˆ์ง€).\n * location ์€ role ๋กœ ๋…ธ๋“œ(์šด์˜์ )ยทarea(๊ณต๊ฐ„์˜์—ญ)ยทboth ๋ฅผ ๊ตฌ๋ถ„ โ€” ๋…ธ๋“œโ†’TwinModelDef, areaโ†’Space.areas.\n * ์ขŒํ‘œยทrepresentations ๋Š” ํŠธ์œˆ ๊ณต๊ฐ„์ธต(๋ณด์™„/์ถ”๊ฐ€). ์‹ค ์‹œ์Šคํ…œ์ด ์ขŒํ‘œ๋ฅผ ์•ˆ ์ฃผ๋ฉด layout ์—†์ด ์œ„์ƒ๋งŒ ์ธ์ œ์ŠคํŠธ.\n */\n\nimport type { DomainSystem, EquipmentLevel, TestSpecificationCriterion, WorkCalendarEntry } from '@operato/ops-contract'\n\nexport interface RefLocation {\n id: string\n type: string // ๋…ธ๋“œ๋Š” ์ปค๋„ ๋…ธ๋“œํƒ€์ž…(dock/storage/yard-slotโ€ฆ), area ๋Š” ๊ณต๊ฐ„ region ํƒ€์ž…\n name?: string\n description?: string\n role: 'location' | 'area' | 'both'\n parentId?: string\n /**\n * **์ „๊ธฐ์ ์œผ๋กœ ์–ด๋””์„œ ๋ฐ›๋Š”๊ฐ€** โ€” ์ด ์ž๋ฆฌ์— ์ „๊ธฐ๋ฅผ ์ฃผ๋Š” ์ƒ๋ฅ˜ ์ž๋ฆฌ(์ปค๋„ ๊ณ„์•ฝ์˜ `upstreamId`).\n *\n * `parentId`(๊ณต๊ฐ„ ํฌํ•จ)์™€ ๋”ฐ๋กœ ๋‘๋Š” ์ด์œ ๋Š” ์ปค๋„ ๊ณ„์•ฝ์— ์ ํ˜€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋น ๋œจ๋ฆฌ๋ฉด ๋งˆ์Šคํ„ฐ๊ฐ€ ๋งํ•œ ๊ณ„ํ†ต์ด\n * ๋ชจ๋ธ๊นŒ์ง€ ์˜ค์ง€ ๋ชปํ•˜๊ณ , ๋ฟŒ๋ฆฌ ๊ณ„๋Ÿ‰ ํŒ์ •์ด ๋ถ„๊ธฐ ๊ณ„๋Ÿ‰๊ธฐ๊นŒ์ง€ ๋ฟŒ๋ฆฌ๋กœ ์„ธ์–ด **๋ถ€ํ•˜๊ฐ€ ๋‘ ๋ฐฐ๋กœ** ๋ณด์ธ๋‹ค.\n */\n upstreamId?: 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 /**\n * ์ž๋ฆฌ์˜ **์—ด๋ฆฐ ์†์„ฑ** โ€” ํ‘œ์ค€ `OperationalLocationProperty`(์„ค๋น„ยท์‚ฌ๋žŒยท์ž์‚ฐ๊ณผ ๊ฐ™์€ ๋ชจ์–‘).\n *\n * ๋ฌด์—‡์ด ์—ฌ๊ธฐ ์‹ค๋ฆฌ๋‚˜: **์ž๋ฆฌ์˜ ๋ฌผ๋ฆฌ๋Ÿ‰**์ด๋‹ค. ์—๋„ˆ์ง€์˜ ๊ณ„์•ฝ์ „๋ ฅ(`contract.kW`)์ด ์ฒซ ์‚ฌ๋ก€๋‹ค โ€”\n * ๊ทธ ๊ฐ’์ด ์•‰์„ ์ž๋ฆฌ๊ฐ€ ์—†์–ด์„œ EMS ์ปค๋„์€ ๊ณ„์•ฝ ๋Œ€๋น„ ํŒ์ •์„ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค(์ž๋ฆฌ๊ฐ€ ์—†์œผ๋ฉด ์‚ฌ์‹ค์ด\n * ๋“ค์–ด์˜ค์ง€ ๋ชปํ•œ๋‹ค). ์ปค๋„์€ ์ž๊ธฐ๊ฐ€ **์ฝ๋Š”** ์†์„ฑ id ๋งŒ ์„ ์–ธํ•˜๊ณ (`EMS_PROPERTY`) ๋‚˜๋จธ์ง€๋Š” ๋‚˜๋ฅธ๋‹ค.\n */\n properties?: RefResourceProperty[]\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\n/**\n * ๊ฒ€์‚ฌ ๋ช…์„ธ โ€” **์ž์›์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ**(ISA-95 `TestSpecification`).\n *\n * ํ‘œ์ค€ ํ•„๋“œ๋Š” ์…‹๋งŒ ๋‹ด๋Š”๋‹ค(`ID`ยท`Description`ยท`Version`) โ€” ์žฌ๋Š” ์†์„ฑ๊ณผ ํ•ฉ๊ฒฉ ๊ธฐ์ค€์€ ์•„์ง 1์ฐจ ์ถœ์ฒ˜์™€\n * ๋Œ€์กฐํ•˜์ง€ ์•Š์•˜๋‹ค(์ปค๋„ ๊ณ„์•ฝ์˜ ๋จธ๋ฆฌ๋ง์ด ๊ทธ ์‚ฌ์‹ค์„ ์ ์–ด ๋‘์—ˆ๋‹ค).\n */\n/**\n * ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” **\"์ด ๊ฐœ์ฒด๊ฐ€ ๊ทธ ์‹œํ—˜์„ ํ†ต๊ณผํ–ˆ๋‹ค\"** ๋Š” ๊ธฐ๋ก(ISA-95 ๊ฒฐ๊ณผ).\n *\n * ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ๋Š” ๊ณณ์€ ํŠธ์œˆ์ด ์•„๋‹ˆ๋‹ค(์ธ์‚ฌยท์ •๋น„ ์‹œ์Šคํ…œ์ด ๊ธฐ๋กํ•œ๋‹ค) โ€” ๊ทธ๋ž˜์„œ ๊ด€์ธก์ด๋ฉด์„œ **์„ ์–ธ ๊ฒฝ๋กœ๋กœ** ์˜จ๋‹ค.\n * ์ปค๋„์€ ์ด ๊ฐ’์ด ์žˆ์„ ๋•Œ๋งŒ ์ž๊ฒฉ์„ ํŒ์ •ํ•œ๋‹ค: ์—†์œผ๋ฉด ์ œ์•ฝ์ด ์•„๋‹ˆ๊ณ (๋ผ์ธ์ด ๊ตถ์ง€ ์•Š๋Š”๋‹ค), ์žˆ์œผ๋ฉด ๋งŒ๋ฃŒยท\n * ๋ถˆํ•ฉ๊ฒฉ์ด ๋ฐฐ์ •์„ ๋ง‰๋Š”๋‹ค.\n */\nexport interface RefTestResult {\n specId: string\n result: 'pass' | 'fail'\n at?: string\n /** ์—†์œผ๋ฉด ๋ฌด๊ธฐํ•œ โ€” ์ง์ž‘์œผ๋กœ ๊ธฐํ•œ์„ ๋งŒ๋“ค๋ฉด ๋ฉ€์ฉกํ•œ ์ž๊ฒฉ์ž๊ฐ€ ์˜ค๋ฅ˜ ์—†์ด ์‚ฌ๋ผ์ง„๋‹ค. */\n expiresAt?: string\n}\n\nexport interface RefTestSpecification {\n id: string\n /** ํ‘œ์‹œ๋ช… โ€” i18n ํ‚ค์ผ ์ˆ˜ ์žˆ๋‹ค. ์ฝ๋Š” ์–ดํœ˜๋ฅผ ํ•˜๋‚˜๋กœ ๋งž์ถ”๋ ค๊ณ  ์ธ์ œ์ŠคํŠธ๊ฐ€ `name` ์œผ๋กœ ์˜ฎ๊ธด๋‹ค. */\n description?: string\n version?: string\n /**\n * ํŒ์ • ๊ธฐ์ค€๋“ค โ€” ์ปค๋„ ๊ณ„์•ฝ์˜ `TestSpecification.criteria` ๋ฅผ ๊ทธ๋Œ€๋กœ ๋‚˜๋ฅธ๋‹ค.\n *\n * **๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค.** ์ปค๋„ ํƒ€์ž…์„ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฏ€๋กœ `limit.{minimum,maximum,uom}` ยท\n * `expression` ยท `evaluatedPropertyId` ๊ฐ€ ์›๋ณธ์—์„œ ์ปค๋„๊นŒ์ง€ ํ•œ ์ด๋ฆ„์œผ๋กœ ๊ฐ„๋‹ค.\n *\n * ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๋ช…์„ธ๋Š” ์„ฑ๋ฆฝํ•œ๋‹ค(์ด๋ฆ„๋งŒ์œผ๋กœ ใ€Œ๋ฌด์—‡์œผ๋กœ ๊ฒ€์ฆํ–ˆ๋‚˜ใ€์— ๋‹ตํ•œ๋‹ค). ์„ ์–ธํ•˜๋ฉด **ํŒ์ •์—\n * ๊ทผ๊ฑฐ๊ฐ€ ์žˆ๋Š”์ง€**๋ฅผ ๋ฌผ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค โ€” ์ปค๋„์˜ `criterionSaysNothing` ์ด ๊ทธ๊ฒƒ์„ ์„ผ๋‹ค.\n */\n criteria?: TestSpecificationCriterion[]\n}\n\nexport interface RefEquipment {\n id: string\n kind: string\n /**\n * ์†ํ•œ **๋“ฑ๊ธ‰๋“ค** โ€” ๊ณ„์•ฝ ์„ ์–ธ์˜ `equipment[].equipmentClassIds` ๋กœ ๊ทธ๋Œ€๋กœ ๊ฐ„๋‹ค.\n *\n * โ”€โ”€ ์™œ ๋น ์ ธ ์žˆ์—ˆ๋‚˜ (2026-09-04) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„์— ์ด ์ถ•์„ ์—ฌ๋Š” ๋‚  ๋ชจ๋ธยท์ƒํƒœยท์ €๋„ยท๋ฏธ๋Ÿฌ๊นŒ์ง€ ๋ฐฐ์„ ํ–ˆ๋Š”๋ฐ **์ ‘์ˆ˜๋ฉด์ด ๋น ์กŒ๋‹ค.** ์‚ฌ๋žŒ๊ณผ ์ž์‚ฐ์€\n * ๋ฐ›๋Š”๋ฐ(`personnelClassIds`ยท`assetClassIds`) ์„ค๋น„๋งŒ ์—†์—ˆ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์›๋ณธ์ด ์„ค๋น„ 22๋Œ€์— ๋“ฑ๊ธ‰์„ ๋‹ค ์ฑ„์›Œ ๋ณด๋ƒˆ๋Š”๋ฐ **๋ฌธํ„ฑ์—์„œ ๋ฒ„๋ ค์กŒ๋‹ค** โ€” ๊ฑฐ์ ˆ๋„ ๊ฒฝ๊ณ ๋„ ์—†์ด.\n * ๋“ฑ๊ธ‰ ๋ชฉ๋ก์€ ์„œ๊ณ  ์†Œ์†์€ ์•„๋ฌด๋„ ์—†์–ด์„œ, ํ™”๋ฉด์—์„œ ๋“ฑ๊ธ‰์„ ๊ณจ๋ผ๋„ ์„ค๋น„๊ฐ€ ์•ˆ ๋‚˜์™”๋‹ค.\n *\n * ์†Œ์†์€ ์ด ์„ ์–ธ๊ณผ `kind` ๋ฅผ ํ•ฉ์นœ ๊ฒƒ์ด๋‹ค(ยง`equipmentClassMembership`) โ€” ํŒ์ •ํ•˜๋Š” ์ชฝ์ด ๊ทธ ํ•จ์ˆ˜๋ฅผ\n * ์ง€๋‚œ๋‹ค.\n */\n equipmentClassIds?: string[]\n /** ์‚ฌ๋žŒ์ด ๋ถ€๋ฅด๋Š” ์ด๋ฆ„ โ€” ์—†์œผ๋ฉด ํ™”๋ฉด์ด id ๋ฅผ ๋ณด์ธ๋‹ค(id ๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋ฒ ๋ผ์ง€ ์•Š๋Š”๋‹ค). */\n name?: string\n /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\n description?: string\n homeLocationId: string\n mtbfMs?: number // ํ‰๊ท  ๊ณ ์žฅ ๊ฐ„๊ฒฉ(ํ™•๋ฅ ์  ๊ณ ์žฅ) โ€” ์ง€์ • ์‹œ ์ปค๋„์ด breakdown ์‹œ๋ฎฌ โ†’ ์ฃผ๋ชฉ(๊ณ ์žฅ) ๋ฐœ์ƒ\n mttrMs?: number // ํ‰๊ท  ์ˆ˜๋ฆฌ ์‹œ๊ฐ„\n /**\n * **์ด ์„ค๋น„์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์ปค๋„ ์„ ์–ธ์˜ `equipment[].identity` ๋กœ ๊ทธ๋Œ€๋กœ ๊ฐ„๋‹ค.\n *\n * ์˜ˆ์ „ ์ด๋ฆ„์€ `gs1Id` ์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ **GS1 ํ‚ค๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค** โ€” ์‹ค์ธกํ•œ ๊ฐ’์€ ์ธ๋ฒ„ํ„ฐ์˜\n * ํ•˜๋“œ์›จ์–ด ์‹๋ณ„์ž(`ES100000007d8d061d-1`)์ด๊ณ , ์›๋ณธ์ด GIAI ๋ฅผ ์ฃผ๋ฉด ๊ทธ๊ฒƒ๋„ ์—ฌ๊ธฐ ๋“ค์–ด์˜จ๋‹ค.\n * ์ด๋ฆ„์ด ํ•œ ์ข…๋ฅ˜๋งŒ ๊ฐ€๋ฆฌํ‚ค๋ฉด ๋‹ค๋ฅธ ์ข…๋ฅ˜๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ ๊ทธ ์ž๋ฆฌ๋ฅผ ๋ชป ์“ด๋‹ค.\n *\n * ์ž๋ฆฌ(`RefLocation.gs1Id`)๋Š” ๊ทธ๋Œ€๋กœ๋‹ค โ€” ๊ทธ์ชฝ์€ ์‹ค์ œ๋กœ SGLN ์ด ์˜จ๋‹ค.\n */\n identity?: string\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 /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\n /**\n * **์ด ์‚ฌ๋žŒ์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์ปค๋„ ์„ ์–ธ์˜ `personnel[].identity` ๋กœ ๊ฐ„๋‹ค.\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๋ ˆ์ธ์ด ๋ฌผ์Œ, 2026-09-05) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์„ค๋น„์—์„œ ์ด ์ž๋ฆฌ๋ฅผ ๋งŒ๋“  ์ด์œ ๊ฐ€ ์‚ฌ๋žŒ์—๊ฒŒ๋„ ๊ทธ๋Œ€๋กœ ๊ฑธ๋ฆฐ๋‹ค: **์ง€์—ญ ์ด๋ฆ„์€ ๊ทธ ํ˜„์žฅ ์•ˆ์—์„œ๋งŒ\n * ๊ณ ์œ ํ•˜๋‹ค.** ์ธ๋ฒ„ํ„ฐ `001` ์ด ๋‘ ๋ฐœ์ „์†Œ์— ์žˆ์–ด์„œ ํ•จ๊ป˜ ์ง‘๊ณ„ํ•˜๋‹ˆ ํ•œ์ชฝ ๋ฐœ์ „๋Ÿ‰์ด ์‚ฌ๋ผ์กŒ๋‹ค.\n * `E-1001` ๋„ ๋‹ค๋ฅธ ๊ณต์žฅ์— ์žˆ์„ ์ˆ˜ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ํ˜„์žฅ์„ ํ•จ๊ป˜ ๋ณด๋Š” ์ˆœ๊ฐ„ ๊ฐ™์€ ์ผ์ด ๋‚œ๋‹ค.\n *\n * โ”€โ”€ **์—ฌ๊ธฐ์— ๊ฐœ์ธ์ •๋ณด๋ฅผ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค** โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์„ค๋น„์™€ ์‚ฌ๋žŒ์ด ๊ฐˆ๋ฆฌ๋Š” ์ž๋ฆฌ๊ฐ€ ์ด๊ฒƒ์ด๋‹ค. ์„ค๋น„์˜ ์ •์ฒด์„ฑ์€ ํ•˜๋“œ์›จ์–ด ์ผ๋ จ๋ฒˆํ˜ธ์ด๊ณ  ์•„๋ฌด์—๊ฒŒ๋„ ํ•ด๊ฐ€\n * ์—†๋‹ค. ์‚ฌ๋žŒ์˜ ใ€Œ์ „์—ญ์—์„œ ๊ณ ์œ ํ•œ ๊ฐ’ใ€์€ ์‚ฌ์›๋ฒˆํ˜ธยท์ถœ์ž…์นด๋“œยท์ฃผ๋ฏผ๋“ฑ๋ก์ฒ˜๋Ÿผ **๊ทธ ์‚ฌ๋žŒ์— ๊ด€ํ•œ ์‚ฌ์‹ค**\n * ์ด๊ณ , ์ €๋„์€ ๋˜ํ’€์ด ์ฝํžˆ๊ณ  ๋ฏธ๋Ÿฌ๋กœ ๋ณต์ œ๋˜๊ณ  ๊ตฌ๋…์œผ๋กœ ๋ฐฉ์†ก๋œ๋‹ค โ€” ํ•œ ๋ฒˆ ๋“ค์–ด๊ฐ€๋ฉด ์ง€์›Œ์ง€์ง€ ์•Š๋Š”๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด ์นธ์ด ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ **ํ˜„์žฅ์„ ์•ž์— ๋ถ™์—ฌ ์ „์—ญ์—์„œ ๊ณ ์œ ํ•ด์ง„ ์ด๋ฆ„**์ด๋‹ค. ๊ทธ ์ด์ƒ์ด ์•„๋‹ˆ๋‹ค.\n *\n * ```\n * ๋งž๋‹ค urn:hatiolab:mes-line-a:obj:E-1001 (ยง`objectUri` ๊ฐ€ ๋งŒ๋“ ๋‹ค)\n * https://hatiotrailer.com/twin/obj/E-1001\n * ์•„๋‹ˆ๋‹ค ์นด๋“œ๋ฒˆํ˜ธ ยท ์‚ฌ์›๋ฒˆํ˜ธ ์›๋ฌธ ยท ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ ยท ์ƒ์ฒด ์‹๋ณ„์ž\n * ```\n *\n * ใ€Œ์ด ์‚ฌ๋žŒ์ด ๋ˆ„๊ตฌ์ธ๊ฐ€ใ€๋Š” ์ธ์‚ฌ ์‹œ์Šคํ…œ์ด ๋‹ตํ•  ๋ฌผ์Œ์ด๊ณ  ํŠธ์œˆ์˜ ๋ฌผ์Œ์ด ์•„๋‹ˆ๋‹ค. ํŠธ์œˆ์€ **๊ฐ™์€\n * ์‚ฌ๋žŒ์ธ์ง€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ธ์ง€**๋งŒ ์•Œ๋ฉด ๋œ๋‹ค โ€” ๊ทธ ์ผ์— ๊ฐœ์ธ์ •๋ณด๋Š” ํ•„์š” ์—†๋‹ค.\n *\n * ๊ฐ’์ด ์—†์œผ๋ฉด ๋น„์šด๋‹ค. ์ง€๊ธˆ ์›๋ณธ์ด ๊ทธ๋Ÿฐ ๊ฐ’์„ ์ฃผ์ง€ ์•Š์œผ๋ฏ€๋กœ ๋‹น๋ถ„๊ฐ„ ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค.\n */\n identity?: 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 /** ์‹œํ—˜ ๊ฒฐ๊ณผ โ€” ์ž๊ฒฉ์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋Š” ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค(ยงRefTestResult). */\n testResults?: RefTestResult[]\n /**\n * ์†ํ•œ ๋“ฑ๊ธ‰๋“ค โ€” ํ‘œ์ค€ `PhysicalAssetClassID`(๋ณต์ˆ˜). ํŒ”๋ ˆํŠธ๊ฐ€ 'euro-pallet' ์ด๋ฉด์„œ 'food-grade' ์ผ ์ˆ˜ ์žˆ๋‹ค.\n * ๊ณต์ •์˜ ์š”๊ตฌ๋Š” ๋“ฑ๊ธ‰ ํ•˜๋‚˜ + ์ˆ˜๋Ÿ‰์ด๋‹ค(ํ‘œ์ค€ `PhysicalAssetSpecification`).\n */\n assetClassIds?: string[]\n /** ๊ธฐ๋ณธ ์œ„์น˜. */\n homeLocationId?: string\n /**\n * **์ด ์ž์‚ฐ์˜ ์ „์—ญ ์ •์ฒด์„ฑ** โ€” ์„ค๋น„์™€ ๊ฐ™์€ ์ด๋ฆ„์ด๋‹ค(ยง`RefEquipment.identity`).\n *\n * โ”€โ”€ ์™œ ์ด๋ฆ„์„ ๋ฐ”๊ฟจ๋‚˜ (2026-09-04) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `gs1Id` ์˜€๋‹ค. ์„ค๋น„์—์„œ ๊ทธ ์ด๋ฆ„์„ ๋ฐ”๊พผ ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์—๋„ ๊ทธ๋Œ€๋กœ ์ ์šฉ๋œ๋‹ค โ€” **GS1 ํ‚ค๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด\n * ์ •์ƒ์ด๋‹ค.** ์ž์‚ฐ์˜ ์‹ค์ธก ๊ฐ’๋„ ์ œ์กฐ๋ฒˆํ˜ธยท์‚ฌ๋‚ด ๊ด€๋ฆฌ๋ฒˆํ˜ธ์ด๊ณ , GS1 ์„ ์š”๊ตฌํ•˜๋Š” ์ด๋ฆ„์„ ๋‘๋ฉด ๊ทธ๊ฒƒ์„\n * ์ฑ„์šฐ๋Š” ์ชฝ์ด ์—†๋Š” ํ‚ค๋ฅผ ์ง€์–ด๋‚ด๊ฑฐ๋‚˜ ์นธ์„ ๋น„์›Œ ๋‘”๋‹ค.\n *\n * ๊ทธ๋ฆฌ๊ณ  ๋งˆ์Šคํ„ฐ๋Š” ์ด๋ฏธ `identity` ๋กœ ๋‚ธ๋‹ค(์„ค๋น„ยท์ž์‚ฐ ๋‘˜ ๋‹ค). ์ด ์ž๋ฆฌ๋งŒ ๋‹ค๋ฅธ ์ด๋ฆ„์ด๋ผ **์›๋ณธ์ด\n * ์ฑ„์šฐ๋Š” ์ˆœ๊ฐ„ ์กฐ์šฉํžˆ ์‚ฌ๋ผ์กŒ๋‹ค.** ์ง€๊ธˆ ์ž์‚ฐ 26๋Œ€๊ฐ€ ๋‹ค ๋น„์–ด ์žˆ์–ด ๋ฒ„๋ ค์ง€๋Š” ๊ฐ’์€ ์—†์—ˆ๋‹ค โ€”\n * ์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๋ ˆ์ธ์ด ๊ทธ๊ฒƒ์„ ์žฌ์„œ ใ€Œ๋ˆ„๊ฐ€ ์ฑ„์šฐ๋Š” ์ˆœ๊ฐ„ใ€์ด๋ผ๊ณ  ์งš์—ˆ๋‹ค.\n *\n * ์ž๋ฆฌ ์ชฝ(`RefLocation.gs1Id`)์€ ๊ทธ๋Œ€๋กœ๋‹ค โ€” ๊ฑฐ๊ธฐ๋Š” ์‹ค์ œ๋กœ SGLN ์ด ์˜จ๋‹ค.\n */\n identity?: 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\n/**\n * **์ด ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•** โ€” ํŠธ์œˆ์ด ์ž๊ธฐ ์›๋ณธ์„ ๊ธฐ์–ตํ•˜๋Š” ์ž๋ฆฌ.\n *\n * ํŠธ์œˆ์€ ์›๋ณธ์„ ๋น„์ถœ ๋ฟ์ด๋ฏ€๋กœ(ADR-0028), ์›๋ณธ์ด ๋‹ฌ๋ผ์ง€๋ฉด **๋‹ค์‹œ ์ฝ์–ด์•ผ** ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ง€๊ธˆ๊นŒ์ง€\n * ํŠธ์œˆ์€ \"๋‚ด๊ฐ€ ๋ฌด์—‡์—์„œ ๋‚˜์™”๋‚˜\" ๋ฅผ ๋‚จ๊ธฐ์ง€ ์•Š์•˜๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๋กœ ๋“ค์–ด์˜จ ํŠธ์œˆ์€ `TwinReference` ํ–‰์ด\n * ์žˆ์—ˆ์ง€๋งŒ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์„ธ์šด ํŠธ์œˆ์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†์—ˆ๊ณ , ๊ทธ๋ž˜์„œ **๋‹ค์‹œ ์ฝ์„ ๋Œ€์ƒ์ด ์—†๋Š” ํŠธ์œˆ**์ด\n * ๋งŒ๋“ค์–ด์กŒ๋‹ค. ์›๋ณธ์„ ์žƒ์€ ํŠธ์œˆ์€ ์ฒซ๋‚ ์˜ ๋ชจ์Šต์— ์˜์›ํžˆ ๋จธ๋ฌธ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์›์ฒœ์ด ๋ฌด์—‡์ด๋“  ์—ฌ๊ธฐ ํ•œ ์ž๋ฆฌ์— ๋‚จ๊ธด๋‹ค. ๋‹ค์‹œ ์ฝ๊ธฐ๋Š” ์ด ๊ฐ’ ํ•˜๋‚˜๋งŒ ๋ณด๋ฉด ๋œ๋‹ค.\n */\nexport type MasterOrigin =\n /**\n * ๋“ฑ๋ก๋œ ๋ ˆํผ๋Ÿฐ์Šค(์–ด๋Œ‘ํ„ฐ)์—์„œ ์™”๋‹ค โ€” ๋‹ค์‹œ ์ฝ๊ธฐ = ๊ทธ ์–ด๋Œ‘ํ„ฐ๋กœ ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜จ๋‹ค.\n *\n * `source` ๋Š” **๋ ˆํผ๋Ÿฐ์Šค ๋“ฑ๋ก ์ด๋ฆ„**์ด๊ณ  ๊ทธ ์ฐธ์กฐ๊ฐ€ ๋ณด๊ณ ํ•˜๋Š” ์‚ฌ์ดํŠธ ์ „๋ถ€์— ๊ฐ™๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋А ์‚ฌ์ดํŠธ์—์„œ\n * ์˜จ ํŠธ์œˆ์ธ์ง€๋Š” `siteId` ๊ฐ€ ์žˆ์–ด์•ผ ์•ˆ๋‹ค โ€” ์—†์œผ๋ฉด ๋‹ค์‹œ ์ฝ๊ธฐ๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ ์ฐพ์ง€ ๋ชปํ•œ๋‹ค(2026-08-18 ์‹ค์ธก:\n * ์‚ฌ์ดํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ์ฐธ์กฐ์—์„œ ์˜จ ํŠธ์œˆ์€ ์žฌ๋™๊ธฐ๊ฐ€ ์ „๋ถ€ ๊ฑฐ์ ˆ๋๋‹ค. ์ฐธ์กฐ ์ด๋ฆ„์„ ์‚ฌ์ดํŠธ๋ณ„ ๋งˆ์Šคํ„ฐ์˜\n * `source`(=์ธ์Šคํ„ด์Šค id)์™€ ๋น„๊ตํ•˜๊ณ  ์žˆ์—ˆ๋‹ค โ€” ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋น„๊ตํ•œ ๊ฒƒ์ด๋‹ค).\n */\n | { kind: 'reference'; source: string; siteId?: string; spaceId?: string }\n /**\n * ํ…œํ”Œ๋ฆฟ + ๋…ธ๋ธŒ๋กœ ํ•ฉ์„ฑํ–ˆ๋‹ค โ€” ๋‹ค์‹œ ์ฝ๊ธฐ = ๊ฐ™์€ ๋…ธ๋ธŒ๋กœ ๋‹ค์‹œ ์ง“๋Š”๋‹ค(ํ•ฉ์„ฑ์€ ๊ฒฐ์ •์ ์ด๋‹ค).\n *\n * `spaceId` ๋Š” **๋งŒ๋“ค ๋•Œ ๊ณ ๋ฅธ ํ˜„์žฅ**์ด๋‹ค(ํ•ฉ์ณ ๋„ฃ๊ธฐ). ๊ธฐ์–ตํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์‹œ ์ฝ์„ ๋•Œ ํŠธ์œˆ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ž๊ธฐ\n * ํ˜„์žฅ์„ ๋– ๋‚œ๋‹ค โ€” ํ…œํ”Œ๋ฆฟ์ด ๋‚ธ ๊ธฐ๋ณธ ๊ณต๊ฐ„์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ทธ ํ˜„์žฅ์˜ ๊ฐ’(์š”๊ธˆ ๋“ฑ)๋„ ํ•จ๊ป˜\n * ์žƒ๋Š”๋‹ค(2026-08-18 ์‹ค์ธก: ํ•œ ํ˜„์žฅ์— ํ•ฉ์ณ ๋‘” EMS ํŠธ์œˆ ์—ฌ๋Ÿ์ด ์žฌ๋™๊ธฐ ๋’ค ๊ฐ์ž ๊ณต๊ฐ„์œผ๋กœ ํฉ์–ด์กŒ๋‹ค).\n */\n | { kind: 'template'; templateId: string; params: Record<string, unknown>; spaceId?: string }\n\nexport interface ReferenceMaster {\n source: string\n /**\n * ์–ด๋А ์ข…๋ฅ˜์˜ ํŠธ์œˆ์ธ๊ฐ€ โ€” **์ปค๋„ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ์ •๋ณธ**์ด๋‹ค(`DomainSystem`).\n *\n * ์˜ˆ์ „์—๋Š” `'wms' | 'yms' | 'mes'` ๋ฅผ ์—ฌ๊ธฐ ์ ์–ด ๋’€๋‹ค. ์ปค๋„์— ์ข…๋ฅ˜๊ฐ€ ํ•˜๋‚˜ ๋Š˜ ๋•Œ(์—๋„ˆ์ง€) ์ด ์ค„์ด\n * ํ•จ๊ป˜ ์›€์ง์—ฌ์•ผ ํ•˜๋Š”๋ฐ, ์†์œผ๋กœ ์ ํžŒ ๋ชฉ๋ก์€ ๊ทธ๊ฒƒ์„ ์•Œ๋ ค ์ฃผ์ง€ ์•Š๋Š”๋‹ค โ€” ์–ดํœ˜์˜ ์ง‘์€ ํ•œ ๊ณณ์ด์–ด์•ผ ํ•œ๋‹ค.\n */\n system: DomainSystem\n siteName: string\n /** ๊ฒ€์‚ฌ ๋ช…์„ธ โ€” ์ž์›ยท๋“ฑ๊ธ‰์˜ `testSpecificationIds` ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ. */\n testSpecifications?: RefTestSpecification[]\n /**\n * ์ด ๋งˆ์Šคํ„ฐ๊ฐ€ ์–ด๋””์„œ ๋‚˜์™”๋‚˜ โ€” **๋‹ค์‹œ ์ฝ๊ธฐ์˜ ์œ ์ผํ•œ ๊ทผ๊ฑฐ.** ์—†์œผ๋ฉด ๊ทธ ํŠธ์œˆ์€ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์—†๊ณ ,\n * ์กฐํšŒ ํ™”๋ฉด์ด ๊ทธ ์‚ฌ์‹ค์„ ๊ทธ๋Œ€๋กœ ๋งํ•œ๋‹ค(์—†๋Š” ๊ฒƒ์„ ์žˆ๋Š” ์ฒ™ํ•˜์ง€ ์•Š๋Š”๋‹ค).\n */\n origin?: MasterOrigin\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 * ์ƒ์‚ฐ ์„ ์–ธ โ€” `TwinModelDef.productionSpec` ์œผ๋กœ ํ†ต๊ณผํ•œ๋‹ค(ISA-95 OperationsSegment + BOM).\n *\n * ์˜ˆ์ „ ์ด๋ฆ„์€ `mesSpec` ์ด์—ˆ๋‹ค. ๋‹ด๊ธด ๊ฒƒ์€ MES ๋งŒ์˜ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ \"์ž์žฌ๋ฅผ ์†Œ๋น„ํ•ด ์ž์žฌ๋ฅผ ์‚ฐ์ถœํ•˜๋Š”\n * ๊ณต์ •\" ์ด๊ณ , ์ด๋ฆ„์ด MES ์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ฐฝ๊ณ  ํŠธ์œˆ์€ ์ด ์ž๋ฆฌ๋ฅผ ์“ธ ์ƒ๊ฐ์กฐ์ฐจ ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค(์œ ํ†ต๊ฐ€๊ณต ์ฐฝ๊ณ ๊ฐ€\n * BOM ์„ ์„ค๋ช… ๋ฌธ์„œ์—๋งŒ ์ ์–ด ๋‘” ์ฑ„ ํ‚คํŠธ๋ฅผ ๋ชป ๋งŒ๋“œ๋Š” ํŠธ์œˆ์„ ๋งŒ๋“  ์›์ธ). ๊ทผ๊ฑฐ๋Š” ์ปค๋„ ๊ณ„์•ฝ ์ฃผ์„์—.\n */\n productionSpec?: unknown\n /**\n * **์ด ์›๋ณธ์ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“œ๋Š” ์ด๋ฆ„๊ณต๊ฐ„** โ€” `TwinModelDef.identity` ๋กœ ํ†ต๊ณผํ•œ๋‹ค.\n *\n * **์„ ์–ธ์ด ์—†์œผ๋ฉด ์ปค๋„์ด ๊ฑฐ์ ˆํ•œ๋‹ค** (0.7.45~). ์˜ˆ์ „์—๋Š” ์ƒ์ˆ˜ ํ”„๋ฆฌํ”ฝ์Šค๋กœ ํŒ”๋ ˆํŠธยทํŠธ๋ ˆ์ผ๋Ÿฌยท๋ฌธ์„œ๋ฅผ\n * ๋งŒ๋“ค์—ˆ๋Š”๋ฐ(`0614141` โ€” GS1 ์ด ๊ทœ๊ฒฉ ์˜ˆ์ œ๋กœ ์“ฐ๋‹ค ๋ฒ„๋ฆฐ ๊ฐ’์ด๊ณ  `06โ€ฆ` ์€ ์‹ค ๋ฐฐ์ • ๋Œ€์—ญ์ด๋‹ค), ๊ทธ ๊ฐ’์€\n * ์ €๋„์— ์˜์›ํžˆ ๋‚จ์œผ๋ฉด์„œ ์ง€์–ด๋‚ธ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•ด ์ฃผ๋Š” ๋ฐ๊ฐ€ ์—†์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋„์ด ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์›๋ณธ์ด ์ž๊ธฐ ๋„๋ฉ”์ธ์„ ๋งํ•˜๋ฉด ๊ทธ ์•„๋ž˜์—์„œ ๋งŒ๋“ ๋‹ค โ€” ๊ทธ๊ฒƒ์ด ํ‘œ์ค€ ์ •ํ•ฉ์ด๋‹ค(CBV 2.0 ยง8.2.4ยทยง8.5.5,\n * ใ€Œ๊ทธ ์ธํ„ฐ๋„ท ๋„๋ฉ”์ธ ์†Œ์œ ์ž๊ฐ€ ๋ฐฐ์ •ํ•œ๋‹คใ€). GS1 ํ‚ค๋ฅผ ์“ฐ๋ ค๋ฉด `documentTypes` + `companyPrefix` ์ด๊ณ ,\n * ๊ทธ๋•Œ **์ž๋ฆฌ ์ˆ˜๊ฐ€ ๋งž์•„์•ผ ํ•œ๋‹ค**(SGTIN ์€ ํ”„๋ฆฌํ”ฝ์Šค + ํ’ˆ๋ชฉ์ฐธ์กฐ = 13์ž๋ฆฌ, GS1 TDS).\n *\n * ์ •์ฒด์„ฑ์€ ์ƒ์‚ฐ๊ณผ ๋ฌด๊ด€ํ•˜๋ฏ€๋กœ `productionSpec` ์ด ์•„๋‹ˆ๋ผ **๋ชจ๋ธ**์ด ๊ฐ–๋Š”๋‹ค โ€” ์ฐฝ๊ณ ยท์•ผ๋“œ๋Š” ์•„๋ฌด๊ฒƒ๋„\n * ์ƒ์‚ฐํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ํŒ”๋ ˆํŠธยทํŠธ๋ ˆ์ผ๋Ÿฌ๋ฅผ ์‹๋ณ„ํ•œ๋‹ค.\n */\n identity?: 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 * ์ปค๋„ฅํ„ฐ๊ฐ€ **์˜ฎ๊ธฐ๋Š” ๋™์•ˆ ์•Œ๊ฒŒ ๋œ ๊ฒƒ.** ์™ธ๋ถ€ ์‹œ์Šคํ…œ์˜ ๊ฐ’์„ ์šฐ๋ฆฌ ์–ดํœ˜๋กœ ๋ชป ์˜ฎ๊ฒจ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค๋ฉด\n * ์—ฌ๊ธฐ์— ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด `masterToTwin` ์˜ ๊ฒฝ๊ณ ์™€ ํ•œ ์ค„๊ธฐ๋กœ ํ•ฉ์ณ์ ธ ํ™”๋ฉด๊นŒ์ง€ ๊ฐ„๋‹ค.\n *\n * ์ด ์ž๋ฆฌ๊ฐ€ ์—†๋˜ ๋™์•ˆ ์ปค๋„ฅํ„ฐ๋Š” ํ•  ๋ง์ด ์žˆ์–ด๋„ **๋งํ•  ๊ณณ์ด ์—†์—ˆ๋‹ค.** ๊ทธ๋ž˜์„œ ๋„ํฌ๋ฅผ ๋ž™์œผ๋กœ ๋ฐ”๊ฟ”\n * ๋†“๊ณ ๋„ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์„ฑ๊ณตํ–ˆ๋‹ค. ์˜ฎ๊ธฐ๋Š” ์‚ฌ๋žŒ๋งŒ ์•„๋Š” ์‚ฌ์‹ค์€ ์˜ฎ๊ธฐ๋Š” ์ž๋ฆฌ์—์„œ ์‹ค์–ด์•ผ ํ•œ๋‹ค.\n */\n warnings?: IngestWarning[]\n /**\n * **์›๋ณธ์ด ๊ฐ€์ง„ ์ˆ˜** โ€” ์˜ฎ๊ธด ์ˆ˜์˜ ๋ถ„๋ชจ๋‹ค.\n *\n * ์ดํ‰์€ ๋„์ฐฉํ•œ ๋ชจ๋ธ๋งŒ ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ใ€Œ๋ ˆ์‹œํ”ผ 1,261ใ€๊นŒ์ง€๋งŒ ๋งํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ๋žŒ์ด ๋ฌป๋Š” ๊ฒƒ์€\n * ใ€Œ๊ทธ๊ฒŒ ์ „๋ถ€์ธ๊ฐ€ใ€๋‹ค โ€” ์›๋ณธ์— 1,408๊ฐœ๊ฐ€ ์žˆ์—ˆ๊ณ  147๊ฐœ๋ฅผ ์˜ฎ๊ธฐ์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ๊ทธ ์‚ฌ์‹ค์ด ์ดํ‰์˜ ์ฒซ ์ค„์—\n * ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ’ˆ๋ชฉ 2,789 ์™€ ์ž์žฌ 1,789 ์˜ ์ฐจ์ด๋ฅผ ํ™”๋ฉด์—์„œ ์ฝ์–ด ๋‚ด์ง€ ๋ชปํ•ด ์ง์ ‘\n * ๋ฌผ์—ˆ๋‹ค(2026-08-22).\n *\n * ๋ถ„๋ชจ๋ฅผ ์•„๋Š” ๊ฒƒ์€ **์ปค๋„ฅํ„ฐ๋ฟ์ด๋‹ค.** ๊ทธ๋ž˜์„œ ์ปค๋„ฅํ„ฐ๊ฐ€ ์‹ค์–ด ๋ณด๋‚ธ๋‹ค. ๋ณด๋‚ด์ง€ ์•Š์œผ๋ฉด ์ดํ‰์€ ๋ถ„๋ชจ ์—†์ด\n * ์˜ฎ๊ธด ์ˆ˜๋งŒ ๋งํ•œ๋‹ค โ€” **์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์—ด์‡ ๋Š” ์ดํ‰์ด ์„ธ๋Š” ์ด๋ฆ„๊ณผ ๊ฐ™๋‹ค(`recipes`ยท`materials`ยท`totalInputs`ยทโ€ฆ). ๊ฐ’์€ **์›๋ณธ์„ ๋๊นŒ์ง€ ์ฝ์–ด์„œ\n * ์„ผ ๊ฒƒ**์ด์–ด์•ผ ํ•œ๋‹ค. ์ž˜๋ฆฐ ์ฝ๊ธฐ์˜ ์ˆ˜๋ฅผ ์—ฌ๊ธฐ ๋‹ด์œผ๋ฉด ใ€Œ์ „๋ถ€ ์˜ฎ๊ฒผ๋‹คใ€๋Š” ๊ฑฐ์ง“์ด ๋œ๋‹ค.\n */\n originCounts?: Record<string, number>\n}\n\nexport interface IngestedTwin {\n model: any // TwinModelDef(+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/**\n * **์‹œ๊ฐ์„ ๋ชจ๋ฅด๋Š” ์ฑ„ ์‹œ๊ฐ์œผ๋กœ ํŒ์ •ํ•˜๋ ค ํ•œ๋‹ค** โ€” ๋ฐœ์ „ ํ˜•์ƒ์€ ํ•˜๋ฃจ์˜ ์‹œ๊ฐ์„ ์ฝ๋Š”๋ฐ ์ด ํŠธ์œˆ์˜ ๊ณต๊ฐ„์ด\n * ์‹œ๊ฐ„๋Œ€๋ฅผ ๋งํ•˜์ง€ ์•Š์•˜๋‹ค.\n *\n * โ”€โ”€ ์™œ ๊ฒฝ๊ณ ์ธ๊ฐ€ (2026-08-18) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„์€ ์‹œ๊ฐ„๋Œ€๋ฅผ ๋ชจ๋ฅด๋ฉด UTC ๋กœ ์ฝ๋Š”๋‹ค(๊ณ„์•ฝ์— ๋ฐํ˜€ ๋‘” ๊ทœ์œจ โ€” ๋ชจ๋ฅด๋Š” ๊ฐ’์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค). ๊ทธ๋Ÿฐ๋ฐ ๋ฐœ์ „\n * ํ˜•์ƒ์€ **์‹œ๊ฐ๋ณ„ ๋น„์œจ**์ด๋ผ, ์‹œ๊ฐ„๋Œ€๊ฐ€ ์—†์œผ๋ฉด ํ˜„์žฅ ์ •์˜ค๊ฐ€ ์•„๋‹ˆ๋ผ UTC ์ •์˜ค์— ํ”ผํฌ๊ฐ€ ์„ ๋‹ค(KST ํ˜„์žฅ์ด๋ฉด\n * ๋ฐค 9์‹œ). ๊ฐ’์ด ๊ทธ๋Ÿด๋“ฏํ•˜๊ฒŒ ๋‚˜์˜ค๋ฏ€๋กœ ์•„๋ฌด๋„ ์•Œ์•„์ฑ„์ง€ ๋ชปํ•œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์‹œ๊ฐ„๋Œ€๋ฅผ **์ง€์–ด๋‚ด์ง€ ์•Š๊ณ **(์„œ๋ฒ„ ๋กœ์ปฌ์ด๋‚˜ ์ž„์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๊ทธ ํŠธ์œˆ์˜ ๋ชจ๋“  ์‹œ๊ฐ ํŒ์ •์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ \n * ๊ทธ ๊ฐ€์ • ์œ„์— ์„ ๋‹ค) ๋Œ€์‹  **๊ทธ ์กฐํ•ฉ์„ ๋งํ•œ๋‹ค** โ€” ๊ณต๊ฐ„์— ์‹œ๊ฐ„๋Œ€๋ฅผ ์„ ์–ธํ•˜๋ฉด ์‚ฌ๋ผ์ง€๋Š” ๊ฒฝ๊ณ ๋‹ค.\n */\nexport const generationWithoutTimeZone = (spaceId: string, equipmentId: string): IngestWarning => ({\n code: 'generation-without-time-zone',\n params: { spaceId, equipmentId },\n message:\n `\"${equipmentId}\" declares a daily generation shape but space \"${spaceId}\" declares no time zone โ€” the hourly fractions will be read in UTC, ` +\n 'so the generation peak will not land at local noon. Declare the space time zone (we do not guess one).'\n})\n\n/**\n * ์•„๋ฌด๋„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ์ž๋ฆฌ ํƒ€์ž… โ€” ๊ทธ ์ž๋ฆฌ๋Š” ํ๋ฆ„์— ์ฐธ์—ฌํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค.\n *\n * **๋ฌป๋Š” ์ƒ๋Œ€๋ฅผ ๊ณ ์ณค๋‹ค (2026-08-20).** ์˜ˆ์ „์—๋Š” ๋‚ด์žฅ ์นดํƒˆ๋กœ๊ทธ์—๊ฒŒ๋งŒ ๋ฌผ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์›๋ณธ์ด ์ž๊ธฐ\n * `DomainDefinition.locationTypes` ๋ฅผ ํ•จ๊ป˜ ๋ณด๋‚ด๋ฉด **๊ทธ ์„ ์–ธ์ด ์ •๋ณธ**์ด๋‹ค โ€” ์นดํƒˆ๋กœ๊ทธ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š”\n * ๋„๋ฉ”์ธ๋“ค์˜ ๊ธฐ๋ณธ ์–ดํœ˜์ผ ๋ฟ์ด๋‹ค. ๋ฌผ์„ ์ƒ๋Œ€๊ฐ€ ํ‹€๋ ธ์œผ๋‹ˆ, ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ•œ ์›๋ณธ์€ ์ •์ƒ์ ์ธ ํƒ€์ž…๋งˆ๋‹ค\n * ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›์•˜๋‹ค(F&B ๋ผ์ธ์„ ๋ถ™์ด๋ฉด ์ž๋ฆฌ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ). ์†Œ์Œ์ด ๋˜๋ฉด ์‚ฌ๋žŒ์€ ๊ฒฝ๊ณ ๋ฅผ ์ฝ์ง€ ์•Š๊ฒŒ ๋˜๊ณ , ๊ทธ๋•Œ\n * ์ง„์งœ ๊ฒฝ๊ณ ๋„ ํ•จ๊ป˜ ์ฃฝ๋Š”๋‹ค.\n */\nexport const unknownLocationType = (system: string, type: string, id: string): IngestWarning => ({\n code: 'unknown-location-type',\n params: { system, type, id },\n /*\n * โ”€โ”€ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€ ๋งํ•œ๋‹ค (2026-08-25) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „ ๋ฌธ์žฅ์€ ใ€Œํ๋ฆ„์— ์ฐธ์—ฌํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹คใ€์˜€๋‹ค. ๋ฌผ๊ฑด์ด ํ๋ฅด๋Š” ๋„๋ฉ”์ธ์—์„œ๋Š” ๋งž๋Š” ๋ง์ธ๋ฐ,\n * ์—๋„ˆ์ง€ ํŠธ์œˆ์—๋Š” ํ๋ฆ„์ด ์—†์–ด์„œ ๊ทธ ๋ฌธ์žฅ์ด ์•„๋ฌด๊ฒƒ๋„ ์•Œ๋ ค ์ฃผ์ง€ ์•Š์•˜๋‹ค(์‹ค์ œ๋กœ ํƒœ์–‘๊ด‘ ๋ฐœ์ „์†Œ๋ฅผ\n * ๋ถ™์ด๋ฉด์„œ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›์€ ์‚ฌ๋žŒ์ด ใ€Œ์ด ๊ฒฝ๊ณ ๊ฐ€ ๋œป์ด ์žˆ๋Š”๊ฐ€ใ€๋ฅผ ๋˜๋ฌผ์—ˆ๋‹ค).\n *\n * ์ข…๋ฅ˜๋ฅผ ๋ชจ๋ฅด๋ฉด ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๋Š” ์ผ์€ ํ•˜๋‚˜๋‹ค: **๊ทธ ์ž๋ฆฌ์— ๋Šฅ๋ ฅ์ด ๋ถ™์ง€ ์•Š๋Š”๋‹ค.** ๋Šฅ๋ ฅ์ด ์—†์œผ๋ฉด\n * ์ƒํƒœ ํ•„๋“œ๋„ ์—†๊ณ , ๋กค์—…์—๋„ ๋“ค์–ด๊ฐ€์ง€ ์•Š๊ณ , ์ €์ž‘๋ฉด ํŒ”๋ ˆํŠธ์—๋„ ์„œ์ง€ ์•Š๋Š”๋‹ค. ๋„๋ฉ”์ธ์„ ๊ฐ€๋ฆฌ์ง€ ์•Š๊ณ \n * ์ฐธ์ธ ๋ฌธ์žฅ์ด๋ฏ€๋กœ ์ด๊ฒƒ์„ ์ ๋Š”๋‹ค.\n */\n message:\n `\"${type}\" is declared nowhere for ${system} (${id}) โ€” neither in the master's own locationTypes nor in the built-in ` +\n `catalog. A location whose type is unknown gets no capabilities, so it carries no state, joins no rollup, ` +\n `and (in domains that move things) may be left out of the flow.`\n})\n\n/**\n * ์›๋ณธ์ด ํ•จ๊ป˜ ๋ณด๋‚ธ ์ž๋ฆฌ ํƒ€์ž… ์„ ์–ธ โ€” ์žˆ์œผ๋ฉด **์ด๊ฒƒ์ด ์ •๋ณธ**์ด๋‹ค.\n *\n * ์ปค๋„ ๊ณ„์•ฝ์˜ `DomainDefinition.locationTypes` ๋Š” `{ key, label, โ€ฆ }` ๋ชฉ๋ก์ด๋‹ค. ์ฝ์„ ์ˆ˜ ์—†๋Š” ๋ชจ์–‘์ด๋ฉด\n * `undefined` ๋ฅผ ๋Œ๋ ค **์นดํƒˆ๋กœ๊ทธ๋กœ ๋–จ์–ด์ง„๋‹ค** โ€” ๋นˆ ๋ฐฐ์—ด์„ ๋Œ๋ ค์ฃผ๋ฉด ใ€Œ์•„๋ฌด ํƒ€์ž…๋„ ์„ ์–ธ๋˜์ง€ ์•Š์•˜๋‹คใ€๊ฐ€\n * ๋˜์–ด ๋ชจ๋“  ์ž๋ฆฌ๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›๋Š”๋‹ค(์—†๋Š” ๊ฒƒ๊ณผ ๋ชป ์ฝ์€ ๊ฒƒ์€ ๋‹ค๋ฅด๋‹ค).\n */\nexport function declaredLocationTypes(productionSpec: unknown): string[] | undefined {\n const list = (productionSpec as any)?.definition?.locationTypes\n if (!Array.isArray(list) || !list.length) return undefined\n const keys = list.map((t: any) => (typeof t === 'string' ? t : t?.key)).filter((k: any) => typeof k === 'string' && k)\n return keys.length ? keys : undefined\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/**\n * ๊ตฌ์กฐ ํˆฌ์˜์—์„œ **๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ์„ ๋ชป ์ฐพ์•˜๋‹ค.**\n *\n * ์˜ˆ์ „์—๋Š” ์ด๋Ÿฐ ์ฐธ์กฐ๊ฐ€ model JSON ์•ˆ์˜ ๋งจ ๋ฌธ์ž์—ด์ด๋ผ ํ™”๋ฉด๋งŒ ๊ฒฝ๊ณ ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜จ\n * ๋ฐ์ดํ„ฐ๋Š” ์•„๋ฌด๋„ ์•ˆ ๋ดค๋‹ค. ์ด์ œ ํ–‰์œผ๋กœ ํ’€๋ฉด์„œ **์ธ์ œ์ŠคํŠธ๊ฐ€ ์ง์ ‘ ์•ˆ๋‹ค** โ€” ๊ทธ๋Ÿฌ๋‹ˆ ์ธ์ œ์ŠคํŠธ๊ฐ€ ๋งํ•œ๋‹ค.\n * ๋ง‰์ง€๋Š” ์•Š๋Š”๋‹ค(ํŠธ์œˆ์€ model ๋กœ ์ด๋ฏธ ๋™์ž‘ํ•œ๋‹ค). ๋‹ค๋งŒ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค.\n */\nexport const unresolvedReference = (field: string, ref: string): IngestWarning => ({\n code: 'unresolved-reference',\n params: { field, ref },\n message: `${field} points at something that is not in this twin (${ref}) โ€” the link was left empty`\n})\n\n/**\n * ๊ตฌ์กฐ ํˆฌ์˜ ์ž์ฒด๊ฐ€ ์‹คํŒจํ–ˆ๋‹ค โ€” ์กฐํšŒ๋Š” ๋ชป ํ•˜์ง€๋งŒ **ํŠธ์œˆ์€ ๋™์ž‘ํ•œ๋‹ค**(์ปค๋„์€ model ๋ฅผ ์ด๋ฏธ ๋ฐ›์•˜๋‹ค).\n * ํ–‰์€ ์›๋ณธ์—์„œ ๋‹ค์‹œ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ธ์ œ์ŠคํŠธ๋ฅผ ์‹คํŒจ๋กœ ๋งŒ๋“ค์ง€ ์•Š๋˜, ์นจ๋ฌตํ•˜์ง€๋„ ์•Š๋Š”๋‹ค.\n */\nexport const projectionFailed = (reason: string): IngestWarning => ({\n code: 'projection-failed',\n params: { reason },\n message: `structure projection failed (${reason}) โ€” the twin runs, but model inspection will be stale until the next ingest`\n})\n\n/**\n * **๋™์ž‘ ์ค‘์— ๊ณต์žฅ์„ ์ „ํ™˜ํ–ˆ๋‹ค** โ€” ๋ฏธ๋Ÿฌ๋Š” ๋ฉˆ์ถ”์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ฌด์—‡์ด ์‚ฌ๋ผ์กŒ๋Š”์ง€ ์—ฌ๊ธฐ์„œ ๋งํ•œ๋‹ค.\n *\n * ๋ฉˆ์ท„๋‹ค ์„ธ์šฐ๋Š” ๊ตฌ์กฐ ์ „ํ™˜์ด๋ผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ \"๋‹ค์‹œ ์„ธ์› ๋‹ค\" ๋Š” ๊ฒƒ์„ ์•ˆ๋‹ค. ๋ฏธ๋Ÿฌ๋Š” ๊ทธ ๋งˆ๋””๊ฐ€ ์—†์–ด์„œ\n * ์ž๋ฆฌ ํ•˜๋‚˜ยท์„ค๋น„ ํ•œ ๋Œ€๊ฐ€ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์—†์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค โ€” ์ž๋ฆฌ๊ฐ€ ์ˆ˜์ฒœ์ธ ํ˜„์žฅ์—์„œ ํ™”๋ฉด์˜ ์ˆ˜๋ฅผ ์„ธ์–ด\n * ๋ˆˆ์น˜์ฑ„๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†๋‹ค. ๋Š˜์–ด๋‚œ ๊ฒƒ๋„ ํ•จ๊ป˜ ๋งํ•œ๋‹ค(๋ฌด์—‡์ด ๋ฐ˜์˜๋˜์—ˆ๋‚˜๊ฐ€ ๊ณง ์ธ์ œ์ŠคํŠธ์˜ ๋‹ต์ด๋‹ค).\n */\nexport const structureAdopted = (rev: number, shift: { locationsAdded: number; locationsDropped: number; equipmentDropped: number; personsDropped: number; assetsDropped: number }): IngestWarning => ({\n code: 'structure-adopted',\n params: { rev, ...shift },\n message:\n `the running mirror adopted a new structure (revision ${rev}) โ€” ` +\n `+${shift.locationsAdded} location(s), -${shift.locationsDropped} location(s), ` +\n `-${shift.equipmentDropped} equipment, -${shift.personsDropped} person(s), -${shift.assetsDropped} asset(s)`\n})\n\n/**\n * ์ปค๋„ฅํ„ฐ๊ฐ€ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์˜ ๊ฐ’์„ **์šฐ๋ฆฌ ์–ดํœ˜๋กœ ์˜ฎ๊ธฐ์ง€ ๋ชปํ•ด ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค.**\n *\n * ์˜ˆ: Oracle WMS ๊ฐ€ ์šฐ๋ฆฌ ํ‘œ์— ์—†๋Š” `locn_type` ์„ ์ฃผ๋ฉด ๊ทธ ์ž๋ฆฌ๋Š” `storage` ๊ฐ€ ๋œ๋‹ค โ€” ๋„ํฌ๊ฐ€ ๋ž™์œผ๋กœ\n * ๋ชจ๋ธ๋ง๋˜๋Š” ๊ฒƒ์ด๋‹ค. ์ธ์ œ์ŠคํŠธ๋ฅผ ํ†ต์งธ๋กœ ์‹คํŒจ์‹œํ‚ฌ ์ผ์€ ์•„๋‹ˆ์ง€๋งŒ(๋กœ์ผ€์ด์…˜ ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ํ˜„์žฅ ์ „์ฒด๊ฐ€\n * ์•ˆ ๋“ค์–ด์˜ค๋Š” ํŽธ์ด ๋” ๋‚˜์˜๋‹ค), **์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋„˜์–ด๊ฐ€๋ฉด ์•ˆ ๋œ๋‹ค.** ํŠธ์œˆ์ด ์‹ค๋ฌผ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ƒ๊ฒผ๋Š”๋ฐ\n * ์•„๋ฌด๋„ ๊ทธ ์‚ฌ์‹ค์„ ๋ชจ๋ฅธ ์ฑ„ ๊ทธ ์œ„์—์„œ ํ๋ฆ„์„ ๋…ผํ•˜๊ฒŒ ๋œ๋‹ค.\n *\n * ๊ฐ’์„ ๋‚˜์—ดํ•˜๋Š” ์ด์œ : \"3๊ฑด\" ๋งŒ์œผ๋กœ๋Š” ์ปค๋„ฅํ„ฐ ๋งคํ•‘์— ๋ฌด์—‡์„ ๋”ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.\n */\nexport const connectorMappingFallback = (field: string, fallback: string, values: readonly string[], count: number): IngestWarning => ({\n code: 'connector-mapping-fallback',\n params: { field, fallback, values: values.join(', '), count },\n message: `${count} ${field} value(s) had no mapping and fell back to \"${fallback}\" (${values.join(', ')}) โ€” the twin's shape differs from the source system here`\n})\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\n/**\n * ์ด ํ˜„์žฅ์˜ ์„ค๋น„๋ฅผ ๋…ธ๋ธŒ ๊ฐ’์œผ๋กœ ์ฑ„์› ๋‹ค โ€” **์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์—๋„ˆ์ง€ ํŠธ์œˆ์˜ ๋ถ€ํ•˜๋ฅผ ์ด์›ƒ ์„ค๋น„ id ๋กœ ์„ ์–ธํ•  ๋•Œ ์“ด๋‹ค. ๋ช‡ ๊ฐœ๋ฅผ ๊ฐ€์ ธ์™”๋Š”์ง€ ๋งํ•ด ์ฃผ์ง€ ์•Š์œผ๋ฉด, ์‚ฌ์šฉ์ž๋Š”\n * ์ž๊ธฐ๊ฐ€ ๊ณ ๋ฅด์ง€ ์•Š์€ ์„ค๋น„๋“ค์ด ๋ถ€ํ•˜๋กœ ์žกํžŒ ๊ฒƒ์„ ๋‚˜์ค‘์— ํ™”๋ฉด์—์„œ์•ผ ์•Œ๊ฒŒ ๋œ๋‹ค.\n */\nexport const siteEquipmentAdopted = (key: string, count: number): IngestWarning => ({\n code: 'site-equipment-adopted',\n params: { key, count },\n message: `${count} piece(s) of equipment already on this site were adopted as loads (knob \"${key}\") โ€” set their coefficients before trusting the numbers`\n})\n\nexport function masterToTwin(master: ReferenceMaster, catalog?: any): IngestedTwin {\n /* ์ปค๋„ฅํ„ฐ๊ฐ€ ์˜ฎ๊ธฐ๋ฉฐ ์•Œ๊ฒŒ ๋œ ๊ฒƒ์„ ๋จผ์ € ์‹ฃ๋Š”๋‹ค โ€” ์›์ธ์ด ์•ž์— ์˜ค๋Š” ํŽธ์ด ์ฝ๊ธฐ ์‰ฝ๋‹ค(๋Œ€์ฒด๊ฐ€ ๋จผ์ €, ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ๋’ค). */\n const warnings: IngestWarning[] = [...(master.warnings ?? [])]\n /*\n * ์›๋ณธ์ด ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ–ˆ์œผ๋ฉด **๊ทธ๊ฒƒ์— ๋Œ€์กฐํ•œ๋‹ค.** ๋‚ด์žฅ ์นดํƒˆ๋กœ๊ทธ๋Š” ๊ทธ ์„ ์–ธ์ด ์—†์„ ๋•Œ์˜ ๊ธฐ๋ณธ์ด๋‹ค โ€”\n * ์ƒ๋Œ€๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š์œผ๋ฉด, ์ž๊ธฐ ์–ดํœ˜๋ฅผ ์„ ์–ธํ•œ ์›๋ณธ์ด ์ •์ƒ์ ์ธ ์ž๋ฆฌ๋งˆ๋‹ค ๊ฒฝ๊ณ ๋ฅผ ๋ฐ›๋Š”๋‹ค.\n */\n const known: string[] = declaredLocationTypes(master.productionSpec) ?? 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 /*\n * **์ด๋ฆ„์„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค.** ์—ฌ๊ธฐ์„œ ๋ฒ„๋ฆฌ๊ณ  ์žˆ์—ˆ๋‹ค โ€” ๊ทธ๋ž˜์„œ ๋ชจ๋ธ์—๋„, ํˆฌ์˜ํ•œ ํ–‰์—๋„ ์ด๋ฆ„์ด ์—†๊ณ \n * ํ™”๋ฉด์€ ์ž๋ฆฌ id ๋ฅผ ๊ทธ๋Œ€๋กœ ์ฐ์—ˆ๋‹ค(`cut-station`). ๋ชฉ๋กยทํ‘œยท๊ด€๊ณ„ ๊ทธ๋ฆผ์—์„œ ๊ฐ™์€ ๊ฒฐํ•จ์ด ๋”ฐ๋กœ\n * ๋ณด์˜€๋˜ ์ด์œ ๊ฐ€ ์ด ํ•œ ์ค„์ด๋‹ค. ์ด๋ฆ„ ์—†๋Š” ์›๋ณธ์€ ์ด๋ฆ„ ์—†์ด ํ†ต๊ณผํ•œ๋‹ค(id ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).\n */\n /*\n * **์†์„ฑ๋„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค** โ€” ์„ค๋น„์™€ ๊ฐ™์€ ๊ทœ์œจ(์†๋Œ€์ง€ ์•Š๊ณ  ๋‚˜๋ฅธ๋‹ค). ์—ฌ๊ธฐ๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฆฌ์— ์‹ค์€ ๊ฐ’์ด\n * ์ปค๋„์— ๋‹ฟ์ง€ ์•Š๋Š”๋‹ค: ์—๋„ˆ์ง€์˜ ๊ณ„์•ฝ์ „๋ ฅ(`contract.kW`)์ด ๊ทธ ๊ฒฝ๋กœ์ด๊ณ , ํ†ต๊ณผํ•˜์ง€ ์•Š์œผ๋ฉด ์ปค๋„์ด\n * ๊ณ„์•ฝ์„ ๋ชจ๋ฅด๋Š” ์ฑ„๋กœ ์„œ์„œ **ํŒ์ •์„ ์•„์˜ˆ ํ•˜์ง€ ์•Š๋Š”๋‹ค**(์˜ค๋ฅ˜ ์—†์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ ).\n */\n return { id: l.id, type: l.type, ...(l.name ? { name: l.name } : {}), ...(l.description ? { description: l.description } : {}), capacity: l.capacity ?? 0, ...(l.parallelism !== undefined ? { parallelism: l.parallelism } : {}), ...(l.level ? { level: l.level } : {}), ...(l.properties?.length ? { properties: l.properties } : {}), parentId: l.parentId, ...(l.upstreamId ? { upstreamId: l.upstreamId } : {}), gs1Id: l.gs1Id }\n })\n\n /*\n * โ”€โ”€ ์„ค๋น„๊ฐ€ ๊ตฌ์—ญ์— ์„œ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค (2026-09-06) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋งˆ์Šคํ„ฐ๋Š” ์ž๋ฆฌ์™€ ๊ตฌ์—ญ์„ **ํ•œ ๋ชฉ๋ก**์— ๋‹ด๊ณ  `role` ๋กœ ๊ฐ€๋ฅธ๋‹ค(ยง`locationEntries` ยท `areaLocs`).\n * ๊ทธ๋ž˜์„œ ์„ค๋น„์˜ `homeLocationId` ๊ฐ€ ๊ตฌ์—ญ์„ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค โ€” ์‹ค์ œ๋กœ `EQ-CAM-SHOWER-01` ์ด\n * `LINE-CAM`(๊ตฌ์—ญ)์— ์„œ ์žˆ๊ณ , ๊ทธ๊ฒƒ์ด ์ •์ƒ์ด๋‹ค(์—์–ด์ƒค์›Œ๋Š” ๋ผ์ธ ์ „์ฒด์— ๋”ธ๋ฆฐ๋‹ค).\n *\n * ๊ณ„์•ฝ์ด ๊ทธ ๊ตฌ๋ถ„์„ ์œ„ํ•ด `homeLocationKind` ๋ฅผ ๋‘์—ˆ๋Š”๋ฐ(`HomeKind = 'location' | 'area'`)\n * **์•„๋ฌด๋„ ์•ˆ ์ฑ„์šฐ๊ณ  ์žˆ์—ˆ๋‹ค.** ๊ทธ๋ž˜์„œ ์ธ์ œ์ŠคํŠธ๊ฐ€ ๊ทธ ์ฐธ์กฐ๋ฅผ ใ€Œ๋Š์–ด์กŒ๋‹คใ€๊ณ  ๊ฒฝ๊ณ ํ–ˆ๋‹ค.\n *\n * ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๋งˆ์Šคํ„ฐ๊ฐ€ ์ด๋ฏธ `role` ๋กœ ๋งํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ทธ๊ฒƒ์„ ์ฝ๋Š”๋‹ค.\n */\n const areaIds = new Set(master.locations.filter(l => l.role === 'area').map(l => l.id))\n\n const equipment = (master.equipment ?? []).map(e => ({\n id: e.id, kind: e.kind, ...(e.name ? { name: e.name } : {}), ...(e.description ? { description: e.description } : {}), ...(e.testResults?.length ? { testResults: e.testResults } : {}),\n /* ๋“ฑ๊ธ‰ ์†Œ์† โ€” ์‚ฌ๋žŒยท์ž์‚ฐ๊ณผ ๊ฐ™์€ ์ž๋ฆฌ. ๋น ๋œจ๋ฆฌ๋ฉด ์›๋ณธ์ด ์ฑ„์šด ๋“ฑ๊ธ‰์ด ๋ฌธํ„ฑ์—์„œ ์กฐ์šฉํžˆ ๋ฒ„๋ ค์ง„๋‹ค. */\n ...(e.equipmentClassIds?.length ? { equipmentClassIds: e.equipmentClassIds } : {}),\n homeLocation: e.homeLocationId,\n /* ์ž๋ฆฌ๋ฉด ์•ˆ ์ ๋Š”๋‹ค โ€” ๊ณ„์•ฝ์˜ ๊ธฐ๋ณธ๊ฐ’์ด `location` ์ด๊ณ , ์—†๋Š” ์นธ์„ ๋งŒ๋“ค๋ฉด ํ™”๋ฉด์ด ๊ทธ๊ฒƒ์„ ๊ทธ๋ฆฐ๋‹ค. */\n ...(e.homeLocationId && areaIds.has(e.homeLocationId) ? { homeLocationKind: 'area' as const } : {}),\n mtbfMs: e.mtbfMs, mttrMs: e.mttrMs, ...(e.identity ? { identity: e.identity } : {}),\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 * **๋ถ„ ์˜คํ”„์…‹**๋งŒ ๋ฐ›๋Š”๋‹ค(๊ณ„์•ฝ `TwinModelDef.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 * โ”€โ”€ ์ด๋ฆ„๋„ ํ•จ๊ป˜ ์‹ฃ๋Š”๋‹ค (2026-09-07) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์œ„์—์„œ ํ‘ผ ์˜คํ”„์…‹์€ **์ด ์ˆœ๊ฐ„์˜** ๊ฐ’์ด๊ณ , ์ด ๋ชจ๋ธ์€ ์ €์žฅ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ์ˆ˜๋Š” ๋งˆ์Šคํ„ฐ๋ฅผ ๋ฐ›์€ ๋‚ ์˜\n * ๊ณ„์ ˆ๋กœ ๊ตณ๋Š”๋‹ค โ€” `America/Tijuana`(PST โˆ’480 / PDT โˆ’420)๊ฐ€ ์ž๋ฃŒ์— ์žˆ๊ณ , ์ง€๋‚œ ๊ตฌ๊ฐ„์„ ๊ต๋Œ€๋ณ„๋กœ ์ ‘์œผ๋ฉด\n * ๊ทธ ์•ˆ์˜ ์ „ํ™˜์ด ์‚ฌ์‹ค์„ ํ•œ ์‹œ๊ฐ„ ๋ฐ€์–ด **๋‹ค๋ฅธ ๊ต๋Œ€๋กœ** ์„ธ๊ฒŒ ํ•œ๋‹ค. ์˜ค๋ฅ˜๋Š” ๋‚˜์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์ด๋ฆ„์ด ํ•จ๊ป˜ ์žˆ์œผ๋ฉด ์†Œ๋น„์ฒ˜๊ฐ€ ์ˆœ๊ฐ„๋งˆ๋‹ค ๋‹ค์‹œ ํ’€ ์ˆ˜ ์žˆ๋‹ค(ยง`shiftContext`). ์ปค๋„์€ ์ด ๊ฐ’์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์˜คํ”„์…‹์ด ์•ˆ ํ’€๋ฆฐ ์ด๋ฆ„์€ ์‹ฃ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ทธ ๊ฒฝ์šฐ๋Š” ์œ„์—์„œ ๊ฒฝ๊ณ ๋กœ ๋งํ–ˆ๊ณ , ํ’€๋ฆฌ์ง€ ์•Š๋Š” ์ด๋ฆ„์„ ์‹ค์–ด\n * ๋‘๋ฉด ์†Œ๋น„์ฒ˜๊ฐ€ ๊ทธ๊ฒƒ์„ ๋ฏฟ๊ณ  ๋งค๋ฒˆ ์‹คํŒจํ•œ๋‹ค.\n */\n const timezone = utcOffsetMinutes !== undefined ? master.space.timezone : undefined\n /*\n * ์˜คํผ๋ ˆ์ด์…˜ ๋ช…์„ธ๋ฅผ model ์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค โ€” ์ปค๋„์ด `loadOperations` ๋กœ ์†Œ๋น„ํ•œ๋‹ค(TwinModelDef ํ™•์žฅ ํ•„๋“œ,\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, ...(p.name ? { name: p.name } : {}), ...(p.testResults?.length ? { testResults: p.testResults } : {}), personnelClassIds: p.personnelClassIds, ...(p.identity ? { identity: p.identity } : {}), ...(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, ...(a.name ? { name: a.name } : {}), ...(a.testResults?.length ? { testResults: a.testResults } : {}), assetClassIds: a.assetClassIds, homeLocation: a.homeLocationId, ...(a.identity ? { identity: a.identity } : {}), ...(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 /* ์ด๋ฆ„์€ ์ด๋ฆ„ ์ž๋ฆฌ์— โ€” ์˜ˆ์ „์—๋Š” `name` ์„ `description` ์œผ๋กœ ์˜ฎ๊ฒจ ๋‹ด์•˜๋‹ค(์–ดํœ˜๊ฐ€ ๋’ค์ง‘ํ˜€ ์žˆ์—ˆ๋‹ค). */\n ...(d.name ? { name: 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 /*\n * **๋“ฑ๊ธ‰์˜ ํ‘œ์‹œ๋ช…์€ `name` ์ด๋‹ค.**\n *\n * ํ‘œ์ค€ ๋งˆ์Šคํ„ฐ๋Š” ๋“ฑ๊ธ‰์˜ ํ‘œ์‹œ๋ช…์„ `description` ์— ๋‹ด๋Š”๋‹ค(`RefResourceClass.description` = i18n ํ‚ค).\n * ๊ทธ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋ชจ๋ธ์— ์‹ค์œผ๋ฉด ํ™”๋ฉด์˜ \"์„ค๋ช…\" ์—ด์— ์ด๋ฆ„์ด ์•‰๋Š”๋‹ค โ€” ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ด๋ฆ„์ธ๋ฐ ๋จธ๋ฆฌ๊ธ€์€\n * ์„ค๋ช…์ด๋ผ, ๊ฐ™์€ ๊ฒƒ์„ ์ถ•๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๋ถ€๋ฅด๊ฒŒ ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ **๋ฌธ ํ•˜๋‚˜์—์„œ ์–ดํœ˜๋ฅผ ๋งž์ถ˜๋‹ค**: ํ‘œ์‹œ๋ช…์€ ์–ด๋А ์ถ•์ด๋“  `name`. ์›๋ž˜์˜ `description` ์€\n * ๋‚จ๊ฒจ ๋‘์ง€ ์•Š๋Š”๋‹ค โ€” ๋‘ ์ž๋ฆฌ์— ๊ฐ™์€ ๊ฐ’์ด ์žˆ์œผ๋ฉด ์–ด๋А ๊ฒƒ์ด ์ •๋ณธ์ธ์ง€ ๋‹ค์‹œ ํ—ท๊ฐˆ๋ฆฐ๋‹ค.\n */\n const asName = (list?: RefResourceClass[]) =>\n list?.map(({ description, ...rest }) => ({ ...rest, ...(description ? { name: description } : {}) }))\n /*\n * ๊ฒ€์‚ฌ ๋ช…์„ธ๋„ **ํ‘œ์‹œ๋ช…์€ `name`** ์ด๋‹ค โ€” ๋“ฑ๊ธ‰๊ณผ ๊ฐ™์€ ๊ทœ์น™์„ ์“ด๋‹ค(์–ดํœ˜๋ฅผ ํ•˜๋‚˜๋กœ). ํ‘œ์ค€ ๋งˆ์Šคํ„ฐ๋Š”\n * ํ‘œ์‹œ๋ช…์„ `description` ์— ๋‹ด์œผ๋ฏ€๋กœ ๋ฌธ ํ•˜๋‚˜์—์„œ ์˜ฎ๊ธด๋‹ค. ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ํ™”๋ฉด์˜ \"์„ค๋ช…\" ์—ด์— ์ด๋ฆ„์ด\n * ์•‰์•„ ์ถ•๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๊ฐ™์€ ๊ฒƒ์„ ๋ถ€๋ฅด๊ฒŒ ๋œ๋‹ค(๋“ฑ๊ธ‰์—์„œ ์ด๋ฏธ ๊ฒช์—ˆ๋‹ค).\n */\n const testSpecifications = master.testSpecifications?.map(({ description, ...rest }) => ({\n ...rest,\n ...(description ? { name: description } : {})\n }))\n const personnelClasses = asName(master.personnelClasses)\n const equipmentClasses = asName(master.equipmentClasses)\n const assetClasses = asName(master.assetClasses)\n const materialClasses = asName(master.materialClasses)\n\n const model = {\n locations, equipment, layout, spaceId,\n /* ์ƒ์‚ฐ ์ •์˜๋„ ์†๋Œ€์ง€ ์•Š๊ณ  ํ†ต๊ณผ โ€” ๊ฒฝ๊ณ„์—์„œ ์–ดํœ˜๋ฅผ ๊ฐˆ์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๊ทธ๋Œ€๋กœ ์†Œ๋น„ํ•œ๋‹ค). */\n ...(master.productionSpec ? { productionSpec: master.productionSpec } : {}),\n /* ์ •์ฒด์„ฑ ์„ ์–ธ๋„ ๊ทธ๋Œ€๋กœ ํ†ต๊ณผํ•œ๋‹ค โ€” ์—†์œผ๋ฉด ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๋ ˆ๊ฑฐ์‹œ ์ƒ์ˆ˜๋กœ ๋–จ์–ด์ง„๋‹ค). */\n ...(master.identity ? { identity: master.identity } : {}),\n ...(materialDefinitions?.length ? { materialDefinitions } : {}),\n ...(materialClasses?.length ? { materialClasses } : {}),\n ...(utcOffsetMinutes !== undefined ? { utcOffsetMinutes } : {}),\n ...(timezone ? { timezone } : {}),\n ...(operations?.length ? { operations } : {}),\n ...(testSpecifications?.length ? { testSpecifications } : {}),\n ...(personnelClasses?.length ? { personnelClasses } : {}),\n ...(equipmentClasses?.length ? { equipmentClasses } : {}),\n ...(assetClasses?.length ? { 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, ...(l.upstreamId ? { upstreamId: l.upstreamId } : {}),\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 /*\n * โ”€โ”€ ์ด๋ฆ„์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค (2026-08-26) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์—ฌ๊ธฐ๊ฐ€ ํ•ฉ์„ฑํ•œ ํ‘œํ˜„์— `name: '์œ„์„ฑ ์ง€๋„'` ๋ฅผ ๋„ฃ๊ณ  ์žˆ์—ˆ๋‹ค. ์ด ์ธต์€ ์–ธ์–ด ์ค‘๋ฆฝ์ด์–ด์•ผ ํ•˜๋Š”๋ฐ ํ•œ๊ตญ์–ด๊ฐ€\n * ๊ทธ๋Œ€๋กœ ์ €์žฅ๋๋‹ค.\n *\n * ๋‚ฑ๋ง ์—ด์‡ (`twin.representation.map` ๊ฐ™์€ ๊ฒƒ)๋ฅผ ๋„ฃ๋Š” ๊ธธ๋„ ์žˆ๋Š”๋ฐ ํƒํ•˜์ง€ ์•Š์•˜๋‹ค. **ํ‘œํ˜„์˜ ์ด๋ฆ„์€\n * ์‚ฌ๋žŒ์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ฐ’**์ด๊ณ , ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ฐ’ ์•ˆ์— ์—ด์‡ ๊ฐ€ ๋“ค์–ด ์žˆ์œผ๋ฉด ์‚ฌ๋žŒ์ด ํ•œ ๋ฒˆ ๊ณ ์น˜๋Š” ์ˆœ๊ฐ„\n * ๊ทธ ์ž๋ฆฌ๋งŒ ์—ด์‡ ๊ฐ€ ์•„๋‹ˆ๊ฒŒ ๋˜์–ด ๊ทœ์น™์ด ๋‘˜์ด ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด๋ฆ„์„ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค. ํ™”๋ฉด์ด ์ข…๋ฅ˜(`map`)๋กœ ๋ถ€๋ฅด๊ณ , ์‚ฌ๋žŒ์ด ๋ถ™์ด๋ฉด ๊ทธ๋•Œ๋ถ€ํ„ฐ ๊ทธ ์ด๋ฆ„์ด๋‹ค.\n */\n const representations =\n givenReps.length > 0\n ? givenReps\n : geo\n ? [{ id: 'r-map', type: 'map', 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\n }\n\n return { model, spaceContent, warnings }\n}\n\n/**\n * ๋‹ค์‹œ ์ฝ์„ ์‚ฌ์ดํŠธ๋ฅผ ๊ณ ๋ฅธ๋‹ค โ€” **๊ธฐ์–ตํ•ด ๋‘” ์‚ฌ์ดํŠธ ํ•˜๋‚˜๋งŒ**.\n *\n * ๋ชป ์ฐพ์œผ๋ฉด **์ฒซ ์‚ฌ์ดํŠธ๋กœ ๋•Œ์šฐ์ง€ ์•Š๋Š”๋‹ค**: ๋‹ค๋ฅธ ํ˜„์žฅ์˜ ๊ตฌ์กฐ๋ฅผ ์ด ํŠธ์œˆ์— ๋ฎ์–ด์“ฐ๋Š” ์ผ์ด๊ณ , ๊ทธ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€\n * ์•„๋‹ˆ๋ผ **์˜ค๋ฅ˜ ์—†์ด ํ‹€๋ฆฐ ๊ณต์žฅ**์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. ๊ธฐ์–ต์ด ์—†๋Š” ์˜› ํŠธ์œˆ์€ `undefined` ๋ฅผ ๋Œ๋ ค์ฃผ๊ณ , ๋ถ€๋ฅด๋Š” ์ชฝ์ด\n * ๋งˆ์Šคํ„ฐ์˜ ์ •์ฒด(`source` = ์ธ์Šคํ„ด์Šค id)๋กœ ์ฐพ๋Š” ๊ธธ์„ ํƒํ•œ๋‹ค.\n */\nexport function pickOriginSite<T extends { siteId: string }>(\n sites: readonly T[],\n origin: { siteId?: string } | undefined | null\n): { site?: T; reason?: 'no-remembered-site' | 'site-gone' } {\n const wanted = String(origin?.siteId ?? '').trim()\n if (!wanted) return { reason: 'no-remembered-site' }\n const site = sites.find(s => String(s.siteId) === wanted)\n return site ? { site } : { reason: 'site-gone' }\n}\n"]}
@@ -21,6 +21,33 @@ export declare class TwinReferenceResolver {
21
21
  * `origin` ์ด ์—†๋Š” ํŠธ์œˆ(์ด ์ž๋ฆฌ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ์ „์— ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ)์€ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์—†๋‹ค. ์ง์ž‘์œผ๋กœ
22
22
  * ํ…œํ”Œ๋ฆฟ์„ ๊ณ ๋ฅด๊ฑฐ๋‚˜ ์ฒซ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ง‘์ง€ ์•Š๋Š”๋‹ค โ€” ์—‰๋šฑํ•œ ์›๋ณธ์œผ๋กœ ํ˜„์žฅ์„ ๋ฎ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋‚˜์˜๋‹ค.
23
23
  */
24
+ /**
25
+ * **๊ทธ ๋ฒˆํ˜ธ๋“ค์ด ๋ฌด์—‡์ด์—ˆ๋‚˜** โ€” ๊ตฌ๋ฉ์„ ๋งŒ๋‚ฌ์„ ๋•Œ ์›๋ณธ์— ๋ฌป๋Š”๋‹ค.
26
+ *
27
+ * `fillTwinScope` ๊ฐ€ ใ€Œ418 ๋‹ค์Œ์ด 420ใ€์ด๋ผ๊ณ  ๋ฉˆ์ถ”๋ฉด, ๊ทธ 419 ๊ฐ€ ๋ฌด์—‡์ด์—ˆ๋Š”์ง€ ์•Œ์•„์•ผ ๋‹ค์Œ์„
28
+ * ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ๊ธธ์ด ์—†์–ด์„œ ์‚ฌ๋žŒ์ด ์›๋ณธ DB ๋ฅผ ์†์œผ๋กœ ๋’ค์กŒ๋‹ค.
29
+ *
30
+ * **ํŒ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.** ์›๋ณธ์ด ์•„๋Š” ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋‚ธ๋‹ค โ€” `lost` ๋Š” ใ€Œ๋ฒˆํ˜ธ๋Š” ๋‚˜๊ฐ”๋Š”๋ฐ ํ–‰์ด ์—†๋‹คใ€์ด์ง€
31
+ * ใ€Œํฌ๊ธฐํ•ด๋„ ๋œ๋‹คใ€๊ฐ€ ์•„๋‹ˆ๋‹ค. ๊ทธ ํŒ๋‹จ์€ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์–ด์„œ(์ปค์„œ๊ฐ€ ์ง€๋‚˜๊ฐ€๋ฉด ๋์ด๋‹ค) ์‚ฌ๋žŒ์˜ ๋ชซ์ด๋‹ค.
32
+ */
33
+ twinSeqReport(instanceId: string, scope: string, from: number, to: number, context: ResolverContext): Promise<any>;
34
+ /**
35
+ * **๋น ์ง„ ๊ตฌ๊ฐ„์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค** โ€” ํ›…์€ ๋ฐ˜๋“œ์‹œ ๋†“์นฉ๋‹ˆ๋‹ค: ์šฐ๋ฆฌ๊ฐ€ ๋‚ด๋ ค๊ฐ€ ์žˆ์„ ๋•Œ, ๊ทธ์ชฝ์ด ๋ชป ๋ณด๋ƒˆ์„ ๋•Œ.
36
+ *
37
+ * โ”€โ”€ ์™œ ๋ฌธ์ด ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
+ * ๋ฒˆํ˜ธ๊ฐ€ ๋น„๋ฉด `takeInSequence` ๊ฐ€ ์•Œ์•„์ฑ•๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ **์•Œ์•„์ฑˆ ๋’ค ๊ทธ ์‚ฌ์ด๋ฅผ ์ฑ„์šฐ๋Š” ๊ธธ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.**
39
+ * `fillSince` ๋Š” 2026-08-31 ๋ถ€ํ„ฐ ์žˆ์—ˆ๊ณ  ๋ถ€๋ฅด๋Š” ๊ณณ์ด 0๊ณณ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
40
+ *
41
+ * ์‹ค์ œ๋กœ plant ์•„์›ƒ๋ฐ•์Šค์˜ 1~20 ์„ ์žƒ๊ณ  ๋˜์ฐพ์„ ๋ฐฉ๋ฒ•์ด ์—†๋Š” ์ƒํƒœ๋ฅผ ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค.
42
+ *
43
+ * โ”€โ”€ `from` ์€ ์žƒ์€ ๊ตฌ๊ฐ„์„ ๋˜์ฐพ์„ ๋•Œ๋งŒ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
44
+ * ์ฃผ์ง€ ์•Š์œผ๋ฉด ์ปค์„œ๋ถ€ํ„ฐ ์ด์–ด ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ฃผ๋ฉด **๊ทธ ๋ฒˆํ˜ธ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ฌป์Šต๋‹ˆ๋‹ค** โ€” ์ด๋ฏธ ๋“ค์–ด๊ฐ„ ๊ฒƒ์€ ์œ ์ž…
45
+ * ๊ฒฝ๊ณ„๊ฐ€ ๋˜ํ’€์ด๋กœ ๊ฑฐ๋ฅด๋ฏ€๋กœ ๋‘ ๋ฒˆ ์•‰์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
46
+ *
47
+ * ์ €์žฅ๋œ ์ปค์„œ๋ฅผ ๋˜๋Œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `fillSince` ๋Š” ๋ฒˆํ˜ธ ๊ฒ€์‚ฌ๋ฅผ ์ง€๋‚œ ๋งŒํผ๋งŒ ์ ์œผ๋ฏ€๋กœ, ๋˜์ฐพ์€ ๋’ค
48
+ * ์ปค์„œ๊ฐ€ ์›๋ž˜ ์ž๋ฆฌ๋ณด๋‹ค ์•ž์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
49
+ */
50
+ fillTwinScope(instanceId: string, scope: string, context: ResolverContext, from?: number, maxPages?: number): Promise<any>;
24
51
  resyncTwin(instanceId: string, context: ResolverContext): Promise<any>;
25
52
  /** ๊ธฐ์–ตํ•ด ๋‘” ์›์ฒœ์—์„œ ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ์–ป๋Š”๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๋“  ํ…œํ”Œ๋ฆฟ์ด๋“  ์ด ํ•œ ๊ณณ์—์„œ ๊ฐˆ๋ฆฐ๋‹ค. */
26
53
  private masterFromOrigin;