@things-factory/headless-twin 10.0.6 โ†’ 10.0.8

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 (150) hide show
  1. package/README.md +37 -24
  2. package/dist-server/engine/entity-delta.d.ts +13 -1
  3. package/dist-server/engine/entity-delta.js +130 -16
  4. package/dist-server/engine/entity-delta.js.map +1 -1
  5. package/dist-server/engine/index.d.ts +4 -0
  6. package/dist-server/engine/index.js +4 -0
  7. package/dist-server/engine/index.js.map +1 -1
  8. package/dist-server/engine/kpi-fold.d.ts +20 -3
  9. package/dist-server/engine/kpi-fold.js +21 -4
  10. package/dist-server/engine/kpi-fold.js.map +1 -1
  11. package/dist-server/engine/kpi-query.d.ts +9 -0
  12. package/dist-server/engine/kpi-query.js +118 -19
  13. package/dist-server/engine/kpi-query.js.map +1 -1
  14. package/dist-server/engine/kpi-target.d.ts +141 -0
  15. package/dist-server/engine/kpi-target.js +137 -0
  16. package/dist-server/engine/kpi-target.js.map +1 -0
  17. package/dist-server/engine/live-attentions.d.ts +4 -2
  18. package/dist-server/engine/live-attentions.js +5 -1
  19. package/dist-server/engine/live-attentions.js.map +1 -1
  20. package/dist-server/engine/measured-estimator.d.ts +50 -0
  21. package/dist-server/engine/measured-estimator.js +78 -0
  22. package/dist-server/engine/measured-estimator.js.map +1 -0
  23. package/dist-server/engine/model-basis.d.ts +23 -0
  24. package/dist-server/engine/model-basis.js +100 -0
  25. package/dist-server/engine/model-basis.js.map +1 -0
  26. package/dist-server/engine/oee-accumulator.d.ts +2 -2
  27. package/dist-server/engine/oee-accumulator.js +4 -4
  28. package/dist-server/engine/oee-accumulator.js.map +1 -1
  29. package/dist-server/engine/spec-coverage.d.ts +49 -0
  30. package/dist-server/engine/spec-coverage.js +60 -0
  31. package/dist-server/engine/spec-coverage.js.map +1 -0
  32. package/dist-server/engine/structure-diff.d.ts +25 -0
  33. package/dist-server/engine/structure-diff.js +63 -0
  34. package/dist-server/engine/structure-diff.js.map +1 -0
  35. package/dist-server/engine/travel-estimator.d.ts +57 -0
  36. package/dist-server/engine/travel-estimator.js +120 -0
  37. package/dist-server/engine/travel-estimator.js.map +1 -0
  38. package/dist-server/engine/twin-engine.d.ts +153 -17
  39. package/dist-server/engine/twin-engine.js +473 -81
  40. package/dist-server/engine/twin-engine.js.map +1 -1
  41. package/dist-server/engine/warm-start.d.ts +5 -5
  42. package/dist-server/engine/warm-start.js +4 -4
  43. package/dist-server/engine/warm-start.js.map +1 -1
  44. package/dist-server/service/index.d.ts +4 -2
  45. package/dist-server/service/index.js +21 -14
  46. package/dist-server/service/index.js.map +1 -1
  47. package/dist-server/service/reference/reference-live.js +2 -1
  48. package/dist-server/service/reference/reference-live.js.map +1 -1
  49. package/dist-server/service/reference/reference-master.d.ts +307 -1
  50. package/dist-server/service/reference/reference-master.js +96 -8
  51. package/dist-server/service/reference/reference-master.js.map +1 -1
  52. package/dist-server/service/reference/reference-resolver.js +3 -3
  53. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  54. package/dist-server/service/reference/template-registry.d.ts +1 -1
  55. package/dist-server/service/reference/template-registry.js.map +1 -1
  56. package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
  57. package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
  58. package/dist-server/service/twin-control/twin-control-mutation.js +1 -1
  59. package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
  60. package/dist-server/service/twin-event/twin-event-keys.d.ts +1 -1
  61. package/dist-server/service/twin-event/twin-event-keys.js +3 -3
  62. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  63. package/dist-server/service/twin-event/twin-event.d.ts +11 -0
  64. package/dist-server/service/twin-event/twin-event.js +6 -1
  65. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  66. package/dist-server/service/twin-forecast/twin-forecast-query.js +50 -7
  67. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
  68. package/dist-server/service/twin-instance/twin-instance.js +1 -1
  69. package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
  70. package/dist-server/service/twin-journal/twin-journal-query.d.ts +9 -0
  71. package/dist-server/service/twin-journal/twin-journal-query.js +54 -3
  72. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  73. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +1 -1
  74. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +4 -3
  75. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
  76. package/dist-server/service/twin-space/twin-space-area.js +1 -1
  77. package/dist-server/service/twin-space/twin-space-area.js.map +1 -1
  78. package/dist-server/service/twin-space/twin-space-resolver.js +3 -3
  79. package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
  80. package/dist-server/service/twin-space/twin-space.d.ts +11 -0
  81. package/dist-server/service/twin-space/twin-space.js +5 -0
  82. package/dist-server/service/twin-space/twin-space.js.map +1 -1
  83. package/dist-server/service/twin-structure/index.d.ts +2 -0
  84. package/dist-server/service/twin-structure/index.js +6 -0
  85. package/dist-server/service/twin-structure/index.js.map +1 -0
  86. package/dist-server/service/twin-structure/twin-structure.d.ts +28 -0
  87. package/dist-server/service/twin-structure/twin-structure.js +97 -0
  88. package/dist-server/service/twin-structure/twin-structure.js.map +1 -0
  89. package/dist-server/service/twin-target/index.d.ts +4 -0
  90. package/dist-server/service/twin-target/index.js +8 -0
  91. package/dist-server/service/twin-target/index.js.map +1 -0
  92. package/dist-server/service/twin-target/twin-target-resolver.d.ts +7 -0
  93. package/dist-server/service/twin-target/twin-target-resolver.js +143 -0
  94. package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -0
  95. package/dist-server/service/twin-target/twin-target.d.ts +25 -0
  96. package/dist-server/service/twin-target/twin-target.js +112 -0
  97. package/dist-server/service/twin-target/twin-target.js.map +1 -0
  98. package/dist-server/tsconfig.tsbuildinfo +1 -1
  99. package/package.json +7 -7
  100. package/server/engine/entity-delta.ts +135 -15
  101. package/server/engine/index.ts +4 -0
  102. package/server/engine/kpi-fold.ts +40 -8
  103. package/server/engine/kpi-query.ts +129 -19
  104. package/server/engine/kpi-target.ts +226 -0
  105. package/server/engine/live-attentions.ts +12 -2
  106. package/server/engine/measured-estimator.ts +91 -0
  107. package/server/engine/model-basis.ts +94 -0
  108. package/server/engine/oee-accumulator.ts +5 -5
  109. package/server/engine/spec-coverage.ts +85 -0
  110. package/server/engine/structure-diff.ts +88 -0
  111. package/server/engine/travel-estimator.ts +133 -0
  112. package/server/engine/twin-engine.ts +498 -84
  113. package/server/engine/warm-start.ts +8 -8
  114. package/server/service/index.ts +7 -0
  115. package/server/service/reference/reference-live.ts +2 -1
  116. package/server/service/reference/reference-master.ts +383 -10
  117. package/server/service/reference/reference-resolver.ts +3 -3
  118. package/server/service/reference/template-registry.ts +1 -1
  119. package/server/service/twin-attention/twin-attention-query.ts +1 -1
  120. package/server/service/twin-control/twin-control-mutation.ts +1 -1
  121. package/server/service/twin-event/twin-event-keys.ts +2 -2
  122. package/server/service/twin-event/twin-event.ts +15 -1
  123. package/server/service/twin-forecast/twin-forecast-query.ts +56 -8
  124. package/server/service/twin-instance/twin-instance.ts +1 -1
  125. package/server/service/twin-journal/twin-journal-query.ts +52 -4
  126. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +4 -3
  127. package/server/service/twin-space/twin-space-area.ts +1 -1
  128. package/server/service/twin-space/twin-space-resolver.ts +3 -3
  129. package/server/service/twin-space/twin-space.ts +14 -0
  130. package/server/service/twin-structure/index.ts +3 -0
  131. package/server/service/twin-structure/twin-structure.ts +93 -0
  132. package/server/service/twin-target/index.ts +5 -0
  133. package/server/service/twin-target/twin-target-resolver.ts +124 -0
  134. package/server/service/twin-target/twin-target.ts +97 -0
  135. package/test/capability-mapping.test.ts +5 -5
  136. package/test/duration-estimators.test.ts +144 -0
  137. package/test/entity-delta.test.ts +150 -19
  138. package/test/ingest-bench.test.ts +9 -9
  139. package/test/kpi-fold.test.ts +232 -3
  140. package/test/live-mirror-parity.test.ts +53 -19
  141. package/test/master-to-twin.test.ts +87 -13
  142. package/test/model-basis.test.ts +86 -0
  143. package/test/oee-accumulator.test.ts +9 -9
  144. package/test/scale-twin-bench.test.ts +22 -22
  145. package/test/spec-coverage.test.ts +113 -0
  146. package/test/streamline-e2e.test.ts +10 -10
  147. package/test/structure-revision-db.test.ts +310 -0
  148. package/test/twin-event-keys.test.ts +2 -2
  149. package/test/vocabulary-guard.test.ts +43 -0
  150. package/test/warm-start.test.ts +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * TwinEngine โ€” operato-twin ์ปค๋„ ์ธ์Šคํ„ด์Šค๋ฅผ things-factory ์œ„์—์„œ ํ˜ธ์ŠคํŒ….\n * integration-base ์˜ ScenarioEngine ํŒจํ„ด ๋ฏธ๋Ÿฌ: ๋ฉ”๋ชจ๋ฆฌ ์ธ์Šคํ„ด์Šค ๋งต + ๋ฐฑ๊ทธ๋ผ์šด๋“œ tick + pubsub ์ƒํƒœ ๋ฐœํ–‰.\n *\n * ์ปค๋„(zero-dep, ESM+CJS ์ด์ค‘๋ฐฐํฌ)์€ CJS require ๋กœ ๋กœ๋“œ(Node 20 CommonJS ์†Œ๋น„ โ€” require(ESM) ํšŒํ”ผ).\n * ์ปค๋„์€ ๊ฒฐ์ •์  ๋…ผ๋ฆฌ ์—ฐ์‚ฐ ์ฝ”์–ด โ€” ์ด host ๊ฐ€ ์ „์†ก(pubsub)ยท์˜์†(TypeORM)ยท์Šค์ผ€์ค„(tick)ยท๋ณต๊ตฌ(replay)๋งŒ ์–‡๊ฒŒ ๋ž˜ํ•‘.\n * (์„ค๊ณ„ SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { twinEventKeys } from '../service/twin-event/twin-event-keys.js'\nimport { planWarmStart } from './warm-start.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\nimport { withLiveAttentions } from './live-attentions.js'\n\nimport type { TwinKernel, BoardDef, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* ์ปค๋„ ๋Ÿฐํƒ€์ž„ ๋กœ๋“œ โ€” CJS ๋ฒˆ๋“ค(dist-cjs). ํƒ€์ž…์€ ์œ„ import type ๋กœ. replay = ์ด๋ฒคํŠธ์—ดโ†’์ƒํƒœ ์žฌ๊ตฌ์„ฑ(๋ณต๊ตฌยท์‹œ๊ฐ„์—ฌํ–‰). */\nconst { WmsKernel, YmsKernel, MesKernel, TwinRuntime, StateProjector, replay, DOMAIN_CATALOG, OP_EVENT } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel }\n\n/* ๋ผ์ด๋ธŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ) โ€” ์œ ์ž…/๋ฐฉ์†ก/์ €๋„๋ฅ ยท๋ฐฑ๋กœ๊ทธ. ์‹ค ๋™๊ธฐ ์ธํ„ฐํŽ˜์ด์Šค ๋ถ€ํ•˜๋ฅผ ์ฝ๋Š” ์ผ๊ธ‰ ์ง€ํ‘œ. */\ninterface TwinMetrics {\n ingestedTotal: number // ๋ˆ„์  ์œ ์ž… ์ด๋ฒคํŠธ\n broadcastTotal: number // ๋ˆ„์  ๋ฐฉ์†ก ํšŸ์ˆ˜\n journaledTotal: number // ๋ˆ„์  ์ €๋„ ๊ธฐ๋ก ์ด๋ฒคํŠธ\n ingestRate: number // ์ตœ๊ทผ ์œ ์ž…๋ฅ (ev/s)\n broadcastRate: number // ์ตœ๊ทผ ๋ฐฉ์†ก๋ฅ (ํšŒ/s)\n journalRate: number // ์ตœ๊ทผ ์ €๋„๋ฅ (ev/s)\n backlog: number // ๋งˆ์ง€๋ง‰ flush ์‹œ ๋Œ€๊ธฐ ์ €๋„ ํฌ๊ธฐ(๋ฐฑํ”„๋ ˆ์…” ์‹ ํ˜ธ)\n // ์ฐฝ(window) ์ง‘๊ณ„์šฉ ๋‚ด๋ถ€ ๋ˆ„์ \n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * realityMode โ€” ์ด ํŠธ์œˆ์˜ \"ํ˜„์‹ค์ด ์–ด๋””์„œ ์˜ค๋‚˜\"(runtime-state-model ยง0ยทยง1 ํ”„๋ ˆ์ž„์˜ โ‘  ์„ ์–ธ).\n * ๋ถ€ํŒ… ๊ฑฐ๋™์„ ๊ฒฐ์ •ํ•˜๋Š” 1๊ธ‰ ์„ ์–ธ: mirror=์™ธ๋ถ€ ์‹ค๋ฌผ ์žฌ๋™๊ธฐ / sim-world=์ƒ์„ฑ ํƒ€์ž„๋ผ์ธ ์ง€์†(resume) / sim-experiment=seed ์žฌํ˜„(reset).\n * ๋ฏธ์„ ์–ธ = 'sim-experiment'(๊ฐ€์žฅ ๋ณด์ˆ˜์  โ€” ๊ธฐ์กด ๋ฐ๋ชจ ๊ฑฐ๋™ ๋ณด์กด).\n */\nexport type RealityMode = 'mirror' | 'sim-world' | 'sim-experiment'\nexport const DEFAULT_REALITY_MODE: RealityMode = 'sim-experiment'\n\n/* ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ผ์ด๋ธŒ ๋Ÿฐํƒ€์ž„ ํ™€๋”(์˜์† ์—”ํ‹ฐํ‹ฐ TwinInstance ์™€ ๊ตฌ๋ถ„). */\ninterface InstanceRuntime {\n /** ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 ํ”„๋ ˆ์ž„ โ‘ ). ๋ถ€ํŒ… ๊ฑฐ๋™(reset/resume/resync)์˜ ๊ทผ๊ฑฐ. */\n realityMode?: RealityMode\n id: string\n domainId: string\n domain?: any // ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(data ์ฑ„๋„)์šฉ Domain ๊ฐ์ฒด(subdomain ํ•„ํ„ฐ). start ์‹œ ๋น„๋™๊ธฐ ํ•ด์„.\n runtime?: TwinRuntimeType // sim: ์ปค๋„ ๋Ÿฐํƒ€์ž„(tick/subscribe/dispatch). live ๋Š” projector ์‚ฌ์šฉ.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live ๋ฏธ์‚ฌ์šฉ.\n mode?: 'sim' | 'live' // ์ƒํƒœ ๋“œ๋ผ์ด๋ฒ„ โ€” sim=์ปค๋„ tick / live=projector ๋ฏธ๋Ÿฌ(face2-inbound-live). ๋ฏธ์ง€์ •=sim.\n projector?: any // live: StateProjector(์ด๋ฒคํŠธโ†’State ์žฌ๊ตฌ์„ฑ). sim ๋ฏธ์‚ฌ์šฉ.\n oee?: OeeAccumulator // live: OEE ๊ณ„์‚ฐ ์ธต(์ด๋ฒคํŠธ ๋ˆ„์  โ†’ mover payload ๋ณด๊ฐ•). sim ์€ ์ปค๋„์ด ๊ณ„์‚ฐ.\n unsub: () => void\n timer?: any\n /** ์—”ํ‹ฐํ‹ฐ๋ณ„ ๋งˆ์ง€๋ง‰ ๋ฐœํ–‰ ์‹œ๊ทธ๋‹ˆ์ฒ˜ โ€” ๊ฐ’์ด ๋ฐ”๋€ ์—”ํ‹ฐํ‹ฐ๋งŒ ์žฌ๋ฐœํ–‰(๋ฌด๋ณ€ํ™” ๋ฐ˜๋ณต push ๋ฐฉ์ง€). */\n entitySigs?: Map<string, string>\n /** live ๋ฐฉ์†ก ๋ณ‘ํ•ฉ(ingest-scale ยง4.4) โ€” ingest ๋งˆ๋‹ค ๋ฐฉ์†กํ•˜์ง€ ์•Š๊ณ  dirty ํ‘œ์‹œ โ†’ coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์†ก. */\n dirty?: boolean\n /** live ์ €๋„ ๊ฒฐ์„  โ€” ingest ์ด๋ฒคํŠธ๋ฅผ ๋ชจ์•˜๋‹ค๊ฐ€ coalescer tick ์—์„œ ๋ฐฐ์น˜ ๊ธฐ๋ก(์ด๋ฒคํŠธ๋งˆ๋‹ค DB write ๊ธˆ์ง€). */\n pendingJournal?: any[]\n /** live ์ €๋„ revision ์นด์šดํ„ฐ(sim ์˜ delta revision ๋Œ€์‘ โ€” ์‹œ๊ฐ„์—ฌํ–‰ยทํžˆ์Šคํ† ๋ฆฌ ๋…ธ๋ธŒ ์•ต์ปค). */\n revision?: number\n /** live ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ, โ‘ฃ-1). */\n metrics?: TwinMetrics\n}\n\nexport class TwinEngine {\n static instances: Record<string, InstanceRuntime> = {}\n /** ๋ผ์ด๋ธŒ ๋Ÿฐํƒ€์ž„์ด ์—†์„ ๋•Œ(๋ณต๊ตฌ ํ›„ ๋ฏธ๊ธฐ๋™) ์ €๋„์—์„œ ์žฌ๊ตฌ์„ฑํ•œ ์ƒํƒœ ์บ์‹œ. */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /* ์ตœ์‹  ์Šค๋ƒ…์ƒท ์˜์†(warm-start) โ€” ์žฌ๊ธฐ๋™ ์‹œ ์ €๋„ fold-from-0 replay ๋Œ€์‹  ๋งˆ์ง€๋ง‰ ๋ผ์ด๋ธŒ ์Šค๋ƒ…์ƒท์œผ๋กœ ๋ณต์›.\n * ํ”„๋ ˆ์ž„์›Œํฌ ๊ณตํ†ต cache-service(@things-factory/cache-service) ์žฌ์‚ฌ์šฉ(์žฌ๋ฐœ๋ช… ๊ธˆ์ง€, framework-leverage ยง4).\n * ์ €๋„์€ ๊ทธ๋Œ€๋กœ ์ง„์‹ค(์‹œ๊ฐ„์—ฌํ–‰/history replay ๋ฌด๋ณ€๊ฒฝ) โ€” ์บ์‹œ๋Š” display-only ์›œ์Šคํƒ€ํŠธ ์ตœ์ ํ™”. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7์ผ โ€” ์ •์ƒ ๋‹ค์šดํƒ€์ž„ ์ƒ์กด, ๋งŒ๋ฃŒ ์‹œ ์ €๋„ replay ํด๋ฐฑ\n static CHECKPOINT_MS = 20000 // ์ฒดํฌํฌ์ธํŠธ ์ฃผ๊ธฐ(ํ•ซ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๊ฒฝ๋กœ์™€ ๋ถ„๋ฆฌ, O(state) ์Šค๋กœํ‹€)\n private static checkpointTimer?: any\n\n /** ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ cache-service ์— ์ฒดํฌํฌ์ธํŠธ(๋„๋ฉ”์ธ+instanceId ํ‚ค). display-onlyยท๋น„์ฐจ๋‹จยท์˜ค๋ฅ˜ํก์ˆ˜. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n if (!inst) return\n const state = this.snapshot(instanceId)\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state }, this.SNAPSHOT_TTL_S)\n }\n\n /** ์ฒดํฌํฌ์ธํŠธ๋œ ์ตœ์‹  ์Šค๋ƒ…์ƒท ๋กœ๋“œ(์—†์œผ๋ฉด null). getFromCache ๋Š” CacheStore ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ โ†’ ํŽ˜์ด๋กœ๋“œ๋Š” .value. */\n static async loadSnapshot(domainId: string, instanceId: string): Promise<{ revision: number; state: any } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /** ์ฒดํฌํฌ์ธํŠธ ๋ฃจํ”„ ๊ธฐ๋™(1ํšŒ) โ€” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋“ค์˜ ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ ์ฃผ๊ธฐ ์˜์†. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [instanceId, inst] of Object.entries(this.instances)) {\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n console.error(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * ๋ถ€ํŒ… ํ›… โ€” DB ์— status='running' ์œผ๋กœ ๋‚จ์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ €๋„์—์„œ ์ƒํƒœ ์žฌ๊ตฌ์„ฑ(DBโ†’replay).\n * ๋ผ์ด๋ธŒ tick ์žฌ๊ฐœ(sim ๊ฒฐ์ •์  re-run / live ์ธ์ œ์ŠคํŠธ ์ง€์†)๋Š” ํ›„์†. ์—ฌ๊ธฐ์„  ์ƒํƒœ ๋ณต์› + ๋…ธ์ถœ.\n */\n static async bootstrap(): Promise<void> {\n try {\n // ๋ฐฑํ•„(space #3) โ€” spaceId ์ปฌ๋Ÿผ ์—†๋Š” ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๋ฅผ board.spaceId ๋กœ ์ฑ„์›€(1ํšŒ, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์•ˆ์ „).\n const repo = getRepository(TwinInstance)\n const missing = (await repo.find()).filter(r => !r.spaceId && (r.board as any)?.spaceId)\n for (const r of missing) {\n r.spaceId = (r.board as any).spaceId\n r.areaId = (r.board as any).areaId ?? r.areaId\n await repo.save(r)\n }\n if (missing.length) console.log(`[twin-engine] backfilled spaceId for ${missing.length} instance(s).`)\n\n // ๋ฐฑํ•„(area ๋‹จ์ผํ™” P3) โ€” deprecated content.areas โ†’ TwinArea ์ด๊ด€(ํด๋ฐฑ ์ œ๊ฑฐ ์ „ ์™„์ „์„ฑ ๋ณด์žฅ, 1ํšŒ).\n const spaceRepo = getRepository(TwinSpace)\n const twinAreaRepo = getRepository(TwinArea)\n for (const sp of await spaceRepo.find()) {\n const cAreas = ((sp.content as any)?.areas ?? []) as any[]\n for (const a of cAreas) {\n if (!a?.id) continue\n const ex = await twinAreaRepo.findOne({ where: { domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id } })\n if (ex) continue\n await twinAreaRepo.save(twinAreaRepo.create({\n domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id,\n name: a.name ?? a.id, type: a.type, parentId: a.parentId ?? null,\n layout: a.x != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n }))\n }\n }\n\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // ์›œ์Šคํƒ€ํŠธ: ์บ์‹œ๋œ ์ตœ์‹  ์Šค๋ƒ…์ƒท ์šฐ์„ (O(1) + attentions/OEE ๋“ฑ ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ ๋ณด์กด).\n // ์—†์œผ๋ฉด ์ €๋„ fold-from-0 replay(์ง„์‹ค ํด๋ฐฑ โ€” replay ๋Š” ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ๋ฅผ ๋ชป ๋‹ด์œผ๋ฏ€๋กœ ์บ์‹œ๊ฐ€ ๋” ์ถฉ์‹ค).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[row.instanceId] = { revision: cached.revision, state: cached.state }\n console.log(`[twin-engine] warm-started \"${row.instanceId}\" from snapshot cache โ†’ revision ${cached.revision}.`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[row.instanceId] = { revision: state.revision, state }\n console.log(`[twin-engine] recovered \"${row.instanceId}\" from journal โ†’ revision ${state.revision}.`)\n }\n }\n this.startCheckpointLoop() // ์ดํ›„ ๊ธฐ๋™๋˜๋Š” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค์˜ ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ ์ฃผ๊ธฐ ์˜์†\n } catch (err) {\n console.error('[twin-engine] recovery scan failed', err)\n }\n }\n\n /**\n * ์›œ์Šคํƒ€ํŠธ โ€” ๊ธฐ๋™ํ•˜๋Š” ์ปค๋„์— **์ง์ „ ๊ด€์ธก ์ƒํƒœ**๋ฅผ ์‹ฌ๋Š”๋‹ค.\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `loadBoard` ๋Š” **๊ตฌ์กฐ๋งŒ** ์‹ฃ๋Š”๋‹ค(๋…ธ๋“œยท๋ฌด๋ฒ„). ์ƒํƒœ(๋ฌด์—‡์ด ์–ด๋””์— ์–ผ๋งˆ๋‚˜)๋Š” ์—†๋‹ค. ๊ทธ๋ž˜์„œ ์žฌ๊ธฐ๋™ํ•œ\n * ํŠธ์œˆ์€ ์ €๋„์— ์ž…๊ณ  540๊ฑด์ด ๋‚จ์•„ ์žˆ์–ด๋„ ์žฌ๊ณ ๊ฐ€ 0 ์ด์—ˆ๊ณ , ํ™”๋ฉด์€ \"๋ณด์œ  ์ค‘์ธ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค\" ๋ผ๊ณ \n * ๋งํ–ˆ๋‹ค โ€” ์žˆ๋Š” ์žฌ๊ณ ๋ฅผ ์—†๋‹ค๊ณ  ํ•˜๋Š” ์…ˆ์ด๋‹ค(2026-07-31 hatiolab-wms ์‹ค์ธก์œผ๋กœ ํ™•์ธ).\n * `bootstrap()` ์ด ์ด๋ฏธ ์ฒดํฌํฌ์ธํŠธ ์บ์‹œ(์—†์œผ๋ฉด ์ €๋„ replay)๋กœ ์ƒํƒœ๋ฅผ ๋ณต๊ตฌํ•ด `recovered` ์— ๋‹ด์•„ ๋‘๋Š”๋ฐ,\n * ๊ธฐ๋™ ์ˆœ๊ฐ„ ๊ทธ๊ฑธ **๋ฒ„๋ฆฌ๊ณ ** ์žˆ์—ˆ๋‹ค. ๋ฐ˜๋งŒ ์—ฐ๊ฒฐ๋ผ ์žˆ๋˜ ์žฅ์น˜๋ฅผ ์ž‡๋Š”๋‹ค.\n *\n * โ”€โ”€ ์ •์งํ•œ ํ•œ๊ณ„ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ยท **์˜ค๋”๋Š” ๋ณต์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.** `hydrateObserved` ์˜ ์˜ค๋” ์ธ์ž๋Š” requested/fulfilled/lines ๋ฅผ ์š”๊ตฌํ•˜๋Š”๋ฐ\n * ์Šค๋ƒ…์ƒท์˜ `OrderState` ์—๋Š” `progress` ๋ฐ–์— ์—†๋‹ค. progress ์—์„œ ์—ญ์‚ฐํ•˜๋ฉด ์—†๋Š” ์ˆซ์ž๋ฅผ ์ง€์–ด๋‚ด๋Š” ๊ฒƒ์ด๋ผ\n * ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์žฌ๊ณ ยท๋…ธ๋“œยท๋ฌด๋ฒ„๋งŒ ๋ณต์›๋˜๊ณ  ์ง„ํ–‰ ์ค‘ ์˜ค๋”๋Š” ๋น„์–ด์„œ ์‹œ์ž‘ํ•œ๋‹ค.\n * ยท ์ง„ํ–‰ ์ค‘ ๊ฐœ๋ณ„ task ์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋„ ๊ด€์ธก๋งŒ์œผ๋กœ๋Š” ๋ณต์›๋˜์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๋ช…์‹œํ•œ ํ•œ๊ณ„, ์žฌ๊ณ„ํš์— ๋งก๊น€).\n * ยท ๊ทผ๋ณธ ํ•ด๋ฒ•(์ƒํƒœ ์˜์† ๊ณ„์•ฝยทrevision ์ด์–ด๋ถ™์ž„)์€ ๋ณ„๋„ ๊ณผ์ œ.\n *\n * โ”€โ”€ ๋ฒค์น˜๋Š” ์‹œ๋“œํ•˜์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ถ€ํ•˜ ๋ฒค์น˜๋Š” **์ƒˆ ์‹œ์ž‘์—์„œ ์šฉ๋Ÿ‰์„ ์žฌ๋Š” ๊ฒƒ**์ด ๋ชฉ์ ์ด๋ผ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์‹ฌ์œผ๋ฉด ์ธก์ •์ด ์˜ค์—ผ๋œ๋‹ค.\n */\n private static warmStart(id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[id]?.state, purpose, typeof hydrate === 'function')\n\n if (plan.action === 'skip') {\n if (plan.reason === 'bench') {\n console.log(`[twin-engine] \"${id}\" is a bench twin โ€” starting empty on purpose (seeding would skew the measurement).`)\n } else if (plan.reason === 'unsupported') {\n console.warn(\n `[twin-engine] kernel for \"${id}\" cannot be warm-started (no hydrateObserved) โ€” it starts with structure only, so held stock will read as zero.`\n )\n }\n return\n }\n\n hydrate.call(kernel, plan.seed)\n console.log(\n `[twin-engine] warm-started \"${id}\" โ€” ${plan.itemCount} item(s), ${plan.moverCount} mover(s) restored. ` +\n 'Open orders are not restored (the snapshot carries no requested/fulfilled counts).'\n )\n }\n\n /** ํŠธ์œˆ ์ธ์Šคํ„ด์Šค ์‹œ์ž‘ โ€” ์ปค๋„ ์ƒ์„ฑ + ๋ณด๋“œ ๋กœ๋“œ + ์ง์ „ ์ƒํƒœ ์›œ์Šคํƒ€ํŠธ + State ์ŠคํŠธ๋ฆผ ๋ธŒ๋ฆฌ์ง€ + ์›Œ์ปค tick + ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์˜์†. */\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode, purpose?: string): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId)\n kernel.loadBoard(board) // ๊ตฌ์กฐ๋งŒ. ์ƒํƒœ๋Š” ์•„๋ž˜ ์›œ์Šคํƒ€ํŠธ๊ฐ€ ์‹ฌ๋Š”๋‹ค.\n this.warmStart(id, kernel, purpose)\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe ๋Š” RuntimeSubscription({ unsubscribe() }) ๋ฐ˜ํ™˜ โ†’ () => void ๋กœ ๊ฐ์Œˆ. */\n const inst: InstanceRuntime = { id, domainId, runtime, kernel, realityMode: realityMode ?? DEFAULT_REALITY_MODE, unsub: () => {} }\n this.instances[id] = inst\n delete this.recovered[id] // ์›œ์Šคํƒ€ํŠธ๋กœ ์ปค๋„์— ์˜ฎ๊ฒจ ์‹ฌ์—ˆ๋‹ค โ€” ์ด์ œ ๋ผ์ด๋ธŒ๊ฐ€ ์ง„์‹ค์ด๋‹ค.\n\n /* ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(P3): data ์ฑ„๋„ ํ•„ํ„ฐ๊ฐ€ subdomain ์„ ๋ณด๋ฏ€๋กœ Domain ๊ฐ์ฒด๋ฅผ 1ํšŒ ํ•ด์„ํ•ด ๋‘”๋‹ค. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State ์ฑ„๋„: runtime.subscribe(snapshotโ†’deltaโ†’clock) โ†’ pubsub ๋ฐฉ์†ก(๊ตฌ๋… ๋ฆฌ์กธ๋ฒ„๊ฐ€ instanceId ํ•„ํ„ฐ). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n pubsub.publish('twin-state', {\n twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg }\n })\n /* ์˜์† + ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ ๋ธŒ๋ฆฌ์ง€: delta ๋งˆ๋‹ค ์ €๋„ ์ €์žฅ + ์—”ํ‹ฐํ‹ฐ๋ณ„ data(tag:) publish โ†’ ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ. */\n if (msg.kind === 'delta') {\n this.persist(domainId, id, msg).catch(err => console.error('twin persist fail', err))\n this.publishEntityData(inst)\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* ๋ณต๊ตฌ ์•ต์ปค: ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— board/kind/status/realityMode ์˜์†(์žฌ๋ถ€ํŒ… ์‹œ ์ด๊ฒŒ ์žˆ์–ด์•ผ replayยท์„ ์–ธ ๊ฑฐ๋™ ๊ฐ€๋Šฅ). */\n this.register(domainId, id, kind, board, 'running', inst.realityMode).catch(err => console.error('twin register fail', err))\n\n /* ์›Œ์ปค tick โ€” ์Šค์ผˆ๋ ˆํ†ค์€ setInterval(๋ฉ”์ธ ๋ฃจํ”„). ๊ธด ์‹œ๋ฎฌ ์˜คํ”„-๋ฃจํ”„(worker thread)๋Š” ์Šค์ผ€์ผ ํ•˜๋“œ๋‹(ํ–ฅํ›„, ยงhost ๊ฒฝ๊ณ„). */\n inst.timer = setInterval(() => runtime.tick(this.TICK_MS), this.TICK_MS)\n return inst\n }\n\n /**\n * live-๋ชจ๋“œ ๊ธฐ๋™(face2-inbound-live ยง1.1) โ€” ์ปค๋„ tick ๋Œ€์‹  StateProjector ๋กœ ์‹ค ์ด๋ฒคํŠธ๋ฅผ ๋ฏธ๋Ÿฌ.\n * ๊ด€์ธก ์ƒํƒœ(์ ์œ ยท์œ„์น˜ยท์•„์ดํ…œ)๋Š” projector ๊ฐ€ ์žฌ๊ตฌ์„ฑ โ†’ sim ๊ณผ ๋™์ผ data(tag) payload โ†’ **๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ ๋™์ผ ๋ Œ๋”**\n * (live-mirror-parity ๋กœ payload ์ธต ๊ฒ€์ฆ๋จ). ๊ณ„์‚ฐ ์ธต(attentionsยทOEE)์€ ์ด๋ฒคํŠธ์— ์—†์–ด ๋ถ€์žฌ โ€” derive ์ธต์€ ํ›„์†.\n * ์‹ค ์ด๋ฒคํŠธ์› = reference ์–ด๋Œ‘ํ„ฐ openLiveFeed โ†’ face2-adapter.ingest โ†’ CanonicalEnvelope โ†’ ingestLive().\n */\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n const projector = new StateProjector(board)\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', projector, oee: new OeeAccumulator(), unsub: () => {} }\n inst.metrics = { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n this.instances[id] = inst\n delete this.recovered[id]\n /* ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(data ์ฑ„๋„) subdomain ํ•„ํ„ฐ์šฉ Domain 1ํšŒ ํ•ด์„(sim ๊ณผ ๋™์ผ). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /* ์ €๋„ revision ์นด์šดํ„ฐ ์‹œ๋“œ โ€” ๊ธฐ์กด ์ €๋„ ์ตœ๋Œ€์น˜์—์„œ ์ด์–ด๋ถ™์ž„(์žฌ๊ธฐ๋™ ์‹œ revision ์ถฉ๋Œ ๋ฐฉ์ง€). ์ดํ›„ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€. */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => (inst.revision = top?.revision ?? 0))\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, board, 'running', 'mirror').catch(err => console.error('twin register fail', err))\n return inst\n }\n\n /**\n * live ์ด๋ฒคํŠธ ์ธ์ œ์ŠคํŠธ โ€” projector ๊ตฌ๋™ + data(tag) ๋ฐฉ์†ก(ํ๋ฃจํ”„์˜ ์ธ๋ฐ”์šด๋“œ ๋„์ฐฉ ์ง€์ , command-routing ยง8.2).\n * reference ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋‚ธ records โ†’ ์ปค๋„ face2-adapter.ingest โ†’ CanonicalEnvelope ๋ฅผ ์—ฌ๊ธฐ๋กœ ๋ฐ€์–ด๋„ฃ๋Š”๋‹ค.\n * (State ์ฑ„๋„ ๋ธํƒ€/์ €๋„ ๊ฒฐ์„ ์€ ํ›„์† โ€” ์Šค์ผˆ๋ ˆํ†ค์€ data(tag) ๋ฏธ๋Ÿฌ ์ค‘์‹ฌ.)\n */\n static ingestLive(id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[id]\n if (inst?.mode !== 'live' || !inst.projector) return\n for (const e of envelopes) { inst.projector.apply(e); inst.oee?.apply(e) } // ๊ด€์ธก(projector) + ๊ณ„์‚ฐ(OEE ๋ˆ„์ )\n // ์ €๋„ ๊ฒฐ์„ (๋ผ์ด๋ธŒ๋„ sim ์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ ์˜์†) โ€” ๋‹จ ์ด๋ฒคํŠธ๋งˆ๋‹ค DB write ํ•˜๋ฉด ๋ถ€ํ•˜ํญ๋ฐœ์ด๋ผ ๋ชจ์•„๋’€๋‹ค๊ฐ€\n // coalescer tick ์—์„œ ๋ฐฐ์น˜ ๊ธฐ๋ก(๋ฐฉ์†ก๊ณผ ๋™์ผ ์ฃผ๊ธฐ). ํžˆ์Šคํ† ๋ฆฌ ๋…ธ๋ธŒยทํƒ€์ž„๋ผ์ธยท๋น„์ฆˆ๋‹ˆ์Šค ์›์žฅ์ด ์ด ์ €๋„์„ ์ฝ๋Š”๋‹ค.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // ๊ณ„์ธก(โ‘ฃ-1)\n // ๋ฐฉ์†ก ๋ณ‘ํ•ฉ(ingest-scale ยง1.1/ยง4.4) โ€” apply ๋Š” O(1)ยท์‹ธ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐฉ์†ก(snapshot O(state))์€ ๋น„์‹ธ(๋Œ€๊ทœ๋ชจ 5ms+)\n // ์ด๋ฒคํŠธ๋งˆ๋‹ค ๋ฐฉ์†กํ•˜๋ฉด ํญ๋ฐœ โ†’ dirty ๋งŒ ์ฐ๊ณ  coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์†ก(๋ฐฉ์†ก๋ฅ  โ‰  ์ธ์ œ์ŠคํŠธ๋ฅ ).\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n\n /** ๋ฐฉ์†ก ๋ณ‘ํ•ฉ ์ฃผ๊ธฐ(ms) โ€” ๋ฐฉ์†ก๋ฅ  ์ƒํ•œ. ์ธ์ œ์ŠคํŠธ๊ฐ€ ์•„๋ฌด๋ฆฌ ๋นจ๋ผ๋„ ์ด ์ฃผ๊ธฐ๋กœ๋งŒ ๋ฐฉ์†ก. */\n static BROADCAST_COALESCE_MS = 200\n private static broadcastTimer?: any\n\n /** live ๋ฐฉ์†ก coalescer โ€” dirty ์ธ live ์ธ์Šคํ„ด์Šค๋งŒ ์ฃผ๊ธฐ์ ์œผ๋กœ 1ํšŒ ๋ฐฉ์†ก(entitySigs ๋กœ ๋ณ€๊ฒฝ ์—”ํ‹ฐํ‹ฐ๋งŒ). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.BROADCAST_COALESCE_MS)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // ์ข…๋ฃŒ ๋น„์ฐจ๋‹จ\n }\n\n /** dirty live ์ธ์Šคํ„ด์Šค ๋ฐฉ์†ก flush(์ฃผ๊ธฐ tick ๋˜๋Š” ๋ช…์‹œ ํ˜ธ์ถœ). ํ…Œ์ŠคํŠธ/์ฆ‰์‹œ ๋ฐฉ์†ก์šฉ์œผ๋กœ public. */\n static flushLiveBroadcasts(): void {\n let anyLive = false\n const now = Date.now()\n for (const inst of Object.values(this.instances)) {\n if (inst.mode !== 'live') continue\n anyLive = true\n // ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(โ‘ฃ-1) โ€” ์ฐฝ(โ‰ฅ1s)๋งˆ๋‹ค ์œ ์ž…/๋ฐฉ์†ก/์ €๋„๋ฅ  ๊ฐฑ์‹ . dirty ๋ฌด๊ด€(์œ ํœด๋ฉด 0์œผ๋กœ ์ˆ˜๋ ด). ๋ถ€ํ•˜๋ฅผ ์ฝ๋Š” ์‹ ํ˜ธ.\n const m = inst.metrics\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n // โ‘  ์—”ํ‹ฐํ‹ฐ data(tag) ๋ฐฉ์†ก โ€” ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ ๋ Œ๋”.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n // โ‘ข ์ €๋„ ๋ฐฐ์น˜ ๊ธฐ๋ก โ€” ๋ชจ์•„๋‘” ์ด๋ฒคํŠธ์— revision ๋ถ€์—ฌํ•ด ๋ฒŒํฌ ์ €์žฅ(์ด๋ฒคํŠธ๋งˆ๋‹ค write ์•„๋‹˜).\n // revision ์นด์šดํ„ฐ๋Š” ์ธ๋ฉ”๋ชจ๋ฆฌ(startLive ์—์„œ ์ €๋„ high-water ๋กœ 1ํšŒ ์‹œ๋“œ) โ†’ tick ๋งˆ๋‹ค DB ์งˆ์˜ ์—†์Œ.\n const batch = inst.pendingJournal\n if (batch?.length && inst.revision != null) {\n inst.pendingJournal = []\n const start = inst.revision\n inst.revision = start + batch.length\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = batch.length }\n this.persistBatch(inst.domainId, inst.id, batch, start).catch(err => console.error('twin live journal fail', err))\n }\n // โ‘ก State ์ฑ„๋„ ๋ฐฉ์†ก โ€” \"๋ฐ”๋€Œ์—ˆ๋‹ค\"๋Š” ๊ฐ€๋ฒผ์šด ์‹ ํ˜ธ๋งŒ(kind+revision). ๋งต ๊ตฌ๋…(subscribeTwinState)์€ ์ด ์‹ ํ˜ธ์—\n // scheduleRefresh(250ms ๋””๋ฐ”์šด์Šค)โ†’pollLive ๋กœ ๋˜๋ฌผ์–ด๋ด„. ์Šค๋ƒ…์ƒท(O(state))์€ ๋ณด๋Š” ์‚ฌ๋žŒ์ด ๋ฌผ์„ ๋•Œ๋งŒ 1ํšŒ ๊ณ„์‚ฐ.\n // (์—ฌ๊ธฐ์„œ payload ๋กœ ์Šค๋ƒ…์ƒท์„ ์‹ค์œผ๋ฉด ์•„๋ฌด๋„ ์•ˆ ์ฝ๋Š”๋ฐ tick ๋งˆ๋‹ค ํ†ต์งธ๋กœ ๋– ์„œ ์ˆœ์ˆ˜ ๋‚ญ๋น„ โ€” ์‹ ํ˜ธ๋งŒ ๋ณด๋‚ธ๋‹ค.)\n pubsub.publish('twin-state', {\n twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 }\n })\n }\n if (!anyLive && this.broadcastTimer) { clearInterval(this.broadcastTimer); this.broadcastTimer = undefined } // live ์—†์œผ๋ฉด tick ์ •์ง€\n }\n\n /**\n * ์ €๋„ ํ–‰ ํ•œ ์ค„ โ€” **๊ธฐ๋ก ๊ฒฝ๋กœ๊ฐ€ ๋‘˜์ด๋ผ(๋ผ์ด๋ธŒ ๋ฒŒํฌยท์‹ฌ ๋‹จ๊ฑด) ํ–‰ ๋ชจ์–‘์€ ๋ฐ˜๋“œ์‹œ ํ•œ ๊ณณ์—์„œ ๋งŒ๋“ ๋‹ค.**\n * ๋‘ ๊ณณ์— ๊ฐ์ž ์ ์œผ๋ฉด ์Šน๊ฒฉ ๊ฒ€์ƒ‰ ํ‚ค๊ฐ€ ํ•œ์ชฝ์—๋งŒ ์ฑ„์›Œ์ง€๊ณ , ๋ฐ˜์ฏค ๋นˆ ์ƒ‰์ธ์€ \"์ €๋„์—๋Š” ์žˆ๋Š”๋ฐ\n * ๊ฒ€์ƒ‰์œผ๋กœ๋Š” ์•ˆ ๋‚˜์˜ค๋Š” ์ด๋ฒคํŠธ\" ๋ฅผ ๋งŒ๋“ ๋‹ค โ€” ์ €๋„์—์„œ ๊ฐ€์žฅ ๋‚˜์œ ์ข…๋ฅ˜์˜ ๊ฒฐํ•จ์ด๋‹ค.\n */\n private static journalRow(repo: any, domainId: string, instanceId: string, e: any, revision: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision,\n eventTime: e?.eventTime,\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /** live ์ €๋„ ๋ฐฐ์น˜ ๊ธฐ๋ก โ€” ๋ชจ์•„๋‘” CanonicalEnvelope ๋“ค์— startRevision+1.. ์„ ๋ถ€์—ฌํ•ด ๋ฒŒํฌ ์ €์žฅ(coalescer tick ๋‹น 1ํšŒ). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1))\n await repo.save(rows, { chunk: 500 })\n }\n\n /** ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ upsert(๋„๋ฉ”์ธ+instanceId ์œ ๋‹ˆํฌ). status ์ธ์ž๋กœ provision(stopped)/start(running) ๊ณต์šฉ. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n board: BoardDef,\n status: 'running' | 'stopped' = 'running',\n realityMode?: RealityMode\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n board,\n // ์ธ์Šคํ„ด์Šคโ†”๊ณต๊ฐ„ 1๊ธ‰ ๋งํฌ(space #3) โ€” board.spaceId/areaId ๋ฅผ ์ปฌ๋Ÿผ์œผ๋กœ ์Šน๊ฒฉ(dual-write). board JSON ๋„ ์œ ์ง€(์ปค๋„ยท๋ณต๊ตฌ์šฉ).\n spaceId: (board as any)?.spaceId ?? existing?.spaceId,\n areaId: (board as any)?.areaId ?? existing?.areaId,\n // ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 โ‘ ) โ€” ๋ช…์‹œ๊ฐ’ ์šฐ์„ , ์—†์œผ๋ฉด ๊ธฐ์กด๊ฐ’ ๋ณด์กด(์žฌํ”„๋กœ๋น„์ „์ด ์„ ์–ธ์„ ์ง€์šฐ์ง€ ์•Š๊ฒŒ).\n realityMode: realityMode ?? existing?.realityMode ?? undefined,\n status\n })\n )\n }\n\n /**\n * ๋ผ์ด๋ธŒ ๊ตฌ์กฐ ๋ณ€์ด(resource.add ๋“ฑ)๋ฅผ ์ €์žฅ๋œ board ์— ๋ฐ˜์˜ โ€” ๋Ÿฐํƒ€์ž„ ์ปค๋„์˜ ๋ฌด๋ฒ„๋ฅผ registry board.movers ์— ๋™๊ธฐ.\n * ์ด๊ฒŒ ์—†์œผ๋ฉด ๋Ÿฐํƒ€์ž„์—” ์ถ”๊ฐ€๋ผ๋„(์ƒํƒœยท์ €๋„์—” ๋ฐ˜์˜) ์ €์žฅ board ๋Š” ์›๋ณธ์ด๋ผ ํ”„๋กœ๋น„์ €๋‹ ํŽธ์ง‘๊ธฐยท์žฌ๊ธฐ๋™(loadBoard)์ด\n * ์ถ”๊ฐ€๋ถ„์„ ์žƒ๋Š”๋‹ค. ๊ธฐ์กด board.movers ํ•ญ๋ชฉ์€ ๋ณด์กด(homeNode ์œ ์ง€)ํ•˜๊ณ  ์ƒˆ id ๋งŒ append(์ถ”๊ฐ€ ์‹œ์  location=homeNode).\n * ์ขŒํ‘œ(layout)๋งŒ ๋‹ค๋ฃจ๋Š” register ์™€ ๋‹ฌ๋ฆฌ movers ์ง‘ํ•ฉ์„ ๊ฐฑ์‹ ํ•˜๋‚˜, ์žฌํ”„๋กœ๋น„์ „(purge)์ด ์•„๋‹ˆ๋ผ in-place ๊ฐฑ์‹ ์ด๋ผ\n * ์ €๋„์€ ๋ณด์กด๋œ๋‹ค(์ถ”๊ฐ€๋Š” ์ด๋ฏธ equipment ๋ธํƒ€๋กœ ์ €๋„๋จ โ†’ replay ๋Š” id-keyed upsert ๋ผ ์ด์ค‘๊ณ„์‚ฐ ์—†์Œ).\n */\n static async syncBoardMovers(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.movers) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return\n const board = reg.board as BoardDef\n const known = new Set((board.movers ?? []).map(m => m.id))\n const added = snap.movers\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeNode: m.location }))\n if (!added.length) return\n board.movers = [...(board.movers ?? []), ...added]\n reg.board = board\n await repo.save(reg)\n }\n\n /**\n * ํ”„๋กœ๋น„์ €๋‹ โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๊ตฌ์กฐ(board)๋ฅผ ๋“ฑ๋ก๋งŒ ํ•˜๊ณ  ๊ธฐ๋™ํ•˜์ง€ ์•Š์Œ(status='stopped').\n * ์žฌํ”„๋กœ๋น„์ „ ์‹œ ๊ตฌ์กฐ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๋ฐ”๋€Œ๋ฉด(๋…ธ๋“œยท๋ฌด๋ฒ„ ์ง‘ํ•ฉ/์†์„ฑ ๋ณ€๊ฒฝ) ๊ธฐ์กด ์ €๋„์„ purge ํ•œ๋‹ค(ADR-0015):\n * board ๋Š” replay ์˜ ๋งˆ์Šคํ„ฐ๋ผ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๊ณผ๊ฑฐ ์ด๋ฒคํŠธ์˜ ์ „์ œ๊ฐ€ ๊นจ์ง„๋‹ค. ์ขŒํ‘œ(layout)๋งŒ ๋ฐ”๋€Œ๋ฉด ์ €๋„ ๋ณด์กด.\n */\n static async provision(domainId: string, instanceId: string, kind: string, board: BoardDef): Promise<void> {\n if (this.instances[instanceId]) throw new Error(`instance \"${instanceId}\" is running โ€” stop before re-provisioning`)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n if (existing?.board && this.structureSignature(existing.board as BoardDef) !== this.structureSignature(board)) {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /** ๊ตฌ์กฐ ๋™์ผ์„ฑ ์ง€๋ฌธ โ€” ์ขŒํ‘œ(layout) ๋“ฑ ๋ทฐ ๊ด€์‹ฌ์‚ฌ๋Š” ์ œ์™ธํ•˜๊ณ  ์ปค๋„์ด ๋ณด๋Š” ์œ„์ƒยท์šฉ๋Ÿ‰ยท๋ฌด๋ฒ„๋งŒ. */\n private static structureSignature(board: BoardDef): string {\n const nodes = [...(board.nodes ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const movers = [...(board.movers ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeNode}`)\n .sort()\n .join('|')\n return `N[${nodes}]M[${movers}]`\n }\n\n /** ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ board ๋กœ ๊ธฐ๋™(ํ”„๋กœ๋น„์ „๋œ ์ธ์Šคํ„ด์Šค start). board ์ธ์ž ์—†์ด ์ €์žฅ๋œ ๊ตฌ์กฐ๋กœ ์žฌ๊ธฐ๋™. */\n static async startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime> {\n if (this.instances[instanceId]) return this.instances[instanceId]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n\n /*\n * ์›œ์Šคํƒ€ํŠธ ์žฌ๋ฃŒ๋ฅผ **์—ฌ๊ธฐ์„œ ํ™•์‹คํžˆ ํ™•๋ณดํ•œ๋‹ค.**\n * `start()` ๋Š” ๋™๊ธฐ๋ผ ์Šค์Šค๋กœ ์บ์‹œ๋ฅผ ์ฝ์„ ์ˆ˜ ์—†์–ด์„œ `recovered` ์— ๋ฏธ๋ฆฌ ๋‹ด๊ฒจ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š”๋ฐ,\n * ๊ทธ๊ฑด `bootstrap()` ์ด ๋จผ์ € ๋Œ์•˜์„ ๋•Œ๋งŒ ์ฐธ์ด๋‹ค. ๋ถ€ํŒ… ์ˆœ์„œ์— ๊ธฐ๋Œ€๋ฉด ์–ด๋–ค ๋‚ ์€ ์žฌ๊ณ ๊ฐ€ ์‚ด์•„๋‚˜๊ณ \n * ์–ด๋–ค ๋‚ ์€ ์กฐ์šฉํžˆ ๋นˆ ์ฑ„๋กœ ๋œฌ๋‹ค โ€” ์žฌํ˜„๋˜์ง€ ์•Š๋Š” ๊ฒฐํ•จ์ด ๊ฐ€์žฅ ๋‚˜์˜๋‹ค.\n * ์ฒดํฌํฌ์ธํŠธ ์บ์‹œ ์šฐ์„ (O(1) + ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ ๋ณด์กด), ์—†์œผ๋ฉด ์ €๋„ replay ํด๋ฐฑ(๋ถ€ํŒ…๊ณผ ๊ฐ™์€ ์ˆœ์„œ).\n */\n if (!this.recovered[instanceId] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[instanceId] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[instanceId] = { revision: state.revision, state }\n }\n }\n\n return this.start(\n instanceId,\n domainId,\n reg.kind ?? 'wms',\n reg.board as BoardDef,\n realityMode ?? (reg.realityMode as RealityMode) ?? undefined,\n reg.purpose ?? undefined\n )\n }\n\n /**\n * ์„ ์–ธ ๊ธฐ๋ฐ˜ ๋ถ€ํŒ…(ยง0 ํ”„๋ ˆ์ž„ โ‘  โ†’ ๋ถ€ํŒ… ๊ฑฐ๋™ ๋งคํ•‘) โ€” ํŠธ์œˆ์ด ์„ ์–ธํ•œ realityMode ์— ๋”ฐ๋ผ ์žฌ๊ธฐ๋™ ๋ฐฉ์‹์„ ๊ฐ€๋ฅธ๋‹ค.\n * ๋ถ€ํŒ… ๊ฒฝ๋กœ๋ฅผ ํ•œ ๊ณณ์— ๋ชจ์•„ \"๋Ÿฐํƒ€์ž„ โ‰  ํ˜„์‹ค\" ๋ฒ”์ฃผ์˜ค๋ฅ˜๋ฅผ ์ฝ”๋“œ๋กœ ๊ฐ•์ œํ•œ๋‹ค.\n * - 'mirror' : ํ˜„์‹ค=์™ธ๋ถ€ ์‹ค๋ฌผ โ†’ startLive(์žฌ๋™๊ธฐ). ์ด๋ฒคํŠธ๋Š” ์–ด๋Œ‘ํ„ฐ ingest ๋กœ ์œ ์ž…, ์ปค๋„ tick ์—†์Œ.\n * - 'sim-world' : ์ƒ์„ฑ ํƒ€์ž„๋ผ์ธ ์ง€์† โ†’ ์ €๋„ ๋ณด์กด + resume(ํ˜„์‹ค ์ด์–ด๊ฐ).\n * โš  GATE(ยง8 โ‘กโ‘ข): ์ปค๋„ ์ƒํƒœ ์ง๋ ฌํ™”/์žฌ๊ฐœ๊ฐ€ ์•„์ง ์—†์–ด ์ง„์งœ resume ๋ถˆ๊ฐ€ โ†’ ์‹ค ํ•„์š”ยท์‹ค๋ถ€ํ•˜ ์‹œ ๊ตฌํ˜„.\n * ๊ทธ๋•Œ๊นŒ์ง€๋Š” ์ €๋„์„ ๋ณด์กดํ•˜๋˜ revision ์ถฉ๋Œ์„ ํ”ผํ•˜๋ ค fresh ๋กœ ๊ธฐ๋™ํ•˜๊ณ , ์„ ์–ธ๊ณผ ๊ตฌํ˜„์˜ ๊ฐ„๊ทน์„ ํฌ๊ฒŒ ๊ฒฝ๊ณ ํ•œ๋‹ค.\n * - 'sim-experiment' : seed ์žฌํ˜„ โ†’ resetJournal + fresh ๊ธฐ๋™(๋ฐฑ์ง€ ์‹œ์ž‘์ด ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ์„ ์–ธ๋œ ๊ฑฐ๋™).\n * ๋ฐ˜ํ™˜: ๊ธฐ๋™๋œ InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RealityMode = DEFAULT_REALITY_MODE): Promise<InstanceRuntime> {\n if (mode === 'mirror') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n return this.startLive(instanceId, domainId, reg.kind ?? 'wms', reg.board as BoardDef)\n }\n if (mode === 'sim-world') {\n // ์„ ์–ธ์€ world(์ง€์†)์ง€๋งŒ resume ๊ธฐ๊ณ„์žฅ์น˜(์ปค๋„ ์ƒํƒœ ๋ณต์›)๊ฐ€ ์•„์ง ์—†๋‹ค โ†’ ์ •์งํ•˜๊ฒŒ ํฐ ๊ฒฝ๊ณ  ํ›„ fresh ๊ธฐ๋™.\n console.warn(\n `[twin-engine] \"${instanceId}\" declared sim-world but resume is not yet implemented (runtime-state-model ยง8 gate โ‘กโ‘ข) โ€” booting FRESH (journal reset). Persisted continuity will attach here once kernel-state resume lands.`\n )\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-world')\n }\n // sim-experiment(๊ธฐ๋ณธ): seed ์žฌํ˜„ โ€” ์ €๋„ ์ดˆ๊ธฐํ™” ํ›„ revision 0 ๋ถ€ํ„ฐ ์žฌ์‹คํ–‰.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-experiment')\n }\n\n /**\n * ์ €๋„ ์ดˆ๊ธฐํ™” โ€” ์ธ์Šคํ„ด์Šค ์ด๋ฒคํŠธ ์ €๋„ purge(๋ ˆ์ง€์ŠคํŠธ๋ฆฌยท์ƒํƒœ๋Š” ์œ ์ง€).\n * ๋ฐ๋ชจ fresh-start ์šฉ: ๋งค ๋ถ€ํŒ… seed ๋ถ€ํ„ฐ ์ƒˆ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐ๋ชจ์—์„œ, ๋ณต๊ตฌ๋ณธ ํ๊ธฐ ํ›„ revision 0 ๋ถ€ํ„ฐ ์žฌ์‹คํ–‰ํ•˜๋ฉด\n * ์˜› ๋Ÿฐ๊ณผ revision ์ด ๊ฒน์ณ ์ €๋„์ด ์˜ค์—ผ๋œ๋‹ค โ†’ start ์ „์— ํ˜ธ์ถœํ•ด ํ˜„์žฌ ๋Ÿฐ๋งŒ ๋‚จ๊ธด๋‹ค.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n\n /** ์‚ญ์ œ โ€” ์ •์ง€ + ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์‚ญ์ œ + ์ €๋„ purge(domain ์Šค์ฝ”ํ”„). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(instanceId)\n delete this.recovered[instanceId]\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /** ๊ด€๋ฆฌ ๋ชฉ๋ก โ€” domain ์˜ ๋“ฑ๋ก ์ธ์Šคํ„ด์Šค ์ „์ฒด(๋ผ์ด๋ธŒ ์—ฌ๋ถ€ยท์ตœ์‹  ์ €๋„ revisionยท๋…ธ๋“œ/๋ฌด๋ฒ„ ์ˆ˜ ํฌํ•จ). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const out: any[] = []\n for (const r of rows) {\n const board = (r.board as BoardDef) ?? { nodes: [], movers: [] }\n const last = await getRepository(TwinEvent).findOne({\n where: { domain: { id: domainId } as any, instanceId: r.instanceId },\n order: { revision: 'DESC' }\n })\n out.push({\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: ๊ฐ™์€ spaceId ์ธ์Šคํ„ด์Šค๋“ค์ด ํ•œ ๊ณต๊ฐ„(๊ณต์žฅ) ๊ณต์œ  โ€” ๊ณต๊ฐ„๋ทฐ ์ง‘์•ฝ ํ‚ค(G7)\n realityMode: r.realityMode ?? DEFAULT_REALITY_MODE, // ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 โ‘ ) โ€” mirror/sim-world/sim-experiment\n purpose: r.purpose ?? 'operational', // ์šด์˜ vs ๋ฒค์น˜ ์‚ฌ๋ณธ(1๊ธ‰ ๊ตฌ๋ณ„ โ€” ์ด๋ฆ„ ์ ‘๋‘์‚ฌ ์•„๋‹˜)\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[r.instanceId],\n revision: last?.revision ?? 0,\n nodeCount: board.nodes?.length ?? 0,\n moverCount: board.movers?.length ?? 0\n })\n }\n return out\n }\n\n /** ๋ ˆ๊ฑฐ์‹œ ๋ฒค์น˜ ์ž”์žฌ ๊ฐ€๋“œ โ€” purpose ๋„์ž… ์ „ ๋งŒ๋“ค์–ด์ง„ ๋ฒค์น˜/๋ถ€ํ•˜ ๊ณต๊ฐ„(์ด๋ฆ„ ๊ทœ์•ฝ)๊นŒ์ง€ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค. */\n static isBenchSpace(spaceId?: string): boolean {\n return !!spaceId && (/^bench-/.test(spaceId) || spaceId === 'rosarito-load' || /^loadtest/.test(spaceId))\n }\n\n /** ์šด์˜ ๊ณต๊ฐ„ ๋ชฉ๋ก(๋ฒค์น˜ ์†Œ์Šค ์„ ํƒ๊ธฐ) โ€” ์ด๋ฆ„ยท๊ทœ๋ชจ ํฌํ•จ, ๋ฒค์น˜ ์‚ฌ๋ณธยท์ž”์žฌ ์ œ์™ธ. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; nodes: number; movers: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; nodes: number; movers: number }>()\n for (const r of insts) {\n if (!r.spaceId || r.purpose === 'bench' || this.isBenchSpace(r.spaceId)) continue // ๋ฒค์น˜ยท์ž”์žฌ ์ œ์™ธ\n const board: any = r.board ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, nodes: 0, movers: 0 }\n a.instances++\n a.nodes += board.nodes?.length ?? 0\n a.movers += board.movers?.length ?? 0\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** ์ธ์Šคํ„ด์Šค ๋ชฉ์  ํ‘œ์‹(์šด์˜/๋ฒค์น˜) ์„ค์ • โ€” ๋ฒค์น˜ ์‚ฌ๋ณธ์„ 1๊ธ‰ ์†์„ฑ์œผ๋กœ ๊ตฌ๋ณ„(์ด๋ฆ„ ์ ‘๋‘์‚ฌ ์•„๋‹˜). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * ๊ณต๊ฐ„ ๊ตฌ์กฐ ํŒ๋… โ€” ์™„์ „๋ณต์ œ(๋ฒค์น˜ ์‚ฌ๋ณธ)์˜ ์†Œ์Šค. ์ €์žฅ๋ฌผ์ด board(์œ„์ƒ)ยทTwinSpace.content(์น˜์ˆ˜ยทgeoยทํ‘œํ˜„)ยทTwinArea(์˜์—ญ)๋กœ\n * ๋ถ„์‚ฐ๋ผ ์žˆ์œผ๋ฏ€๋กœ ์…‹์„ ๋ชจ์•„ ๋Œ๋ ค์ค€๋‹ค. ํ˜ธ์ถœ์ธก์ด ReferenceMaster ๋กœ ์žฌ๊ตฌ์„ฑ โ†’ ์žฌ์‹๋ณ„ โ†’ ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{ name?: string; content: any; areas: any[]; instances: { instanceId: string; kind?: string; board: any }[] } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return { name: sp?.name, content: sp?.content ?? {}, areas, instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, board: i.board })) }\n }\n\n /** ๊ณต๊ฐ„(+ํ‘œํ˜„ยท์˜์—ญ) ์‚ญ์ œ โ€” ๋ฒค์น˜ ์ •๋ฆฌ ๋“ฑ. ํ˜ธ์ถœ์ธก์ด ๋ฐ”์ธ๋”ฉ ์ธ์Šคํ„ด์Šค๋ฅผ ๋จผ์ € ์ œ๊ฑฐํ•˜๋Š” ์ „์ œ(๊ฐ€๋“œ ์—†์Œ). deleteTwinSpace ๋ฆฌ์กธ๋ฒ„์™€ ๋™ํ˜•. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 ๋งˆ์Šคํ„ฐ ์ธ์ œ์ŠคํŠธ(ADR-0018) โ€” ๋ ˆํผ๋Ÿฐ์Šค ์‹œ์Šคํ…œ(์‹ค ๋˜๋Š” ๊ฐ€์ƒ)์˜ ๋งˆ์Šคํ„ฐ๋ฅผ ์ฝ์–ด ํŠธ์œˆ์„ ์ƒ์„ฑ.\n * ์—”ํ‹ฐํ‹ฐ๋ฅผ ์†๋ฐฐ์„ /๋ฐœ๋ช…ํ•˜์ง€ ์•Š๊ณ  ๋งˆ์Šคํ„ฐ์—์„œ ๋ฐ˜์˜: ๊ณต๊ฐ„(Space) upsert + ์ธ์Šคํ„ด์Šค provision(๋ฏธ๊ธฐ๋™).\n * ๋…ธ๋“œํƒ€์ž…์€ ์ปค๋„ ์นดํƒˆ๋กœ๊ทธ๋กœ ๊ฒ€์ฆ(warning). start ๋Š” ํ˜ธ์ถœ์ธก(bootstrap/mutation)์ด ๊ฒฐ์ •.\n */\n static async ingestMaster(domainId: string, master: ReferenceMaster): Promise<{ instanceId: string; spaceId: string; warnings: string[] }> {\n const { board, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n const spaceId: string = board.spaceId\n const repo = getRepository(TwinSpace)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /*\n * ๊ณต์œ  ๊ณต๊ฐ„(์—ฌ๋Ÿฌ ํŠธ์œˆ์ด ํ•œ spaceId, N:1) content ๋ณ‘ํ•ฉ โ€” ๋งˆ์ง€๋ง‰ ์ธ์ œ์ŠคํŠธ๊ฐ€ ํ†ต์งธ๋กœ ๋ฎ์–ด์จ area(๊ทธ๋ฃน)ยทํ‘œํ˜„์ด\n * ์œ ์‹ค๋˜๋˜ ๋ฌธ์ œ ๋ณด์ •. areaยทlandmark ๋Š” id ํ•ฉ์ง‘ํ•ฉ, representations ๋Š” ๋น„์–ด์žˆ์ง€ ์•Š์€ ์ชฝ ๋ณด์กด, ๋‚˜๋จธ์ง€๋Š” first-wins.\n */\n const prev: any = existing?.content ?? {}\n const cur: any = spaceContent\n const unionById = (a: any[] = [], b: any[] = []) => {\n const m = new Map<string, any>()\n for (const x of [...a, ...b]) if (x?.id) m.set(x.id, x)\n return [...m.values()]\n }\n const mergedContent = {\n width: prev.width ?? cur.width,\n depth: prev.depth ?? cur.depth,\n unit: prev.unit ?? cur.unit,\n geo: prev.geo ?? cur.geo,\n primaryId: prev.primaryId ?? cur.primaryId,\n representations: (cur.representations?.length ? cur.representations : prev.representations) ?? [],\n // areas ๋Š” content ์— ๋” ์ด์ƒ ์“ฐ์ง€ ์•Š๋Š”๋‹ค(area ๋‹จ์ผํ™” P3) โ€” ๊ถŒ์œ„=TwinArea. ์•„๋ž˜ TwinArea ๋กœ๋งŒ ๊ธฐ๋ก.\n landmarks: unionById(prev.landmarks, cur.landmarks)\n }\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, content: mergedContent }))\n /*\n * ํ‘œํ˜„์„ twin_space_representations ํ…Œ์ด๋ธ”์— ์ €์žฅํ•œ๋‹ค โ€” ๋ทฐ(twin-map-page ๋“ฑ)๋Š” content ๊ฐ€ ์•„๋‹ˆ๋ผ ํ…Œ์ด๋ธ” ํ‘œํ˜„์„ ์†Œ์‹ฑํ•˜๋ฏ€๋กœ,\n * ์ €์žฅํ•˜์ง€ ์•Š์œผ๋ฉด ์ธ์ œ์ŠคํŠธ ์‚ฌ์ดํŠธ์— \"๋Œ€ํ‘œ ํ‘œํ˜„\" ์ด ์—†์–ด ์ง€๋„๋กœ ์‹œ์ž‘ํ•˜์ง€ ๋ชปํ•œ๋‹ค. rep.areas ๊ฐ€ ์žˆ์œผ๋ฉด TwinSpaceArea ๋„ ํ•จ๊ป˜ ์ €์žฅ.\n * ์ตœ์ดˆ ์ธ์ œ์ŠคํŠธ๋งŒ(๊ธฐ์กด ํ‘œํ˜„ ์žˆ์œผ๋ฉด ์‚ฌ์šฉ์ž ํŽธ์ง‘ ๋ณด์กด).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n }\n /*\n * area ๋‹จ์ผํ™”(space #2, P1) โ€” ๋…ผ๋ฆฌ ๊ตฌ์—ญ์„ TwinArea(์ •๊ทœยทํ‘œํ˜„๋ฌด๊ด€ยท๊ณต์œ )์— dual-write(upsert by areaId).\n * P3: content.areas ์ €์žฅ ํ๊ธฐ โ†’ TwinArea ๊ฐ€ ์œ ์ผ ๊ถŒ์œ„. ์†Œ์Šค = masterToTwin ์‚ฐ์ถœ spaceContent.areas(cur).\n * (์›์ฒœ diff ์ œ๊ฑฐ[master ์—์„œ ๋น ์ง„ area ์‚ญ์ œ]๋Š” ์‚ฌ์šฉ์ž์ €์ž‘ area ๋ณดํ˜ธ ์œ„ํ•ด per-area provenance ํ•„์š” โ†’ ํ›„์†.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n await this.provision(domainId, master.source, master.system, board)\n if (warnings.length) console.warn(`[twin-engine] ingest \"${master.source}\" warnings:`, warnings)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** ๋‹จ๊ฑด ์ƒ์„ธ โ€” ํ”„๋กœ๋น„์ €๋‹ ์—๋””ํ„ฐ๊ฐ€ ํŽธ์ง‘ํ•  board(๊ตฌ์กฐ+layout) ํฌํ•จ. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[r.instanceId],\n realityMode: r.realityMode, // ํ˜„์‹ค ์„ ์–ธ โ€” what-if ์ ์šฉ ๊ฐ€๋“œ์šฉ(mirror=์˜ˆ์ธก ์ „์šฉ, ์ž๊ทน ์ฃผ์ž… ๋ถˆ๊ฐ€)\n board: r.board\n }\n }\n\n /**\n * ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ ๋ธŒ๋ฆฌ์ง€(P3, ADR-0018) โ€” ํŠธ์œˆ ์—”ํ‹ฐํ‹ฐ ์ƒํƒœ๋ฅผ `data(tag=์—”ํ‹ฐํ‹ฐid)` ์ฑ„๋„๋กœ publish.\n * ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ tag ๋กœ ๊ตฌ๋…(board-ui provider)ํ•ด `component.data` ๋กœ ๋ผ์ด๋ธŒ ๊ฐฑ์‹ . delta ์‹œ์—๋งŒ(ํฌ์†Œ).\n * tag=์—”ํ‹ฐํ‹ฐ id(๋ฐ๋ชจ=๋‹จ์ผ ์ธ์Šคํ„ด์Šค). ๋ฉ€ํ‹ฐ ์ธ์Šคํ„ด์Šค/๋ณด๋“œ ์žฌ์‚ฌ์šฉ ์‹œ tag ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ํ›„์†.\n */\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* ์ƒํƒœ ์ถœ์ฒ˜ ์Šค์™‘ โ€” sim: ์ปค๋„ runtime, live: projector ๋ฏธ๋Ÿฌ(+OEE ๊ณ„์‚ฐ ์ธต ๋ณด๊ฐ•). ๊ณ„์•ฝยทpayload ๋™์ผ, ๋“œ๋ผ์ด๋ฒ„๋งŒ ๋‹ค๋ฆ„. */\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // ๊ด€์ธก ๋ฏธ๋Ÿฌ + ๊ณ„์‚ฐ(OEE) โ†’ mover payload ์— oee ํฌํ•จ(sim ๋™ํ˜•)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n if (!st) return\n /*\n * ๋ณ€ํ™”ํ•œ ์—”ํ‹ฐํ‹ฐ๋งŒ ๋ฐœํ–‰ โ€” ์ด์ „์—” delta ๋งˆ๋‹ค ์ „ ์—”ํ‹ฐํ‹ฐ(๋…ธ๋“œ+๋ฌด๋ฒ„+์˜ค๋”)๋ฅผ ๊ฐ’ ๋ณ€ํ™”์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์ „๋Ÿ‰ ์žฌ๋ฐœํ–‰ํ•ด\n * ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋งค์ดˆ ๋ฐ˜๋ณต push ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค(์˜ค์šฉ). ์ตœ์‹ -์ƒํƒœ ์ฑ„๋„์ด๋ฏ€๋กœ ๋ฌด๋ณ€ํ™” ์žฌ๋ฐฉ์†ก์€ ๋ฌด์˜๋ฏธํ•˜๋‹ค.\n * ์—”ํ‹ฐํ‹ฐ๋ณ„ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋น„๊ตํ•ด ๋ฐ”๋€ ๊ฒƒ๋งŒ push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload ๋งคํ•‘์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜(buildEntityDeltas)๋กœ ๋ถ„๋ฆฌ โ€” ์—ฌ๊ธฐ์„  ์‹œ๊ทธ๋‹ˆ์ฒ˜ dedup + ๋ฐœํ–‰๋งŒ.\n * ๋ณ€ํ™”ํ•œ ์—”ํ‹ฐํ‹ฐ๋งŒ ๋ฐœํ–‰(์ตœ์‹ -์ƒํƒœ ์ฑ„๋„์ด๋ผ ๋ฌด๋ณ€ํ™” ์žฌ๋ฐฉ์†ก ๋ฌด์˜๋ฏธ). */\n for (const { tag, data } of buildEntityDeltas(st)) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // ๋ฌด๋ณ€ํ™” โ†’ ๋ฐœํ–‰ ์ƒ๋žต\n sigs.set(tag, sig)\n pubsub.publish('data', { data: { domain, tag, data } })\n }\n /* ์‚ฌ๋ผ์ง„ ์—”ํ‹ฐํ‹ฐ์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ •๋ฆฌ(๋งต ๋ฌดํ•œ ์„ฑ์žฅ ๋ฐฉ์ง€). */\n if (sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n static async persist(domainId: string, instanceId: string, msg: any): Promise<void> {\n const repo = getRepository(TwinEvent)\n await repo.save(this.journalRow(repo, domainId, instanceId, msg.event, msg.revision))\n }\n\n /**\n * ์žฌ๋ถ€ํŒ… ๋ณต๊ตฌ / ์‹œ๊ฐ„์—ฌํ–‰ โ€” DB ์ €๋„์„ replay ํ•ด ์ƒํƒœ ์žฌ๊ตฌ์„ฑ.\n * board ๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(TwinInstance)์—์„œ, ์ด๋ฒคํŠธ๋Š” TwinEvent(revision ASC)์—์„œ.\n * ์ปค์„œ ๋‘ ์ถ•(runtime-state-model ยง4): **์‹œ๊ฐ(untilTime, ์‚ฌ์šฉ์ž ๋ชจ๊ตญ์–ดยท๊ณต๊ฐ„ ๊ณตํ†ต์ถ•)** ์šฐ์„ , ์—†์œผ๋ฉด ๋ฆฌ๋น„์ „(untilRevision, ๋ Œ์ฆˆ ๋‚ด๋ถ€).\n * - untilTime ์ฃผ๋ฉด `eventTime โ‰ค T` ์ธ ์ด๋ฒคํŠธ๋งŒ(๊ทธ ์‹œ์  watermark) โ€” ๊ณต๋™๋ฐฐ์น˜ ์—ฌ๋Ÿฌ ํŠธ์œˆ์„ ํ•˜๋‚˜์˜ ์‹œ๊ฐ T๋กœ ํ†ต์ผ ํ•ด์†Œ.\n * - ๋‘˜ ๋‹ค ์—†์œผ๋ฉด ์ตœ์‹ (๋ผ์ด๋ธŒ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ง„์‹ค).\n * ์ด๋ฒคํŠธ๋Š” ํ•ญ์ƒ revision ASC(์ธ๊ณผ ์ˆœ์„œ)๋กœ ์ ์šฉ โ€” ์‹œ๊ฐ ํ•„ํ„ฐ๋Š” ์ปท์˜คํ”„ ์ง‘ํ•ฉ๋งŒ ์ •ํ•œ๋‹ค.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // ๋ผ์ด๋ธŒ ์ตœ์‹ (์‹œ๊ฐ„์—ฌํ–‰ ์•„๋‹˜) + ์ธ๋ฉ”๋ชจ๋ฆฌ ์ธ์Šคํ„ด์Šค โ†’ ๋ผ์ด๋ธŒ ์ปค๋„ ์Šค๋ƒ…์ƒท์„ ์ง์ ‘ ์‚ฌ์šฉ.\n // replay(StateProjector)๋Š” attentionsยทack ๋“ฑ ๋ผ์ด๋ธŒ ์ „์šฉ ํŒŒ์ƒ ์ƒํƒœ๋ฅผ ๋‹ด์ง€ ๋ชปํ•˜๋ฏ€๋กœ, ์ตœ์‹ ์€ ์ปค๋„ ์ง„์‹ค์„ ์“ด๋‹ค.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[instanceId]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live ๋ชจ๋“œ๋Š” kernel ์ด ์—†๊ณ  projector ๋ฏธ๋Ÿฌ โ†’ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ตœ์‹  ์Šค๋ƒ…์ƒท(projector+OEE+attentions) ์ง์ ‘ ์‚ฌ์šฉ.\n // (์ €๋„์ด ์žˆ์–ด๋„ ์ตœ์‹ ์€ ์ธ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ง„์‹ค โ€” replay ๋Š” ์‹œ๊ฐ„์—ฌํ–‰/๋ณต๊ตฌ ์ „์šฉ.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(instanceId)\n }\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`twin instance \"${instanceId}\" not registered (no board to replay)`)\n\n const rows = await getRepository(TwinEvent).find({\n where: { domain: { id: domainId }, instanceId },\n order: { revision: 'ASC' }\n })\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const events = rows\n .filter(r => {\n if (untilTime != null && !Number.isNaN(cutoffMs)) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n return Number.isNaN(t) ? true : t <= cutoffMs // eventTime ์—†๋Š” ๋ ˆ๊ฑฐ์‹œ ํ–‰์€ ํฌํ•จ(๋ณด์ˆ˜์ )\n }\n return untilRevision == null || (r.revision ?? 0) <= untilRevision\n })\n .map(r => r.payload)\n .filter(Boolean)\n\n return replay(reg.board as BoardDef, events)\n }\n\n /**\n * ๊ณต๊ฐ„(๊ณต๋™๋ฐฐ์น˜) ์‹œ๊ฐ ๋ฒ”์œ„ โ€” ์Šคํฌ๋Ÿฌ๋ฒ„ ์•ต์ปค(runtime-state-model ยง4ยทยง6). ๊ทธ ๊ณต๊ฐ„ ์ „ ์ธ์Šคํ„ด์Šค ์ €๋„์˜ min/max eventTime.\n * ๋ฐ˜ํ™˜ {minTime, maxTime}(ISO) โ€” ์ด๋ฒคํŠธ/์‹œ๊ฐ ์—†์œผ๋ฉด null. ํด๋ผ ํžˆ์Šคํ† ๋ฆฌ ์Šคํฌ๋Ÿฌ๋ฒ„๊ฐ€ ์ด ๋ฒ”์œ„๋ฅผ ์‹œ๊ฐ์ถ•์œผ๋กœ ๊ทธ๋ฆฐ๋‹ค.\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n let min = Infinity\n let max = -Infinity\n for (const instanceId of ids) {\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId } })\n for (const r of rows) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n if (Number.isNaN(t)) continue\n if (t < min) min = t\n if (t > max) max = t\n }\n }\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** ์ •์ง€ ํ›… โ€” ์ธ์Šคํ„ด์Šค ์ •์ง€ ์‹œ ๋ถ€์ˆ˜์ž์› ์ •๋ฆฌ(์˜ˆ: reference-live ํ”ผ๋“œ unsubscribe). ์ˆœํ™˜ ์ž„ํฌํŠธ ์—†์ด ๊ฒฐ์„ . */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(id: string): Promise<void> {\n const i = this.instances[id]\n if (i) {\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[id]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => console.error('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* ํ›… ๊ฒฉ๋ฆฌ */ } }\n }\n\n static runtime(id: string): TwinRuntimeType | undefined {\n return this.instances[id]?.runtime\n }\n\n /**\n * ๋„๋ฉ”์ธ ์†Œ์œ  ๊ฒŒ์ดํŠธ โ€” ์ธ์Šคํ„ด์Šค๊ฐ€ ์ด ๋„๋ฉ”์ธ ์†Œ์œ ์ผ ๋•Œ๋งŒ true(ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ).\n * ์—†๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์ด๋ฉด false. ๋…ธ์ถœ ๋ฆฌ์กธ๋ฒ„(per-id metrics/attentions/state/stop/forecast)๊ฐ€\n * this.instances[id] ๋ฅผ ๋งŒ์ง€๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ์ด๊ฑธ๋กœ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ์ธ์Šคํ„ด์Šค id ๋Š” ์ถ”์ธก ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ\n * ๊ฒ€์ฆ ์—†์ด ์ ‘๊ทผํ•˜๋ฉด ํฌ๋กœ์Šคํ…Œ๋„ŒํŠธ ์ฝ๊ธฐ/์ •์ง€๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.\n */\n static owns(domainId: string, id: string): boolean {\n return this.instances[id]?.domainId === domainId\n }\n\n /** ๋ผ์ด๋ธŒ ์ปค๋„(ForecastTwin) โ€” forecast/divergence ์˜ˆ์ธก ์—ฐ์‚ฐ์šฉ. */\n static kernel(id: string): any {\n return this.instances[id]?.kernel\n }\n\n /** ๋ผ์ด๋ธŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก ์Šค๋ƒ…์ƒท(๋ชจ๋‹ˆํ„ฐ, โ‘ฃ-1) โ€” ๋‚ด๋ถ€ ๋ˆ„์ (_acc*) ์ œ์™ธํ•œ ๊ณต๊ฐœ ์ง€ํ‘œ. live ์•„๋‹ˆ๋ฉด null. */\n static metrics(id: string): any {\n const m = this.instances[id]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.BROADCAST_COALESCE_MS\n }\n }\n\n /** ์ „์ฒด ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ ๋Œ€์‹œ๋ณด๋“œ์šฉ). */\n static async allMetrics(domainId?: string): Promise<any[]> {\n const rows = Object.keys(this.instances)\n .filter(id => !domainId || this.instances[id].domainId === domainId)\n .map(id => this.metrics(id))\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // ํ‘œ์‹œ ์ด๋ฆ„ ๋ถ€์—ฌ โ€” ์‹คํ–‰์ค‘ ์นด๋“œ๊ฐ€ id ๋งŒ ๋ณด์ด์ง€ ์•Š๋„๋ก ๊ณต๊ฐ„๋ช…์„ ์‹ค์–ด์ค€๋‹ค(๊ณต๊ฐ„ ์นด๋“œ์™€ ๋™์ผ). name=๊ณต๊ฐ„๋ช… ํด๋ฐฑ spaceId ํด๋ฐฑ instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /**\n * ๋ผ์ด๋ธŒ ์˜ˆ์ธก์šฉ ์ž„์‹œ ์ปค๋„(kernel-unification P1) โ€” ๋ผ์ด๋ธŒ๋Š” projector ๋ฏธ๋Ÿฌ๋ผ ์ปค๋„์ด ์—†์–ด ์˜ˆ์ธก์„ ๋ชป ํ•œ๋‹ค.\n * ๊ด€์ธก ์Šค๋ƒ…์ƒท(์žฌ๊ณ ยท๋ฌด๋ฒ„ยท๋…ธ๋“œ) + ์ €๋„์˜ ์˜ค๋” ์›๊ฐ’ยท๋ผ์ธ์„ hydrate ํ•ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์ž„์‹œ ์ปค๋„์„ ๋งŒ๋“ ๋‹ค.\n * ๋ผ์ด๋ธŒ ๋Ÿฐํƒ€์ž„์€ ๋ฌด๊ฐ„์„ญ(์ด ์ปค๋„์€ fork ๋Œ€์ƒ ์ž„์‹œ๋ณธ, instances ์— ๋„ฃ์ง€ ์•Š์Œ). sim ์ธ์Šคํ„ด์Šค๋ฉด null(๊ทธ์ชฝ์€ kernel() ์‚ฌ์šฉ).\n */\n static async buildForecastKernel(domainId: string, instanceId: string): Promise<any | null> {\n const inst = this.instances[instanceId]\n if (inst?.mode !== 'live' || !inst.projector) return null\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n // ์ €๋„์—์„œ ์˜ค๋”๋ณ„ ์ตœ์‹  ๊ด€์ธก(์›๊ฐ’+๋ผ์ธ) ์ˆ˜์ง‘ โ€” projector ์Šค๋ƒ…์ƒท์€ ์˜ค๋”์— ์†์‹ค์ (progress ๋งŒ)์ด๋ผ ์ €๋„์„ ์“ด๋‹ค.\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) { const d = (r.payload as any)?.data; if (d?.orderId) latest.set(d.orderId, d) }\n k.hydrateObserved(this.snapshot(instanceId), [...latest.values()])\n return k\n }\n\n /**\n * ์˜ˆ์ธก์šฉ ์ปค๋„์„ **์ž„์˜ ์‹œ๊ฐ T ๊ธฐ์ค€**์œผ๋กœ ์žฌ๊ตฌ์„ฑ โ€” ๊ณผ๊ฑฐ-vantage ์˜ˆ์ธก(๋ฐฑํ…Œ์ŠคํŠธ)ยท\"๊ทธ๋•Œ ์„œ์„œ ๋ณธ ๋ฏธ๋ž˜\".\n * recover(untilTime)๋กœ T ์‹œ์  ์ƒํƒœ๋ฅผ, T ์ดํ•˜ ์˜ค๋” ๊ด€์ธก์„ ๋ชจ์•„ hydrate โ†’ monteCarloForecast ๊ฐ€ T ์—์„œ ์•ž์œผ๋กœ ๊ตด๋ฆฐ๋‹ค.\n * sim/live ๋ฌด๊ด€(์ €๋„ ๊ธฐ๋ฐ˜ ์žฌ๊ตฌ์„ฑ). untilTime ์ƒ๋žต ์‹œ ์ตœ์‹ . ๋„๋ฉ”์ธ ์Šค์ฝ”ํ”„(regยทjournal ์กฐํšŒ๊ฐ€ domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId)\n k.loadBoard(reg.board as BoardDef)\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && Date.parse(r.eventTime) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** ํ˜„์žฌ ์ „์ฒด ์Šค๋ƒ…์ƒท โ€” ๋ผ์ด๋ธŒ ์šฐ์„ , ์—†์œผ๋ฉด ์ €๋„ ๋ณต๊ตฌ ์บ์‹œ. */\n static snapshot(id: string): any {\n const inst = this.instances[id]\n if (inst?.mode === 'live' && inst.projector) {\n // live: projector ๋ฏธ๋Ÿฌ + ๊ณ„์‚ฐ ์ธต(OEEยทattentions) ๋ณด๊ฐ• โ†’ ์งˆ์˜(attention ๋“ฑ)๊ฐ€ sim ๋™ํ˜• ์Šค๋ƒ…์ƒท์„ ๋ด„.\n const st = inst.oee ? withLiveOee(inst.projector.snapshot(), inst.oee) : inst.projector.snapshot()\n return withLiveAttentions(st)\n }\n return inst?.runtime?.resync() ?? this.recovered[id]\n }\n}\n"]}
1
+ {"version":3,"file":"twin-engine.js","sourceRoot":"","sources":["../../server/engine/twin-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * TwinEngine โ€” operato-twin ์ปค๋„ ์ธ์Šคํ„ด์Šค๋ฅผ things-factory ์œ„์—์„œ ํ˜ธ์ŠคํŒ….\n * integration-base ์˜ ScenarioEngine ํŒจํ„ด ๋ฏธ๋Ÿฌ: ๋ฉ”๋ชจ๋ฆฌ ์ธ์Šคํ„ด์Šค ๋งต + ๋ฐฑ๊ทธ๋ผ์šด๋“œ tick + pubsub ์ƒํƒœ ๋ฐœํ–‰.\n *\n * ์ปค๋„(zero-dep, ESM+CJS ์ด์ค‘๋ฐฐํฌ)์€ CJS require ๋กœ ๋กœ๋“œ(Node 20 CommonJS ์†Œ๋น„ โ€” require(ESM) ํšŒํ”ผ). (vocabulary-guard: allow โ€” Node ๋Ÿฐํƒ€์ž„ ๋ฒ„์ „ ํ‘œ๊ธฐ)\n * ์ปค๋„์€ ๊ฒฐ์ •์  ๋…ผ๋ฆฌ ์—ฐ์‚ฐ ์ฝ”์–ด โ€” ์ด host ๊ฐ€ ์ „์†ก(pubsub)ยท์˜์†(TypeORM)ยท์Šค์ผ€์ค„(tick)ยท๋ณต๊ตฌ(replay)๋งŒ ์–‡๊ฒŒ ๋ž˜ํ•‘.\n * (์„ค๊ณ„ SoT: operato-twin/design/integration/things-factory-host.md)\n */\n\nimport { pubsub, getRepository, Domain } from '@things-factory/shell'\nimport { cacheService } from '@things-factory/cache-service'\n\nimport { TwinEvent } from '../service/twin-event/twin-event.js'\nimport { twinEventKeys } from '../service/twin-event/twin-event-keys.js'\nimport { planWarmStart } from './warm-start.js'\nimport { TwinInstance } from '../service/twin-instance/twin-instance.js'\nimport { TwinStructure } from '../service/twin-structure/twin-structure.js'\nimport { TwinSpace } from '../service/twin-space/twin-space.js'\nimport { utcOffsetOf } from '../service/reference/reference-master.js'\nimport { TwinSpaceRepresentation } from '../service/twin-space/twin-space-representation.js'\nimport { TwinSpaceArea } from '../service/twin-space/twin-space-area.js'\nimport { TwinArea } from '../service/twin-space/twin-area.js'\nimport { masterToTwin, type ReferenceMaster } from '../service/reference/reference-master.js'\nimport { buildTravelEstimator, chainEstimators } from './travel-estimator.js'\nimport { buildMeasuredEstimator } from './measured-estimator.js'\nimport { describeModelBasis, type ModelBasis } from './model-basis.js'\nimport { computeTwinKpi } from './kpi-query.js'\nimport { createHash } from 'node:crypto'\n\nimport { buildEntityDeltas } from './entity-delta.js'\nimport { diffStructures, type StructureDiff } from './structure-diff.js'\nimport { OeeAccumulator, withLiveOee } from './oee-accumulator.js'\n\nimport type { TwinKernel, BoardDef, SubscriptionMessage, TwinRuntime as TwinRuntimeType, CanonicalEnvelope } from '@operato/twin-kernel'\n\n/* ์ปค๋„ ๋Ÿฐํƒ€์ž„ ๋กœ๋“œ โ€” CJS ๋ฒˆ๋“ค(dist-cjs). ํƒ€์ž…์€ ์œ„ import type ๋กœ. replay = ์ด๋ฒคํŠธ์—ดโ†’์ƒํƒœ ์žฌ๊ตฌ์„ฑ(๋ณต๊ตฌยท์‹œ๊ฐ„์—ฌํ–‰). */\nconst { WmsKernel, YmsKernel, MesKernel, TwinRuntime, StateProjector, replay, replaySegments, DOMAIN_CATALOG, OP_EVENT } = require('@operato/twin-kernel')\n\nconst KERNELS: Record<string, any> = { wms: WmsKernel, yms: YmsKernel, mes: MesKernel }\n\n/* ๋ผ์ด๋ธŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ) โ€” ์œ ์ž…/๋ฐฉ์†ก/์ €๋„๋ฅ ยท๋ฐฑ๋กœ๊ทธ. ์‹ค ๋™๊ธฐ ์ธํ„ฐํŽ˜์ด์Šค ๋ถ€ํ•˜๋ฅผ ์ฝ๋Š” ์ผ๊ธ‰ ์ง€ํ‘œ. */\ninterface TwinMetrics {\n ingestedTotal: number // ๋ˆ„์  ์œ ์ž… ์ด๋ฒคํŠธ\n broadcastTotal: number // ๋ˆ„์  ๋ฐฉ์†ก ํšŸ์ˆ˜\n journaledTotal: number // ๋ˆ„์  ์ €๋„ ๊ธฐ๋ก ์ด๋ฒคํŠธ\n ingestRate: number // ์ตœ๊ทผ ์œ ์ž…๋ฅ (ev/s)\n broadcastRate: number // ์ตœ๊ทผ ๋ฐฉ์†ก๋ฅ (ํšŒ/s)\n journalRate: number // ์ตœ๊ทผ ์ €๋„๋ฅ (ev/s)\n backlog: number // ๋งˆ์ง€๋ง‰ flush ์‹œ ๋Œ€๊ธฐ ์ €๋„ ํฌ๊ธฐ(๋ฐฑํ”„๋ ˆ์…” ์‹ ํ˜ธ)\n // ์ฐฝ(window) ์ง‘๊ณ„์šฉ ๋‚ด๋ถ€ ๋ˆ„์ \n _accIngest: number\n _accBroadcast: number\n _accJournal: number\n _windowStartMs: number\n}\n\n/*\n * realityMode โ€” ์ด ํŠธ์œˆ์˜ \"ํ˜„์‹ค์ด ์–ด๋””์„œ ์˜ค๋‚˜\"(runtime-state-model ยง0ยทยง1 ํ”„๋ ˆ์ž„์˜ โ‘  ์„ ์–ธ).\n * ๋ถ€ํŒ… ๊ฑฐ๋™์„ ๊ฒฐ์ •ํ•˜๋Š” 1๊ธ‰ ์„ ์–ธ: mirror=์™ธ๋ถ€ ์‹ค๋ฌผ ์žฌ๋™๊ธฐ / sim-world=์ƒ์„ฑ ํƒ€์ž„๋ผ์ธ ์ง€์†(resume) / sim-experiment=seed ์žฌํ˜„(reset).\n * ๋ฏธ์„ ์–ธ = 'sim-experiment'(๊ฐ€์žฅ ๋ณด์ˆ˜์  โ€” ๊ธฐ์กด ๋ฐ๋ชจ ๊ฑฐ๋™ ๋ณด์กด).\n */\nexport type RealityMode = 'mirror' | 'sim-world' | 'sim-experiment'\nexport const DEFAULT_REALITY_MODE: RealityMode = 'sim-experiment'\n\n/* ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ผ์ด๋ธŒ ๋Ÿฐํƒ€์ž„ ํ™€๋”(์˜์† ์—”ํ‹ฐํ‹ฐ TwinInstance ์™€ ๊ตฌ๋ถ„). */\ninterface InstanceRuntime {\n /** ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 ํ”„๋ ˆ์ž„ โ‘ ). ๋ถ€ํŒ… ๊ฑฐ๋™(reset/resume/resync)์˜ ๊ทผ๊ฑฐ. */\n realityMode?: RealityMode\n id: string\n domainId: string\n domain?: any // ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(data ์ฑ„๋„)์šฉ Domain ๊ฐ์ฒด(subdomain ํ•„ํ„ฐ). start ์‹œ ๋น„๋™๊ธฐ ํ•ด์„.\n runtime?: TwinRuntimeType // sim: ์ปค๋„ ๋Ÿฐํƒ€์ž„(tick/subscribe/dispatch). live ๋Š” projector ์‚ฌ์šฉ.\n kernel?: any // sim: ForecastTwin(fork/getSnapshot/tick/scenario). live ๋ฏธ์‚ฌ์šฉ.\n mode?: 'sim' | 'live' // ์ƒํƒœ ๋“œ๋ผ์ด๋ฒ„ โ€” sim=์ปค๋„ tick / live=projector ๋ฏธ๋Ÿฌ(face2-inbound-live). ๋ฏธ์ง€์ •=sim.\n /**\n * live ์˜ ์ƒํƒœ ์ ‘๊ทผ ์–ด๋Œ‘ํ„ฐ โ€” ์ด์ œ **๊ด€์ธก ๋ชจ๋“œ ์ปค๋„**์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค(`kernel` ๊ณผ ๊ฐ™์€ ๊ฒƒ).\n * ์ด๋ฆ„์€ ์†Œ๋น„์ฒ˜ ํ˜ธํ™˜์œผ๋กœ ๋‚จ์•˜๊ณ , P3 ์—์„œ ์ปค๋„ ์–ดํœ˜๋กœ ์ •๋ฆฌํ•˜๋ฉด ์‚ฌ๋ผ์ง„๋‹ค.\n */\n projector?: any\n oee?: OeeAccumulator // live: OEE ๊ณ„์‚ฐ ์ธต(์ด๋ฒคํŠธ ๋ˆ„์  โ†’ equipment payload ๋ณด๊ฐ•). sim ์€ ์ปค๋„์ด ๊ณ„์‚ฐ.\n unsub: () => void\n timer?: any\n /** ์—”ํ‹ฐํ‹ฐ๋ณ„ ๋งˆ์ง€๋ง‰ ๋ฐœํ–‰ ์‹œ๊ทธ๋‹ˆ์ฒ˜ โ€” ๊ฐ’์ด ๋ฐ”๋€ ์—”ํ‹ฐํ‹ฐ๋งŒ ์žฌ๋ฐœํ–‰(๋ฌด๋ณ€ํ™” ๋ฐ˜๋ณต push ๋ฐฉ์ง€). */\n entitySigs?: Map<string, string>\n /** live ๋ฐฉ์†ก ๋ณ‘ํ•ฉ(ingest-scale ยง4.4) โ€” ingest ๋งˆ๋‹ค ๋ฐฉ์†กํ•˜์ง€ ์•Š๊ณ  dirty ํ‘œ์‹œ โ†’ coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์†ก. */\n dirty?: boolean\n /** live ์ €๋„ ๊ฒฐ์„  โ€” ingest ์ด๋ฒคํŠธ๋ฅผ ๋ชจ์•˜๋‹ค๊ฐ€ coalescer tick ์—์„œ ๋ฐฐ์น˜ ๊ธฐ๋ก(์ด๋ฒคํŠธ๋งˆ๋‹ค DB write ๊ธˆ์ง€). */\n pendingJournal?: any[]\n /** live ์ €๋„ revision ์นด์šดํ„ฐ(sim ์˜ delta revision ๋Œ€์‘ โ€” ์‹œ๊ฐ„์—ฌํ–‰ยทํžˆ์Šคํ† ๋ฆฌ ๋…ธ๋ธŒ ์•ต์ปค). */\n revision?: number\n /** live ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ, โ‘ฃ-1). */\n metrics?: TwinMetrics\n}\n\nexport class TwinEngine {\n static instances: Record<string, InstanceRuntime> = {}\n /** ๋ผ์ด๋ธŒ ๋Ÿฐํƒ€์ž„์ด ์—†์„ ๋•Œ(๋ณต๊ตฌ ํ›„ ๋ฏธ๊ธฐ๋™) ์ €๋„์—์„œ ์žฌ๊ตฌ์„ฑํ•œ ์ƒํƒœ ์บ์‹œ. */\n static recovered: Record<string, any> = {}\n static TICK_MS = 1000\n\n /* ์ตœ์‹  ์Šค๋ƒ…์ƒท ์˜์†(warm-start) โ€” ์žฌ๊ธฐ๋™ ์‹œ ์ €๋„ fold-from-0 replay ๋Œ€์‹  ๋งˆ์ง€๋ง‰ ๋ผ์ด๋ธŒ ์Šค๋ƒ…์ƒท์œผ๋กœ ๋ณต์›.\n * ํ”„๋ ˆ์ž„์›Œํฌ ๊ณตํ†ต cache-service(@things-factory/cache-service) ์žฌ์‚ฌ์šฉ(์žฌ๋ฐœ๋ช… ๊ธˆ์ง€, framework-leverage ยง4).\n * ์ €๋„์€ ๊ทธ๋Œ€๋กœ ์ง„์‹ค(์‹œ๊ฐ„์—ฌํ–‰/history replay ๋ฌด๋ณ€๊ฒฝ) โ€” ์บ์‹œ๋Š” display-only ์›œ์Šคํƒ€ํŠธ ์ตœ์ ํ™”. */\n static SNAPSHOT_CACHE_ID = 'twin-snapshot'\n static SNAPSHOT_TTL_S = 7 * 24 * 3600 // 7์ผ โ€” ์ •์ƒ ๋‹ค์šดํƒ€์ž„ ์ƒ์กด, ๋งŒ๋ฃŒ ์‹œ ์ €๋„ replay ํด๋ฐฑ\n static CHECKPOINT_MS = 20000 // ์ฒดํฌํฌ์ธํŠธ ์ฃผ๊ธฐ(ํ•ซ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๊ฒฝ๋กœ์™€ ๋ถ„๋ฆฌ, O(state) ์Šค๋กœํ‹€)\n private static checkpointTimer?: any\n\n /** ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ cache-service ์— ์ฒดํฌํฌ์ธํŠธ(๋„๋ฉ”์ธ+instanceId ํ‚ค). display-onlyยท๋น„์ฐจ๋‹จยท์˜ค๋ฅ˜ํก์ˆ˜. */\n static async persistSnapshot(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n if (!inst) return\n const state = this.snapshot(instanceId)\n if (!state) return\n const revision = inst.revision ?? state.revision ?? 0\n await cacheService.setInCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId }, { revision, state }, this.SNAPSHOT_TTL_S)\n }\n\n /** ์ฒดํฌํฌ์ธํŠธ๋œ ์ตœ์‹  ์Šค๋ƒ…์ƒท ๋กœ๋“œ(์—†์œผ๋ฉด null). getFromCache ๋Š” CacheStore ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ˜ํ™˜ โ†’ ํŽ˜์ด๋กœ๋“œ๋Š” .value. */\n static async loadSnapshot(domainId: string, instanceId: string): Promise<{ revision: number; state: any } | null> {\n const entry = await cacheService.getFromCache(this.SNAPSHOT_CACHE_ID, { domainId, instanceId })\n return (entry as any)?.value ?? null\n }\n\n /** ์ฒดํฌํฌ์ธํŠธ ๋ฃจํ”„ ๊ธฐ๋™(1ํšŒ) โ€” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋“ค์˜ ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ ์ฃผ๊ธฐ ์˜์†. */\n static startCheckpointLoop(): void {\n if (this.checkpointTimer) return\n this.checkpointTimer = setInterval(() => {\n for (const [instanceId, inst] of Object.entries(this.instances)) {\n this.persistSnapshot(inst.domainId, instanceId).catch(err =>\n console.error(`[twin-engine] snapshot checkpoint fail \"${instanceId}\"`, err?.message ?? err)\n )\n }\n }, this.CHECKPOINT_MS)\n if (typeof this.checkpointTimer?.unref === 'function') this.checkpointTimer.unref()\n }\n\n /**\n * ๋ถ€ํŒ… ํ›… โ€” DB ์— status='running' ์œผ๋กœ ๋‚จ์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ €๋„์—์„œ ์ƒํƒœ ์žฌ๊ตฌ์„ฑ(DBโ†’replay).\n * ๋ผ์ด๋ธŒ tick ์žฌ๊ฐœ(sim ๊ฒฐ์ •์  re-run / live ์ธ์ œ์ŠคํŠธ ์ง€์†)๋Š” ํ›„์†. ์—ฌ๊ธฐ์„  ์ƒํƒœ ๋ณต์› + ๋…ธ์ถœ.\n */\n static async bootstrap(): Promise<void> {\n try {\n // ๋ฐฑํ•„(space #3) โ€” spaceId ์ปฌ๋Ÿผ ์—†๋Š” ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๋ฅผ board.spaceId ๋กœ ์ฑ„์›€(1ํšŒ, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์•ˆ์ „).\n const repo = getRepository(TwinInstance)\n const missing = (await repo.find()).filter(r => !r.spaceId && (r.board as any)?.spaceId)\n for (const r of missing) {\n r.spaceId = (r.board as any).spaceId\n r.areaId = (r.board as any).areaId ?? r.areaId\n await repo.save(r)\n }\n if (missing.length) console.log(`[twin-engine] backfilled spaceId for ${missing.length} instance(s).`)\n\n // ๋ฐฑํ•„(area ๋‹จ์ผํ™” P3) โ€” deprecated content.areas โ†’ TwinArea ์ด๊ด€(ํด๋ฐฑ ์ œ๊ฑฐ ์ „ ์™„์ „์„ฑ ๋ณด์žฅ, 1ํšŒ).\n const spaceRepo = getRepository(TwinSpace)\n const twinAreaRepo = getRepository(TwinArea)\n for (const sp of await spaceRepo.find()) {\n const cAreas = ((sp.content as any)?.areas ?? []) as any[]\n for (const a of cAreas) {\n if (!a?.id) continue\n const ex = await twinAreaRepo.findOne({ where: { domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id } })\n if (ex) continue\n await twinAreaRepo.save(twinAreaRepo.create({\n domain: { id: sp.domainId } as any, space: { id: sp.id } as any, areaId: a.id,\n name: a.name ?? a.id, type: a.type, parentId: a.parentId ?? null,\n layout: a.x != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n }))\n }\n }\n\n const rows = await repo.find({ where: { status: 'running' } })\n for (const row of rows) {\n if (!row.domainId || !row.instanceId) continue\n // ์›œ์Šคํƒ€ํŠธ: ์บ์‹œ๋œ ์ตœ์‹  ์Šค๋ƒ…์ƒท ์šฐ์„ (O(1) + attentions/OEE ๋“ฑ ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ ๋ณด์กด).\n // ์—†์œผ๋ฉด ์ €๋„ fold-from-0 replay(์ง„์‹ค ํด๋ฐฑ โ€” replay ๋Š” ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ๋ฅผ ๋ชป ๋‹ด์œผ๋ฏ€๋กœ ์บ์‹œ๊ฐ€ ๋” ์ถฉ์‹ค).\n const cached = await this.loadSnapshot(row.domainId, row.instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[row.instanceId] = { revision: cached.revision, state: cached.state }\n console.log(`[twin-engine] warm-started \"${row.instanceId}\" from snapshot cache โ†’ revision ${cached.revision}.`)\n continue\n }\n const state = await this.recover(row.domainId, row.instanceId).catch(() => null)\n if (state) {\n this.recovered[row.instanceId] = { revision: state.revision, state }\n console.log(`[twin-engine] recovered \"${row.instanceId}\" from journal โ†’ revision ${state.revision}.`)\n }\n }\n this.startCheckpointLoop() // ์ดํ›„ ๊ธฐ๋™๋˜๋Š” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค์˜ ์ตœ์‹  ์Šค๋ƒ…์ƒท์„ ์ฃผ๊ธฐ ์˜์†\n } catch (err) {\n console.error('[twin-engine] recovery scan failed', err)\n }\n }\n\n /**\n * ์›œ์Šคํƒ€ํŠธ โ€” ๊ธฐ๋™ํ•˜๋Š” ์ปค๋„์— **์ง์ „ ๊ด€์ธก ์ƒํƒœ**๋ฅผ ์‹ฌ๋Š”๋‹ค.\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `loadBoard` ๋Š” **๊ตฌ์กฐ๋งŒ** ์‹ฃ๋Š”๋‹ค(๋…ธ๋“œยท๋ฌด๋ฒ„). ์ƒํƒœ(๋ฌด์—‡์ด ์–ด๋””์— ์–ผ๋งˆ๋‚˜)๋Š” ์—†๋‹ค. ๊ทธ๋ž˜์„œ ์žฌ๊ธฐ๋™ํ•œ\n * ํŠธ์œˆ์€ ์ €๋„์— ์ž…๊ณ  540๊ฑด์ด ๋‚จ์•„ ์žˆ์–ด๋„ ์žฌ๊ณ ๊ฐ€ 0 ์ด์—ˆ๊ณ , ํ™”๋ฉด์€ \"๋ณด์œ  ์ค‘์ธ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค\" ๋ผ๊ณ \n * ๋งํ–ˆ๋‹ค โ€” ์žˆ๋Š” ์žฌ๊ณ ๋ฅผ ์—†๋‹ค๊ณ  ํ•˜๋Š” ์…ˆ์ด๋‹ค(2026-07-31 hatiolab-wms ์‹ค์ธก์œผ๋กœ ํ™•์ธ).\n * `bootstrap()` ์ด ์ด๋ฏธ ์ฒดํฌํฌ์ธํŠธ ์บ์‹œ(์—†์œผ๋ฉด ์ €๋„ replay)๋กœ ์ƒํƒœ๋ฅผ ๋ณต๊ตฌํ•ด `recovered` ์— ๋‹ด์•„ ๋‘๋Š”๋ฐ,\n * ๊ธฐ๋™ ์ˆœ๊ฐ„ ๊ทธ๊ฑธ **๋ฒ„๋ฆฌ๊ณ ** ์žˆ์—ˆ๋‹ค. ๋ฐ˜๋งŒ ์—ฐ๊ฒฐ๋ผ ์žˆ๋˜ ์žฅ์น˜๋ฅผ ์ž‡๋Š”๋‹ค.\n *\n * โ”€โ”€ ์ •์งํ•œ ํ•œ๊ณ„ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ยท **์˜ค๋”๋Š” ๋ณต์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.** `hydrateObserved` ์˜ ์˜ค๋” ์ธ์ž๋Š” requested/fulfilled/lines ๋ฅผ ์š”๊ตฌํ•˜๋Š”๋ฐ\n * ์Šค๋ƒ…์ƒท์˜ `OrderState` ์—๋Š” `progress` ๋ฐ–์— ์—†๋‹ค. progress ์—์„œ ์—ญ์‚ฐํ•˜๋ฉด ์—†๋Š” ์ˆซ์ž๋ฅผ ์ง€์–ด๋‚ด๋Š” ๊ฒƒ์ด๋ผ\n * ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์žฌ๊ณ ยท๋…ธ๋“œยท๋ฌด๋ฒ„๋งŒ ๋ณต์›๋˜๊ณ  ์ง„ํ–‰ ์ค‘ ์˜ค๋”๋Š” ๋น„์–ด์„œ ์‹œ์ž‘ํ•œ๋‹ค.\n * ยท ์ง„ํ–‰ ์ค‘ ๊ฐœ๋ณ„ task ์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋„ ๊ด€์ธก๋งŒ์œผ๋กœ๋Š” ๋ณต์›๋˜์ง€ ์•Š๋Š”๋‹ค(์ปค๋„์ด ๋ช…์‹œํ•œ ํ•œ๊ณ„, ์žฌ๊ณ„ํš์— ๋งก๊น€).\n * ยท ๊ทผ๋ณธ ํ•ด๋ฒ•(์ƒํƒœ ์˜์† ๊ณ„์•ฝยทrevision ์ด์–ด๋ถ™์ž„)์€ ๋ณ„๋„ ๊ณผ์ œ.\n *\n * โ”€โ”€ ๋ฒค์น˜๋Š” ์‹œ๋“œํ•˜์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ถ€ํ•˜ ๋ฒค์น˜๋Š” **์ƒˆ ์‹œ์ž‘์—์„œ ์šฉ๋Ÿ‰์„ ์žฌ๋Š” ๊ฒƒ**์ด ๋ชฉ์ ์ด๋ผ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์‹ฌ์œผ๋ฉด ์ธก์ •์ด ์˜ค์—ผ๋œ๋‹ค.\n */\n private static warmStart(id: string, kernel: TwinKernel, purpose?: string): void {\n const hydrate = (kernel as any).hydrateObserved\n const plan = planWarmStart(this.recovered[id]?.state, purpose, typeof hydrate === 'function')\n\n if (plan.action === 'skip') {\n if (plan.reason === 'bench') {\n console.log(`[twin-engine] \"${id}\" is a bench twin โ€” starting empty on purpose (seeding would skew the measurement).`)\n } else if (plan.reason === 'unsupported') {\n console.warn(\n `[twin-engine] kernel for \"${id}\" cannot be warm-started (no hydrateObserved) โ€” it starts with structure only, so held stock will read as zero.`\n )\n }\n return\n }\n\n hydrate.call(kernel, plan.seed)\n console.log(\n `[twin-engine] warm-started \"${id}\" โ€” ${plan.itemCount} item(s), ${plan.equipmentCount} equipment restored. ` +\n 'Open orders are not restored (the snapshot carries no requested/fulfilled counts).'\n )\n }\n\n /** ํŠธ์œˆ ์ธ์Šคํ„ด์Šค ์‹œ์ž‘ โ€” ์ปค๋„ ์ƒ์„ฑ + ๋ณด๋“œ ๋กœ๋“œ + ์ง์ „ ์ƒํƒœ ์›œ์Šคํƒ€ํŠธ + State ์ŠคํŠธ๋ฆผ ๋ธŒ๋ฆฌ์ง€ + ์›Œ์ปค tick + ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์˜์†. */\n /**\n * ๊ณต์ • ๋ช…์„ธ๋ฅผ ์ปค๋„์— ์‹ฃ๋Š”๋‹ค โ€” **์‹œ๋ฎฌ๋ ˆ์ด์…˜์˜ ์‹œ๊ฐ„์„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งํ•˜๊ฒŒ ํ•˜๋Š” ๋งˆ์ง€๋ง‰ ํ•œ ์นธ.**\n *\n * `board.operations`(๋งˆ์Šคํ„ฐ ์ธ์ œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผ์‹œํ‚จ ISA-95 OperationsSegment ๋ช…์„ธ)๋ฅผ ์ปค๋„์ด ์†Œ๋น„ํ•œ๋‹ค.\n * ์—†์œผ๋ฉด ์ปค๋„ ๊ธฐ๋ณธ ์ƒ์ˆ˜๋กœ ๊ตด๋Ÿฌ๊ฐ€๊ณ , ์ปค๋„ `specCoverage()` ๊ฐ€ ๋ฌด์—‡์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ผ๋Š”์ง€ ๋ณด๊ณ ํ•œ๋‹ค.\n *\n * ์ปค๋„์ด ์•„์ง ์ด API ๋ฅผ ๊ฐ–์ง€ ์•Š์€ ๋ฒ„์ „์ด๋ฉด(๋ฐœํ–‰ ์ด์ „) **์กฐ์šฉํžˆ ๋„˜์–ด๊ฐ€์ง€ ์•Š๊ณ  ๊ฒฝ๊ณ ํ•œ๋‹ค** โ€” ๋ช…์„ธ๋ฅผ\n * ์„ ์–ธํ–ˆ๋Š”๋ฐ ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š” ์ƒํƒœ๋ฅผ ๋ชจ๋ฅด๊ณ  ์ง€๋‚˜๊ฐ€๋ฉด, ์˜ˆ์ธก์ด ์ƒ์ˆ˜๋กœ ๋Œ์•„๊ฐ„ ๊ฒƒ์„ ์•„๋ฌด๋„ ์•Œ ์ˆ˜ ์—†๋‹ค.\n */\n private static applyOperations(kernel: any, board: any, id: string): void {\n const ops = board?.operations\n if (!ops?.length) return\n if (typeof kernel?.loadOperations !== 'function') {\n console.warn(`[twin-engine] \"${id}\": board declares ${ops.length} operation spec(s) but the kernel cannot consume them (loadOperations missing โ€” kernel needs publishing). Simulation will use built-in default durations.`)\n return\n }\n kernel.loadOperations(ops)\n }\n\n /**\n * ์†Œ์š”์‹œ๊ฐ„ ์ถ”์ •๊ธฐ ์ฃผ์ž… โ€” **์ƒ์ˆ˜๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ๋ฐ”๊พธ๋Š” ๋‘ ๋ฒˆ์งธยท์„ธ ๋ฒˆ์งธ ์ธต.**\n *\n * ์ปค๋„ `durationOf` ์˜ ์šฐ์„ ์ˆœ์œ„๋Š” ์ถ”์ •๊ธฐ > ๋ช…์„ธ > ์ƒ์ˆ˜๋‹ค. ๊ทธ ์ถ”์ •๊ธฐ ์ž๋ฆฌ์— ๋‘ ๊ฐ€์ง€๋ฅผ ์‚ฌ์Šฌ๋กœ ๋„ฃ๋Š”๋‹ค:\n * โ‘  **์‹ค์ธก**(์ €๋„์˜ ์ž‘์—… ์ข…๋ฅ˜๋ณ„ ์ž‘์—…์‹œ๊ฐ„ p50) โ€” ๊ทธ ํ˜„์žฅ์—์„œ ์‹ค์ œ๋กœ ์–ผ๋งˆ ๊ฑธ๋ ธ๋‚˜. ๊ฐ€์žฅ ๊ฐ•ํ•œ ๊ทผ๊ฑฐ.\n * โ‘ก **๊ฑฐ๋ฆฌ ร— ์†๋„**(board.layout + ์„ค๋น„ ์†๋„ ์†์„ฑ) โ€” ์ด๋™์€ ๊ฑฐ๋ฆฌ์— ๋น„๋ก€ํ•œ๋‹ค. ์ปค๋„์€ ์ขŒํ‘œ๋ฅผ ๋ชจ๋ฅด๋ฏ€๋กœ\n * ํ˜ธ์ŠคํŠธ๊ฐ€ ๊ณ„์‚ฐํ•ด ๋„ฃ๋Š”๋‹ค.\n * ๋‘˜ ๋‹ค ๋ชป ๋งŒ๋“ค๋ฉด ์ฃผ์ž…ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์ปค๋„์ด ๋ช…์„ธยท์ƒ์ˆ˜๋กœ ๊ตด๋Ÿฌ๊ฐ€๊ณ  `specCoverage()` ๊ฐ€ ๊ทธ ์‚ฌ์‹ค์„ ๋‚จ๊ธด๋‹ค.\n *\n * ์‹ค์ธก์€ DB ์กฐํšŒ๋ผ ๋น„๋™๊ธฐ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” **await ํ•˜์ง€ ์•Š๋Š” ์ชฝ์—์„œ๋„ ์•ˆ์ „**ํ•˜๋„๋ก ์‹คํŒจ๋ฅผ ์‚ผํ‚ค๋˜,\n * ๋ฌด์—‡์„ ์™œ ๋ชป ๋„ฃ์—ˆ๋Š”์ง€๋Š” ๋กœ๊ทธ๋กœ ๋‚จ๊ธด๋‹ค(์กฐ์šฉํ•œ ๋ฌดํšจํ™” ๊ธˆ์ง€).\n */\n static async installEstimators(kernel: any, domainId: string, instanceId: string, board: any): Promise<void> {\n if (!kernel || typeof kernel !== 'object') return\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n const measured = await this.measuredEstimator(domainId, instanceId)\n const chained = chainEstimators([measured?.estimator, travel.estimator])\n if (!chained) {\n /* ์™œ ๋ชป ๋„ฃ์—ˆ๋Š”์ง€ ํ•œ ๋ฒˆ๋งŒ ์•Œ๋ฆฐ๋‹ค โ€” ์ด๋™์‹œ๊ฐ„์ด ์ƒ์ˆ˜๋กœ ๋‚จ์€ ์ด์œ ๋ฅผ ๋ชจ๋ฅด๊ณ  ์ง€๋‚˜๊ฐ€์ง€ ์•Š๊ฒŒ. */\n if (travel.reasons.length) console.warn(`[twin-engine] \"${instanceId}\": no duration estimator installed โ€” ${travel.reasons.join('; ')}`)\n return\n }\n kernel.durationEstimator = chained\n const learned = Object.keys(measured?.learned ?? {})\n const spread = Object.keys(measured?.spreads ?? {})\n console.log(\n `[twin-engine] \"${instanceId}\": duration estimator installed โ€” measured kinds: ${learned.length ? learned.join(',') : 'none'}` +\n ` (with observed spread: ${spread.length ? spread.join(',') : 'none'})` +\n `${travel.estimator ? `, travel from distance (speeds: ${Object.keys(travel.speedsByKind).join(',')})` : `, travel not derived (${travel.reasons.join('; ')})`}`\n )\n }\n\n /**\n * ์‹ค์ธก ์ถ”์ •๊ธฐ โ€” **์˜ˆ์ธก ์š”์ฒญ๋งˆ๋‹ค ์ €๋„์„ ๋‹ค์‹œ ์ ‘์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์˜ˆ์ธก ์ปค๋„์€ ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ ์„ธ์›Œ์ง€๊ณ (๋ฏธ๋Ÿฌ ์˜ˆ์ธกยท๋ฐฑํ…Œ์ŠคํŠธ), ํ™”๋ฉด์€ ์‹œ๊ฐ์„ ๊ธ์œผ๋ฉด ๊ณ„์† ์žฌ์˜ˆ์ธกํ•œ๋‹ค.\n * ๊ฑฐ๊ธฐ์— KPI ์กฐํšŒ๋ฅผ ๊ทธ๋Œ€๋กœ ๋‹ฌ๋ฉด ์š”์ฒญ๋‹น ์ €๋„ ์Šค์บ”์ด ํ•˜๋‚˜์”ฉ ๋ถ™๋Š”๋‹ค โ€” ์‹ค์ธก์€ ๋ถ„ ๋‹จ์œ„๋กœ ๋ฐ”๋€Œ์ง€ ์•Š์œผ๋ฏ€๋กœ\n * ์งง์€ TTL ๋กœ ์žฌ์‚ฌ์šฉํ•œ๋‹ค. ์บ์‹œ๋Š” ์ธ์Šคํ„ด์Šค๋ณ„์ด๊ณ , ๋งŒ๋ฃŒ ์ „์—๋Š” ๊ฐ™์€ ๊ฐ’์„ ์“ด๋‹ค(์˜ˆ์ธก ๊ฐ„ ์ผ๊ด€์„ฑ๋„ ์–ป๋Š”๋‹ค).\n */\n private static measuredCache = new Map<string, { at: number; value: ReturnType<typeof buildMeasuredEstimator> | undefined }>()\n private static readonly MEASURED_TTL_MS = 60_000\n\n private static async measuredEstimator(domainId: string, instanceId: string) {\n const key = `${domainId}:${instanceId}`\n const hit = this.measuredCache.get(key)\n if (hit && Date.now() - hit.at < this.MEASURED_TTL_MS) return hit.value\n let value: ReturnType<typeof buildMeasuredEstimator> | undefined\n try {\n /* ์ž‘์—… ์ข…๋ฅ˜๋ณ„ ์‹ค์ธก โ€” ์ฐฝ์€ ๋„‰๋„‰ํžˆ(ํ•˜๋ฃจ) ๋‘๊ณ  ํ‘œ๋ณธ์ด ๋ชจ์ž๋ž€ ์ข…๋ฅ˜๋Š” ์ถ”์ •๊ธฐ๊ฐ€ ์Šค์Šค๋กœ ๋บ€๋‹ค. */\n const kpi: any = await computeTwinKpi({ domainId, instanceId, windowMinutes: 24 * 60, groupBy: 'taskKind' })\n value = buildMeasuredEstimator(kpi?.groups?.items, {})\n } catch (err) {\n console.warn(`[twin-engine] \"${instanceId}\": measured duration lookup failed โ€” falling back to declared/default durations.`, (err as any)?.message)\n }\n this.measuredCache.set(key, { at: Date.now(), value })\n return value\n }\n\n /**\n * ์ง€๊ธˆ ์ด ํŠธ์œˆ์ด ์–ด๋–ค ๋ชจ๋ธ๋กœ ๊ตด๋Ÿฌ๊ฐ€๋Š”๊ฐ€ โ€” ์˜ˆ์ธก ์ถœ๋ ฅ ๋ณด์ •์ด **์ž๊ธฐ๊ฐ€ ๋ฐฐ์šด ๋ชจ๋ธ**์—๋งŒ ์ ์šฉ๋˜๋„๋ก\n * ๋น„๊ตํ•˜๋Š” ์ง€๋ฌธ. ์žฌ๋ฃŒ๋Š” ํ˜ธ์ŠคํŠธ๊ฐ€ ์•„๋Š” ๊ฒƒ(์‹ค์ธกยท์†๋„ยท์„ ์–ธ ๋ช…์„ธ)์ด๋ผ ์ปค๋„ ๋ฐœํ–‰ ์ƒํƒœ์™€ ๋ฌด๊ด€ํ•˜๋‹ค.\n * ์‹คํŒจํ•˜๋ฉด undefined โ€” ๊ทธ๋•Œ๋Š” ๋น„๊ต๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค(๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๊ทผ๊ฑฐ๋กœ ๋ณด์ •์„ ๋Š์ง€ ์•Š๋Š”๋‹ค).\n */\n static async modelBasis(domainId: string, instanceId: string): Promise<ModelBasis | undefined> {\n try {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n const board: any = reg?.board\n const measured = await this.measuredEstimator(domainId, instanceId)\n const travel = buildTravelEstimator({ layout: board?.layout, equipment: board?.equipment, unit: board?.unit })\n return { measured: measured?.learned, speeds: travel.speedsByKind, declared: board?.operations }\n } catch {\n return undefined\n }\n }\n\n /**\n * **์ด ํŠธ์œˆ์ด ํ•˜๋ฃจ ๋ช‡ ๋Œ€๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋Š”๊ฐ€** โ€” ๊ตด๋ ค ๋ณด์ง€ ์•Š๊ณ  ๋‹ตํ•œ๋‹ค.\n *\n * ๊ณ„์‚ฐ์€ ์ปค๋„์ด ์ž๊ธฐ ์ƒํƒœ์—์„œ ํ•œ๋‹ค(`kernel.capacity`). ์—ฌ๊ธฐ์„œ ํ•˜๋Š” ์ผ์€ **๊ธฐ์ค€ ์ฃผ๋ฅผ ์ •ํ•ด ์ฃผ๋Š”\n * ๊ฒƒ**๋ฟ์ด๋‹ค: ๊ณตํœด์ผ์ด ์—†๋Š” ํ‰์ƒ์ฃผ์—ฌ์•ผ ํ•œ๋‹ค โ€” ๊ณตํœด์ผ์€ ์—ฐ๊ฐ„ ๊ฐ€์šฉ๋Ÿ‰์„ ๋”ฐ๋กœ ๊นŽ์ง€, ์ด ๊ณต์žฅ์˜ ํ‰์ƒ์‹œ\n * ์ฒœ์žฅ์„ ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ปค๋„์ด ์ž„์˜๋กœ ๊ณ ๋ฅด๊ฒŒ ๋‘๋ฉด ๊ทธ ์ฃผ์— ๊ณตํœด์ผ์ด ๋ผ์—ˆ์„ ๋•Œ ์ฒœ์žฅ์ด ์กฐ์šฉํžˆ ๋‚ฎ์•„์ง„๋‹ค.\n *\n * ํŠธ์œˆ์ด ์•ˆ ๋–  ์žˆ์œผ๋ฉด `undefined` ๋‹ค โ€” 0 ์ด ์•„๋‹ˆ๋‹ค. ์•ˆ ๋œฌ ํŠธ์œˆ์˜ ์ฒœ์žฅ์„ 0 ์ด๋ผ๊ณ  ๋‹ตํ•˜๋ฉด ํ™”๋ฉด์€\n * \"์ด ๊ณต์žฅ์€ ์•„๋ฌด๊ฒƒ๋„ ๋ชป ๋งŒ๋“ ๋‹ค\" ๊ณ  ๋งํ•œ๋‹ค.\n */\n static async capacity(\n domainId: string,\n target: { instanceId?: string; spaceId?: string },\n unitsPerDay: number,\n sampleWeekStartMs: number\n ): Promise<{ instanceId: string; kind?: string; analysis?: any; reason?: 'not-running' | 'no-operations' }[]> {\n /* ๋Œ€์ƒ์€ **๋“ฑ๋ก๋ถ€**๊ฐ€ ์ •ํ•œ๋‹ค โ€” ๋–  ์žˆ๋Š” ๋Ÿฐํƒ€์ž„๋งŒ ํ›‘์œผ๋ฉด \"์•ˆ ๋–  ์žˆ์–ด์„œ ์•ˆ ๋ณด์ด๋Š” ๊ฒƒ\" ๊ณผ \"์—†๋Š” ๊ฒƒ\" ์ด\n ๊ตฌ๋ณ„๋˜์ง€ ์•Š๋Š”๋‹ค. ํ™”๋ฉด์€ ๊ทธ ๋‘˜์„ ๋‹ค๋ฅด๊ฒŒ ๋งํ•ด์•ผ ํ•œ๋‹ค. */\n const where: any = { domain: { id: domainId } }\n if (target.instanceId) where.instanceId = target.instanceId\n else where.spaceId = target.spaceId\n const registered = await getRepository(TwinInstance).find({ where })\n\n return registered.map(reg => {\n const rt = this.instances[reg.instanceId]\n const kernel: any = rt?.domainId === domainId ? rt.kernel : undefined\n if (typeof kernel?.capacity !== 'function') return { instanceId: reg.instanceId, kind: reg.kind, reason: 'not-running' as const }\n\n const analysis = kernel.capacity({ unitsPerDay, sampleWeekStartMs })\n /* ๊ณต์ •์„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ํŠธ์œˆ(๋Œ€๊ฐœ YMSยทWMS)์€ **ํŒ์ • ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค.** 0 ์œผ๋กœ ์ฑ„์›Œ ๋„ฃ์œผ๋ฉด\n \"์•ผ๋“œ๊ฐ€ ๋ณ‘๋ชฉ\" ์ด๋ผ๋Š” ์—†๋Š” ์‚ฌ์‹ค์ด ์ƒ๊ธด๋‹ค โ€” ์žด ๊ฒƒ์ด ์—†๋‹ค๊ณ  ๋งํ•œ๋‹ค. */\n if (!analysis?.operations?.length) return { instanceId: reg.instanceId, kind: reg.kind, reason: 'no-operations' as const }\n return { instanceId: reg.instanceId, kind: reg.kind, analysis }\n })\n }\n\n static start(id: string, domainId: string, kind: string, board: BoardDef, realityMode?: RealityMode, purpose?: string, resumeFrom?: number): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: TwinKernel = new Kernel(domainId, undefined, this.mesSpecOf(board))\n kernel.loadBoard(board) // ๊ตฌ์กฐ๋งŒ. ์ƒํƒœ๋Š” ์•„๋ž˜ ์›œ์Šคํƒ€ํŠธ๊ฐ€ ์‹ฌ๋Š”๋‹ค.\n this.applyOperations(kernel, board, id) // ์‹œ๊ฐ„ยท์ˆ˜์œจ ๋ช…์„ธ(์žˆ์œผ๋ฉด) โ€” ์—†์œผ๋ฉด ์ปค๋„ ๊ธฐ๋ณธ๊ฐ’\n /* ์ถ”์ •๊ธฐ๋Š” DB ์กฐํšŒ๋ฅผ ํฌํ•จํ•ด ๋น„๋™๊ธฐ โ€” ๊ธฐ๋™์„ ๋ง‰์ง€ ์•Š๊ณ  ๋ถ™๋Š”๋‹ค(๋ถ™๊ธฐ ์ „ ์ž‘์—…์€ ๋ช…์„ธยท์ƒ์ˆ˜๋กœ ์‚ฐ์ถœ). */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n this.warmStart(id, kernel, purpose)\n /*\n * **๋ฒˆํ˜ธ๋ฅผ ์ด์–ด ์„ผ๋‹ค** โ€” ์ €๋„์— ์ด๋ฏธ ์žˆ๋Š” ๋ฒˆํ˜ธ์™€ ๊ฒน์น˜์ง€ ์•Š๊ฒŒ.\n *\n * ์ €๋„์ด ๋น„์–ด ์žˆ์œผ๋ฉด(0) ์•„๋ฌด ์ผ๋„ ์•ˆ ํ•œ๋‹ค. ๋น„์–ด ์žˆ์ง€ ์•Š์€๋ฐ 0๋ถ€ํ„ฐ ๋‹ค์‹œ ์„ธ๋ฉด ๊ฐ™์€ ํŠธ์œˆ์— ๊ฐ™์€\n * ๋ฆฌ๋น„์ „์ด ๋‘˜ ์ƒ๊ธฐ๊ณ , ์žฌ์ƒ ์ˆœ์„œ๊ฐ€ ๋’ค์„ž์ด๋ฉฐ, ์‹œ๊ฐ„์—ฌํ–‰์ด ์—‰๋šฑํ•œ ์‹œ์ ์„ ๋‹ตํ•œ๋‹ค โ€” ์˜ค๋ฅ˜๋Š” ์•ˆ ๋‚œ๋‹ค.\n */\n if (resumeFrom && typeof (kernel as any).resumeRevision === 'function') (kernel as any).resumeRevision(resumeFrom)\n const runtime: TwinRuntimeType = new TwinRuntime(kernel)\n\n /* subscribe ๋Š” RuntimeSubscription({ unsubscribe() }) ๋ฐ˜ํ™˜ โ†’ () => void ๋กœ ๊ฐ์Œˆ. */\n const inst: InstanceRuntime = { id, domainId, runtime, kernel, realityMode: realityMode ?? DEFAULT_REALITY_MODE, unsub: () => {} }\n this.instances[id] = inst\n delete this.recovered[id] // ์›œ์Šคํƒ€ํŠธ๋กœ ์ปค๋„์— ์˜ฎ๊ฒจ ์‹ฌ์—ˆ๋‹ค โ€” ์ด์ œ ๋ผ์ด๋ธŒ๊ฐ€ ์ง„์‹ค์ด๋‹ค.\n\n /* ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(P3): data ์ฑ„๋„ ํ•„ํ„ฐ๊ฐ€ subdomain ์„ ๋ณด๋ฏ€๋กœ Domain ๊ฐ์ฒด๋ฅผ 1ํšŒ ํ•ด์„ํ•ด ๋‘”๋‹ค. */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n\n /* State ์ฑ„๋„: runtime.subscribe(snapshotโ†’deltaโ†’clock) โ†’ pubsub ๋ฐฉ์†ก(๊ตฌ๋… ๋ฆฌ์กธ๋ฒ„๊ฐ€ instanceId ํ•„ํ„ฐ). */\n const sub = runtime.subscribe((msg: SubscriptionMessage) => {\n pubsub.publish('twin-state', {\n twinState: { instanceId: id, kind: msg.kind, revision: (msg as any).revision, payload: msg }\n })\n /* ์˜์† + ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ ๋ธŒ๋ฆฌ์ง€: delta ๋งˆ๋‹ค ์ €๋„ ์ €์žฅ + ์—”ํ‹ฐํ‹ฐ๋ณ„ data(tag:) publish โ†’ ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ. */\n if (msg.kind === 'delta') {\n this.persist(domainId, id, msg).catch(err => console.error('twin persist fail', err))\n this.publishEntityData(inst)\n }\n })\n inst.unsub = () => sub.unsubscribe()\n\n /* ๋ณต๊ตฌ ์•ต์ปค: ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— board/kind/status/realityMode ์˜์†(์žฌ๋ถ€ํŒ… ์‹œ ์ด๊ฒŒ ์žˆ์–ด์•ผ replayยท์„ ์–ธ ๊ฑฐ๋™ ๊ฐ€๋Šฅ). */\n this.register(domainId, id, kind, board, 'running', inst.realityMode).catch(err => console.error('twin register fail', err))\n\n /* ์›Œ์ปค tick โ€” ์Šค์ผˆ๋ ˆํ†ค์€ setInterval(๋ฉ”์ธ ๋ฃจํ”„). ๊ธด ์‹œ๋ฎฌ ์˜คํ”„-๋ฃจํ”„(worker thread)๋Š” ์Šค์ผ€์ผ ํ•˜๋“œ๋‹(ํ–ฅํ›„, ยงhost ๊ฒฝ๊ณ„). */\n inst.timer = setInterval(() => runtime.tick(this.TICK_MS), this.TICK_MS)\n return inst\n }\n\n /**\n * live-๋ชจ๋“œ ๊ธฐ๋™ โ€” **๊ด€์ธก ๋ชจ๋“œ ์ปค๋„**๋กœ ์‹ค ์ด๋ฒคํŠธ๋ฅผ ๋ฏธ๋Ÿฌํ•œ๋‹ค(ํ†ตํ•ฉ P2).\n *\n * ์˜ˆ์ „์—๋Š” `StateProjector` ๋ฅผ ์„ธ์› ๋‹ค. ๊ทธ๋ž˜์„œ ๋ผ์ด๋ธŒ์—๋Š” **์ปค๋„์ด ์—†์—ˆ๊ณ **, ๊ทธ ํ•˜๋‚˜ ๋•Œ๋ฌธ์— ์šฐํšŒ๊ฐ€\n * ์ค„์ค„์ด ์ƒ๊ฒผ๋‹ค: ์˜ˆ์ธกํ•˜๋ ค๋ฉด ์ž„์‹œ ์ปค๋„์„ ์„ธ์›Œ์•ผ ํ–ˆ๊ณ (`buildForecastKernel`), ์ฃผ๋ชฉ ์‹ ํ˜ธ๋ฅผ ํ˜ธ์ŠคํŠธ๊ฐ€\n * ๋ง๋ถ™์—ฌ์•ผ ํ–ˆ๊ณ (`withLiveAttentions`), AI ์˜ˆ์ธก ๋„๊ตฌ๋Š” ๋ฏธ๋Ÿฌ์—์„œ \"์ฐพ์„ ์ˆ˜ ์—†๋‹ค\" ๋กœ ๋๋‚ฌ๋‹ค.\n *\n * ์ด์ œ ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋„ **์ปค๋„์ด๋‹ค.** ๊ฐ™์€ ๊ทœ์น™(`ObservedReducer`)์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ ‘๊ณ , ์ฃผ๋ชฉ ์‹ ํ˜ธ๋ฅผ\n * ์Šค์Šค๋กœ ๋‚ด๊ณ , ๊ทธ ์ž๋ฆฌ์—์„œ `fork` ํ•ด ์˜ˆ์ธกํ•œ๋‹ค. ๊ตฌ๋™๋งŒ ๋‹ค๋ฅด๋‹ค โ€” sim ์€ `tick`, live ๋Š” `apply`.\n *\n * ์‹ค ์ด๋ฒคํŠธ์› = reference ์–ด๋Œ‘ํ„ฐ openLiveFeed โ†’ face2-adapter.ingest โ†’ CanonicalEnvelope โ†’ ingestLive().\n */\n /**\n * ๋ณด๋“œ๊ฐ€ ์‹ค์€ **์ƒ์‚ฐ ์ •์˜**(๋ ˆ์‹œํ”ผยท๋ผ์šฐํŠธยท๋ฐ”์ธ๋”ฉ)๋ฅผ ๊บผ๋‚ธ๋‹ค โ€” ์ปค๋„์˜ ์ •์˜-๊ตฌ๋™ ๋ชจ๋“œ ์ž…๊ตฌ.\n *\n * โ”€โ”€ ์—†์„ ๋•Œ ๋ฌด์—‡์ด ์ผ์–ด๋‚ฌ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„์—๋Š” ์ •์˜-๊ตฌ๋™ MES ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋Š”๋ฐ **ํ˜ธ์ŠคํŠธ๊ฐ€ ๊ทธ๊ฒƒ์„ ํ•œ ๋ฒˆ๋„ ๋„˜๊ธฐ์ง€ ์•Š์•˜๋‹ค.** ๊ทธ๋ž˜์„œ ๋ชจ๋“  MES\n * ํŠธ์œˆ์ด **ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ ˆ๊ฑฐ์‹œ ํ๋ฆ„**์œผ๋กœ ๋Œ์•˜๋‹ค โ€” ํ˜„์žฅ ๋ ˆ์‹œํ”ผ๋ฅผ ์•„๋ฌด๋ฆฌ ์ •์„ฑ๊ป ์ ์–ด๋„ ์ปค๋„์€ ๊ทธ๊ฒƒ์„\n * ๋ณด์ง€ ๋ชปํ•˜๊ณ  ํ† ์ด ๋ถ€ํ’ˆ์œผ๋กœ ํ† ์ด ์ œํ’ˆ์„ ๋งŒ๋“ค์—ˆ๋‹ค. ์„ ์–ธ๊ณผ ์‹คํ–‰์ด ๊ฐˆ๋ผ์ ธ ์žˆ๋˜ ์ž๋ฆฌ๋‹ค.\n *\n * ๋ณด๋“œ์— ์—†์œผ๋ฉด `undefined` โ€” ๋ ˆ๊ฑฐ์‹œ ๊ฒฝ๋กœ ๊ทธ๋Œ€๋กœ๋‹ค(๊ธฐ์กด ํŠธ์œˆ์˜ ๊ฑฐ๋™์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค).\n */\n private static mesSpecOf(board: BoardDef | undefined): any {\n return (board as any)?.mesSpec\n }\n\n /**\n * ํ˜„์žฅ(๊ณต๊ฐ„)์˜ **์‹œ๊ฐ ๊ธฐ์ค€**์„ ๋ณด๋“œ์— ์–น๋Š”๋‹ค โ€” ์ปค๋„์ด ๊ต๋Œ€์˜ `HH:MM` ์„ ์ฝ์„ ๊ธฐ์ค€.\n *\n * **ํ…Œ๋„ŒํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ณต๊ฐ„์ด ๊ถŒ์œ„๋‹ค.** ํ•œ ํ…Œ๋„ŒํŠธ๊ฐ€ Rosarito(ํƒœํ‰์–‘)์™€ ํ•œ๊ตญ ๊ณต์žฅ์„ ํ•จ๊ป˜ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ ,\n * ํ…Œ๋„ŒํŠธ ๋‹จ์œ„(`Domain.timezone`)๋กœ ๋‘๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ˜๋“œ์‹œ ํ‹€๋ฆฐ๋‹ค. ๊ทธ๋ž˜์„œ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฌถ์ธ ๊ณต๊ฐ„์˜\n * `timezone` ์„ ์ฝ๋Š”๋‹ค. ๊ณต๊ฐ„์ด ๋งํ•˜์ง€ ์•Š์œผ๋ฉด **ํ…Œ๋„ŒํŠธ๋กœ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š๋Š”๋‹ค** โ€” ์ž˜๋ชป๋œ ์ž…์ž๋กœ ๋‹ตํ•˜๋Š” ๊ฒƒ์ด\n * ๋ชจ๋ฅด๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚˜์˜๋‹ค(๊ทธ๋•Œ๋Š” ์ปค๋„์ด UTC ๋กœ ์ฝ๊ณ , ๊ทธ ๊ธฐ๋ณธ๊ฐ’์€ ๊ณ„์•ฝ์— ๋ฐํ˜€์ ธ ์žˆ๋‹ค).\n *\n * ์ปค๋„์€ zero-dep ์ด๋ผ ์‹œ๊ฐ„๋Œ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ฐ–์ง€ ์•Š์œผ๋ฏ€๋กœ **๋ถ„ ์˜คํ”„์…‹**์œผ๋กœ ํ’€์–ด ๋„˜๊ธด๋‹ค. ๊ทธ ๊ฐ’์€\n * ์ง€๊ธˆ ๊ณ„์ ˆ์˜ ๊ฒƒ์ด๋‹ค(์ผ๊ด‘์ ˆ์•ฝ์‹œ๊ฐ„) โ€” ๊ณ„์ ˆ์„ ๋„˜๋Š” ๊ธด ์˜ˆ์ธก์€ ํ•œ ์‹œ๊ฐ„ ์–ด๊ธ‹๋‚œ๋‹ค(๊ณ„์•ฝ์— ๋ช…์‹œ).\n */\n static async withSpaceTimeBase(board: BoardDef, domainId: string, spaceId?: string): Promise<BoardDef> {\n const sid = spaceId ?? (board as any)?.spaceId\n if (!sid) return board\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: sid } }).catch(() => null)\n const offset = utcOffsetOf(space?.timezone)\n if (offset === undefined) {\n if (space?.timezone) console.warn(`[twin-engine] space \"${sid}\" declares time zone \"${space.timezone}\" but it is not a known IANA zone โ€” times will be read as UTC.`)\n return board\n }\n return { ...board, utcOffsetMinutes: offset }\n }\n\n static startLive(id: string, domainId: string, kind: string, board: BoardDef): InstanceRuntime {\n if (this.instances[id]) return this.instances[id]\n const Kernel = KERNELS[kind] ?? WmsKernel\n const kernel: any = new Kernel(domainId, undefined, this.mesSpecOf(board))\n kernel.loadBoard(board)\n this.applyOperations(kernel, board, id) // ๋ช…์„ธ๋Š” ๋ผ์ด๋ธŒ์—๋„ ์‹ค๋ฆฐ๋‹ค(์˜ˆ์ธก ์ž๊ฒฉ์ด sim ๊ณผ ๊ฐ™์•„์ง„๋‹ค)\n /* `projector` ํ•„๋“œ๋Š” ์˜› ์ด๋ฆ„์œผ๋กœ ๋‚จ๊ธด๋‹ค โ€” ์†Œ๋น„์ฒ˜๊ฐ€ `snapshot()` ์„ ๋ถ€๋ฅด๋ฏ€๋กœ ์–‡์€ ์–ด๋Œ‘ํ„ฐ๋กœ ์ž‡๋Š”๋‹ค.\n * (P3 ์—์„œ ์†Œ๋น„์ฒ˜๋ฅผ ์ปค๋„ ์–ดํœ˜๋กœ ๋ฐ”๊พธ๋ฉด ์‚ฌ๋ผ์ง„๋‹ค.) */\n const projector = { apply: (e: CanonicalEnvelope) => kernel.apply(e), snapshot: () => kernel.getSnapshot() }\n const inst: InstanceRuntime = { id, domainId, mode: 'live', realityMode: 'mirror', kernel, projector, oee: new OeeAccumulator(), unsub: () => {} }\n /* ์ถ”์ •๊ธฐ(์‹ค์ธกยท๊ฑฐ๋ฆฌ)๋„ ๋ผ์ด๋ธŒ์— ๋ถ™์ธ๋‹ค โ€” ์˜ˆ์ธก์ด ์ƒ์ˆ˜๋กœ ๋Œ์ง€ ์•Š๊ฒŒ. ๊ธฐ๋™์„ ๋ง‰์ง€ ์•Š๋Š”๋‹ค. */\n this.installEstimators(kernel, domainId, id, board).catch(err => console.warn('[twin-engine] estimator install failed', err?.message))\n inst.metrics = { ingestedTotal: 0, broadcastTotal: 0, journaledTotal: 0, ingestRate: 0, broadcastRate: 0, journalRate: 0, backlog: 0, _accIngest: 0, _accBroadcast: 0, _accJournal: 0, _windowStartMs: Date.now() }\n this.instances[id] = inst\n delete this.recovered[id]\n /* ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ(data ์ฑ„๋„) subdomain ํ•„ํ„ฐ์šฉ Domain 1ํšŒ ํ•ด์„(sim ๊ณผ ๋™์ผ). */\n getRepository(Domain).findOne({ where: { id: domainId } }).then(d => (inst.domain = d)).catch(() => {})\n /* ์ €๋„ revision ์นด์šดํ„ฐ ์‹œ๋“œ โ€” ๊ธฐ์กด ์ €๋„ ์ตœ๋Œ€์น˜์—์„œ ์ด์–ด๋ถ™์ž„(์žฌ๊ธฐ๋™ ์‹œ revision ์ถฉ๋Œ ๋ฐฉ์ง€). ์ดํ›„ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€. */\n getRepository(TwinEvent)\n .findOne({ where: { domain: { id: domainId }, instanceId: id }, order: { revision: 'DESC' } })\n .then(top => (inst.revision = top?.revision ?? 0))\n .catch(() => (inst.revision = 0))\n this.register(domainId, id, kind, board, 'running', 'mirror').catch(err => console.error('twin register fail', err))\n return inst\n }\n\n /**\n * live ์ด๋ฒคํŠธ ์ธ์ œ์ŠคํŠธ โ€” projector ๊ตฌ๋™ + data(tag) ๋ฐฉ์†ก(ํ๋ฃจํ”„์˜ ์ธ๋ฐ”์šด๋“œ ๋„์ฐฉ ์ง€์ , command-routing ยง8.2).\n * reference ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋‚ธ records โ†’ ์ปค๋„ face2-adapter.ingest โ†’ CanonicalEnvelope ๋ฅผ ์—ฌ๊ธฐ๋กœ ๋ฐ€์–ด๋„ฃ๋Š”๋‹ค.\n * (State ์ฑ„๋„ ๋ธํƒ€/์ €๋„ ๊ฒฐ์„ ์€ ํ›„์† โ€” ์Šค์ผˆ๋ ˆํ†ค์€ data(tag) ๋ฏธ๋Ÿฌ ์ค‘์‹ฌ.)\n */\n static ingestLive(id: string, envelopes: CanonicalEnvelope[]): void {\n const inst = this.instances[id]\n if (inst?.mode !== 'live' || !inst.projector) return\n for (const e of envelopes) { inst.projector.apply(e); inst.oee?.apply(e) } // ๊ด€์ธก(projector) + ๊ณ„์‚ฐ(OEE ๋ˆ„์ )\n // ์ €๋„ ๊ฒฐ์„ (๋ผ์ด๋ธŒ๋„ sim ์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ ์˜์†) โ€” ๋‹จ ์ด๋ฒคํŠธ๋งˆ๋‹ค DB write ํ•˜๋ฉด ๋ถ€ํ•˜ํญ๋ฐœ์ด๋ผ ๋ชจ์•„๋’€๋‹ค๊ฐ€\n // coalescer tick ์—์„œ ๋ฐฐ์น˜ ๊ธฐ๋ก(๋ฐฉ์†ก๊ณผ ๋™์ผ ์ฃผ๊ธฐ). ํžˆ์Šคํ† ๋ฆฌ ๋…ธ๋ธŒยทํƒ€์ž„๋ผ์ธยท๋น„์ฆˆ๋‹ˆ์Šค ์›์žฅ์ด ์ด ์ €๋„์„ ์ฝ๋Š”๋‹ค.\n ;(inst.pendingJournal ?? (inst.pendingJournal = [])).push(...envelopes)\n if (inst.metrics) { inst.metrics.ingestedTotal += envelopes.length; inst.metrics._accIngest += envelopes.length } // ๊ณ„์ธก(โ‘ฃ-1)\n // ๋ฐฉ์†ก ๋ณ‘ํ•ฉ(ingest-scale ยง1.1/ยง4.4) โ€” apply ๋Š” O(1)ยท์‹ธ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐฉ์†ก(snapshot O(state))์€ ๋น„์‹ธ(๋Œ€๊ทœ๋ชจ 5ms+)\n // ์ด๋ฒคํŠธ๋งˆ๋‹ค ๋ฐฉ์†กํ•˜๋ฉด ํญ๋ฐœ โ†’ dirty ๋งŒ ์ฐ๊ณ  coalescer tick ์ด ์ฃผ๊ธฐ ๋ฐฉ์†ก(๋ฐฉ์†ก๋ฅ  โ‰  ์ธ์ œ์ŠคํŠธ๋ฅ ).\n inst.dirty = true\n this.ensureBroadcastCoalescer()\n }\n\n /** ๋ฐฉ์†ก ๋ณ‘ํ•ฉ ์ฃผ๊ธฐ(ms) โ€” ๋ฐฉ์†ก๋ฅ  ์ƒํ•œ. ์ธ์ œ์ŠคํŠธ๊ฐ€ ์•„๋ฌด๋ฆฌ ๋นจ๋ผ๋„ ์ด ์ฃผ๊ธฐ๋กœ๋งŒ ๋ฐฉ์†ก. */\n static BROADCAST_COALESCE_MS = 200\n private static broadcastTimer?: any\n\n /** live ๋ฐฉ์†ก coalescer โ€” dirty ์ธ live ์ธ์Šคํ„ด์Šค๋งŒ ์ฃผ๊ธฐ์ ์œผ๋กœ 1ํšŒ ๋ฐฉ์†ก(entitySigs ๋กœ ๋ณ€๊ฒฝ ์—”ํ‹ฐํ‹ฐ๋งŒ). */\n private static ensureBroadcastCoalescer(): void {\n if (this.broadcastTimer) return\n this.broadcastTimer = setInterval(() => this.flushLiveBroadcasts(), this.BROADCAST_COALESCE_MS)\n if (typeof this.broadcastTimer.unref === 'function') this.broadcastTimer.unref() // ์ข…๋ฃŒ ๋น„์ฐจ๋‹จ\n }\n\n /** dirty live ์ธ์Šคํ„ด์Šค ๋ฐฉ์†ก flush(์ฃผ๊ธฐ tick ๋˜๋Š” ๋ช…์‹œ ํ˜ธ์ถœ). ํ…Œ์ŠคํŠธ/์ฆ‰์‹œ ๋ฐฉ์†ก์šฉ์œผ๋กœ public. */\n static flushLiveBroadcasts(): void {\n let anyLive = false\n const now = Date.now()\n for (const inst of Object.values(this.instances)) {\n if (inst.mode !== 'live') continue\n anyLive = true\n // ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก(โ‘ฃ-1) โ€” ์ฐฝ(โ‰ฅ1s)๋งˆ๋‹ค ์œ ์ž…/๋ฐฉ์†ก/์ €๋„๋ฅ  ๊ฐฑ์‹ . dirty ๋ฌด๊ด€(์œ ํœด๋ฉด 0์œผ๋กœ ์ˆ˜๋ ด). ๋ถ€ํ•˜๋ฅผ ์ฝ๋Š” ์‹ ํ˜ธ.\n const m = inst.metrics\n if (m) {\n const dt = (now - m._windowStartMs) / 1000\n if (dt >= 1) {\n m.ingestRate = Math.round(m._accIngest / dt)\n m.broadcastRate = Math.round((m._accBroadcast / dt) * 10) / 10\n m.journalRate = Math.round(m._accJournal / dt)\n m._accIngest = 0; m._accBroadcast = 0; m._accJournal = 0; m._windowStartMs = now\n }\n }\n if (!inst.dirty) continue\n inst.dirty = false\n // โ‘  ์—”ํ‹ฐํ‹ฐ data(tag) ๋ฐฉ์†ก โ€” ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ ๋ Œ๋”.\n this.publishEntityData(inst)\n if (m) { m.broadcastTotal++; m._accBroadcast++ }\n // โ‘ข ์ €๋„ ๋ฐฐ์น˜ ๊ธฐ๋ก โ€” ๋ชจ์•„๋‘” ์ด๋ฒคํŠธ์— revision ๋ถ€์—ฌํ•ด ๋ฒŒํฌ ์ €์žฅ(์ด๋ฒคํŠธ๋งˆ๋‹ค write ์•„๋‹˜).\n // revision ์นด์šดํ„ฐ๋Š” ์ธ๋ฉ”๋ชจ๋ฆฌ(startLive ์—์„œ ์ €๋„ high-water ๋กœ 1ํšŒ ์‹œ๋“œ) โ†’ tick ๋งˆ๋‹ค DB ์งˆ์˜ ์—†์Œ.\n const batch = inst.pendingJournal\n if (batch?.length && inst.revision != null) {\n inst.pendingJournal = []\n const start = inst.revision\n inst.revision = start + batch.length\n if (m) { m.journaledTotal += batch.length; m._accJournal += batch.length; m.backlog = batch.length }\n this.persistBatch(inst.domainId, inst.id, batch, start).catch(err => console.error('twin live journal fail', err))\n }\n // โ‘ก State ์ฑ„๋„ ๋ฐฉ์†ก โ€” \"๋ฐ”๋€Œ์—ˆ๋‹ค\"๋Š” ๊ฐ€๋ฒผ์šด ์‹ ํ˜ธ๋งŒ(kind+revision). ๋งต ๊ตฌ๋…(subscribeTwinState)์€ ์ด ์‹ ํ˜ธ์—\n // scheduleRefresh(250ms ๋””๋ฐ”์šด์Šค)โ†’pollLive ๋กœ ๋˜๋ฌผ์–ด๋ด„. ์Šค๋ƒ…์ƒท(O(state))์€ ๋ณด๋Š” ์‚ฌ๋žŒ์ด ๋ฌผ์„ ๋•Œ๋งŒ 1ํšŒ ๊ณ„์‚ฐ.\n // (์—ฌ๊ธฐ์„œ payload ๋กœ ์Šค๋ƒ…์ƒท์„ ์‹ค์œผ๋ฉด ์•„๋ฌด๋„ ์•ˆ ์ฝ๋Š”๋ฐ tick ๋งˆ๋‹ค ํ†ต์งธ๋กœ ๋– ์„œ ์ˆœ์ˆ˜ ๋‚ญ๋น„ โ€” ์‹ ํ˜ธ๋งŒ ๋ณด๋‚ธ๋‹ค.)\n pubsub.publish('twin-state', {\n twinState: { instanceId: inst.id, kind: 'delta', revision: inst.revision ?? 0 }\n })\n }\n if (!anyLive && this.broadcastTimer) { clearInterval(this.broadcastTimer); this.broadcastTimer = undefined } // live ์—†์œผ๋ฉด tick ์ •์ง€\n }\n\n /**\n * ์ €๋„ ํ–‰ ํ•œ ์ค„ โ€” **๊ธฐ๋ก ๊ฒฝ๋กœ๊ฐ€ ๋‘˜์ด๋ผ(๋ผ์ด๋ธŒ ๋ฒŒํฌยท์‹ฌ ๋‹จ๊ฑด) ํ–‰ ๋ชจ์–‘์€ ๋ฐ˜๋“œ์‹œ ํ•œ ๊ณณ์—์„œ ๋งŒ๋“ ๋‹ค.**\n * ๋‘ ๊ณณ์— ๊ฐ์ž ์ ์œผ๋ฉด ์Šน๊ฒฉ ๊ฒ€์ƒ‰ ํ‚ค๊ฐ€ ํ•œ์ชฝ์—๋งŒ ์ฑ„์›Œ์ง€๊ณ , ๋ฐ˜์ฏค ๋นˆ ์ƒ‰์ธ์€ \"์ €๋„์—๋Š” ์žˆ๋Š”๋ฐ\n * ๊ฒ€์ƒ‰์œผ๋กœ๋Š” ์•ˆ ๋‚˜์˜ค๋Š” ์ด๋ฒคํŠธ\" ๋ฅผ ๋งŒ๋“ ๋‹ค โ€” ์ €๋„์—์„œ ๊ฐ€์žฅ ๋‚˜์œ ์ข…๋ฅ˜์˜ ๊ฒฐํ•จ์ด๋‹ค.\n */\n private static journalRow(repo: any, domainId: string, instanceId: string, e: any, revision: number, structureRev?: number) {\n return repo.create({\n domain: { id: domainId } as any,\n instanceId,\n tenantId: e?.tenantId,\n eventType: e?.eventType,\n revision,\n /* **์ด ์‚ฌ์‹ค์ด ์ผ์–ด๋‚œ ๊ณต์žฅ**์„ ํ•จ๊ป˜ ์ฐ๋Š”๋‹ค โ€” ์ด๊ฒƒ์ด ์—†์œผ๋ฉด ๋‚˜์ค‘์— ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ์ด ํ–‰์„\n ์ƒˆ ๊ณต์žฅ์— ๋Œ€๊ณ  ์ ‘๊ฒŒ ๋˜๊ณ , ๊ทธ๋•Œ ์—†๋˜ ์„ค๋น„์—์„œ ์ผ์ด ์žˆ์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. */\n ...(structureRev === undefined ? {} : { structureRev }),\n eventTime: e?.eventTime,\n ...twinEventKeys(e),\n payload: e\n })\n }\n\n /**\n * ์ด ํŠธ์œˆ์ด ์ง€๊ธˆ ์–ด๋А ๊ตฌ์กฐ๋กœ ๋„๋Š”๊ฐ€ โ€” ์ด๋ฒคํŠธ์— ์ฐ์„ ๋ฒˆํ˜ธ. ํ•œ ๋ฒˆ ์ฝ๊ณ  ์บ์‹œํ•œ๋‹ค(์“ฐ๊ธฐ๋งˆ๋‹ค ์กฐํšŒ ๊ธˆ์ง€).\n *\n * ์—†์œผ๋ฉด `undefined` ๋‹ค โ€” 0 ์ด ์•„๋‹ˆ๋‹ค. ๊ตฌ์กฐ ๋ฆฌ๋น„์ „์ด ์ƒ๊ธฐ๊ธฐ ์ „์— ๋งŒ๋“ค์–ด์ง„ ํŠธ์œˆ์€ ์•„์ง ๋ฆฌ๋น„์ „์ด\n * ์—†๊ณ , ๊ทธ ์‚ฌ์‹ค์„ 0 ์ด๋ผ๋Š” **์œ ํšจํ•ด ๋ณด์ด๋Š” ๋ฒˆํ˜ธ**๋กœ ์œ„์žฅํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.\n */\n private static structureRevCache: Record<string, number> = {}\n static async structureRevOf(domainId: string, instanceId: string): Promise<number | undefined> {\n const key = `${domainId}:${instanceId}`\n const cached = this.structureRevCache[key]\n if (cached !== undefined) return cached\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) this.structureRevCache[key] = latest.rev\n return latest?.rev\n }\n\n /** live ์ €๋„ ๋ฐฐ์น˜ ๊ธฐ๋ก โ€” ๋ชจ์•„๋‘” CanonicalEnvelope ๋“ค์— startRevision+1.. ์„ ๋ถ€์—ฌํ•ด ๋ฒŒํฌ ์ €์žฅ(coalescer tick ๋‹น 1ํšŒ). */\n static async persistBatch(domainId: string, instanceId: string, envelopes: any[], startRevision: number): Promise<void> {\n const repo = getRepository(TwinEvent)\n const structureRev = await this.structureRevOf(domainId, instanceId)\n const rows = envelopes.map((e, i) => this.journalRow(repo, domainId, instanceId, e, startRevision + i + 1, structureRev))\n await repo.save(rows, { chunk: 500 })\n }\n\n /** ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ upsert(๋„๋ฉ”์ธ+instanceId ์œ ๋‹ˆํฌ). status ์ธ์ž๋กœ provision(stopped)/start(running) ๊ณต์šฉ. */\n static async register(\n domainId: string,\n instanceId: string,\n kind: string,\n board: BoardDef,\n status: 'running' | 'stopped' = 'running',\n realityMode?: RealityMode\n ): Promise<void> {\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n instanceId,\n kind,\n board,\n // ์ธ์Šคํ„ด์Šคโ†”๊ณต๊ฐ„ 1๊ธ‰ ๋งํฌ(space #3) โ€” board.spaceId/areaId ๋ฅผ ์ปฌ๋Ÿผ์œผ๋กœ ์Šน๊ฒฉ(dual-write). board JSON ๋„ ์œ ์ง€(์ปค๋„ยท๋ณต๊ตฌ์šฉ).\n spaceId: (board as any)?.spaceId ?? existing?.spaceId,\n areaId: (board as any)?.areaId ?? existing?.areaId,\n // ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 โ‘ ) โ€” ๋ช…์‹œ๊ฐ’ ์šฐ์„ , ์—†์œผ๋ฉด ๊ธฐ์กด๊ฐ’ ๋ณด์กด(์žฌํ”„๋กœ๋น„์ „์ด ์„ ์–ธ์„ ์ง€์šฐ์ง€ ์•Š๊ฒŒ).\n realityMode: realityMode ?? existing?.realityMode ?? undefined,\n status\n })\n )\n }\n\n /**\n * ๋ผ์ด๋ธŒ ๊ตฌ์กฐ ๋ณ€์ด(resource.add ๋“ฑ)๋ฅผ ์ €์žฅ๋œ board ์— ๋ฐ˜์˜ โ€” ๋Ÿฐํƒ€์ž„ ์ปค๋„์˜ ๋ฌด๋ฒ„๋ฅผ registry board.equipment ์— ๋™๊ธฐ.\n * ์ด๊ฒŒ ์—†์œผ๋ฉด ๋Ÿฐํƒ€์ž„์—” ์ถ”๊ฐ€๋ผ๋„(์ƒํƒœยท์ €๋„์—” ๋ฐ˜์˜) ์ €์žฅ board ๋Š” ์›๋ณธ์ด๋ผ ํ”„๋กœ๋น„์ €๋‹ ํŽธ์ง‘๊ธฐยท์žฌ๊ธฐ๋™(loadBoard)์ด\n * ์ถ”๊ฐ€๋ถ„์„ ์žƒ๋Š”๋‹ค. ๊ธฐ์กด board.equipment ํ•ญ๋ชฉ์€ ๋ณด์กด(homeLocation ์œ ์ง€)ํ•˜๊ณ  ์ƒˆ id ๋งŒ append(์ถ”๊ฐ€ ์‹œ์  location=homeLocation).\n * ์ขŒํ‘œ(layout)๋งŒ ๋‹ค๋ฃจ๋Š” register ์™€ ๋‹ฌ๋ฆฌ equipment ์ง‘ํ•ฉ์„ ๊ฐฑ์‹ ํ•˜๋‚˜, ์žฌํ”„๋กœ๋น„์ „(purge)์ด ์•„๋‹ˆ๋ผ in-place ๊ฐฑ์‹ ์ด๋ผ\n * ์ €๋„์€ ๋ณด์กด๋œ๋‹ค(์ถ”๊ฐ€๋Š” ์ด๋ฏธ equipment ๋ธํƒ€๋กœ ์ €๋„๋จ โ†’ replay ๋Š” id-keyed upsert ๋ผ ์ด์ค‘๊ณ„์‚ฐ ์—†์Œ).\n */\n static async syncBoardEquipment(domainId: string, instanceId: string): Promise<void> {\n const inst = this.instances[instanceId]\n const snap = inst?.kernel?.getSnapshot?.()\n if (!snap?.equipment) return\n const repo = getRepository(TwinInstance)\n const reg = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return\n const board = reg.board as BoardDef\n const known = new Set((board.equipment ?? []).map(m => m.id))\n const added = snap.equipment\n .filter((m: any) => !known.has(m.id))\n .map((m: any) => ({ id: m.id, kind: m.kind, homeLocation: m.location }))\n if (!added.length) return\n board.equipment = [...(board.equipment ?? []), ...added]\n reg.board = board\n await repo.save(reg)\n }\n\n /**\n * ํ”„๋กœ๋น„์ €๋‹ โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๊ตฌ์กฐ(board)๋ฅผ ๋“ฑ๋ก๋งŒ ํ•˜๊ณ  ๊ธฐ๋™ํ•˜์ง€ ์•Š์Œ(status='stopped').\n * ์žฌํ”„๋กœ๋น„์ „ ์‹œ ๊ตฌ์กฐ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๋ฐ”๋€Œ๋ฉด(๋…ธ๋“œยท๋ฌด๋ฒ„ ์ง‘ํ•ฉ/์†์„ฑ ๋ณ€๊ฒฝ) ๊ธฐ์กด ์ €๋„์„ purge ํ•œ๋‹ค(ADR-0015):\n * board ๋Š” replay ์˜ ๋งˆ์Šคํ„ฐ๋ผ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๊ณผ๊ฑฐ ์ด๋ฒคํŠธ์˜ ์ „์ œ๊ฐ€ ๊นจ์ง„๋‹ค. ์ขŒํ‘œ(layout)๋งŒ ๋ฐ”๋€Œ๋ฉด ์ €๋„ ๋ณด์กด.\n */\n static async provision(domainId: string, instanceId: string, kind: string, board: BoardDef, comment?: string): Promise<void> {\n if (this.instances[instanceId]) throw new Error(`instance \"${instanceId}\" is running โ€” stop before re-provisioning`)\n const repo = getRepository(TwinInstance)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, instanceId } })\n\n /*\n * **๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ์–ด๋„ ์—ญ์‚ฌ๋ฅผ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์˜ˆ์ „์—๋Š” ์„œ๋ช…์ด ๋‹ค๋ฅด๋ฉด ๊ทธ ํŠธ์œˆ์˜ ์ €๋„์„ ํ†ต์งธ๋กœ ์ง€์› ๋‹ค. ์•ˆ ์ง€์šฐ๋ฉด ์˜› ์ด๋ฒคํŠธ๋ฅผ ์ƒˆ ๊ณต์žฅ์— ๋Œ€๊ณ \n * ์ ‘๊ฒŒ ๋˜์–ด ์ด๋ ฅ์ด ๊ฑฐ์ง“๋ง์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค โ€” ๋ถ€์Šค๊ฐ€ ๋‘˜์ด๋˜ ์‹œ์ ˆ์˜ ์‚ฌ์‹ค์„ ์—ฌ์„ฏ ๊ฐœ์งœ๋ฆฌ ๊ณต์žฅ์—\n * ์ ‘์œผ๋ฉด ๊ทธ๋•Œ ์—†๋˜ ๋ถ€์Šค์—์„œ ์ผ์ด ์žˆ์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ์„ ํƒ์ง€๊ฐ€ **์—ญ์‚ฌ๋ฅผ ์žƒ๊ฑฐ๋‚˜ ๊ฑฐ์ง“๋ง์„\n * ํ•˜๊ฑฐ๋‚˜** ๋‘˜๋ฟ์ด์—ˆ๊ณ , ๊ทธ๋ž˜์„œ ๊ณต์žฅ์„ ๊ณ ์น  ๋•Œ๋งˆ๋‹ค ์ด๋ ฅ์„ ๋ฒ„๋ ค์•ผ ํ–ˆ๋‹ค.\n *\n * ์ด์ œ ์…‹์งธ ๊ธธ๋กœ ๊ฐ„๋‹ค: ๋ฐ”๋€ ๊ตฌ์กฐ๋ฅผ **์ƒˆ ๋ฆฌ๋น„์ „**์œผ๋กœ ๋‚จ๊ธฐ๊ณ , ์•ž์œผ๋กœ ์“ฐ์ด๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๊ทธ ๋ฒˆํ˜ธ๋ฅผ\n * ๋‹ฌ๊ณ  ๋‹ค๋‹Œ๋‹ค. ์žฌ์ƒ์€ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ง€์ ์—์„œ ๊ฐˆ์•„ํƒ„ ๋’ค ์ด์–ด ์ ‘๋Š”๋‹ค(`replaySegments`).\n */\n await this.recordStructure(domainId, instanceId, board, comment)\n await this.register(domainId, instanceId, kind, board, existing?.status === 'running' ? 'stopped' : (existing?.status as any) ?? 'stopped')\n }\n\n /**\n * ์ด ๊ตฌ์กฐ๋ฅผ ๋ฆฌ๋น„์ „์œผ๋กœ ๋‚จ๊ธฐ๊ณ  ๊ทธ ๋ฒˆํ˜ธ๋ฅผ ๋Œ๋ ค์ค€๋‹ค โ€” **๋ฐ”๋€Œ์—ˆ์„ ๋•Œ๋งŒ** ์ƒˆ ๋ฒˆํ˜ธ๊ฐ€ ์ƒ๊ธด๋‹ค.\n *\n * ํ”„๋กœ๋น„์ €๋‹์€ ๋ถ€ํŒ…๋งˆ๋‹ค ๋‹ค์‹œ ๋„๋Š”๋ฐ, ๊ทธ๋•Œ๋งˆ๋‹ค ๋ฆฌ๋น„์ „์ด ๋Š˜๋ฉด ์ด๋ ฅ์ด ๋œป ์—†๋Š” ๋งˆ๋””๋กœ ์ž˜๊ฒŒ ์ชผ๊ฐœ์ง„๋‹ค.\n * ๊ทธ๋ž˜์„œ **๊ตฌ์กฐ ์„œ๋ช…์ด ๊ฐ™์œผ๋ฉด ์žˆ๋˜ ๋ฆฌ๋น„์ „์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค.**\n */\n static async recordStructure(domainId: string, instanceId: string, board: BoardDef, comment?: string): Promise<number> {\n const repo = getRepository(TwinStructure)\n const signature = this.structureFingerprint(board)\n const latest = await repo.findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n\n /*\n * **์ €์žฅ๋œ ์ง€๋ฌธ์ด ์•„๋‹ˆ๋ผ ์ €์žฅ๋œ ๊ณต์žฅ๊ณผ ๋น„๊ตํ•œ๋‹ค.**\n *\n * ์ง€๋ฌธ ๊ณ„์‚ฐ ๋ฐฉ์‹์„ ํ•œ ๋ฒˆ์ด๋ผ๋„ ๋ฐ”๊พธ๋ฉด(์›๋ฌธ โ†’ ํ•ด์‹œ๋กœ ๋ฐ”๊ฟจ๋‹ค) ์ €์žฅ๋œ ๋ฌธ์ž์—ด์€ ์ „๋ถ€ ์˜› ๋ฐฉ์‹์˜\n * ๊ฒƒ์ด๋ผ ๋ฌด์—‡๊ณผ๋„ ์•ˆ ๋งž๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฉด **์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๋ฐ”๋€ ํŠธ์œˆ๋“ค์ด ์ „๋ถ€ \"๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค\"** ๋กœ\n * ๊ธฐ๋ก๋œ๋‹ค โ€” ์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ๋๊ณ , ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์— ๋ฆฌ๋น„์ „์ด ํ†ต์งธ๋กœ ํ•˜๋‚˜์”ฉ ๋Š˜์—ˆ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์•ˆ ๋งž์„ ๋•Œ ํ•œ ๋ฒˆ ๋” ๋ฌป๋Š”๋‹ค: ์ €์žฅ๋œ **๋ณด๋“œ**๋กœ ์ง€๋ฌธ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋ฉด ๊ฐ™์€๊ฐ€? ๊ฐ™๋‹ค๋ฉด\n * ๊ณต์žฅ์€ ๊ทธ๋Œ€๋กœ์ด๊ณ  ์ง€๋ฌธ ํ‘œ๊ธฐ๋งŒ ๋‚ก์€ ๊ฒƒ์ด๋‹ˆ, ๋ฆฌ๋น„์ „์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ํ‘œ๊ธฐ๋งŒ ๊ณ ์นœ๋‹ค.\n */\n if (latest && latest.signature !== signature && this.structureFingerprint(latest.board as BoardDef) === signature) {\n latest.signature = signature\n await repo.save(latest)\n }\n\n if (latest?.signature === signature) {\n this.structureRevCache[`${domainId}:${instanceId}`] = latest.rev\n return latest.rev\n }\n\n const rev = (latest?.rev ?? 0) + 1\n await repo.save(repo.create({ domain: { id: domainId } as any, instanceId, rev, signature, board: board as any, ...(comment ? { comment } : {}) }))\n this.structureRevCache[`${domainId}:${instanceId}`] = rev\n /* ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์žฌ๊ตฌ์„ฑ ์บ์‹œ๋Š” ์˜› ๊ณต์žฅ์˜ ๊ฒƒ์ด๋‹ค โ€” ๋ฒ„๋ฆฐ๋‹ค(์ง€์šฐ๋Š” ๊ฑด ์บ์‹œ๋ฟ, ์‚ฌ์‹ค์€ ๋‚จ๋Š”๋‹ค). */\n delete this.recovered[instanceId]\n if (latest) console.info(`[twin-engine] \"${instanceId}\" structure changed โ†’ revision ${rev} (history kept; older events stay under revision ${latest.rev}).`)\n return rev\n }\n\n /**\n * ์ด ํŠธ์œˆ์ด ๊ฑฐ์ณ ์˜จ ๊ตฌ์กฐ๋“ค โ€” **๋ฌด์—‡์ด ์–ธ์ œ ๋‹ฌ๋ผ์กŒ๋‚˜.**\n *\n * ๋ฆฌ๋น„์ „์€ ๊ทธ ์‹œ์ ˆ ๊ณต์žฅ์„ ํ†ต์งธ๋กœ ๋‹ด์ง€๋งŒ(์žฌ์ƒ์— ํ•„์š”ํ•˜๋‹ค), ์‚ฌ๋žŒ์ด ๋ณด๊ณ  ์‹ถ์€ ๊ฒƒ์€ ํ†ต์งธ๊ฐ€ ์•„๋‹ˆ๋ผ\n * ์ฐจ์ด๋‹ค. ๋ณด๋“œ๋Š” ๋นผ๊ณ  **์ฐจ์ด ์š”์•ฝ๋งŒ** ๋‚ด๋ณด๋‚ธ๋‹ค โ€” 62KB ์งœ๋ฆฌ ๋ณด๋“œ๋ฅผ ํ™”๋ฉด์— ์‹ค์–ด ๋ณด๋‚ผ ์ด์œ ๊ฐ€ ์—†๋‹ค.\n */\n static async structureHistory(\n domainId: string,\n instanceId: string\n ): Promise<{ rev: number; createdAt?: Date; comment?: string; events: number; diff: StructureDiff }[]> {\n const revs = await getRepository(TwinStructure).find({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'ASC' } })\n if (!revs.length) return []\n\n /* ๋ฆฌ๋น„์ „๋งˆ๋‹ค ๊ทธ ์•„๋ž˜์—์„œ ๋ช‡ ๊ฑด์ด ์ผ์–ด๋‚ฌ๋‚˜ โ€” ์ด๋ ฅ์˜ ๋ฌด๊ฒŒ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค(์งง๊ฒŒ ์Šค์ณ๊ฐ„ ๊ตฌ์กฐ์ธ์ง€). */\n const counts = new Map<number | null, number>()\n for (const row of await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('e.structureRev', 'rev')\n .addSelect('COUNT(1)', 'n')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .groupBy('e.structureRev')\n .getRawMany())\n counts.set(row.rev === null || row.rev === undefined ? null : Number(row.rev), Number(row.n))\n\n /* ๋ฒˆํ˜ธ ์—†๋Š” ์˜› ํ–‰์€ **๊ฐ€์žฅ ์˜ค๋ž˜๋œ ๋ฆฌ๋น„์ „**์˜ ๋ชซ์ด๋‹ค โ€” ์žฌ์ƒ์ด ๊ทธ๋ ‡๊ฒŒ ์ ‘์œผ๋ฏ€๋กœ ์„ธ๋Š” ๊ฒƒ๋„ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. */\n const oldest = revs[0].rev\n const legacy = counts.get(null) ?? 0\n\n return revs.map((r, i) => ({\n rev: r.rev,\n createdAt: r.createdAt,\n ...(r.comment ? { comment: r.comment } : {}),\n events: (counts.get(r.rev) ?? 0) + (r.rev === oldest ? legacy : 0),\n diff: diffStructures(i === 0 ? undefined : (revs[i - 1].board as any), r.board as any)\n }))\n }\n\n /** ์ง€๊ธˆ ์“ฐ์ด๋Š” ๊ตฌ์กฐ ๋ฆฌ๋น„์ „ โ€” ์ด๋ฒคํŠธ์— ์ฐ์„ ๋ฒˆํ˜ธ. ์•„์ง ์—†์œผ๋ฉด ๊ธฐ๋กํ•˜๋ฉฐ ๋งŒ๋“ ๋‹ค. */\n static async currentStructureRev(domainId: string, instanceId: string, board?: BoardDef): Promise<number | undefined> {\n const latest = await getRepository(TwinStructure).findOne({ where: { domain: { id: domainId }, instanceId }, order: { rev: 'DESC' } })\n if (latest) return latest.rev\n return board ? this.recordStructure(domainId, instanceId, board) : undefined\n }\n\n /** ๊ตฌ์กฐ ๋™์ผ์„ฑ ์ง€๋ฌธ โ€” ์ขŒํ‘œ(layout) ๋“ฑ ๋ทฐ ๊ด€์‹ฌ์‚ฌ๋Š” ์ œ์™ธํ•˜๊ณ  ์ปค๋„์ด ๋ณด๋Š” ์œ„์ƒยท์šฉ๋Ÿ‰ยท๋ฌด๋ฒ„๋งŒ. */\n /**\n * ์ง€๋ฌธ์„ **64์ž๋กœ ์ค„์ธ๋‹ค** โ€” ์ปฌ๋Ÿผ์ด varchar(64) ๋‹ค.\n *\n * ์›๋ฌธ ์ง€๋ฌธ์€ ์ž๋ฆฌยท์„ค๋น„๋ฅผ ์ „๋ถ€ ์ด์–ด ๋ถ™์ธ ๋ฌธ์ž์—ด์ด๋ผ ํฐ ๊ณต์žฅ์—์„œ๋Š” ์ˆ˜๋งŒ ์ž๊ฐ€ ๋œ๋‹ค. sqlite ๋Š”\n * ๊ธธ์ด๋ฅผ ๊ฐ•์ œํ•˜์ง€ ์•Š์•„ ๊ทธ๋ƒฅ ๋“ค์–ด๊ฐ€์ง€๋งŒ **Postgres ๋Š” ๊ฑฐ๊ธฐ์„œ ํ„ฐ์ง„๋‹ค** โ€” ๊ฐœ๋ฐœ์—์„œ๋Š” ๋ฉ€์ฉกํ•˜๊ณ \n * ์šด์˜์—์„œ๋งŒ ์ฃฝ๋Š” ์ข…๋ฅ˜์˜ ์‹คํŒจ๋‹ค. ๋น„๊ต์—๋งŒ ์“ฐ๋Š” ๊ฐ’์ด๋ฏ€๋กœ ํ•ด์‹œ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.\n */\n private static structureFingerprint(board: BoardDef): string {\n return createHash('sha256').update(this.structureSignature(board)).digest('hex')\n }\n\n private static structureSignature(board: BoardDef): string {\n const locations = [...(board.locations ?? [])]\n .map(n => `${n.id}:${n.type}:${n.capacity}`)\n .sort()\n .join('|')\n const equipment = [...(board.equipment ?? [])]\n .map(m => `${m.id}:${m.kind}:${m.homeLocation}`)\n .sort()\n .join('|')\n return `N[${locations}]M[${equipment}]`\n }\n\n /** ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ board ๋กœ ๊ธฐ๋™(ํ”„๋กœ๋น„์ „๋œ ์ธ์Šคํ„ด์Šค start). board ์ธ์ž ์—†์ด ์ €์žฅ๋œ ๊ตฌ์กฐ๋กœ ์žฌ๊ธฐ๋™. */\n static async startFromRegistry(domainId: string, instanceId: string, realityMode?: RealityMode): Promise<InstanceRuntime> {\n if (this.instances[instanceId]) return this.instances[instanceId]\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n\n /*\n * ์›œ์Šคํƒ€ํŠธ ์žฌ๋ฃŒ๋ฅผ **์—ฌ๊ธฐ์„œ ํ™•์‹คํžˆ ํ™•๋ณดํ•œ๋‹ค.**\n * `start()` ๋Š” ๋™๊ธฐ๋ผ ์Šค์Šค๋กœ ์บ์‹œ๋ฅผ ์ฝ์„ ์ˆ˜ ์—†์–ด์„œ `recovered` ์— ๋ฏธ๋ฆฌ ๋‹ด๊ฒจ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š”๋ฐ,\n * ๊ทธ๊ฑด `bootstrap()` ์ด ๋จผ์ € ๋Œ์•˜์„ ๋•Œ๋งŒ ์ฐธ์ด๋‹ค. ๋ถ€ํŒ… ์ˆœ์„œ์— ๊ธฐ๋Œ€๋ฉด ์–ด๋–ค ๋‚ ์€ ์žฌ๊ณ ๊ฐ€ ์‚ด์•„๋‚˜๊ณ \n * ์–ด๋–ค ๋‚ ์€ ์กฐ์šฉํžˆ ๋นˆ ์ฑ„๋กœ ๋œฌ๋‹ค โ€” ์žฌํ˜„๋˜์ง€ ์•Š๋Š” ๊ฒฐํ•จ์ด ๊ฐ€์žฅ ๋‚˜์˜๋‹ค.\n * ์ฒดํฌํฌ์ธํŠธ ์บ์‹œ ์šฐ์„ (O(1) + ๋ผ์ด๋ธŒ ํŒŒ์ƒ์ƒํƒœ ๋ณด์กด), ์—†์œผ๋ฉด ์ €๋„ replay ํด๋ฐฑ(๋ถ€ํŒ…๊ณผ ๊ฐ™์€ ์ˆœ์„œ).\n */\n if (!this.recovered[instanceId] && reg.purpose !== 'bench') {\n const cached = await this.loadSnapshot(domainId, instanceId).catch(() => null)\n if (cached?.state) {\n this.recovered[instanceId] = { revision: cached.revision, state: cached.state }\n } else {\n const state = await this.recover(domainId, instanceId).catch(() => null)\n if (state) this.recovered[instanceId] = { revision: state.revision, state }\n }\n }\n\n /*\n * ์ €๋„์— ๋‚จ์•„ ์žˆ๋Š” ๋งˆ์ง€๋ง‰ ๋ฒˆํ˜ธ โ€” **๋ชจ๋“œ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ** ์ด๊ฒƒ์„ ์ด์–ด ์„ผ๋‹ค.\n *\n * ์ €๋„์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ๊ธฐ๋™ํ•˜๋Š” ๋ชจ๋“œ(sim-experiment)๋ผ๋ฉด ์ด ๊ฐ’์ด 0์ด๋ผ ์•„๋ฌด ์˜ํ–ฅ์ด ์—†๋‹ค. ๊ทœ์น™์„\n * ๋ชจ๋“œ๋ณ„๋กœ ๊ฐ€๋ฅด์ง€ ์•Š๋Š” ์ด์œ : \"์ €๋„์ด ๋น„์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ๊ทธ ๋’ค๋ถ€ํ„ฐ\" ํ•˜๋‚˜๋ฉด ์–ด๋А ๋ชจ๋“œ์—์„œ๋„\n * ๊ฒน์น  ์ˆ˜ ์—†๊ณ , ๋ชจ๋“œ๊ฐ€ ๋Š˜์–ด๋„ ์ด ์ž๋ฆฌ๋ฅผ ๋‹ค์‹œ ์†๋ณผ ์ผ์ด ์—†๋‹ค.\n */\n const last = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select('MAX(e.revision)', 'max')\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .getRawOne()\n\n return this.start(\n instanceId,\n domainId,\n reg.kind ?? 'wms',\n reg.board as BoardDef,\n realityMode ?? (reg.realityMode as RealityMode) ?? undefined,\n reg.purpose ?? undefined,\n Number(last?.max ?? 0) || 0\n )\n }\n\n /**\n * ์„ ์–ธ ๊ธฐ๋ฐ˜ ๋ถ€ํŒ…(ยง0 ํ”„๋ ˆ์ž„ โ‘  โ†’ ๋ถ€ํŒ… ๊ฑฐ๋™ ๋งคํ•‘) โ€” ํŠธ์œˆ์ด ์„ ์–ธํ•œ realityMode ์— ๋”ฐ๋ผ ์žฌ๊ธฐ๋™ ๋ฐฉ์‹์„ ๊ฐ€๋ฅธ๋‹ค.\n * ๋ถ€ํŒ… ๊ฒฝ๋กœ๋ฅผ ํ•œ ๊ณณ์— ๋ชจ์•„ \"๋Ÿฐํƒ€์ž„ โ‰  ํ˜„์‹ค\" ๋ฒ”์ฃผ์˜ค๋ฅ˜๋ฅผ ์ฝ”๋“œ๋กœ ๊ฐ•์ œํ•œ๋‹ค.\n * - 'mirror' : ํ˜„์‹ค=์™ธ๋ถ€ ์‹ค๋ฌผ โ†’ startLive(์žฌ๋™๊ธฐ). ์ด๋ฒคํŠธ๋Š” ์–ด๋Œ‘ํ„ฐ ingest ๋กœ ์œ ์ž…, ์ปค๋„ tick ์—†์Œ.\n * - 'sim-world' : ์ƒ์„ฑ ํƒ€์ž„๋ผ์ธ ์ง€์† โ†’ ์ €๋„ ๋ณด์กด + resume(ํ˜„์‹ค ์ด์–ด๊ฐ).\n * โš  GATE(ยง8 โ‘กโ‘ข): ์ปค๋„ ์ƒํƒœ ์ง๋ ฌํ™”/์žฌ๊ฐœ๊ฐ€ ์•„์ง ์—†์–ด ์ง„์งœ resume ๋ถˆ๊ฐ€ โ†’ ์‹ค ํ•„์š”ยท์‹ค๋ถ€ํ•˜ ์‹œ ๊ตฌํ˜„.\n * ๊ทธ๋•Œ๊นŒ์ง€๋Š” ์ €๋„์„ ๋ณด์กดํ•˜๋˜ revision ์ถฉ๋Œ์„ ํ”ผํ•˜๋ ค fresh ๋กœ ๊ธฐ๋™ํ•˜๊ณ , ์„ ์–ธ๊ณผ ๊ตฌํ˜„์˜ ๊ฐ„๊ทน์„ ํฌ๊ฒŒ ๊ฒฝ๊ณ ํ•œ๋‹ค.\n * - 'sim-experiment' : seed ์žฌํ˜„ โ†’ resetJournal + fresh ๊ธฐ๋™(๋ฐฑ์ง€ ์‹œ์ž‘์ด ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ์„ ์–ธ๋œ ๊ฑฐ๋™).\n * ๋ฐ˜ํ™˜: ๊ธฐ๋™๋œ InstanceRuntime.\n */\n static async bootDeclared(domainId: string, instanceId: string, mode: RealityMode = DEFAULT_REALITY_MODE): Promise<InstanceRuntime> {\n if (mode === 'mirror') {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`instance \"${instanceId}\" not provisioned (no board)`)\n return this.startLive(instanceId, domainId, reg.kind ?? 'wms', reg.board as BoardDef)\n }\n if (mode === 'sim-world') {\n /*\n * **์ด์–ด์ง€๋Š” ํ˜„์‹ค** โ€” ์ €๋„์„ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์˜ˆ์ „์—๋Š” ์—ฌ๊ธฐ์„œ ์ €๋„์„ ์ง€์šฐ๊ณ  fresh ๋กœ ๋„์› ๋‹ค. resume ๊ธฐ๊ณ„์žฅ์น˜๊ฐ€ ์—†๋‹ค๊ณ  ๋ดค๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ,\n * ์‹ค์ œ๋กœ ์—†๋˜ ๊ฒƒ์€ **๋ฒˆํ˜ธ ์ด์–ด ์„ธ๊ธฐ ํ•˜๋‚˜**์˜€๋‹ค: ์ƒํƒœ ๋ณต์›์€ ์ด๋ฏธ `startFromRegistry` ๊ฐ€\n * ์ €๋„ ์žฌ์ƒ(๋˜๋Š” ์ฒดํฌํฌ์ธํŠธ)์œผ๋กœ ํ•˜๊ณ  ์žˆ์—ˆ๊ณ , ๋ง‰ํžŒ ๊ฒƒ์€ ์ปค๋„์ด ๋ฆฌ๋น„์ „์„ 0๋ถ€ํ„ฐ ๋‹ค์‹œ ์„ธ์–ด\n * ๊ธฐ์กด ํ–‰๊ณผ ๊ฒน์น˜๋Š” ๋ฌธ์ œ์˜€๋‹ค. ๊ทธ ํ•˜๋‚˜๋ฅผ `resumeRevision` ์œผ๋กœ ํ’€์—ˆ์œผ๋ฏ€๋กœ ์ด์ œ ์ด์–ด ๊ฐ„๋‹ค.\n *\n * ์•„์ง ์ด์–ด์ง€์ง€ ์•Š๋Š” ๊ฒƒ(์ •์งํ•˜๊ฒŒ): ์‹œ๋‚˜๋ฆฌ์˜ค ์ƒ์„ฑ๊ธฐ์˜ ๋‚œ์ˆ˜ ํ๋ฆ„์€ ์žฌ๊ธฐ๋™์— ์ด์–ด์ง€์ง€ ์•Š๋Š”๋‹ค โ€”\n * ๊ฐ™์€ ์”จ์•—์—์„œ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฏ€๋กœ ์ž๊ทน์˜ ํŒจํ„ด์ด ์žฌ๊ธฐ๋™ ์ง€์ ์—์„œ ํ•œ ๋ฒˆ ๋Š๊ธด๋‹ค. ์Œ“์ธ ์‚ฌ์‹ค๊ณผ\n * ์ƒํƒœ๋Š” ์ด์–ด์ง€๊ณ , ์•ž์œผ๋กœ ์ผ์–ด๋‚  ์ผ์˜ ๋ฌด์ž‘์œ„ ์ˆœ์„œ๋งŒ ์ƒˆ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.\n */\n return this.startFromRegistry(domainId, instanceId, 'sim-world')\n }\n // sim-experiment(๊ธฐ๋ณธ): seed ์žฌํ˜„ โ€” ์ €๋„ ์ดˆ๊ธฐํ™” ํ›„ revision 0 ๋ถ€ํ„ฐ ์žฌ์‹คํ–‰.\n await this.resetJournal(domainId, instanceId)\n return this.startFromRegistry(domainId, instanceId, 'sim-experiment')\n }\n\n /**\n * ์ €๋„ ์ดˆ๊ธฐํ™” โ€” ์ธ์Šคํ„ด์Šค ์ด๋ฒคํŠธ ์ €๋„ purge(๋ ˆ์ง€์ŠคํŠธ๋ฆฌยท์ƒํƒœ๋Š” ์œ ์ง€).\n * ๋ฐ๋ชจ fresh-start ์šฉ: ๋งค ๋ถ€ํŒ… seed ๋ถ€ํ„ฐ ์ƒˆ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐ๋ชจ์—์„œ, ๋ณต๊ตฌ๋ณธ ํ๊ธฐ ํ›„ revision 0 ๋ถ€ํ„ฐ ์žฌ์‹คํ–‰ํ•˜๋ฉด\n * ์˜› ๋Ÿฐ๊ณผ revision ์ด ๊ฒน์ณ ์ €๋„์ด ์˜ค์—ผ๋œ๋‹ค โ†’ start ์ „์— ํ˜ธ์ถœํ•ด ํ˜„์žฌ ๋Ÿฐ๋งŒ ๋‚จ๊ธด๋‹ค.\n */\n static async resetJournal(domainId: string, instanceId: string): Promise<void> {\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n delete this.recovered[instanceId]\n }\n\n /** ์‚ญ์ œ โ€” ์ •์ง€ + ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์‚ญ์ œ + ์ €๋„ purge(domain ์Šค์ฝ”ํ”„). */\n static async remove(domainId: string, instanceId: string): Promise<void> {\n await this.stop(instanceId)\n delete this.recovered[instanceId]\n await getRepository(TwinEvent).delete({ domain: { id: domainId } as any, instanceId })\n await getRepository(TwinInstance).delete({ domain: { id: domainId } as any, instanceId })\n }\n\n /** ๊ด€๋ฆฌ ๋ชฉ๋ก โ€” domain ์˜ ๋“ฑ๋ก ์ธ์Šคํ„ด์Šค ์ „์ฒด(๋ผ์ด๋ธŒ ์—ฌ๋ถ€ยท์ตœ์‹  ์ €๋„ revisionยท๋…ธ๋“œ/๋ฌด๋ฒ„ ์ˆ˜ ํฌํ•จ). */\n static async list(domainId: string): Promise<any[]> {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const out: any[] = []\n for (const r of rows) {\n const board = (r.board as BoardDef) ?? { locations: [], equipment: [] }\n const last = await getRepository(TwinEvent).findOne({\n where: { domain: { id: domainId } as any, instanceId: r.instanceId },\n order: { revision: 'DESC' }\n })\n out.push({\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n spaceId: r.spaceId, // co-location: ๊ฐ™์€ spaceId ์ธ์Šคํ„ด์Šค๋“ค์ด ํ•œ ๊ณต๊ฐ„(๊ณต์žฅ) ๊ณต์œ  โ€” ๊ณต๊ฐ„๋ทฐ ์ง‘์•ฝ ํ‚ค(G7)\n realityMode: r.realityMode ?? DEFAULT_REALITY_MODE, // ํ˜„์‹ค ์ถœ์ฒ˜ ์„ ์–ธ(ยง0 โ‘ ) โ€” mirror/sim-world/sim-experiment\n purpose: r.purpose ?? 'operational', // ์šด์˜ vs ๋ฒค์น˜ ์‚ฌ๋ณธ(1๊ธ‰ ๊ตฌ๋ณ„ โ€” ์ด๋ฆ„ ์ ‘๋‘์‚ฌ ์•„๋‹˜)\n copyOf: r.copyOf ?? undefined,\n running: !!this.instances[r.instanceId],\n revision: last?.revision ?? 0,\n locationCount: board.locations?.length ?? 0,\n equipmentCount: board.equipment?.length ?? 0\n })\n }\n return out\n }\n\n /** ๋ ˆ๊ฑฐ์‹œ ๋ฒค์น˜ ์ž”์žฌ ๊ฐ€๋“œ โ€” purpose ๋„์ž… ์ „ ๋งŒ๋“ค์–ด์ง„ ๋ฒค์น˜/๋ถ€ํ•˜ ๊ณต๊ฐ„(์ด๋ฆ„ ๊ทœ์•ฝ)๊นŒ์ง€ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค. */\n static isBenchSpace(spaceId?: string): boolean {\n return !!spaceId && (/^bench-/.test(spaceId) || spaceId === 'rosarito-load' || /^loadtest/.test(spaceId))\n }\n\n /** ์šด์˜ ๊ณต๊ฐ„ ๋ชฉ๋ก(๋ฒค์น˜ ์†Œ์Šค ์„ ํƒ๊ธฐ) โ€” ์ด๋ฆ„ยท๊ทœ๋ชจ ํฌํ•จ, ๋ฒค์น˜ ์‚ฌ๋ณธยท์ž”์žฌ ์ œ์™ธ. */\n static async listSpaces(domainId: string): Promise<{ spaceId: string; name: string; instances: number; locations: number; equipment: number }[]> {\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const agg = new Map<string, { spaceId: string; name: string; instances: number; locations: number; equipment: number }>()\n for (const r of insts) {\n if (!r.spaceId || r.purpose === 'bench' || this.isBenchSpace(r.spaceId)) continue // ๋ฒค์น˜ยท์ž”์žฌ ์ œ์™ธ\n const board: any = r.board ?? {}\n const a = agg.get(r.spaceId) ?? { spaceId: r.spaceId, name: nameOf.get(r.spaceId) ?? r.spaceId, instances: 0, locations: 0, equipment: 0 }\n a.instances++\n a.locations += board.locations?.length ?? 0\n a.equipment += board.equipment?.length ?? 0\n agg.set(r.spaceId, a)\n }\n return [...agg.values()]\n }\n\n /** ์ธ์Šคํ„ด์Šค ๋ชฉ์  ํ‘œ์‹(์šด์˜/๋ฒค์น˜) ์„ค์ • โ€” ๋ฒค์น˜ ์‚ฌ๋ณธ์„ 1๊ธ‰ ์†์„ฑ์œผ๋กœ ๊ตฌ๋ณ„(์ด๋ฆ„ ์ ‘๋‘์‚ฌ ์•„๋‹˜). */\n static async setPurpose(domainId: string, instanceId: string, purpose: 'operational' | 'bench', copyOf?: string): Promise<void> {\n await getRepository(TwinInstance).update({ domain: { id: domainId } as any, instanceId }, { purpose, copyOf: copyOf ?? null } as any)\n }\n\n /**\n * ๊ณต๊ฐ„ ๊ตฌ์กฐ ํŒ๋… โ€” ์™„์ „๋ณต์ œ(๋ฒค์น˜ ์‚ฌ๋ณธ)์˜ ์†Œ์Šค. ์ €์žฅ๋ฌผ์ด board(์œ„์ƒ)ยทTwinSpace.content(์น˜์ˆ˜ยทgeoยทํ‘œํ˜„)ยทTwinArea(์˜์—ญ)๋กœ\n * ๋ถ„์‚ฐ๋ผ ์žˆ์œผ๋ฏ€๋กœ ์…‹์„ ๋ชจ์•„ ๋Œ๋ ค์ค€๋‹ค. ํ˜ธ์ถœ์ธก์ด ReferenceMaster ๋กœ ์žฌ๊ตฌ์„ฑ โ†’ ์žฌ์‹๋ณ„ โ†’ ingestMaster.\n */\n static async spaceStructure(domainId: string, spaceId: string): Promise<{ name?: string; content: any; areas: any[]; instances: { instanceId: string; kind?: string; board: any }[] } | null> {\n const sp = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n const areas = sp\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: sp.id } as any } })).map(a => ({ id: a.areaId, type: a.type, name: a.name, parentId: a.parentId, layout: a.layout }))\n : []\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (!insts.length) return null\n return { name: sp?.name, content: sp?.content ?? {}, areas, instances: insts.map(i => ({ instanceId: i.instanceId, kind: i.kind, board: i.board })) }\n }\n\n /** ๊ณต๊ฐ„(+ํ‘œํ˜„ยท์˜์—ญ) ์‚ญ์ œ โ€” ๋ฒค์น˜ ์ •๋ฆฌ ๋“ฑ. ํ˜ธ์ถœ์ธก์ด ๋ฐ”์ธ๋”ฉ ์ธ์Šคํ„ด์Šค๋ฅผ ๋จผ์ € ์ œ๊ฑฐํ•˜๋Š” ์ „์ œ(๊ฐ€๋“œ ์—†์Œ). deleteTwinSpace ๋ฆฌ์กธ๋ฒ„์™€ ๋™ํ˜•. */\n static async deleteSpace(domainId: string, spaceId: string): Promise<void> {\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (space) {\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id: rep.id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any })\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n }\n\n /**\n * Face2 ๋งˆ์Šคํ„ฐ ์ธ์ œ์ŠคํŠธ(ADR-0018) โ€” ๋ ˆํผ๋Ÿฐ์Šค ์‹œ์Šคํ…œ(์‹ค ๋˜๋Š” ๊ฐ€์ƒ)์˜ ๋งˆ์Šคํ„ฐ๋ฅผ ์ฝ์–ด ํŠธ์œˆ์„ ์ƒ์„ฑ.\n * ์—”ํ‹ฐํ‹ฐ๋ฅผ ์†๋ฐฐ์„ /๋ฐœ๋ช…ํ•˜์ง€ ์•Š๊ณ  ๋งˆ์Šคํ„ฐ์—์„œ ๋ฐ˜์˜: ๊ณต๊ฐ„(Space) upsert + ์ธ์Šคํ„ด์Šค provision(๋ฏธ๊ธฐ๋™).\n * ๋…ธ๋“œํƒ€์ž…์€ ์ปค๋„ ์นดํƒˆ๋กœ๊ทธ๋กœ ๊ฒ€์ฆ(warning). start ๋Š” ํ˜ธ์ถœ์ธก(bootstrap/mutation)์ด ๊ฒฐ์ •.\n */\n static async ingestMaster(domainId: string, master: ReferenceMaster): Promise<{ instanceId: string; spaceId: string; warnings: string[] }> {\n const { board, spaceContent, warnings } = masterToTwin(master, DOMAIN_CATALOG)\n const spaceId: string = board.spaceId\n const repo = getRepository(TwinSpace)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /*\n * ๊ณต์œ  ๊ณต๊ฐ„(์—ฌ๋Ÿฌ ํŠธ์œˆ์ด ํ•œ spaceId, N:1) content ๋ณ‘ํ•ฉ โ€” ๋งˆ์ง€๋ง‰ ์ธ์ œ์ŠคํŠธ๊ฐ€ ํ†ต์งธ๋กœ ๋ฎ์–ด์จ area(๊ทธ๋ฃน)ยทํ‘œํ˜„์ด\n * ์œ ์‹ค๋˜๋˜ ๋ฌธ์ œ ๋ณด์ •. areaยทlandmark ๋Š” id ํ•ฉ์ง‘ํ•ฉ, representations ๋Š” ๋น„์–ด์žˆ์ง€ ์•Š์€ ์ชฝ ๋ณด์กด, ๋‚˜๋จธ์ง€๋Š” first-wins.\n */\n const prev: any = existing?.content ?? {}\n const cur: any = spaceContent\n const unionById = (a: any[] = [], b: any[] = []) => {\n const m = new Map<string, any>()\n for (const x of [...a, ...b]) if (x?.id) m.set(x.id, x)\n return [...m.values()]\n }\n const mergedContent = {\n width: prev.width ?? cur.width,\n depth: prev.depth ?? cur.depth,\n unit: prev.unit ?? cur.unit,\n geo: prev.geo ?? cur.geo,\n primaryId: prev.primaryId ?? cur.primaryId,\n representations: (cur.representations?.length ? cur.representations : prev.representations) ?? [],\n // areas ๋Š” content ์— ๋” ์ด์ƒ ์“ฐ์ง€ ์•Š๋Š”๋‹ค(area ๋‹จ์ผํ™” P3) โ€” ๊ถŒ์œ„=TwinArea. ์•„๋ž˜ TwinArea ๋กœ๋งŒ ๊ธฐ๋ก.\n landmarks: unionById(prev.landmarks, cur.landmarks)\n }\n /*\n * **ํ˜„์žฅ์˜ ์‹œ๊ฐ ๊ธฐ์ค€์„ ๊ณต๊ฐ„์— ๋‚จ๊ธด๋‹ค** โ€” ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ๊ณต๊ฐ„์ด ๊ถŒ์œ„์ธ๋ฐ ๊ทธ ๊ฐ’์„ ์˜์›ํžˆ ๋ชจ๋ฅธ๋‹ค.\n *\n * ๋งˆ์Šคํ„ฐ๊ฐ€ ๋ณด๋“œ์— ์˜คํ”„์…‹์„ ์‹ค์–ด ์ฃผ๋ฏ€๋กœ ๊ฐ“ ํ”„๋กœ๋น„์ €๋‹ํ•œ ํŠธ์œˆ์€ ๋งž๊ฒŒ ๋Œ์ง€๋งŒ, `withSpaceTimeBase` ๊ฐ€\n * ์ฝ๋Š” ๊ณณ์€ **๊ณต๊ฐ„**์ด๋‹ค. ์—ฌ๊ธฐ์„œ ์˜ฎ๊ธฐ์ง€ ์•Š์œผ๋ฉด ๊ณต๊ฐ„์˜ ์‹œ๊ฐ„๋Œ€๊ฐ€ ๊ณ„์† ๋น„์–ด ์žˆ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ\n * ๊ทธ๊ฒƒ์„ ๋ณด๊ฑฐ๋‚˜ ๊ณ ์น  ์ˆ˜๋„ ์—†๋‹ค(๋งŒ๋“ค๊ณ  ์ž‡์ง€ ์•Š์œผ๋ฉด ์—†๋Š” ๊ฒƒ์ด๋‹ค).\n *\n * **์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ์นœ ๊ฐ’์„ ๋งˆ์Šคํ„ฐ๊ฐ€ ๋ฎ์ง€ ์•Š๋Š”๋‹ค** โ€” ์ด๋ฏธ ์žˆ์œผ๋ฉด ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค(ํ˜„์žฅ์ด ์ •๋ณธ์„ ์ด๊ธด๋‹ค).\n */\n const timezone = existing?.timezone || master.space.timezone\n const savedSpace = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, spaceId, name: existing?.name || master.siteName, ...(timezone ? { timezone } : {}), content: mergedContent }))\n /*\n * ํ‘œํ˜„์„ twin_space_representations ํ…Œ์ด๋ธ”์— ์ €์žฅํ•œ๋‹ค โ€” ๋ทฐ(twin-map-page ๋“ฑ)๋Š” content ๊ฐ€ ์•„๋‹ˆ๋ผ ํ…Œ์ด๋ธ” ํ‘œํ˜„์„ ์†Œ์‹ฑํ•˜๋ฏ€๋กœ,\n * ์ €์žฅํ•˜์ง€ ์•Š์œผ๋ฉด ์ธ์ œ์ŠคํŠธ ์‚ฌ์ดํŠธ์— \"๋Œ€ํ‘œ ํ‘œํ˜„\" ์ด ์—†์–ด ์ง€๋„๋กœ ์‹œ์ž‘ํ•˜์ง€ ๋ชปํ•œ๋‹ค. rep.areas ๊ฐ€ ์žˆ์œผ๋ฉด TwinSpaceArea ๋„ ํ•จ๊ป˜ ์ €์žฅ.\n * ์ตœ์ดˆ ์ธ์ œ์ŠคํŠธ๋งŒ(๊ธฐ์กด ํ‘œํ˜„ ์žˆ์œผ๋ฉด ์‚ฌ์šฉ์ž ํŽธ์ง‘ ๋ณด์กด).\n */\n const repRepo = getRepository(TwinSpaceRepresentation)\n const areaRepo = getRepository(TwinSpaceArea)\n if ((await repRepo.count({ where: { space: { id: savedSpace.id } } })) === 0) {\n const reps: any[] = (spaceContent as any).representations ?? []\n for (let i = 0; i < reps.length; i++) {\n const rep = reps[i]\n const config =\n rep.type === 'map' ? { center: rep.center, zoom: rep.zoom }\n : rep.type === 'board' ? { boardId: rep.boardId }\n : rep.type === 'image' ? { imageUrl: rep.imageUrl, width: rep.width, height: rep.height }\n : {}\n const savedRep = await repRepo.save(repRepo.create({ domain: { id: domainId } as any, space: { id: savedSpace.id } as any, type: rep.type, name: rep.name, seq: i, isPrimary: !!rep.primary || rep.id === (spaceContent as any).primaryId, config }))\n for (const area of (rep.areas ?? []) as any[]) {\n await areaRepo.save(areaRepo.create({ domain: { id: domainId } as any, representation: { id: savedRep.id } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style ?? null }))\n }\n }\n }\n /*\n * area ๋‹จ์ผํ™”(space #2, P1) โ€” ๋…ผ๋ฆฌ ๊ตฌ์—ญ์„ TwinArea(์ •๊ทœยทํ‘œํ˜„๋ฌด๊ด€ยท๊ณต์œ )์— dual-write(upsert by areaId).\n * P3: content.areas ์ €์žฅ ํ๊ธฐ โ†’ TwinArea ๊ฐ€ ์œ ์ผ ๊ถŒ์œ„. ์†Œ์Šค = masterToTwin ์‚ฐ์ถœ spaceContent.areas(cur).\n * (์›์ฒœ diff ์ œ๊ฑฐ[master ์—์„œ ๋น ์ง„ area ์‚ญ์ œ]๋Š” ์‚ฌ์šฉ์ž์ €์ž‘ area ๋ณดํ˜ธ ์œ„ํ•ด per-area provenance ํ•„์š” โ†’ ํ›„์†.)\n */\n const twinAreaRepo = getRepository(TwinArea)\n for (const a of ((spaceContent as any).areas ?? []) as any[]) {\n if (!a?.id) continue\n const existingArea = await twinAreaRepo.findOne({ where: { domain: { id: domainId }, space: { id: savedSpace.id }, areaId: a.id } })\n await twinAreaRepo.save(\n twinAreaRepo.create({\n ...(existingArea ?? {}),\n domain: { id: domainId } as any,\n space: { id: savedSpace.id } as any,\n areaId: a.id,\n name: a.name ?? a.id,\n type: a.type,\n parentId: a.parentId ?? null,\n layout: a.x != null || a.w != null ? { x: a.x, y: a.y, w: a.w, h: a.h } : null\n })\n )\n }\n\n await this.provision(domainId, master.source, master.system, board)\n if (warnings.length) console.warn(`[twin-engine] ingest \"${master.source}\" warnings:`, warnings)\n return { instanceId: master.source, spaceId, warnings }\n }\n\n /** ๋‹จ๊ฑด ์ƒ์„ธ โ€” ํ”„๋กœ๋น„์ €๋‹ ์—๋””ํ„ฐ๊ฐ€ ํŽธ์ง‘ํ•  board(๊ตฌ์กฐ+layout) ํฌํ•จ. */\n static async detail(domainId: string, instanceId: string): Promise<any | null> {\n const r = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!r) return null\n return {\n instanceId: r.instanceId,\n kind: r.kind,\n status: r.status,\n running: !!this.instances[r.instanceId],\n realityMode: r.realityMode, // ํ˜„์‹ค ์„ ์–ธ โ€” what-if ์ ์šฉ ๊ฐ€๋“œ์šฉ(mirror=์˜ˆ์ธก ์ „์šฉ, ์ž๊ทน ์ฃผ์ž… ๋ถˆ๊ฐ€)\n board: r.board\n }\n }\n\n /**\n * ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ ๋ธŒ๋ฆฌ์ง€(P3, ADR-0018) โ€” ํŠธ์œˆ ์—”ํ‹ฐํ‹ฐ ์ƒํƒœ๋ฅผ `data(tag=์—”ํ‹ฐํ‹ฐid)` ์ฑ„๋„๋กœ publish.\n * ๋ณด๋“œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ tag ๋กœ ๊ตฌ๋…(board-ui provider)ํ•ด `component.data` ๋กœ ๋ผ์ด๋ธŒ ๊ฐฑ์‹ . delta ์‹œ์—๋งŒ(ํฌ์†Œ).\n * tag=์—”ํ‹ฐํ‹ฐ id(๋ฐ๋ชจ=๋‹จ์ผ ์ธ์Šคํ„ด์Šค). ๋ฉ€ํ‹ฐ ์ธ์Šคํ„ด์Šค/๋ณด๋“œ ์žฌ์‚ฌ์šฉ ์‹œ tag ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ํ›„์†.\n */\n static publishEntityData(inst: InstanceRuntime): void {\n const domain = inst.domain\n if (!domain) return\n /* ์ƒํƒœ ์ถœ์ฒ˜ ์Šค์™‘ โ€” sim: ์ปค๋„ runtime, live: projector ๋ฏธ๋Ÿฌ(+OEE ๊ณ„์‚ฐ ์ธต ๋ณด๊ฐ•). ๊ณ„์•ฝยทpayload ๋™์ผ, ๋“œ๋ผ์ด๋ฒ„๋งŒ ๋‹ค๋ฆ„. */\n const st: any =\n inst.mode === 'live'\n ? inst.oee\n ? withLiveOee(inst.projector?.snapshot?.(), inst.oee) // ๊ด€์ธก ์ปค๋„ + ๊ณ„์‚ฐ(OEE) โ†’ equipment payload ์— oee ํฌํ•จ(sim ๋™ํ˜•)\n : inst.projector?.snapshot?.()\n : inst.runtime?.resync?.()?.state\n if (!st) return\n /*\n * ๋ณ€ํ™”ํ•œ ์—”ํ‹ฐํ‹ฐ๋งŒ ๋ฐœํ–‰ โ€” ์ด์ „์—” delta ๋งˆ๋‹ค ์ „ ์—”ํ‹ฐํ‹ฐ(๋…ธ๋“œ+๋ฌด๋ฒ„+์˜ค๋”)๋ฅผ ๊ฐ’ ๋ณ€ํ™”์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์ „๋Ÿ‰ ์žฌ๋ฐœํ–‰ํ•ด\n * ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋งค์ดˆ ๋ฐ˜๋ณต push ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค(์˜ค์šฉ). ์ตœ์‹ -์ƒํƒœ ์ฑ„๋„์ด๋ฏ€๋กœ ๋ฌด๋ณ€ํ™” ์žฌ๋ฐฉ์†ก์€ ๋ฌด์˜๋ฏธํ•˜๋‹ค.\n * ์—”ํ‹ฐํ‹ฐ๋ณ„ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋น„๊ตํ•ด ๋ฐ”๋€ ๊ฒƒ๋งŒ push.\n */\n const sigs = inst.entitySigs ?? (inst.entitySigs = new Map())\n const seen = new Set<string>()\n /* payload ๋งคํ•‘์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜(buildEntityDeltas)๋กœ ๋ถ„๋ฆฌ โ€” ์—ฌ๊ธฐ์„  ์‹œ๊ทธ๋‹ˆ์ฒ˜ dedup + ๋ฐœํ–‰๋งŒ.\n * ๋ณ€ํ™”ํ•œ ์—”ํ‹ฐํ‹ฐ๋งŒ ๋ฐœํ–‰(์ตœ์‹ -์ƒํƒœ ์ฑ„๋„์ด๋ผ ๋ฌด๋ณ€ํ™” ์žฌ๋ฐฉ์†ก ๋ฌด์˜๋ฏธ). */\n for (const { tag, data } of buildEntityDeltas(st)) {\n seen.add(tag)\n const sig = JSON.stringify(data)\n if (sigs.get(tag) === sig) continue // ๋ฌด๋ณ€ํ™” โ†’ ๋ฐœํ–‰ ์ƒ๋žต\n sigs.set(tag, sig)\n pubsub.publish('data', { data: { domain, tag, data } })\n }\n /* ์‚ฌ๋ผ์ง„ ์—”ํ‹ฐํ‹ฐ์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ •๋ฆฌ(๋งต ๋ฌดํ•œ ์„ฑ์žฅ ๋ฐฉ์ง€). */\n if (sigs.size > seen.size) for (const tag of sigs.keys()) if (!seen.has(tag)) sigs.delete(tag)\n }\n\n static async persist(domainId: string, instanceId: string, msg: any): Promise<void> {\n const repo = getRepository(TwinEvent)\n await repo.save(this.journalRow(repo, domainId, instanceId, msg.event, msg.revision, await this.structureRevOf(domainId, instanceId)))\n }\n\n /**\n * ์žฌ๋ถ€ํŒ… ๋ณต๊ตฌ / ์‹œ๊ฐ„์—ฌํ–‰ โ€” DB ์ €๋„์„ replay ํ•ด ์ƒํƒœ ์žฌ๊ตฌ์„ฑ.\n * board ๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(TwinInstance)์—์„œ, ์ด๋ฒคํŠธ๋Š” TwinEvent(revision ASC)์—์„œ.\n * ์ปค์„œ ๋‘ ์ถ•(runtime-state-model ยง4): **์‹œ๊ฐ(untilTime, ์‚ฌ์šฉ์ž ๋ชจ๊ตญ์–ดยท๊ณต๊ฐ„ ๊ณตํ†ต์ถ•)** ์šฐ์„ , ์—†์œผ๋ฉด ๋ฆฌ๋น„์ „(untilRevision, ๋ Œ์ฆˆ ๋‚ด๋ถ€).\n * - untilTime ์ฃผ๋ฉด `eventTime โ‰ค T` ์ธ ์ด๋ฒคํŠธ๋งŒ(๊ทธ ์‹œ์  watermark) โ€” ๊ณต๋™๋ฐฐ์น˜ ์—ฌ๋Ÿฌ ํŠธ์œˆ์„ ํ•˜๋‚˜์˜ ์‹œ๊ฐ T๋กœ ํ†ต์ผ ํ•ด์†Œ.\n * - ๋‘˜ ๋‹ค ์—†์œผ๋ฉด ์ตœ์‹ (๋ผ์ด๋ธŒ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ง„์‹ค).\n * ์ด๋ฒคํŠธ๋Š” ํ•ญ์ƒ revision ASC(์ธ๊ณผ ์ˆœ์„œ)๋กœ ์ ์šฉ โ€” ์‹œ๊ฐ ํ•„ํ„ฐ๋Š” ์ปท์˜คํ”„ ์ง‘ํ•ฉ๋งŒ ์ •ํ•œ๋‹ค.\n */\n static async recover(domainId: string, instanceId: string, untilRevision?: number, untilTime?: string): Promise<any> {\n // ๋ผ์ด๋ธŒ ์ตœ์‹ (์‹œ๊ฐ„์—ฌํ–‰ ์•„๋‹˜) + ์ธ๋ฉ”๋ชจ๋ฆฌ ์ธ์Šคํ„ด์Šค โ†’ ๋ผ์ด๋ธŒ ์ปค๋„ ์Šค๋ƒ…์ƒท์„ ์ง์ ‘ ์‚ฌ์šฉ.\n // replay(StateProjector)๋Š” attentionsยทack ๋“ฑ ๋ผ์ด๋ธŒ ์ „์šฉ ํŒŒ์ƒ ์ƒํƒœ๋ฅผ ๋‹ด์ง€ ๋ชปํ•˜๋ฏ€๋กœ, ์ตœ์‹ ์€ ์ปค๋„ ์ง„์‹ค์„ ์“ด๋‹ค.\n if (untilRevision == null && untilTime == null) {\n const live = this.instances[instanceId]\n if (live?.kernel?.getSnapshot) return live.kernel.getSnapshot()\n // live ๋ชจ๋“œ๋Š” kernel ์ด ์—†๊ณ  projector ๋ฏธ๋Ÿฌ โ†’ ์ธ๋ฉ”๋ชจ๋ฆฌ ์ตœ์‹  ์Šค๋ƒ…์ƒท(projector+OEE+attentions) ์ง์ ‘ ์‚ฌ์šฉ.\n // (์ €๋„์ด ์žˆ์–ด๋„ ์ตœ์‹ ์€ ์ธ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ง„์‹ค โ€” replay ๋Š” ์‹œ๊ฐ„์—ฌํ–‰/๋ณต๊ตฌ ์ „์šฉ.)\n if (live?.mode === 'live' && live.projector) return this.snapshot(instanceId)\n }\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) throw new Error(`twin instance \"${instanceId}\" not registered (no board to replay)`)\n\n const rows = await getRepository(TwinEvent).find({\n where: { domain: { id: domainId }, instanceId },\n order: { revision: 'ASC' }\n })\n const cutoffMs = untilTime != null ? Date.parse(untilTime) : NaN\n const wanted = rows.filter(r => {\n if (untilTime != null && !Number.isNaN(cutoffMs)) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n return Number.isNaN(t) ? true : t <= cutoffMs // eventTime ์—†๋Š” ๋ ˆ๊ฑฐ์‹œ ํ–‰์€ ํฌํ•จ(๋ณด์ˆ˜์ )\n }\n return untilRevision == null || (r.revision ?? 0) <= untilRevision\n })\n\n /*\n * **๊ทธ๋•Œ์˜ ๊ณต์žฅ์œผ๋กœ ์ ‘๋Š”๋‹ค.**\n *\n * ์˜ˆ์ „์—๋Š” ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ง€๊ธˆ ๋“ฑ๋ก๋œ ๋ณด๋“œ ํ•˜๋‚˜๋กœ ์ ‘์—ˆ๋‹ค. ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€ ์  ์—†์œผ๋ฉด ๋งž์ง€๋งŒ, ๋ฐ”๋€\n * ๋’ค์—๋Š” ์˜› ์‚ฌ์‹ค์„ ์ƒˆ ๊ณต์žฅ์— ๋Œ€๊ณ  ์ ‘๊ฒŒ ๋˜์–ด โ€” ๊ทธ๋•Œ ์—†๋˜ ์„ค๋น„์—์„œ ์ผ์ด ์žˆ์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.\n * (๊ทธ๋ž˜์„œ ์˜ˆ์ „ ํ”„๋กœ๋น„์ €๋‹์€ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์ €๋„์„ ์•„์˜ˆ ์ง€์› ๋‹ค. ์—ญ์‚ฌ๋ฅผ ์žƒ๊ฑฐ๋‚˜ ๊ฑฐ์ง“๋ง์„ ํ•˜๊ฑฐ๋‚˜.)\n *\n * ์ด์ œ ์ด๋ฒคํŠธ๊ฐ€ ์ž๊ธฐ ๊ตฌ์กฐ๋ฅผ ๋‹ฌ๊ณ  ์˜ค๋ฏ€๋กœ, ๋ฆฌ๋น„์ „์ด ๋ฐ”๋€Œ๋Š” ์ง€์ ์—์„œ ๊ตฌ์กฐ๋ฅผ ๊ฐˆ์•„ํƒ€๋ฉฐ ์ด์–ด ์ ‘๋Š”๋‹ค.\n * ๋ฆฌ๋น„์ „์ด ํ•˜๋‚˜๋ฟ์ด๊ฑฐ๋‚˜(๋Œ€๋‹ค์ˆ˜) ์•„์˜ˆ ์—†์œผ๋ฉด(๊ตฌ์กฐ ์ด๋ ฅ ์ด์ „) ์˜ˆ์ „๊ณผ ๋˜‘๊ฐ™์ด ํ•œ ๋ฒˆ์— ์ ‘๋Š”๋‹ค.\n */\n const structures = await getRepository(TwinStructure).find({\n where: { domain: { id: domainId }, instanceId },\n order: { rev: 'ASC' }\n })\n const boardOf = new Map<number, BoardDef>(structures.map(x => [x.rev, x.board as BoardDef]))\n /* ์ปฌ๋Ÿผ์ด ์ƒ๊ธฐ๊ธฐ ์ „ ํ–‰์€ ๋ฆฌ๋น„์ „์ด ๋น„์–ด ์žˆ๋‹ค โ€” **๊ฐ€์žฅ ์˜ค๋ž˜๋œ ๊ตฌ์กฐ**์— ์†ํ•œ๋‹ค(0 ์œผ๋กœ ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค). */\n const oldest = structures[0]?.rev\n const revOf = (r: { structureRev?: number }): number | undefined => r.structureRev ?? oldest\n\n const segments: { board: BoardDef; events: any[] }[] = []\n for (const r of wanted) {\n if (!r.payload) continue\n const rev = revOf(r)\n const board = (rev !== undefined && boardOf.get(rev)) || (reg.board as BoardDef)\n const last = segments[segments.length - 1]\n if (last && last.board === board) last.events.push(r.payload)\n else segments.push({ board, events: [r.payload] })\n }\n /*\n * **๊ฐ€์žฅ ์ƒˆ ๊ตฌ์กฐ๊ฐ€ ์ง€๊ธˆ์˜ ๊ณต์žฅ์ด๋‹ค** โ€” ๊ทธ ์•„๋ž˜์—์„œ ์•„์ง ์•„๋ฌด ์ผ๋„ ์—†์—ˆ๋”๋ผ๋„.\n *\n * ์žฌํ”„๋กœ๋น„์ €๋‹ ์งํ›„๊ฐ€ ์ •ํ™•ํžˆ ๊ทธ ์ƒํƒœ๋‹ค: ๋ถ€์Šค๋ฅผ ๋„ท ๋Š˜๋ ธ๋Š”๋ฐ ์ƒˆ ์ด๋ฒคํŠธ๋Š” ์•„์ง ํ•˜๋‚˜๋„ ์—†๋‹ค. ์ด๋•Œ\n * ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ์˜ ๊ตฌ์กฐ๋กœ๋งŒ ์ ‘์œผ๋ฉด ํ™”๋ฉด์€ **์˜› ๊ณต์žฅ**์„ ๋ณด์—ฌ์ค€๋‹ค โ€” ๋ฐฉ๊ธˆ ๋Š˜๋ฆฐ ๊ฒƒ์ด ์•ˆ ๋ณด์ธ๋‹ค.\n * ๊ทธ๋ž˜์„œ ๋งˆ๋””์˜ ๋์— ์ง€๊ธˆ ๊ตฌ์กฐ๋ฅผ ํ•œ ๋ฒˆ ๋” ์–น๋Š”๋‹ค(์ด๋ฒคํŠธ ์—†๋Š” ๋งˆ๋””).\n *\n * **๋‹ค๋งŒ \"์ง€๊ธˆ\" ์„ ๋ฌผ์—ˆ์„ ๋•Œ๋งŒ์ด๋‹ค.** ๊ณผ๊ฑฐ ์‹œ์ ์„ ๋ฌผ์—ˆ๋Š”๋ฐ ์ตœ์‹  ๊ตฌ์กฐ๋ฅผ ์–น์œผ๋ฉด, ๊ทธ ์‹œ์ ์— ์—†๋˜\n * ์„ค๋น„๊ฐ€ ํ™”๋ฉด์— ์„œ๊ณ  โ€” ์ด ์ž‘์—…์ด ๋ง‰์œผ๋ ค๋˜ ๋ฐ”๋กœ ๊ทธ ๊ฑฐ์ง“๋ง์ด ๋œ๋‹ค.\n */\n const asOfNow = untilRevision == null && untilTime == null\n const newest = structures[structures.length - 1]?.board as BoardDef | undefined\n if (asOfNow && newest && segments[segments.length - 1]?.board !== newest) segments.push({ board: newest, events: [] })\n\n if (!segments.length) return replay(((asOfNow && newest) || reg.board) as BoardDef, [])\n if (segments.length === 1) return replay(segments[0].board, segments[0].events)\n\n const { state, shifts } = replaySegments(segments)\n /* ๊ฒฝ๊ณ„์—์„œ ์‚ฌ๋ผ์ง„ ๊ฒƒ์„ ์กฐ์šฉํžˆ ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์ˆ˜๊ฐ€ ์ค„์–ด๋“  ์ด์œ ๋ฅผ ์–ด๋”˜๊ฐ€์—๋Š” ๋‚จ๊ฒจ์•ผ ํ•œ๋‹ค. */\n for (const sh of shifts)\n if (sh.equipmentDropped || sh.locationsDropped || sh.personsDropped || sh.assetsDropped)\n console.info(`[twin-engine] \"${instanceId}\" replay crossed a structure change โ€” dropped ${sh.equipmentDropped} equipment, ${sh.locationsDropped} locations, ${sh.personsDropped} persons, ${sh.assetsDropped} assets that no longer exist.`)\n return state\n }\n\n /**\n * ๊ณต๊ฐ„(๊ณต๋™๋ฐฐ์น˜) ์‹œ๊ฐ ๋ฒ”์œ„ โ€” ์Šคํฌ๋Ÿฌ๋ฒ„ ์•ต์ปค(runtime-state-model ยง4ยทยง6). ๊ทธ ๊ณต๊ฐ„ ์ „ ์ธ์Šคํ„ด์Šค ์ €๋„์˜ min/max eventTime.\n * ๋ฐ˜ํ™˜ {minTime, maxTime}(ISO) โ€” ์ด๋ฒคํŠธ/์‹œ๊ฐ ์—†์œผ๋ฉด null. ํด๋ผ ํžˆ์Šคํ† ๋ฆฌ ์Šคํฌ๋Ÿฌ๋ฒ„๊ฐ€ ์ด ๋ฒ”์œ„๋ฅผ ์‹œ๊ฐ์ถ•์œผ๋กœ ๊ทธ๋ฆฐ๋‹ค.\n */\n static async timeRange(domainId: string, spaceId: string): Promise<{ minTime: string | null; maxTime: string | null }> {\n const regs = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const ids = regs.map(r => r.instanceId)\n if (!ids.length) return { minTime: null, maxTime: null }\n let min = Infinity\n let max = -Infinity\n for (const instanceId of ids) {\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId } })\n for (const r of rows) {\n const t = r.eventTime != null ? Date.parse(String(r.eventTime)) : NaN\n if (Number.isNaN(t)) continue\n if (t < min) min = t\n if (t > max) max = t\n }\n }\n if (min === Infinity) return { minTime: null, maxTime: null }\n return { minTime: new Date(min).toISOString(), maxTime: new Date(max).toISOString() }\n }\n\n /** ์ •์ง€ ํ›… โ€” ์ธ์Šคํ„ด์Šค ์ •์ง€ ์‹œ ๋ถ€์ˆ˜์ž์› ์ •๋ฆฌ(์˜ˆ: reference-live ํ”ผ๋“œ unsubscribe). ์ˆœํ™˜ ์ž„ํฌํŠธ ์—†์ด ๊ฒฐ์„ . */\n static stopHooks: ((id: string) => void)[] = []\n static onStop(fn: (id: string) => void): void {\n this.stopHooks.push(fn)\n }\n\n static async stop(id: string): Promise<void> {\n const i = this.instances[id]\n if (i) {\n clearInterval(i.timer)\n i.unsub()\n delete this.instances[id]\n await getRepository(TwinInstance)\n .update({ domain: { id: i.domainId }, instanceId: id }, { status: 'stopped' })\n .catch(err => console.error('twin deregister fail', err))\n }\n for (const hook of this.stopHooks) { try { hook(id) } catch { /* ํ›… ๊ฒฉ๋ฆฌ */ } }\n }\n\n static runtime(id: string): TwinRuntimeType | undefined {\n return this.instances[id]?.runtime\n }\n\n /**\n * ๋„๋ฉ”์ธ ์†Œ์œ  ๊ฒŒ์ดํŠธ โ€” ์ธ์Šคํ„ด์Šค๊ฐ€ ์ด ๋„๋ฉ”์ธ ์†Œ์œ ์ผ ๋•Œ๋งŒ true(ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ).\n * ์—†๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์ด๋ฉด false. ๋…ธ์ถœ ๋ฆฌ์กธ๋ฒ„(per-id metrics/attentions/state/stop/forecast)๊ฐ€\n * this.instances[id] ๋ฅผ ๋งŒ์ง€๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ์ด๊ฑธ๋กœ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ์ธ์Šคํ„ด์Šค id ๋Š” ์ถ”์ธก ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ\n * ๊ฒ€์ฆ ์—†์ด ์ ‘๊ทผํ•˜๋ฉด ํฌ๋กœ์Šคํ…Œ๋„ŒํŠธ ์ฝ๊ธฐ/์ •์ง€๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.\n */\n static owns(domainId: string, id: string): boolean {\n return this.instances[id]?.domainId === domainId\n }\n\n /**\n * ์ด ํŠธ์œˆ์ด ์ด ํ…Œ๋„ŒํŠธ ๊ฒƒ์ธ๊ฐ€ โ€” **๋–  ์žˆ๋“  ์•„๋‹ˆ๋“ .**\n *\n * `owns()` ๋Š” **๋–  ์žˆ๋Š”** ๋Ÿฐํƒ€์ž„๋งŒ ์•ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ์ด๋ ฅ ์กฐํšŒ์˜ ๊ด€๋ฌธ์œผ๋กœ ์“ฐ๋ฉด, ๊บผ์ง„ ํŠธ์œˆ์˜ ์ €๋„์„\n * ์ฝ์œผ๋ ค ํ•  ๋•Œ \"์ด ํ…Œ๋„ŒํŠธ์— ์—†๋‹ค\" ๋Š” ๋‹ต์ด ๋Œ์•„์˜จ๋‹ค โ€” ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค. ์ฒซ์งธ, ์ €๋„์€ ํŠธ์œˆ์ด ๊บผ์ ธ\n * ์žˆ์„ ๋•Œ **๊ฐ€์žฅ ํ•„์š”ํ•œ ๊ฒƒ**์ด๋‹ค(๊ทธ๊ฒŒ ์ด๋ ฅ์˜ ์กด์žฌ ์ด์œ ๋‹ค). ๋‘˜์งธ, ๊ทธ ๋ฌธ์žฅ์€ ๋‚จ์˜ ๊ฒƒ์ด๋ผ๋Š” ๋œป์ด๋ผ\n * ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ๋ฌธ์ œ๋กœ ์˜คํ•ดํ•œ๋‹ค. ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ƒฅ ์•ˆ ๋Œ๊ณ  ์žˆ์„ ๋ฟ์ด๋‹ค.\n *\n * ์†Œ์œ ๋Š” **๋“ฑ๋ก๋ถ€**๊ฐ€ ์•ˆ๋‹ค. ์ด๋ ฅยท์ง‘๊ณ„์ฒ˜๋Ÿผ ๋Ÿฐํƒ€์ž„๊ณผ ๋ฌด๊ด€ํ•œ ์งˆ๋ฌธ์€ ์ด์ชฝ์— ๋ฌป๋Š”๋‹ค.\n */\n static async ownsRegistered(domainId: string, instanceId: string): Promise<boolean> {\n if (this.owns(domainId, instanceId)) return true\n return !!(await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } }))\n }\n\n /** ๋ผ์ด๋ธŒ ์ปค๋„(ForecastTwin) โ€” forecast/divergence ์˜ˆ์ธก ์—ฐ์‚ฐ์šฉ. */\n static kernel(id: string): any {\n return this.instances[id]?.kernel\n }\n\n /** ๋ผ์ด๋ธŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ณ„์ธก ์Šค๋ƒ…์ƒท(๋ชจ๋‹ˆํ„ฐ, โ‘ฃ-1) โ€” ๋‚ด๋ถ€ ๋ˆ„์ (_acc*) ์ œ์™ธํ•œ ๊ณต๊ฐœ ์ง€ํ‘œ. live ์•„๋‹ˆ๋ฉด null. */\n static metrics(id: string): any {\n const m = this.instances[id]?.metrics\n if (!m) return null\n return {\n instanceId: id,\n ingestedTotal: m.ingestedTotal, broadcastTotal: m.broadcastTotal, journaledTotal: m.journaledTotal,\n ingestRate: m.ingestRate, broadcastRate: m.broadcastRate, journalRate: m.journalRate,\n backlog: m.backlog, broadcastCoalesceMs: this.BROADCAST_COALESCE_MS\n }\n }\n\n /** ์ „์ฒด ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค ๊ณ„์ธก(๋ชจ๋‹ˆํ„ฐ ๋Œ€์‹œ๋ณด๋“œ์šฉ). */\n static async allMetrics(domainId?: string): Promise<any[]> {\n const rows = Object.keys(this.instances)\n .filter(id => !domainId || this.instances[id].domainId === domainId)\n .map(id => this.metrics(id))\n .filter(Boolean)\n if (!rows.length || !domainId) return rows\n // ํ‘œ์‹œ ์ด๋ฆ„ ๋ถ€์—ฌ โ€” ์‹คํ–‰์ค‘ ์นด๋“œ๊ฐ€ id ๋งŒ ๋ณด์ด์ง€ ์•Š๋„๋ก ๊ณต๊ฐ„๋ช…์„ ์‹ค์–ด์ค€๋‹ค(๊ณต๊ฐ„ ์นด๋“œ์™€ ๋™์ผ). name=๊ณต๊ฐ„๋ช… ํด๋ฐฑ spaceId ํด๋ฐฑ instanceId.\n const insts = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const spaceOf = new Map(insts.map(i => [i.instanceId, i.spaceId]))\n const nameOf = new Map((await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })).map(s => [s.spaceId, s.name]))\n for (const r of rows) {\n const sp = spaceOf.get(r.instanceId)\n r.spaceId = sp\n r.name = (sp && nameOf.get(sp)) || sp || r.instanceId\n }\n return rows\n }\n\n /*\n * `buildForecastKernel` ์€ **์‚ฌ๋ผ์กŒ๋‹ค**(ํ†ตํ•ฉ P3, 2026-08-01).\n *\n * ๋ผ์ด๋ธŒ๊ฐ€ `StateProjector` ์˜€์„ ๋•Œ๋Š” ์ปค๋„์ด ์—†์–ด์„œ, ์˜ˆ์ธกํ•˜๋ ค๋ฉด ๊ด€์ธก ์Šค๋ƒ…์ƒท + ์ €๋„์˜ ์˜ค๋” ์›๊ฐ’์œผ๋กœ\n * **์ผํšŒ์šฉ ์ปค๋„์„ ์„ธ์›Œ์•ผ** ํ–ˆ๋‹ค. ์ด์ œ ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณง ์ปค๋„์ด๋ฏ€๋กœ(`startLive`) ๊ทธ ์ž๋ฆฌ์—์„œ\n * `fork` ํ•˜๋ฉด ๋œ๋‹ค โ€” `TwinEngine.kernel(id)` ๊ฐ€ simยทlive ๋‘˜ ๋‹ค ๋Œ๋ ค์ค€๋‹ค.\n *\n * (์˜ค๋” ์›๊ฐ’์„ ์ €๋„์—์„œ ๋˜์ฐพ๋˜ ์ด์œ ๋„ ์‚ฌ๋ผ์กŒ๋‹ค โ€” ์ƒํƒœ๊ฐ€ requestedยทfulfilledยทlines ๋ฅผ ์ง€ํ‚จ๋‹ค.)\n */\n\n /**\n * ์˜ˆ์ธก์šฉ ์ปค๋„์„ **์ž„์˜ ์‹œ๊ฐ T ๊ธฐ์ค€**์œผ๋กœ ์žฌ๊ตฌ์„ฑ โ€” ๊ณผ๊ฑฐ-vantage ์˜ˆ์ธก(๋ฐฑํ…Œ์ŠคํŠธ)ยท\"๊ทธ๋•Œ ์„œ์„œ ๋ณธ ๋ฏธ๋ž˜\".\n * recover(untilTime)๋กœ T ์‹œ์  ์ƒํƒœ๋ฅผ, T ์ดํ•˜ ์˜ค๋” ๊ด€์ธก์„ ๋ชจ์•„ hydrate โ†’ monteCarloForecast ๊ฐ€ T ์—์„œ ์•ž์œผ๋กœ ๊ตด๋ฆฐ๋‹ค.\n * sim/live ๋ฌด๊ด€(์ €๋„ ๊ธฐ๋ฐ˜ ์žฌ๊ตฌ์„ฑ). untilTime ์ƒ๋žต ์‹œ ์ตœ์‹ . ๋„๋ฉ”์ธ ์Šค์ฝ”ํ”„(regยทjournal ์กฐํšŒ๊ฐ€ domainId).\n */\n static async buildForecastKernelAt(domainId: string, instanceId: string, untilTime?: string): Promise<any | null> {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!reg?.board) return null\n const Kernel = KERNELS[reg.kind ?? 'wms'] ?? WmsKernel\n const k = new Kernel(domainId, undefined, this.mesSpecOf(reg.board as BoardDef))\n k.loadBoard(reg.board as BoardDef)\n this.applyOperations(k, reg.board, instanceId) // ์˜ˆ์ธก๋„ ๊ฐ™์€ ๋ช…์„ธ๋กœ ๊ตด๋Ÿฌ์•ผ ํ•œ๋‹ค(ํ™”๋ฉด๊ณผ ๋‹ค๋ฅธ ์ˆซ์ž ๊ธˆ์ง€)\n await this.installEstimators(k, domainId, instanceId, reg.board) // ์˜ˆ์ธก์€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค โ€” ์‹ค์ธก์„ ๋†“์น˜๋ฉด ์˜ˆ์ธก์ด ์ƒ์ˆ˜๋กœ ๋ˆ๋‹ค\n const state = await this.recover(domainId, instanceId, undefined, untilTime).catch(() => null)\n if (!state) return null\n const cutoff = untilTime != null ? Date.parse(untilTime) : Infinity\n const rows = await getRepository(TwinEvent).find({ where: { domain: { id: domainId }, instanceId, eventType: OP_EVENT.order }, order: { revision: 'ASC' } })\n const latest = new Map<string, any>()\n for (const r of rows) {\n if (Number.isFinite(cutoff) && Date.parse(r.eventTime) > cutoff) continue\n const d = (r.payload as any)?.data\n if (d?.orderId) latest.set(d.orderId, d)\n }\n k.hydrateObserved(state, [...latest.values()])\n return k\n }\n\n /** ํ˜„์žฌ ์ „์ฒด ์Šค๋ƒ…์ƒท โ€” ๋ผ์ด๋ธŒ ์šฐ์„ , ์—†์œผ๋ฉด ์ €๋„ ๋ณต๊ตฌ ์บ์‹œ. */\n static snapshot(id: string): any {\n const inst = this.instances[id]\n if (inst?.mode === 'live' && inst.projector) {\n /* live: **์ปค๋„์ด ์ฃผ๋ชฉ ์‹ ํ˜ธ๋ฅผ ์Šค์Šค๋กœ ๋‚ธ๋‹ค**(๊ด€์ธก ๋ชจ๋“œ) โ€” ํ˜ธ์ŠคํŠธ๊ฐ€ ๋ง๋ถ™์ด๋˜ withLiveAttentions ๋Š”\n * ํ•„์š” ์—†๋‹ค. OEE ๋งŒ ํ˜ธ์ŠคํŠธ๊ฐ€ ์ฑ„์šด๋‹ค: ์› ์‹œ์Šคํ…œ์ด ์‹œ๊ฐ„ ๋ˆ„์ ์„ ๋ณด๋‚ด ์ฃผ์ง€ ์•Š์•„ ์ƒํƒœ ์ „์ด๋ฅผ ์ ๋ถ„ํ•ด\n * ๋งŒ๋“œ๋Š” ๊ฐ’์ด๋ผ ์ปค๋„์ด ๋Œ€์‹ ํ•  ์ˆ˜ ์—†๋‹ค(์ ํ•ฉ์„ฑ ํ•˜๋„ค์Šค์˜ ์œ ์ผํ•œ ์˜ˆ์™ธ). */\n const st = inst.projector.snapshot()\n return inst.oee ? withLiveOee(st, inst.oee) : st\n }\n return inst?.runtime?.resync() ?? this.recovered[id]\n }\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  /** ์ปค๋„์— ์‹ฌ์„ ๊ด€์ธก ์ƒํƒœ โ€” ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๋ผ "๋ฌด์—‡์ด ์–ด๋””์— ์–ผ๋งˆ๋‚˜". */
2
2
  export interface ObservedSeed {
3
- nodes: unknown[];
3
+ locations: unknown[];
4
4
  items: unknown[];
5
- movers: unknown[];
5
+ equipment: unknown[];
6
6
  }
7
7
  export type WarmStartPlan = {
8
8
  action: 'hydrate';
9
9
  seed: ObservedSeed;
10
10
  itemCount: number;
11
- moverCount: number;
11
+ equipmentCount: number;
12
12
  }
13
13
  /** ๋ฒค์น˜ ํŠธ์œˆ โ€” ์ƒˆ ์‹œ์ž‘์—์„œ ์šฉ๋Ÿ‰์„ ์žฌ๋Š” ๊ฒŒ ๋ชฉ์ ์ด๋ผ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์‹ฌ์œผ๋ฉด ์ธก์ •์ด ์˜ค์—ผ๋œ๋‹ค. */
14
14
  | {
@@ -33,7 +33,7 @@ export type WarmStartPlan = {
33
33
  * ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์žฌ๊ณ ยท๋…ธ๋“œยท๋ฌด๋ฒ„๋งŒ ๋ณต์›๋˜๊ณ  ์ง„ํ–‰ ์ค‘ ์˜ค๋”๋Š” ๋น„์–ด์„œ ์‹œ์ž‘ํ•˜๋Š” ํŽธ์ด ์ •์งํ•˜๋‹ค.
34
34
  */
35
35
  export declare function planWarmStart(state: {
36
- nodes?: unknown[];
36
+ locations?: unknown[];
37
37
  items?: unknown[];
38
- movers?: unknown[];
38
+ equipment?: unknown[];
39
39
  } | null | undefined, purpose: string | undefined, canHydrate: boolean): WarmStartPlan;