@things-factory/headless-twin 10.0.12 โ†’ 10.0.13

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 (312) hide show
  1. package/dist-server/engine/canonical-ingest.d.ts +57 -2
  2. package/dist-server/engine/canonical-ingest.js +43 -2
  3. package/dist-server/engine/canonical-ingest.js.map +1 -1
  4. package/dist-server/engine/command-routing.js +1 -1
  5. package/dist-server/engine/command-routing.js.map +1 -1
  6. package/dist-server/engine/index.d.ts +3 -0
  7. package/dist-server/engine/index.js +4 -0
  8. package/dist-server/engine/index.js.map +1 -1
  9. package/dist-server/engine/ingest-health.d.ts +335 -0
  10. package/dist-server/engine/ingest-health.js +434 -0
  11. package/dist-server/engine/ingest-health.js.map +1 -0
  12. package/dist-server/engine/integration-coverage.d.ts +76 -0
  13. package/dist-server/engine/integration-coverage.js +73 -0
  14. package/dist-server/engine/integration-coverage.js.map +1 -0
  15. package/dist-server/engine/integration-probes.d.ts +65 -0
  16. package/dist-server/engine/integration-probes.js +100 -0
  17. package/dist-server/engine/integration-probes.js.map +1 -0
  18. package/dist-server/engine/integration-runner.d.ts +45 -0
  19. package/dist-server/engine/integration-runner.js +59 -0
  20. package/dist-server/engine/integration-runner.js.map +1 -0
  21. package/dist-server/engine/integration-target-profile.d.ts +57 -0
  22. package/dist-server/engine/integration-target-profile.js +79 -0
  23. package/dist-server/engine/integration-target-profile.js.map +1 -0
  24. package/dist-server/engine/kpi-fold.d.ts +27 -0
  25. package/dist-server/engine/kpi-fold.js +47 -4
  26. package/dist-server/engine/kpi-fold.js.map +1 -1
  27. package/dist-server/engine/kpi-query.js +128 -14
  28. package/dist-server/engine/kpi-query.js.map +1 -1
  29. package/dist-server/engine/live-feed-registry.js +2 -16
  30. package/dist-server/engine/live-feed-registry.js.map +1 -1
  31. package/dist-server/engine/load-meter.d.ts +1 -1
  32. package/dist-server/engine/load-meter.js +12 -3
  33. package/dist-server/engine/load-meter.js.map +1 -1
  34. package/dist-server/engine/log.d.ts +18 -0
  35. package/dist-server/engine/log.js +80 -0
  36. package/dist-server/engine/log.js.map +1 -0
  37. package/dist-server/engine/loop-lag.d.ts +54 -0
  38. package/dist-server/engine/loop-lag.js +87 -0
  39. package/dist-server/engine/loop-lag.js.map +1 -0
  40. package/dist-server/engine/model-gap.d.ts +108 -0
  41. package/dist-server/engine/model-gap.js +95 -0
  42. package/dist-server/engine/model-gap.js.map +1 -0
  43. package/dist-server/engine/restart-policy.d.ts +3 -3
  44. package/dist-server/engine/restart-policy.js +4 -4
  45. package/dist-server/engine/restart-policy.js.map +1 -1
  46. package/dist-server/engine/runtime-key.js +1 -1
  47. package/dist-server/engine/runtime-key.js.map +1 -1
  48. package/dist-server/engine/stage-path.d.ts +83 -0
  49. package/dist-server/engine/stage-path.js +118 -0
  50. package/dist-server/engine/stage-path.js.map +1 -0
  51. package/dist-server/engine/twin-engine.d.ts +352 -16
  52. package/dist-server/engine/twin-engine.js +1037 -166
  53. package/dist-server/engine/twin-engine.js.map +1 -1
  54. package/dist-server/index.js +34 -2
  55. package/dist-server/index.js.map +1 -1
  56. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.d.ts +5 -0
  57. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +58 -0
  58. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -0
  59. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.d.ts +5 -0
  60. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +55 -0
  61. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -0
  62. package/dist-server/migrations/index.js +7 -1
  63. package/dist-server/migrations/index.js.map +1 -1
  64. package/dist-server/service/index.d.ts +5 -2
  65. package/dist-server/service/index.js +18 -7
  66. package/dist-server/service/index.js.map +1 -1
  67. package/dist-server/service/reference/discovery-result.d.ts +1 -1
  68. package/dist-server/service/reference/discovery-result.js +1 -1
  69. package/dist-server/service/reference/discovery-result.js.map +1 -1
  70. package/dist-server/service/reference/index.d.ts +4 -1
  71. package/dist-server/service/reference/index.js +6 -1
  72. package/dist-server/service/reference/index.js.map +1 -1
  73. package/dist-server/service/reference/reference-adapter.d.ts +184 -3
  74. package/dist-server/service/reference/reference-adapter.js +28 -4
  75. package/dist-server/service/reference/reference-adapter.js.map +1 -1
  76. package/dist-server/service/reference/reference-assessment.d.ts +68 -0
  77. package/dist-server/service/reference/reference-assessment.js +136 -0
  78. package/dist-server/service/reference/reference-assessment.js.map +1 -0
  79. package/dist-server/service/reference/reference-live.d.ts +12 -1
  80. package/dist-server/service/reference/reference-live.js +116 -11
  81. package/dist-server/service/reference/reference-live.js.map +1 -1
  82. package/dist-server/service/reference/reference-master.d.ts +47 -1
  83. package/dist-server/service/reference/reference-master.js +34 -4
  84. package/dist-server/service/reference/reference-master.js.map +1 -1
  85. package/dist-server/service/reference/reference-probe.d.ts +92 -0
  86. package/dist-server/service/reference/reference-probe.js +186 -0
  87. package/dist-server/service/reference/reference-probe.js.map +1 -0
  88. package/dist-server/service/reference/reference-progress-subscription.d.ts +17 -0
  89. package/dist-server/service/reference/reference-progress-subscription.js +94 -0
  90. package/dist-server/service/reference/reference-progress-subscription.js.map +1 -0
  91. package/dist-server/service/reference/reference-progress.d.ts +38 -0
  92. package/dist-server/service/reference/reference-progress.js +71 -0
  93. package/dist-server/service/reference/reference-progress.js.map +1 -0
  94. package/dist-server/service/reference/reference-resolver.js +210 -43
  95. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  96. package/dist-server/service/reference/twin-reference.d.ts +32 -0
  97. package/dist-server/service/reference/twin-reference.js +10 -0
  98. package/dist-server/service/reference/twin-reference.js.map +1 -1
  99. package/dist-server/service/twin-control/twin-control-mutation.js +4 -3
  100. package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
  101. package/dist-server/service/twin-event/journal-count.d.ts +21 -0
  102. package/dist-server/service/twin-event/journal-count.js +26 -0
  103. package/dist-server/service/twin-event/journal-count.js.map +1 -0
  104. package/dist-server/service/twin-event/twin-event-keys.d.ts +9 -0
  105. package/dist-server/service/twin-event/twin-event-keys.js +15 -18
  106. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  107. package/dist-server/service/twin-event/twin-event-type.d.ts +3 -1
  108. package/dist-server/service/twin-event/twin-event-type.js +18 -1
  109. package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
  110. package/dist-server/service/twin-event/twin-event.d.ts +1 -0
  111. package/dist-server/service/twin-event/twin-event.js +9 -1
  112. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  113. package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
  114. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
  115. package/dist-server/service/twin-ingest-window/index.d.ts +5 -0
  116. package/dist-server/service/twin-ingest-window/index.js +10 -0
  117. package/dist-server/service/twin-ingest-window/index.js.map +1 -0
  118. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +12 -0
  119. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +123 -0
  120. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -0
  121. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.d.ts +1 -0
  122. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +51 -0
  123. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -0
  124. package/dist-server/service/twin-ingest-window/twin-ingest-window.d.ts +16 -0
  125. package/dist-server/service/twin-ingest-window/twin-ingest-window.js +108 -0
  126. package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +1 -0
  127. package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
  128. package/dist-server/service/twin-journal/twin-journal-query.js +58 -5
  129. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  130. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +14 -0
  131. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +72 -2
  132. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
  133. package/dist-server/service/twin-metrics/twin-metrics-query.d.ts +1 -0
  134. package/dist-server/service/twin-metrics/twin-metrics-query.js +78 -3
  135. package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
  136. package/dist-server/service/twin-model/axis-journal-evidence.d.ts +2 -0
  137. package/dist-server/service/twin-model/axis-journal-evidence.js +89 -0
  138. package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -0
  139. package/dist-server/service/twin-model/epcis-coverage.d.ts +1 -1
  140. package/dist-server/service/twin-model/epcis-coverage.js +19 -7
  141. package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
  142. package/dist-server/service/twin-model/iec61850-coverage.d.ts +1 -1
  143. package/dist-server/service/twin-model/iec61850-coverage.js +18 -7
  144. package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
  145. package/dist-server/service/twin-model/isa95-coverage.d.ts +14 -0
  146. package/dist-server/service/twin-model/isa95-coverage.js +23 -9
  147. package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
  148. package/dist-server/service/twin-model/item-ref.d.ts +24 -0
  149. package/dist-server/service/twin-model/item-ref.js +88 -0
  150. package/dist-server/service/twin-model/item-ref.js.map +1 -0
  151. package/dist-server/service/twin-model/name-index.d.ts +36 -0
  152. package/dist-server/service/twin-model/name-index.js +116 -0
  153. package/dist-server/service/twin-model/name-index.js.map +1 -0
  154. package/dist-server/service/twin-model/project-structure.js +1 -1
  155. package/dist-server/service/twin-model/project-structure.js.map +1 -1
  156. package/dist-server/service/twin-model/status-tally.d.ts +9 -0
  157. package/dist-server/service/twin-model/status-tally.js +37 -0
  158. package/dist-server/service/twin-model/status-tally.js.map +1 -0
  159. package/dist-server/service/twin-model/twin-lineage-query.js +40 -12
  160. package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
  161. package/dist-server/service/twin-model/twin-model-item-query.js +38 -39
  162. package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
  163. package/dist-server/service/twin-model/twin-model-query.js +156 -4
  164. package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
  165. package/dist-server/service/twin-model/twin-model-tree-query.js +7 -0
  166. package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
  167. package/dist-server/service/twin-readiness/index.d.ts +2 -0
  168. package/dist-server/service/twin-readiness/index.js +6 -0
  169. package/dist-server/service/twin-readiness/index.js.map +1 -0
  170. package/dist-server/service/twin-readiness/twin-readiness-query.d.ts +3 -0
  171. package/dist-server/service/twin-readiness/twin-readiness-query.js +103 -0
  172. package/dist-server/service/twin-readiness/twin-readiness-query.js.map +1 -0
  173. package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
  174. package/dist-server/service/twin-space/twin-space-resolver.js +5 -4
  175. package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
  176. package/dist-shared/entity-delta.d.ts +23 -3
  177. package/dist-shared/entity-delta.js +12 -8
  178. package/dist-shared/entity-delta.js.map +1 -1
  179. package/dist-shared/kpi-broadcast.js +1 -1
  180. package/dist-shared/kpi-broadcast.js.map +1 -1
  181. package/dist-shared/touched-items.d.ts +7 -0
  182. package/dist-shared/touched-items.js +80 -0
  183. package/dist-shared/touched-items.js.map +1 -0
  184. package/package.json +7 -7
  185. package/server/engine/canonical-ingest.ts +92 -7
  186. package/server/engine/command-routing.ts +1 -1
  187. package/server/engine/index.ts +4 -0
  188. package/server/engine/ingest-health.ts +704 -0
  189. package/server/engine/integration-coverage.ts +147 -0
  190. package/server/engine/integration-probes.ts +144 -0
  191. package/server/engine/integration-runner.ts +95 -0
  192. package/server/engine/integration-target-profile.ts +103 -0
  193. package/server/engine/kpi-fold.ts +72 -4
  194. package/server/engine/kpi-query.ts +129 -15
  195. package/server/engine/live-feed-registry.ts +2 -1
  196. package/server/engine/load-meter.ts +12 -3
  197. package/server/engine/log.ts +72 -0
  198. package/server/engine/loop-lag.ts +120 -0
  199. package/server/engine/model-gap.ts +168 -0
  200. package/server/engine/restart-policy.ts +4 -4
  201. package/server/engine/runtime-key.ts +1 -1
  202. package/server/engine/stage-path.ts +172 -0
  203. package/server/engine/twin-engine.ts +1135 -162
  204. package/server/index.ts +35 -2
  205. package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +54 -0
  206. package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +53 -0
  207. package/server/migrations/index.ts +7 -1
  208. package/server/service/index.ts +11 -0
  209. package/server/service/reference/discovery-result.ts +1 -1
  210. package/server/service/reference/index.ts +6 -1
  211. package/server/service/reference/reference-adapter.ts +197 -5
  212. package/server/service/reference/reference-assessment.ts +215 -0
  213. package/server/service/reference/reference-live.ts +123 -11
  214. package/server/service/reference/reference-master.ts +64 -4
  215. package/server/service/reference/reference-probe.ts +264 -0
  216. package/server/service/reference/reference-progress-subscription.ts +73 -0
  217. package/server/service/reference/reference-progress.ts +95 -0
  218. package/server/service/reference/reference-resolver.ts +200 -12
  219. package/server/service/reference/twin-reference.ts +39 -1
  220. package/server/service/twin-control/twin-control-mutation.ts +4 -3
  221. package/server/service/twin-event/journal-count.ts +53 -0
  222. package/server/service/twin-event/twin-event-keys.ts +16 -1
  223. package/server/service/twin-event/twin-event-type.ts +26 -2
  224. package/server/service/twin-event/twin-event.ts +7 -0
  225. package/server/service/twin-forecast/twin-forecast-query.ts +2 -1
  226. package/server/service/twin-ingest-window/index.ts +7 -0
  227. package/server/service/twin-ingest-window/twin-ingest-window-query.ts +125 -0
  228. package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +57 -0
  229. package/server/service/twin-ingest-window/twin-ingest-window.ts +113 -0
  230. package/server/service/twin-instance/twin-instance.ts +1 -1
  231. package/server/service/twin-journal/twin-journal-query.ts +59 -5
  232. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +77 -3
  233. package/server/service/twin-metrics/twin-metrics-query.ts +81 -3
  234. package/server/service/twin-model/axis-journal-evidence.ts +57 -0
  235. package/server/service/twin-model/epcis-coverage.ts +2 -8
  236. package/server/service/twin-model/iec61850-coverage.ts +2 -8
  237. package/server/service/twin-model/isa95-coverage.ts +22 -9
  238. package/server/service/twin-model/item-ref.ts +80 -0
  239. package/server/service/twin-model/name-index.ts +94 -0
  240. package/server/service/twin-model/project-structure.ts +1 -1
  241. package/server/service/twin-model/status-tally.ts +37 -0
  242. package/server/service/twin-model/twin-lineage-query.ts +38 -9
  243. package/server/service/twin-model/twin-model-item-query.ts +26 -27
  244. package/server/service/twin-model/twin-model-query.ts +155 -4
  245. package/server/service/twin-model/twin-model-tree-query.ts +7 -0
  246. package/server/service/twin-readiness/index.ts +3 -0
  247. package/server/service/twin-readiness/twin-readiness-query.ts +96 -0
  248. package/server/service/twin-space/twin-space-resolver.ts +5 -4
  249. package/shared/entity-delta.ts +31 -7
  250. package/shared/kpi-broadcast.ts +1 -1
  251. package/shared/touched-items.ts +73 -0
  252. package/test/axis-journal-evidence.test.ts +71 -0
  253. package/test/axis-read.test.ts +101 -1
  254. package/test/boot-resume.test.ts +92 -26
  255. package/test/broadcast-cost-baseline.test.ts +200 -0
  256. package/test/broadcast-period.test.ts +58 -0
  257. package/test/canonical-ingest-vocabularies.test.ts +36 -1
  258. package/test/canonical-quantity-door.test.ts +61 -0
  259. package/test/command-routing.test.ts +1 -1
  260. package/test/declared-location-types.test.ts +89 -0
  261. package/test/discovery-result.test.ts +1 -1
  262. package/test/duration-estimators.test.ts +1 -1
  263. package/test/entity-delta.test.ts +2 -2
  264. package/test/ingest-bench.test.ts +3 -3
  265. package/test/ingest-health-engine.test.ts +248 -0
  266. package/test/ingest-health-wiring.test.ts +119 -0
  267. package/test/ingest-health.test.ts +306 -0
  268. package/test/ingest-history.test.ts +247 -0
  269. package/test/integration-probes.test.ts +103 -0
  270. package/test/integration-runner.test.ts +95 -0
  271. package/test/item-ref.test.ts +78 -0
  272. package/test/journal-read-discipline.test.ts +177 -0
  273. package/test/journal-retention.test.ts +133 -0
  274. package/test/journal-sort-axis.test.ts +142 -0
  275. package/test/journal-write-door.test.ts +110 -0
  276. package/test/journal-write-trend.test.ts +115 -0
  277. package/test/kernel-kind-guard.test.ts +4 -4
  278. package/test/kpi-fold.test.ts +90 -3
  279. package/test/kpi-query-bench.test.ts +2 -2
  280. package/test/lineage-survives-restart.test.ts +17 -1
  281. package/test/live-cursor-wiring.test.ts +87 -0
  282. package/test/live-feed-registry.test.ts +9 -1
  283. package/test/live-kernel-facts.test.ts +7 -7
  284. package/test/live-mirror-parity.test.ts +6 -0
  285. package/test/load-meter.test.ts +29 -15
  286. package/test/local-declarations.test.ts +1 -1
  287. package/test/log-stamp.test.ts +59 -0
  288. package/test/loop-lag.test.ts +82 -0
  289. package/test/model-gap.test.ts +153 -0
  290. package/test/oee-accumulator.test.ts +4 -0
  291. package/test/operational-vocabulary.test.ts +4 -4
  292. package/test/read-failure-visible.test.ts +145 -0
  293. package/test/reference-grounding.test.ts +70 -0
  294. package/test/resolve-ts-siblings.mjs +52 -0
  295. package/test/restart-policy.test.ts +7 -7
  296. package/test/revision-axis.test.ts +93 -0
  297. package/test/runtime-key.test.ts +2 -2
  298. package/test/scale-twin-bench.test.ts +2 -2
  299. package/test/spec-coverage.test.ts +1 -1
  300. package/test/stage-path.test.ts +95 -0
  301. package/test/standard-coverage.test.ts +15 -3
  302. package/test/status-tally.test.ts +55 -0
  303. package/test/structure-revision-db.test.ts +4 -0
  304. package/test/tenant-registry-db.test.ts +1 -1
  305. package/test/time-range.test.ts +152 -0
  306. package/test/touched-items.test.ts +61 -0
  307. package/test/twin-event-keys.test.ts +10 -2
  308. package/test/twin-model-item-db.test.ts +2 -0
  309. package/test/warm-start-seam.test.ts +4 -0
  310. package/test/yield-loop.test.ts +57 -2
  311. package/tsconfig.shared.tsbuildinfo +1 -1
  312. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolvers = void 0;
4
+ const twin_readiness_query_js_1 = require("./twin-readiness-query.js");
5
+ exports.resolvers = [twin_readiness_query_js_1.TwinReadinessQuery];
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-readiness/index.ts"],"names":[],"mappings":";;;AAAA,uEAA8D;AAEjD,QAAA,SAAS,GAAG,CAAC,4CAAkB,CAAC,CAAA","sourcesContent":["import { TwinReadinessQuery } from './twin-readiness-query.js'\n\nexport const resolvers = [TwinReadinessQuery]\n"]}
@@ -0,0 +1,3 @@
1
+ export declare class TwinReadinessQuery {
2
+ twinAdoptionPath(instanceId: string, context: ResolverContext): Promise<any>;
3
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TwinReadinessQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const index_js_1 = require("../../engine/index.js");
8
+ const integration_runner_js_1 = require("../../engine/integration-runner.js");
9
+ const spec_coverage_js_1 = require("../../engine/spec-coverage.js");
10
+ const reference_adapter_js_1 = require("../reference/reference-adapter.js");
11
+ const twin_event_js_1 = require("../twin-event/twin-event.js");
12
+ const journal_count_js_1 = require("../twin-event/journal-count.js");
13
+ const twin_instance_js_1 = require("../twin-instance/twin-instance.js");
14
+ const twin_reference_js_1 = require("../reference/twin-reference.js");
15
+ /*
16
+ * ๋„์ž… ๋‹จ๊ณ„ โ€” **ใ€Œ์ด ํŠธ์œˆ์€ ์–ด๋””๊นŒ์ง€ ์ฆ๋ช…๋๋‚˜ใ€.**
17
+ *
18
+ * `twinIngestHealth` ์™€ ๋ฌป๋Š” ๊ฒƒ์ด ๋‹ค๋ฅด๋‹ค: ๊ทธ์ชฝ์€ ใ€Œ์ง€๊ธˆ ํ˜„์žฅ๊ณผ ๋งž์ถฐ์ง€๊ณ  ์žˆ๋‚˜ใ€(ํ”ผ๋“œ์˜ ๊ฑด๊ฐ•)์ด๊ณ ,
19
+ * ์—ฌ๊ธฐ๋Š” ใ€Œ๊ตฌ์กฐยท๋ผ์ด๋ธŒยท์˜ˆ์ธกยทํ๋ฃจํ”„ ์ค‘ ์–ด๋””๊นŒ์ง€ **์ฆ๊ฑฐ๋กœ** ์„ฐ๋‚˜ใ€๋‹ค. ์ฒดํฌ๋ฆฌ์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ํŒ์ •์ด๋ฏ€๋กœ
20
+ * ์‚ฌ๋žŒ์ด ์ฒดํฌํ•ด์„œ ์ดˆ๋ก์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.
21
+ *
22
+ * **์ ‘์† ํ”„๋กœ๋ธŒ๋Š” ์—ฌ๊ธฐ์„œ ๋Œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.** ์กฐํšŒ๋งˆ๋‹ค ๊ณ ๊ฐ ์‹œ์Šคํ…œ์„ ๋‘๋“œ๋ฆฌ๋ฉด ํ™”๋ฉด์„ ์—ด ๋•Œ๋งˆ๋‹ค ๋‚จ์˜
23
+ * ์šด์˜๊ณ„์— ๋ถ€ํ•˜๊ฐ€ ๊ฐ„๋‹ค. ๊ทธ๋ž˜์„œ `connectOk` ๋Š” `null`(์•ˆ ๋Œ๋ ธ๋‹ค)์ด๊ณ , ๊ณ„ํš์˜ ์ฒซ ์นธ์ด ์ ‘์† ํ™•์ธ์ด ๋œ๋‹ค.
24
+ */
25
+ let TwinReadinessQuery = class TwinReadinessQuery {
26
+ async twinAdoptionPath(instanceId, context) {
27
+ const domainId = context.state.domain.id;
28
+ if (!index_js_1.TwinEngine.owns(domainId, instanceId) && !(await index_js_1.TwinEngine.ownsRegistered(domainId, instanceId)))
29
+ return null;
30
+ const inst = await (0, shell_1.getRepository)(twin_instance_js_1.TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } });
31
+ if (!inst)
32
+ return null;
33
+ const ref = await (0, shell_1.getRepository)(twin_reference_js_1.TwinReference)
34
+ .findOne({ where: { domain: { id: domainId }, source: instanceId } })
35
+ .catch(() => null);
36
+ const mode = index_js_1.TwinEngine.modeOf(domainId, instanceId);
37
+ const snapshot = index_js_1.TwinEngine.owns(domainId, instanceId) ? index_js_1.TwinEngine.snapshot(domainId, instanceId) : undefined;
38
+ const events = (0, shell_1.getRepository)(twin_event_js_1.TwinEvent);
39
+ /*
40
+ * ์ €๋„์—์„œ ์„ผ๋‹ค โ€” **์žฌ์‹œ์ž‘์—๋„ ๋‚จ๋Š” ์ž๋ฆฌ**๋‹ค. ์ธ๋ฉ”๋ชจ๋ฆฌ ๊ณ„๊ธฐ๋กœ ์„ธ๋ฉด ์žฌ๊ธฐ๋™๋งˆ๋‹ค 0 ์ด ๋˜๊ณ , ๊ทธ 0 ์ด
41
+ * ใ€Œ์„ธ์—ˆ๋Š”๋ฐ ๋ฐ˜์ถœ์ด ์—†์—ˆ๋‹คใ€๋กœ ์ฝํ˜€ ๋ผ์ด๋ธŒ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ง“์œผ๋กœ ๋ง‰๋Š”๋‹ค.
42
+ *
43
+ * `action` ์Šน๊ฒฉ ์ „์— ๊ธฐ๋ก๋œ ํ–‰์€ ์„ธ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ˜์ถœ์ด **ํ•œ ๊ฑด๋„ ์—†๊ณ ** ์Šน๊ฒฉ ์ดํ›„ ์œ ์ž…๋„
44
+ * ์—†์œผ๋ฉด `null`(๋ชจ๋ฅธ๋‹ค)๋กœ ๋‚ธ๋‹ค โ€” ์˜› ์ €๋„์„ ใ€Œ๋ฐ˜์ถœ 0๊ฑดใ€์œผ๋กœ ๋‹จ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
45
+ */
46
+ /*
47
+ * **์ƒํ•œ๊นŒ์ง€๋งŒ ์„ผ๋‹ค** (2026-08-22 ์‹ค์ธก). ์˜ˆ์ „์—๋Š” ๋„ท์„ ์ „๋ถ€ ์„ธ์—ˆ๊ณ , ์ €๋„ 358๋งŒ ํ–‰์ธ ํŠธ์œˆ์—์„œ ํ•œ ๋ฒˆ์ด
48
+ * 5.32์ดˆ๋ผ ์ด ํ™”๋ฉด ํ•˜๋‚˜๊ฐ€ 20์ดˆ๋ฅผ ์ผ๋‹ค. ํŒ์ •์— ์“ฐ์ด๋Š” ๊ฒƒ์€ ๋ฌธํ„ฑ(โ‰ฅ1)์ด๋ฏ€๋กœ ์ƒํ•œ๊นŒ์ง€์˜ ์ˆ˜๋กœ ์ถฉ๋ถ„ํ•˜๊ณ ,
49
+ * ์Šน๊ฒฉ ์—ฌ๋ถ€๋Š” **ํ•œ ๊ฑด๋งŒ ์ฐพ์œผ๋ฉด** ๋‹ต์ด ๋‚œ๋‹ค(์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค).
50
+ */
51
+ const scope = { domain: { id: domainId }, instanceId };
52
+ const journal = await (0, journal_count_js_1.countUpTo)(events, scope);
53
+ const removalCount = await (0, journal_count_js_1.countUpTo)(events, { ...scope, action: 'DELETE' });
54
+ const journalTotal = journal.count;
55
+ const removals = removalCount.count;
56
+ const anyPromoted = removals > 0 ||
57
+ (await (0, journal_count_js_1.anyJournalRow)(events, { ...scope, action: 'OBSERVE' })) ||
58
+ (await (0, journal_count_js_1.anyJournalRow)(events, { ...scope, action: 'ADD' }));
59
+ const modelLocations = Array.isArray(inst.model?.locations) ? inst.model.locations.length : null;
60
+ const facts = {
61
+ subject: mode === 'live' ? 'live' : mode === 'sim' ? 'sim' : 'unknown',
62
+ fromReference: !!ref,
63
+ adapterCapabilities: ref?.adapterType ? (0, reference_adapter_js_1.capabilitiesOf)((0, reference_adapter_js_1.getAdapter)(ref.adapterType)) : [],
64
+ connectOk: null, // ์กฐํšŒ์—์„œ ๋‚จ์˜ ์šด์˜๊ณ„๋ฅผ ๋‘๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค
65
+ /* ์ด ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ํŠธ์œˆ์„ ์„ธ์šด ์‚ฌ์ดํŠธ ์ˆ˜ โ€” ๋ฐœ๊ฒฌ์˜ ๊ฒฐ๊ณผ๋‹ค(๋ฐœ๊ฒฌ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ๋Œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค). */
66
+ siteCount: ref ? (ref.scopeSpec?.produced?.length ?? null) : null,
67
+ locationCount: snapshot?.locations?.length ?? modelLocations,
68
+ itemCount: snapshot?.items?.length ?? null,
69
+ lastWarningCount: ref?.lastWarningCount ?? null,
70
+ journalTotal,
71
+ /* ์Šน๊ฒฉ ์ดํ›„ ์œ ์ž…์ด ํ•˜๋‚˜๋„ ์—†์œผ๋ฉด ์„ธ์ง€ ๋ชปํ•œ ๊ฒƒ์ด๋‹ค โ€” 0 ์œผ๋กœ ๋‹จ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. */
72
+ removalsJournaled: anyPromoted ? removals : null,
73
+ specCoverage: (() => {
74
+ const c = snapshot ? (0, spec_coverage_js_1.readSpecCoverage)(snapshot) : null;
75
+ if (!c?.operations?.length)
76
+ return null;
77
+ const total = c.operations.length;
78
+ const declared = c.operations.filter((o) => o.duration === 'declared' || o.duration === 'measured').length;
79
+ return { declared, total };
80
+ })(),
81
+ forecastRan: null, // ์˜ˆ์ธก ์‹คํ–‰ ์ด๋ ฅ์„ ๋‚จ๊ธฐ๋Š” ์ž๋ฆฌ๊ฐ€ ์•„์ง ์—†๋‹ค โ€” ๋ชจ๋ฅธ๋‹ค๊ณ  ๋งํ•œ๋‹ค
82
+ feed: 'unknown'
83
+ };
84
+ const assessment = (0, integration_runner_js_1.assessSuite)(facts);
85
+ return { instanceId, ...assessment, spec: integration_runner_js_1.SUITE_SPEC, facts };
86
+ }
87
+ };
88
+ exports.TwinReadinessQuery = TwinReadinessQuery;
89
+ tslib_1.__decorate([
90
+ (0, type_graphql_1.Query)(returns => shell_1.ScalarObject, {
91
+ nullable: true,
92
+ description: 'Which adoption stage this twin has actually reached, judged from evidence rather than a checklist: structure, live, forecast, closed-loop. Each stage reports what blocks it and which signals could not be measured at all โ€” an unmeasured signal never counts as achieved, so a half-run suite cannot claim green. Probes that do not apply to this twin (live probes on a simulation, mapping-warning probes on a template-built twin) come back as notApplicable with a reason, which is neither a pass nor a gap. `forbiddenClaims` lists the claims that must not be made yet (realtime, prediction, automatic control). The connection probe is not run here because a read query should not hit the source system on every page load, so it appears in `planned` as the next step to take. Null if the instance is not in the current domain.'
93
+ }),
94
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('instanceId')),
95
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
96
+ tslib_1.__metadata("design:type", Function),
97
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
98
+ tslib_1.__metadata("design:returntype", Promise)
99
+ ], TwinReadinessQuery.prototype, "twinAdoptionPath", null);
100
+ exports.TwinReadinessQuery = TwinReadinessQuery = tslib_1.__decorate([
101
+ (0, type_graphql_1.Resolver)()
102
+ ], TwinReadinessQuery);
103
+ //# sourceMappingURL=twin-readiness-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twin-readiness-query.js","sourceRoot":"","sources":["../../../server/service/twin-readiness/twin-readiness-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Query, Resolver } from 'type-graphql'\n\nimport { getRepository, ScalarObject } from '@things-factory/shell'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { assessSuite, SUITE_SPEC, type SuiteFacts } from '../../engine/integration-runner.js'\nimport { readSpecCoverage } from '../../engine/spec-coverage.js'\nimport { capabilitiesOf, getAdapter } from '../reference/reference-adapter.js'\nimport { TwinEvent } from '../twin-event/twin-event.js'\nimport { anyJournalRow, countUpTo } from '../twin-event/journal-count.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinReference } from '../reference/twin-reference.js'\n\n/*\n * ๋„์ž… ๋‹จ๊ณ„ โ€” **ใ€Œ์ด ํŠธ์œˆ์€ ์–ด๋””๊นŒ์ง€ ์ฆ๋ช…๋๋‚˜ใ€.**\n *\n * `twinIngestHealth` ์™€ ๋ฌป๋Š” ๊ฒƒ์ด ๋‹ค๋ฅด๋‹ค: ๊ทธ์ชฝ์€ ใ€Œ์ง€๊ธˆ ํ˜„์žฅ๊ณผ ๋งž์ถฐ์ง€๊ณ  ์žˆ๋‚˜ใ€(ํ”ผ๋“œ์˜ ๊ฑด๊ฐ•)์ด๊ณ ,\n * ์—ฌ๊ธฐ๋Š” ใ€Œ๊ตฌ์กฐยท๋ผ์ด๋ธŒยท์˜ˆ์ธกยทํ๋ฃจํ”„ ์ค‘ ์–ด๋””๊นŒ์ง€ **์ฆ๊ฑฐ๋กœ** ์„ฐ๋‚˜ใ€๋‹ค. ์ฒดํฌ๋ฆฌ์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ํŒ์ •์ด๋ฏ€๋กœ\n * ์‚ฌ๋žŒ์ด ์ฒดํฌํ•ด์„œ ์ดˆ๋ก์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค.\n *\n * **์ ‘์† ํ”„๋กœ๋ธŒ๋Š” ์—ฌ๊ธฐ์„œ ๋Œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.** ์กฐํšŒ๋งˆ๋‹ค ๊ณ ๊ฐ ์‹œ์Šคํ…œ์„ ๋‘๋“œ๋ฆฌ๋ฉด ํ™”๋ฉด์„ ์—ด ๋•Œ๋งˆ๋‹ค ๋‚จ์˜\n * ์šด์˜๊ณ„์— ๋ถ€ํ•˜๊ฐ€ ๊ฐ„๋‹ค. ๊ทธ๋ž˜์„œ `connectOk` ๋Š” `null`(์•ˆ ๋Œ๋ ธ๋‹ค)์ด๊ณ , ๊ณ„ํš์˜ ์ฒซ ์นธ์ด ์ ‘์† ํ™•์ธ์ด ๋œ๋‹ค.\n */\n@Resolver()\nexport class TwinReadinessQuery {\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'Which adoption stage this twin has actually reached, judged from evidence rather than a checklist: structure, live, forecast, closed-loop. Each stage reports what blocks it and which signals could not be measured at all โ€” an unmeasured signal never counts as achieved, so a half-run suite cannot claim green. Probes that do not apply to this twin (live probes on a simulation, mapping-warning probes on a template-built twin) come back as notApplicable with a reason, which is neither a pass nor a gap. `forbiddenClaims` lists the claims that must not be made yet (realtime, prediction, automatic control). The connection probe is not run here because a read query should not hit the source system on every page load, so it appears in `planned` as the next step to take. Null if the instance is not in the current domain.'\n })\n async twinAdoptionPath(@Arg('instanceId') instanceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n if (!TwinEngine.owns(domainId, instanceId) && !(await TwinEngine.ownsRegistered(domainId, instanceId))) return null\n\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return null\n const ref = await getRepository(TwinReference)\n .findOne({ where: { domain: { id: domainId }, source: instanceId } })\n .catch(() => null)\n\n const mode = TwinEngine.modeOf(domainId, instanceId)\n const snapshot = TwinEngine.owns(domainId, instanceId) ? TwinEngine.snapshot(domainId, instanceId) : undefined\n const events = getRepository(TwinEvent)\n\n /*\n * ์ €๋„์—์„œ ์„ผ๋‹ค โ€” **์žฌ์‹œ์ž‘์—๋„ ๋‚จ๋Š” ์ž๋ฆฌ**๋‹ค. ์ธ๋ฉ”๋ชจ๋ฆฌ ๊ณ„๊ธฐ๋กœ ์„ธ๋ฉด ์žฌ๊ธฐ๋™๋งˆ๋‹ค 0 ์ด ๋˜๊ณ , ๊ทธ 0 ์ด\n * ใ€Œ์„ธ์—ˆ๋Š”๋ฐ ๋ฐ˜์ถœ์ด ์—†์—ˆ๋‹คใ€๋กœ ์ฝํ˜€ ๋ผ์ด๋ธŒ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ง“์œผ๋กœ ๋ง‰๋Š”๋‹ค.\n *\n * `action` ์Šน๊ฒฉ ์ „์— ๊ธฐ๋ก๋œ ํ–‰์€ ์„ธ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ˜์ถœ์ด **ํ•œ ๊ฑด๋„ ์—†๊ณ ** ์Šน๊ฒฉ ์ดํ›„ ์œ ์ž…๋„\n * ์—†์œผ๋ฉด `null`(๋ชจ๋ฅธ๋‹ค)๋กœ ๋‚ธ๋‹ค โ€” ์˜› ์ €๋„์„ ใ€Œ๋ฐ˜์ถœ 0๊ฑดใ€์œผ๋กœ ๋‹จ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.\n */\n /*\n * **์ƒํ•œ๊นŒ์ง€๋งŒ ์„ผ๋‹ค** (2026-08-22 ์‹ค์ธก). ์˜ˆ์ „์—๋Š” ๋„ท์„ ์ „๋ถ€ ์„ธ์—ˆ๊ณ , ์ €๋„ 358๋งŒ ํ–‰์ธ ํŠธ์œˆ์—์„œ ํ•œ ๋ฒˆ์ด\n * 5.32์ดˆ๋ผ ์ด ํ™”๋ฉด ํ•˜๋‚˜๊ฐ€ 20์ดˆ๋ฅผ ์ผ๋‹ค. ํŒ์ •์— ์“ฐ์ด๋Š” ๊ฒƒ์€ ๋ฌธํ„ฑ(โ‰ฅ1)์ด๋ฏ€๋กœ ์ƒํ•œ๊นŒ์ง€์˜ ์ˆ˜๋กœ ์ถฉ๋ถ„ํ•˜๊ณ ,\n * ์Šน๊ฒฉ ์—ฌ๋ถ€๋Š” **ํ•œ ๊ฑด๋งŒ ์ฐพ์œผ๋ฉด** ๋‹ต์ด ๋‚œ๋‹ค(์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค).\n */\n const scope = { domain: { id: domainId }, instanceId }\n const journal = await countUpTo(events, scope)\n const removalCount = await countUpTo(events, { ...scope, action: 'DELETE' })\n const journalTotal = journal.count\n const removals = removalCount.count\n const anyPromoted =\n removals > 0 ||\n (await anyJournalRow(events, { ...scope, action: 'OBSERVE' })) ||\n (await anyJournalRow(events, { ...scope, action: 'ADD' }))\n\n const modelLocations = Array.isArray((inst.model as any)?.locations) ? (inst.model as any).locations.length : null\n\n const facts: SuiteFacts = {\n subject: mode === 'live' ? 'live' : mode === 'sim' ? 'sim' : 'unknown',\n fromReference: !!ref,\n adapterCapabilities: ref?.adapterType ? capabilitiesOf(getAdapter(ref.adapterType)) : [],\n connectOk: null, // ์กฐํšŒ์—์„œ ๋‚จ์˜ ์šด์˜๊ณ„๋ฅผ ๋‘๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค\n /* ์ด ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ํŠธ์œˆ์„ ์„ธ์šด ์‚ฌ์ดํŠธ ์ˆ˜ โ€” ๋ฐœ๊ฒฌ์˜ ๊ฒฐ๊ณผ๋‹ค(๋ฐœ๊ฒฌ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ๋Œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค). */\n siteCount: ref ? ((ref.scopeSpec as any)?.produced?.length ?? null) : null,\n locationCount: snapshot?.locations?.length ?? modelLocations,\n itemCount: snapshot?.items?.length ?? null,\n lastWarningCount: ref?.lastWarningCount ?? null,\n journalTotal,\n /* ์Šน๊ฒฉ ์ดํ›„ ์œ ์ž…์ด ํ•˜๋‚˜๋„ ์—†์œผ๋ฉด ์„ธ์ง€ ๋ชปํ•œ ๊ฒƒ์ด๋‹ค โ€” 0 ์œผ๋กœ ๋‹จ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. */\n removalsJournaled: anyPromoted ? removals : null,\n specCoverage: (() => {\n const c: any = snapshot ? readSpecCoverage(snapshot) : null\n if (!c?.operations?.length) return null\n const total = c.operations.length\n const declared = c.operations.filter((o: any) => o.duration === 'declared' || o.duration === 'measured').length\n return { declared, total }\n })(),\n forecastRan: null, // ์˜ˆ์ธก ์‹คํ–‰ ์ด๋ ฅ์„ ๋‚จ๊ธฐ๋Š” ์ž๋ฆฌ๊ฐ€ ์•„์ง ์—†๋‹ค โ€” ๋ชจ๋ฅธ๋‹ค๊ณ  ๋งํ•œ๋‹ค\n feed: 'unknown'\n }\n\n const assessment = assessSuite(facts)\n return { instanceId, ...assessment, spec: SUITE_SPEC, facts }\n }\n}\n"]}
@@ -17,9 +17,9 @@ export declare class TwinSpaceResolver {
17
17
  * ๊ณต๊ฐ„ ์‚ญ์ œ โ€” **์ด ๊ณต๊ฐ„์˜ ํŠธ์œˆ์ด ์žˆ์œผ๋ฉด ๊ฑฐ์ ˆํ•œ๋‹ค.** ๊ทธ๋ž˜์„œ ํŠธ์œˆ์ด ํ˜„์žฅ์„ ์žƒ๋Š” ์ผ์€ ์—†๋‹ค.
18
18
  *
19
19
  * โ”€โ”€ ์™œ ๋ชจ์–‘์„ ๋ฐ”๊ฟจ๋‚˜ (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
20
- * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋˜์กŒ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:
20
+ * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋ƒˆ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:
21
21
  * โ‘  ์„œ๋ฒ„๊ฐ€ ํ™”๋ฉด์˜ ๋ง์„ ์ •ํ–ˆ๋‹ค โ€” ์ผ๋ณธ์–ดยท์ŠคํŽ˜์ธ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•œ๊ตญ์–ด๊ฐ€ ์ƒˆ์–ด ๋‚˜๊ฐ„๋‹ค.
22
- * โ‘ก ๋˜์ง„ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ 
22
+ * โ‘ก ์˜ค๋ฅ˜๋ฅผ ๋‚ธ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ 
23
23
  * ํ™”๋ฉด์€ ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ๊ฑฐ์ ˆ์„ ์กฐ์šฉํžˆ ํ•˜๋Š” ๊ฒƒ์€ ์‹คํŒจ๋ณด๋‹ค ๋‚˜์˜๋‹ค.
24
24
  * ์ด์ œ `{ok, errorCode, errorParams}` ๋กœ ๋‚ธ๋‹ค โ€” ํ™”๋ฉด์ด `twin.compose.del.<code>` ๋กœ ๋ง์„ ๋งŒ๋“ ๋‹ค.
25
25
  */
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TwinSpaceResolver = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const log_js_1 = require("../../engine/log.js");
5
6
  const type_graphql_1 = require("type-graphql");
6
7
  const shell_1 = require("@things-factory/shell");
7
8
  const twin_space_js_1 = require("./twin-space.js");
@@ -93,9 +94,9 @@ let TwinSpaceResolver = class TwinSpaceResolver {
93
94
  * ๊ณต๊ฐ„ ์‚ญ์ œ โ€” **์ด ๊ณต๊ฐ„์˜ ํŠธ์œˆ์ด ์žˆ์œผ๋ฉด ๊ฑฐ์ ˆํ•œ๋‹ค.** ๊ทธ๋ž˜์„œ ํŠธ์œˆ์ด ํ˜„์žฅ์„ ์žƒ๋Š” ์ผ์€ ์—†๋‹ค.
94
95
  *
95
96
  * โ”€โ”€ ์™œ ๋ชจ์–‘์„ ๋ฐ”๊ฟจ๋‚˜ (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
96
- * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋˜์กŒ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:
97
+ * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋ƒˆ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:
97
98
  * โ‘  ์„œ๋ฒ„๊ฐ€ ํ™”๋ฉด์˜ ๋ง์„ ์ •ํ–ˆ๋‹ค โ€” ์ผ๋ณธ์–ดยท์ŠคํŽ˜์ธ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•œ๊ตญ์–ด๊ฐ€ ์ƒˆ์–ด ๋‚˜๊ฐ„๋‹ค.
98
- * โ‘ก ๋˜์ง„ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ 
99
+ * โ‘ก ์˜ค๋ฅ˜๋ฅผ ๋‚ธ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ 
99
100
  * ํ™”๋ฉด์€ ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ๊ฑฐ์ ˆ์„ ์กฐ์šฉํžˆ ํ•˜๋Š” ๊ฒƒ์€ ์‹คํŒจ๋ณด๋‹ค ๋‚˜์˜๋‹ค.
100
101
  * ์ด์ œ `{ok, errorCode, errorParams}` ๋กœ ๋‚ธ๋‹ค โ€” ํ™”๋ฉด์ด `twin.compose.del.<code>` ๋กœ ๋ง์„ ๋งŒ๋“ ๋‹ค.
101
102
  */
@@ -191,7 +192,7 @@ let TwinSpaceResolver = class TwinSpaceResolver {
191
192
  }));
192
193
  }
193
194
  catch (err) {
194
- console.error(`[twin-space] move audit not recorded for "${instanceId}"`, err);
195
+ (0, log_js_1.twinError)(`[twin-space] move audit not recorded for "${instanceId}"`, err);
195
196
  }
196
197
  return { ok: true, warnings: judgement.warnings };
197
198
  }
@@ -242,7 +243,7 @@ let TwinSpaceResolver = class TwinSpaceResolver {
242
243
  }));
243
244
  }
244
245
  catch (err) {
245
- console.error(`[twin-space] detach audit not recorded for "${instanceId}"`, err);
246
+ (0, log_js_1.twinError)(`[twin-space] detach audit not recorded for "${instanceId}"`, err);
246
247
  }
247
248
  return { ok: true, warnings: judgement.warnings };
248
249
  }
@@ -1 +1 @@
1
- {"version":3,"file":"twin-space-resolver.js","sourceRoot":"","sources":["../../../server/service/twin-space/twin-space-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Mutation, Query, Resolver, Directive} from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { TwinSpace } from './twin-space.js'\nimport { TwinSpaceRepresentation } from './twin-space-representation.js'\nimport { TwinSpaceArea } from './twin-space-area.js'\nimport { TwinArea } from './twin-area.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinAuditEvent } from '../twin-audit/twin-audit-event.js'\nimport { TwinEngine } from '../../engine/index.js'\nimport { judgeMoveTwinSpace, judgeDetachTwinSpace } from './move-space.js'\nimport { checkSpaceIntegrity, sortFindings, type IntegrityPolygon } from './space-integrity.js'\n\n/*\n * ๊ณต๊ฐ„ ๊ตฌ์„ฑ ์ฑ„๋„(design/ui/space-composition.md) โ€” Site(Space) + ๋ณต์ˆ˜ ํ‘œํ˜„(Representation) + ์˜์—ญ(Area).\n * model ๋‚ด์šฉ์€ board-service Board ์—(ํ‘œํ˜„ config.boardId ์ฐธ์กฐ, ์ค‘๋ณต ์ €์žฅ ๊ธˆ์ง€). ๋ชจ๋‘ domain ์Šค์ฝ”ํ”„.\n */\n@Resolver()\nexport class TwinSpaceResolver {\n /* โ”€โ”€ Space(Site) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n /**\n * ์ด ํ…Œ๋„ŒํŠธ์˜ ํ˜„์žฅ ๋ชฉ๋ก.\n *\n * โ”€โ”€ ์„ธ ๋ฒˆ๋งŒ ๋ฌป๋Š”๋‹ค (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” ํ˜„์žฅ๋งˆ๋‹ค ํ‘œํ˜„ ์ˆ˜๋ฅผ ์„ธ๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ์กฐํšŒํ–ˆ๋‹ค โ€” ํ˜„์žฅ 13๊ณณ์ด๋ฉด **์งˆ์˜ 27๋ฒˆ**์ด๊ณ , ์ฒซ\n * ํ˜ธ์ถœ์ด 2.4์ดˆ์˜€๋‹ค(ํ—ค๋”๊ฐ€ ๋œฐ ๋•Œ๋งˆ๋‹ค ์ด ๋ชฉ๋ก์„ ์ฝ๋Š”๋‹ค). ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ๊ทธ๋Œ€๋กœ ์ž๋ž€๋‹ค.\n *\n * ์ด์ œ ์„ธ ๋ฒˆ ๋ฌป๊ณ  ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋งž์ถ˜๋‹ค: ํ˜„์žฅ ยท ํ‘œํ˜„(๊ณต๊ฐ„ id ๋งŒ) ยท ์ธ์Šคํ„ด์Šค(ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ).\n * ํ‘œํ˜„์€ **id ๋งŒ ์‹ค์–ด ์˜จ๋‹ค**(`loadRelationIds`) โ€” ์„ค์ • blob ์„ ์ฝ์–ด ์„ธ๋Š” ๊ฒƒ์€ ๋‚ญ๋น„๋‹ค.\n */\n @Query(returns => [ScalarObject], { description: 'List tenant Spaces (Sites) in the current domain.' })\n async twinSpaces(@Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const [rows, reps, insts] = await Promise.all([\n getRepository(TwinSpace).find({ where: { domain: { id: domainId } }, order: { createdAt: 'ASC' } }),\n /* ๊ด€๊ณ„๋ฅผ **์กฐ์ธํ•ด์„œ** ์ฝ๋Š”๋‹ค โ€” `loadRelationIds`+`select` ์กฐํ•ฉ์€ ๊ด€๊ณ„ ์ž๋ฆฌ๋ฅผ ๋น„์›Œ ๋‘์–ด\n ํ‘œํ˜„ ์ˆ˜๊ฐ€ ์ „๋ถ€ 0 ์ด ๋๋‹ค(2026-08-13 ์‹ค์ธก์œผ๋กœ ์žก์Œ). ์กฐ์ธ ํ•œ ๋ฒˆ์ด ํ˜„์žฅ๋งˆ๋‹ค ์„ธ๋Š” ๊ฒƒ๋ณด๋‹ค ์‹ธ๋‹ค. */\n getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId } }, relations: { space: true } }),\n getRepository(TwinInstance).find({ where: { domain: { id: domainId } }, select: { instanceId: true, spaceId: true, purpose: true, copyOf: true } })\n ])\n\n const repCount = new Map<string, number>()\n for (const rep of reps) {\n const sid = rep.space?.id\n if (sid) repCount.set(sid, (repCount.get(sid) ?? 0) + 1)\n }\n /* ๋ฒค์น˜ ์—ฌ๋ถ€ยท์›๋ณธ ์ฐธ์กฐ โ€” ์ธ์Šคํ„ด์Šค purpose ๊ทผ๊ฑฐ(1๊ธ‰). ์‚ฌ๋ณธ ํ˜„์žฅ์„ ํ—ค๋” ์„ ํƒ๊ธฐ์—์„œ ๊ตฌ๋ณ„ยท์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ. */\n const benchOf = new Map<string, { copyOf?: string }>()\n for (const i of insts) if ((i as any).purpose === 'bench' && i.spaceId && !benchOf.has(i.spaceId)) benchOf.set(i.spaceId, { copyOf: i.copyOf ?? undefined })\n\n return rows.map(r => {\n const bench = benchOf.get(r.spaceId)\n return {\n spaceId: r.spaceId,\n name: r.name,\n description: r.description,\n geo: r.geo,\n timezone: r.timezone,\n primaryRepresentationId: r.primaryRepresentationId,\n extentX: r.extentX,\n extentY: r.extentY,\n representationCount: repCount.get(r.id) ?? 0,\n bench: !!bench,\n copyOf: bench?.copyOf\n }\n })\n }\n\n /** ๋‹จ๊ฑด โ€” ํ‘œํ˜„(+์˜์—ญ) ํŠธ๋ฆฌ ํฌํ•จ. */\n @Query(returns => ScalarObject, { nullable: true, description: 'Get one Space with its representations (and their areas).' })\n async twinSpace(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any | null> {\n const domainId = context.state.domain.id\n const r = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!r) return null\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: r.id } }, order: { seq: 'ASC' } })\n const representations: any[] = []\n for (const rep of reps) {\n const areas = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId }, representation: { id: rep.id } }, order: { createdAt: 'ASC' } })\n representations.push({ id: rep.id, type: rep.type, name: rep.name, seq: rep.seq, isPrimary: rep.isPrimary, config: rep.config, areas: areas.map(a => ({ id: a.id, name: a.name, type: a.type, geometry: a.geometry, drillTo: a.drillTo, binding: a.binding, style: a.style })) })\n }\n return { spaceId: r.spaceId, name: r.name, description: r.description, geo: r.geo, timezone: r.timezone, primaryRepresentationId: r.primaryRepresentationId, extentX: r.extentX, extentY: r.extentY, representations }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Create or update a Space (name/description/geo/timezone/primaryRepresentationId).' })\n async saveTwinSpace(\n @Arg('spaceId') spaceId: string,\n @Arg('patch', type => ScalarObject) patch: any,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const repo = getRepository(TwinSpace)\n const domainId = context.state.domain.id\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /* ์ง„์งœ ๋ถ€๋ถ„ ๋ณ‘ํ•ฉ โ€” patch ์— ์ค€ ํ‚ค๋งŒ ๊ฐฑ์‹ (๋‚˜๋จธ์ง€ ํ•„๋“œ ๋ณด์กด). id ๋Š” ๊ด€๊ณ„๋กœ ์žฌ์„ค์ •ํ•˜์ง€ ์•Š๋„๋ก ์ œ์™ธ. */\n const { id: _drop, ...clean } = patch ?? {}\n await repo.save(repo.create({ ...(existing ?? {}), ...clean, domain: { id: domainId } as any, spaceId }))\n return true\n }\n\n /**\n * ๊ณต๊ฐ„ ์‚ญ์ œ โ€” **์ด ๊ณต๊ฐ„์˜ ํŠธ์œˆ์ด ์žˆ์œผ๋ฉด ๊ฑฐ์ ˆํ•œ๋‹ค.** ๊ทธ๋ž˜์„œ ํŠธ์œˆ์ด ํ˜„์žฅ์„ ์žƒ๋Š” ์ผ์€ ์—†๋‹ค.\n *\n * โ”€โ”€ ์™œ ๋ชจ์–‘์„ ๋ฐ”๊ฟจ๋‚˜ (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋˜์กŒ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:\n * โ‘  ์„œ๋ฒ„๊ฐ€ ํ™”๋ฉด์˜ ๋ง์„ ์ •ํ–ˆ๋‹ค โ€” ์ผ๋ณธ์–ดยท์ŠคํŽ˜์ธ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•œ๊ตญ์–ด๊ฐ€ ์ƒˆ์–ด ๋‚˜๊ฐ„๋‹ค.\n * โ‘ก ๋˜์ง„ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ \n * ํ™”๋ฉด์€ ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ๊ฑฐ์ ˆ์„ ์กฐ์šฉํžˆ ํ•˜๋Š” ๊ฒƒ์€ ์‹คํŒจ๋ณด๋‹ค ๋‚˜์˜๋‹ค.\n * ์ด์ œ `{ok, errorCode, errorParams}` ๋กœ ๋‚ธ๋‹ค โ€” ํ™”๋ฉด์ด `twin.compose.del.<code>` ๋กœ ๋ง์„ ๋งŒ๋“ ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Delete a Space and its representations/areas. Refused while twins still live in it (a twin never loses its site this way). Returns {ok, errorCode, errorParams}.'\n })\n async deleteTwinSpace(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n // ๋ผ์ดํ”„์‚ฌ์ดํด ๊ฐ€๋“œ โ€” ์ด ๊ณต๊ฐ„์— ๋ฐ”์ธ๋”ฉ๋œ ํŠธ์œˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์œผ๋ฉด ์‚ญ์ œ ์ฐจ๋‹จ(dangling ๋ฐฉ์ง€).\n // spaceId ์ปฌ๋Ÿผ(space #3) ๋กœ ์ง์ ‘ ์งˆ์˜ โ€” ์ „ ์ธ์Šคํ„ด์Šค ๋กœ๋“œ+JSํ•„ํ„ฐ ์ œ๊ฑฐ(ํšจ์œจยท1๊ธ‰ ์งˆ์˜).\n const bound = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (bound.length) {\n const twins = bound.map(i => i.name || i.instanceId)\n return {\n ok: false,\n errorCode: 'space-has-twins',\n errorParams: { spaceId, count: bound.length, twins: twins.slice(0, 5).join(', ') },\n error: `space \"${spaceId}\" still has ${bound.length} twin(s) โ€” remove or move them first (${twins.join(', ')})`\n }\n }\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 }) // ๋…ผ๋ฆฌ area ๋„ ํ•จ๊ป˜ ์ •๋ฆฌ\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n return { ok: true }\n }\n\n /**\n * ์ด๋ฏธ ์žˆ๋Š” ํŠธ์œˆ์„ ์ด ํ˜„์žฅ์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค โ€” **์†Œ์† ๊ฐฑ์‹ **(์ด๋ ฅ ์ด์ „์ด ์•„๋‹ˆ๋‹ค).\n *\n * ์ €๋„ยทํˆฌ์˜ ํ–‰์€ `instanceId` ๋กœ ๋งค์—ฌ ์žˆ์–ด ํŠธ์œˆ์„ ๋”ฐ๋ผ์˜ค๊ณ , ๊ตฌ์—ญยทํ‘œํ˜„์€ ๊ณต๊ฐ„์˜ ๊ฒƒ์ด๋ผ ๋‚จ๋Š”๋‹ค\n * (๊ทผ๊ฑฐยทํŒ์ •: `move-space.ts`). ๊ทธ๋ž˜์„œ ์ด ๋ฎคํ…Œ์ด์…˜์ด ์“ฐ๋Š” ๊ฒƒ์€ ๋‘ ๊ณณ๋ฟ์ด๋‹ค โ€”\n * ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ `spaceId` ์™€ ์ €์žฅ๋œ model ์˜ `spaceId`(์ปค๋„ยท๋ณด๋“œ๊ฐ€ ๊ฐ™์€ ๊ณต๊ฐ„์„ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ•œ๋‹ค).\n * ์ƒˆ ๊ณต๊ฐ„์˜ ์‹œ๊ฐ„๋Œ€๋กœ `utcOffsetMinutes` ๋„ ๋‹ค์‹œ ํŒŒ์ƒํ•œ๋‹ค(๊ณต๊ฐ„์ด ์‹œ๊ฐ„์˜ ๊ธฐ์ค€์ด๋‹ค).\n *\n * `dryRun` ์€ **๊ฐ™์€ ํŒ์ •์„ ๋ฏธ๋ฆฌ** ๋ณด์—ฌ ์ค€๋‹ค โ€” ํ™”๋ฉด์ด ์žƒ์„ ๊ฒƒ์„ ๋จผ์ € ๋งํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ •ํ•œ๋‹ค.\n * ํŒ์ •์„ ๋‘ ๋ฒŒ๋กœ ๋‘๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ์™€ ์‹ค์ œ๊ฐ€ ์–ด๊ธ‹๋‚˜๋ฏ€๋กœ ํ•œ ํ•จ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ ๋ถ€๋ฅธ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Move an existing twin into a space (co-locate it as another lens). The journal and projected rows follow the twin; areas and representations stay with the old space. dryRun returns the same judgement without writing. Returns {ok, warnings, errorCode}.'\n })\n async moveTwinToSpace(\n @Arg('instanceId') instanceId: string,\n @Arg('spaceId') spaceId: string,\n @Ctx() context: ResolverContext,\n @Arg('dryRun', { nullable: true, description: 'Judge only โ€” report refusal/warnings without moving.' }) dryRun?: boolean\n ): Promise<any> {\n const domainId = context.state.domain.id\n const instRepo = getRepository(TwinInstance)\n const spaceRepo = getRepository(TwinSpace)\n\n const inst = await instRepo.findOne({ where: { domain: { id: domainId }, instanceId } })\n const from = inst?.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const to = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n\n /* ํŒ์ •์— ํ•„์š”ํ•œ ์‚ฌ์‹ค๋งŒ ๋ชจ์•„ ๋„˜๊ธด๋‹ค โ€” ํŒ์ • ์ž์ฒด๋Š” ์ˆœ์ˆ˜ ๋ชจ๋“ˆ์ด ํ•œ๋‹ค. */\n const toAreaIds = to\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: to.id } as any } })).map(a => a.areaId)\n : []\n const fromRepresentationCount = from\n ? await getRepository(TwinSpaceRepresentation).count({ where: { domain: { id: domainId } as any, space: { id: from.id } as any } })\n : 0\n const model: any = inst?.model ?? {}\n const areaRefs: (string | undefined)[] = (model.locations ?? []).map((l: any) => l?.parentId)\n\n const judgement = judgeMoveTwinSpace({\n instanceId: inst?.instanceId,\n fromSpaceId: inst?.spaceId,\n toSpaceId: spaceId,\n toSpaceExists: !!to,\n purpose: (inst as any)?.purpose,\n running: !!inst && !!TwinEngine.runtime(domainId, instanceId),\n fromTimezone: from?.timezone ?? undefined,\n toTimezone: to?.timezone ?? undefined,\n areaRefs,\n toAreaIds,\n fromRepresentationCount\n })\n if (judgement.refusal) {\n const r = judgement.refusal\n return { ok: false, error: r.message, errorCode: r.code, errorParams: r.params, warnings: [] }\n }\n if (dryRun) return { ok: true, dryRun: true, warnings: judgement.warnings }\n\n /* ๋‘ ๊ณณ์„ ํ•จ๊ป˜ ์“ด๋‹ค โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ model ์ด ๋‹ค๋ฅธ ๊ณต๊ฐ„์„ ๊ฐ€๋ฆฌํ‚ค๋ฉด ๋ณด๋“œยท์ปค๋„์ด ๊ฐˆ๋ผ์ง„๋‹ค. */\n const moved = { ...model, spaceId }\n const withTime = await TwinEngine.withSpaceTimeBase(moved, domainId, spaceId)\n await instRepo.save(instRepo.create({ ...(inst as any), spaceId, model: withTime }))\n\n /*\n * ๊ฐ์‚ฌ ๊ธฐ๋ก โ€” ์†Œ์†์„ ๋ฐ”๊พผ ๊ฒƒ์€ ์‚ฌ๋žŒ์˜ ๊ฒฐ์ •์ด๊ณ , ๋‚˜์ค‘์— \"์™œ ์ด ํŠธ์œˆ์ด ์ € ํ˜„์žฅ์— ์žˆ๋‚˜\" ๋ฅผ ๋ฌป๊ฒŒ ๋œ๋‹ค.\n * ๊ธฐ๋ก์ด ์‹คํŒจํ•ด๋„ ์ด์ „ ๊ฒฐ๊ณผ๋Š” ๋Œ๋ ค์ค€๋‹ค(๊ฐ์‚ฌ๊ฐ€ ๋ณธ์—…์„ ๋ง‰์ง€ ์•Š๋Š”๋‹ค). ๋‹ค๋งŒ ์‚ผํ‚ค์ง€ ์•Š๊ณ  ๋กœ๊ทธ์— ๋‚จ๊ธด๋‹ค.\n */\n try {\n const repo = getRepository(TwinAuditEvent)\n await repo.save(\n repo.create({\n domain: context.state.domain,\n instanceId,\n commandType: 'twin.moveToSpace',\n accepted: true,\n origin: 'user',\n actorId: context.state.user?.id,\n args: { from: inst?.spaceId ?? null, to: spaceId, warnings: judgement.warnings.map(w => w.code) }\n } as any)\n )\n } catch (err) {\n console.error(`[twin-space] move audit not recorded for \"${instanceId}\"`, err)\n }\n\n return { ok: true, warnings: judgement.warnings }\n }\n\n /**\n * ํŠธ์œˆ์„ ํ˜„์žฅ์—์„œ ๋—€๋‹ค โ€” **์–ด๋А ํ˜„์žฅ์—๋„ ์†ํ•˜์ง€ ์•Š์Œ**์œผ๋กœ ๋˜๋Œ๋ฆฐ๋‹ค.\n *\n * ๋”ํ•˜๊ธฐยท์˜ฎ๊ธฐ๊ธฐ๋งŒ ์žˆ์œผ๋ฉด ์ž˜๋ชป ๋„ฃ์€ ๊ฒƒ์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋‹ค. ๋–ผ๋„ ์ €๋„ยท๋กœ์ผ€์ด์…˜ยท์„ค๋น„๋Š” ํŠธ์œˆ์— ๋‚จ๊ณ \n * (`instanceId` ๋กœ ๋งค์—ฌ ์žˆ๋‹ค), ๊ตฌ์—ญยทํ‘œํ˜„์€ ์˜› ํ˜„์žฅ์— ๋‚จ๋Š”๋‹ค. ์žƒ๋Š” ๊ฒƒ์€ **๋ณผ ๋ฌด๋Œ€**๋‹ค โ€”\n * ํŒ์ •์ด ๊ทธ๊ฒƒ์„ ๋งํ•œ๋‹ค(`judgeDetachTwinSpace`). `dryRun` ์€ ๊ฐ™์€ ํŒ์ •์„ ๋ฏธ๋ฆฌ ๋‚ธ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Detach a twin from its space (it ends up on no site). The journal and projected rows stay with the twin; areas and representations stay with the space. dryRun returns the same judgement without writing. Returns {ok, warnings, errorCode}.'\n })\n async detachTwinFromSpace(\n @Arg('instanceId') instanceId: string,\n @Ctx() context: ResolverContext,\n @Arg('dryRun', { nullable: true, description: 'Judge only โ€” report refusal/warnings without detaching.' }) dryRun?: boolean\n ): Promise<any> {\n const domainId = context.state.domain.id\n const instRepo = getRepository(TwinInstance)\n const inst = await instRepo.findOne({ where: { domain: { id: domainId }, instanceId } })\n const from = inst?.spaceId\n ? await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } })\n : null\n const fromRepresentationCount = from\n ? await getRepository(TwinSpaceRepresentation).count({ where: { domain: { id: domainId } as any, space: { id: from.id } as any } })\n : 0\n\n const judgement = judgeDetachTwinSpace({\n instanceId: inst?.instanceId,\n fromSpaceId: inst?.spaceId,\n purpose: (inst as any)?.purpose,\n fromRepresentationCount,\n fromTimezone: from?.timezone ?? undefined\n })\n if (judgement.refusal) {\n const r = judgement.refusal\n return { ok: false, error: r.message, errorCode: r.code, errorParams: r.params, warnings: [] }\n }\n if (dryRun) return { ok: true, dryRun: true, warnings: judgement.warnings }\n\n /* ๋‘ ๊ณณ์„ ํ•จ๊ป˜ ๋น„์šด๋‹ค โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ model ์ด ์–ด๊ธ‹๋‚˜๋ฉด ์–ด๋А ์ชฝ์ด ์‚ฌ์‹ค์ธ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.\n ์‹œ๊ฐ„ ๊ธฐ์ค€(utcOffsetMinutes)์€ **๋‚จ๊ธด๋‹ค**: ์ง€์šฐ๋ฉด ์กฐ์šฉํžˆ UTC ๋กœ ์ฝํžŒ๋‹ค(ํŒ์ •์ด ๊ทธ๋ ‡๊ฒŒ ๋งํ–ˆ๋‹ค). */\n const { spaceId: _dropped, ...model } = (inst?.model as any) ?? {}\n await instRepo.update({ id: (inst as any).id }, { spaceId: null as any, model })\n\n try {\n const repo = getRepository(TwinAuditEvent)\n await repo.save(\n repo.create({\n domain: context.state.domain,\n instanceId,\n commandType: 'twin.detachFromSpace',\n accepted: true,\n origin: 'user',\n actorId: context.state.user?.id,\n args: { from: inst?.spaceId ?? null, warnings: judgement.warnings.map(w => w.code) }\n } as any)\n )\n } catch (err) {\n console.error(`[twin-space] detach audit not recorded for \"${instanceId}\"`, err)\n }\n\n return { ok: true, warnings: judgement.warnings }\n }\n\n /**\n * ๊ณต๊ฐ„ โ†” ํŠธ์œˆ โ†” ๊ฐ€์‹œํ™” ์ •ํ•ฉ์„ฑ ์ ๊ฒ€ โ€” **์‚ฌ์‹ค์„ ๋ชจ์•„ ์ˆœ์ˆ˜ ํŒ์ •์— ๋„˜๊ธด๋‹ค.**\n *\n * ์„ธ ์ถ•์€ ์„œ๋กœ๋ฅผ id ๋กœ๋งŒ ๊ฐ€๋ฆฌํ‚ค๊ณ  DB ๊ฐ€ ๊ทธ ์ฐธ์กฐ๋ฅผ ์ง€์ผœ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ํŠธ์œˆ์„ ์˜ฎ๊ธฐ๊ฑฐ๋‚˜ ๋–ผ๊ฑฐ๋‚˜ ์›๋ณธ์„\n * ๋‹ค์‹œ ์ฝ์œผ๋ฉด ์•„๋ฌด ์˜ค๋ฅ˜ ์—†์ด **๊ฐ€๋ฆฌํ‚ฌ ๊ฒƒ์ด ์—†๋Š” ๋„ํ˜•**๊ณผ **์†Œ์† ์—†๋Š” ๋กœ์ผ€์ด์…˜**์ด ๋‚จ๋Š”๋‹ค. ์‚ฌ๋žŒ์ด\n * ๋ˆˆ์œผ๋กœ ๋Œ€์กฐํ•˜๋˜ ์ผ์„ ๊ธฐ๊ณ„๊ฐ€ ํ•œ๋‹ค(ํŒ์ •ยท๊ทผ๊ฑฐ: `space-integrity.ts`).\n *\n * `spaceId` ๋ฅผ ์ฃผ๋ฉด ๊ทธ ํ˜„์žฅ๋งŒ, ์—†์œผ๋ฉด ํ…Œ๋„ŒํŠธ ์ „์ฒด๋ฅผ ๋ณธ๋‹ค.\n */\n @Query(returns => [ScalarObject], {\n description:\n 'Check space โ†” twin โ†” visualization integrity: dangling site refs, registry/model mismatch, polygons binding areas or entities that are not there, primary representation, unbound board representations. Pass spaceId to check one site.'\n })\n async twinSpaceIntegrity(\n @Ctx() context: ResolverContext,\n @Arg('spaceId', { nullable: true }) spaceId?: string\n ): Promise<any[]> {\n const domainId = context.state.domain.id\n const spaceRows = await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })\n const instRows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const repRows = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId } }, relations: ['space'] })\n const areaRows = await getRepository(TwinArea).find({ where: { domain: { id: domainId } }, relations: ['space'] })\n const polyRows = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId } }, relations: ['representation'] })\n\n const areasBySpace: Record<string, string[]> = {}\n for (const a of areaRows) {\n const sid = (a as any).space?.spaceId\n if (!sid) continue\n ;(areasBySpace[sid] ??= []).push(a.areaId)\n }\n\n /*\n * ํด๋ฆฌ๊ณค ๋ฐ”์ธ๋”ฉ์˜ ์‹ค์ œ ๋ชจ์–‘์€ `{ groupId?, locationId?, locationIds? }` ๋‹ค(์ง€๋„ ์ €์ž‘๊ธฐ ๊ธฐ์ค€).\n * ์—ฌ๋Ÿฌ ๋กœ์ผ€์ด์…˜์„ ๋ฌถ์€ ๋„ํ˜•์€ **๊ฐ๊ฐ์„ ๋”ฐ๋กœ** ๋ณธ๋‹ค โ€” ํ•˜๋‚˜๋งŒ ๋Š๊ฒจ๋„ ๊ทธ ๋„ํ˜•์€ ๋ฐ˜์ฏค ๊ฑฐ์ง“์ด ๋œ๋‹ค.\n */\n const polysByRep: Record<string, IntegrityPolygon[]> = {}\n for (const p of polyRows) {\n const rid = (p as any).representation?.id\n if (!rid) continue\n const b: any = p.binding ?? {}\n const list = polysByRep[rid] ??= []\n if (b.groupId) list.push({ id: p.id, groupId: b.groupId })\n const targets: string[] = [...(b.locationId ? [b.locationId] : []), ...(Array.isArray(b.locationIds) ? b.locationIds : [])]\n for (const t of targets) list.push({ id: p.id, targetKind: 'location', targetId: t })\n }\n\n /* ๋ณด๋“œ id ๋Š” ํ‘œํ˜„ config ๊ฐ€ ๋“ค๊ณ  ์žˆ๋‹ค โ€” ์กด์žฌ ํ™•์ธ์€ ๋ณด๋“œ ์„œ๋น„์Šค์˜ ์ผ์ด๋ฏ€๋กœ, ์—ฌ๊ธฐ์„œ๋Š” ํ‘œํ˜„์ด\n ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’์ด ์žˆ๋Š”์ง€๋งŒ ๋ณธ๋‹ค(์—†๋Š” ๋ณด๋“œ๊นŒ์ง€ ๋ณด๋ ค๋ฉด board-service ๋ฅผ ๋ฌผ์–ด์•ผ ํ•œ๋‹ค: ์•„๋ž˜ ์ฃผ์„). */\n const boardIds = repRows.map(r => (r.config as any)?.boardId).filter(Boolean) as string[]\n\n const findings = checkSpaceIntegrity({\n spaces: spaceRows.map(s => ({ spaceId: s.spaceId, primaryRepresentationId: s.primaryRepresentationId })),\n instances: instRows.map(i => {\n const model: any = i.model ?? {}\n /*\n * ์–ดํœ˜๊ฐ€ ๋งž๋Š”์ง€๋Š” **์‹คํ–‰ ์ค‘์ธ ํŠธ์œˆ๋งŒ** ๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์ปค๋„์ด ๋ฌด์—‡์„ ๋ฒ„๋ ธ๋Š”์ง€๋Š” ๋Ÿฐํƒ€์ž„์˜ ์‚ฌ์‹ค์ด๋‹ค.\n * ์ •์ง€ํ•œ ํŠธ์œˆ์€ `undefined`(๋ชจ๋ฅธ๋‹ค)๋กœ ๋‘”๋‹ค. ์ €๋„์„ ๋‹ค์‹œ ์ ‘์–ด ์•Œ์•„๋‚ด์ง€๋Š” ์•Š๋Š”๋‹ค: ์ด ์งˆ์˜๋Š”\n * ํ…Œ๋„ŒํŠธ ์ „์ฒด๋ฅผ ํ›‘์œผ๋ฏ€๋กœ ํŠธ์œˆ๋งˆ๋‹ค ํด๋“œ๋ฅผ ๊ฑธ๋ฉด ์ •ํ•ฉ์„ฑ ์ ๊ฒ€์ด ๊ฐ€์žฅ ๋ฌด๊ฑฐ์šด ์งˆ์˜๊ฐ€ ๋œ๋‹ค.\n */\n const live: any = TwinEngine.isRunning(domainId, i.instanceId)\n ? TwinEngine.snapshot(domainId, i.instanceId)\n : undefined\n return {\n instanceId: i.instanceId,\n spaceId: i.spaceId,\n modelSpaceId: model.spaceId,\n purpose: (i as any).purpose,\n locationIds: (model.locations ?? []).map((l: any) => l?.id).filter(Boolean),\n equipmentIds: (model.equipment ?? []).map((e: any) => e?.id).filter(Boolean),\n areaRefs: (model.locations ?? []).map((l: any) => l?.parentId),\n ...(Array.isArray(live?.unhandled) ? { unhandled: live.unhandled } : {})\n }\n }),\n representations: repRows.map(r => ({\n id: r.id,\n spaceId: (r as any).space?.spaceId ?? '',\n type: r.type,\n boardId: (r.config as any)?.boardId ?? null,\n polygons: polysByRep[r.id] ?? []\n })),\n areasBySpace,\n boardIds\n })\n\n const scoped = spaceId ? findings.filter(f => f.spaceId === spaceId || (!f.spaceId && !spaceId)) : findings\n return sortFindings(scoped)\n }\n\n /**\n * ๊ธฐ๊ณ„์ ์œผ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ์–ด๊ธ‹๋‚จ๋งŒ ๊ณ ์นœ๋‹ค โ€” **์‚ฌ๋žŒ์˜ ํŒ๋‹จ์ด ํ•„์š”ํ•œ ๊ฒƒ์€ ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์ง€๊ธˆ ๊ณ ์น˜๋Š” ๊ฒƒ์€ ํ•˜๋‚˜๋‹ค: **๋Œ€ํ‘œ ํ‘œํ˜„ ํฌ์ธํ„ฐ**. ๊ณต๊ฐ„์ด ์—†๋Š” ํ‘œํ˜„ id ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์œผ๋ฉด, ํ–‰์˜\n * `isPrimary` ๊ฐ€ ์ผœ์ง„ ํ‘œํ˜„(์—†์œผ๋ฉด ์ฒซ ํ‘œํ˜„)์œผ๋กœ ๋‹ค์‹œ ๊ฐ€๋ฆฌํ‚ค๊ณ , ํ‘œํ˜„์ด ์—†์œผ๋ฉด ๋น„์šด๋‹ค. ๊ทผ๊ฑฐ๊ฐ€ ์žˆ๊ณ \n * ๋‹ต์ด ํ•˜๋‚˜๋ฟ์ธ ๋ถ€๋ฅ˜๋ผ ์ž๋™์œผ๋กœ ๊ณ ์ณ๋„ ์‚ฌ์‹ค์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ํด๋ฆฌ๊ณค์ด ์—†๋Š” ๊ตฌ์—ญยท๊ฐœ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์€ **๊ณ ์น˜์ง€ ์•Š๋Š”๋‹ค.** ๊ทธ ๋„ํ˜•์„ ์ง€์›Œ์•ผ ํ•˜๋Š”์ง€, ํŠธ์œˆ์„ ๋‹ค์‹œ\n * ๋ฐ๋ ค์™€์•ผ ํ•˜๋Š”์ง€, ๊ตฌ์—ญ์„ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜๋Š”์ง€๋Š” ์‚ฌ๋žŒ์ด ์ •ํ•  ์ผ์ด๋‹ค โ€” ๊ธฐ๊ณ„๊ฐ€ ๊ณ ๋ฅด๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋ฆฐ\n * ๋„ํ˜•์ด ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Repair mechanically fixable space integrity findings (currently: a primary representation pointer that points nowhere). Dangling polygon bindings are left alone โ€” that is a human decision. Returns {repaired:[{spaceId, code}], skipped}.'\n })\n async repairTwinSpaceIntegrity(\n @Ctx() context: ResolverContext,\n @Arg('spaceId', { nullable: true }) spaceId?: string\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const repRepo = getRepository(TwinSpaceRepresentation)\n const spaces = await spaceRepo.find({\n where: spaceId ? { domain: { id: domainId }, spaceId } : { domain: { id: domainId } }\n })\n const repaired: any[] = []\n for (const space of spaces) {\n const reps = await repRepo.find({ where: { domain: { id: domainId } as any, space: { id: space.id } as any }, order: { seq: 'ASC' } })\n const pointer = (space.primaryRepresentationId ?? '').trim()\n if (pointer && reps.some(r => r.id === pointer)) continue /* ์ด๋ฏธ ์˜ณ๋‹ค */\n const primary = reps.find(r => r.isPrimary) ?? reps[0]\n const next = primary?.id ?? null\n if (pointer === (next ?? '')) continue\n await spaceRepo.save(spaceRepo.create({ ...space, primaryRepresentationId: next }))\n if (primary) for (const r of reps) if (!!r.isPrimary !== (r.id === primary.id)) await repRepo.save(repRepo.create({ ...r, isPrimary: r.id === primary.id }))\n repaired.push({ spaceId: space.spaceId, code: 'primary-representation-missing', from: pointer || null, to: next })\n }\n return { ok: true, repaired, count: repaired.length }\n }\n\n /* โ”€โ”€ Area(๋…ผ๋ฆฌ ๊ตฌ์—ญ, ํ‘œํ˜„ ๋ฌด๊ด€ยท๊ณต์œ ยท๊ณ„์ธต) โ€” area ๋‹จ์ผํ™” space #2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Query(returns => [ScalarObject], { description: 'List logical areas (representation-agnostic hierarchy) of a space. (area unification)' })\n async twinAreas(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const rows = await getRepository(TwinArea).find({ where: { domain: { id: domainId }, space: { spaceId } }, order: { createdAt: 'ASC' } })\n return rows.map(a => ({ areaId: a.areaId, name: a.name, type: a.type, parentId: a.parentId, layout: a.layout }))\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Create/update a logical area (shared across representations). (area unification)' })\n async saveTwinArea(\n @Arg('spaceId') spaceId: string,\n @Arg('areaId') areaId: string,\n @Arg('patch', type => ScalarObject) patch: any,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) throw new Error(`space \"${spaceId}\" not found`)\n const repo = getRepository(TwinArea)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, space: { id: space.id }, areaId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n space: { id: space.id } as any,\n areaId,\n name: patch?.name ?? existing?.name ?? areaId,\n type: patch?.type ?? existing?.type,\n parentId: patch?.parentId !== undefined ? patch.parentId : existing?.parentId,\n layout: patch?.layout ?? existing?.layout\n })\n )\n return true\n }\n\n /*\n * ์ฐธ์กฐ๊ธฐ๋ฐ˜ ํšŒ์ˆ˜(reference-counted) โ€” area ๋Š” ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„ ์žˆ์œผ๋ฉด ์‚ญ์ œ ์ฐจ๋‹จ, ๊ณ ์•„๋ฉด ์ œ๊ฑฐ.\n * ์ฐธ์กฐ: ์ž์‹ area(parentId) ยท ํ‘œํ˜„๋ณ„ ํด๋ฆฌ๊ณค(TwinSpaceArea binding.groupId/areaId).\n * (๋…ธ๋“œ/์—”ํ‹ฐํ‹ฐ ๋‹ด๊น€ยทdrillTo ์ฐธ์กฐ๋Š” P2 areaId ๋ฐฐ์„  ํ›„ ํ™•์žฅ.)\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a logical area only if unreferenced (reference-counted). Throws if referenced. (area unification)' })\n async deleteTwinArea(@Arg('spaceId') spaceId: string, @Arg('areaId') areaId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return false\n // ์ฐธ์กฐ 1: ์ž์‹ area\n const children = await getRepository(TwinArea).count({ where: { domain: { id: domainId }, space: { id: space.id }, parentId: areaId } })\n // ์ฐธ์กฐ 2: ํ‘œํ˜„๋ณ„ ํด๋ฆฌ๊ณค(์ด ๊ณต๊ฐ„์˜ ํ‘œํ˜„๋“ค์— ์ด area ๋ฅผ ๊ทธ๋ฆฐ ๊ฒƒ). binding.groupId/areaId ๋Š” JSON โ†’ ๋กœ๋“œ ํ›„ JS ํ•„ํ„ฐ(๋ฉ€ํ‹ฐDB).\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n let polygonRefs = 0\n for (const rep of reps) {\n const polys = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId }, representation: { id: rep.id } } })\n polygonRefs += polys.filter(p => (p.binding as any)?.groupId === areaId || (p.binding as any)?.areaId === areaId).length\n }\n if (children > 0 || polygonRefs > 0) {\n throw new Error(`area \"${areaId}\" ๋Š” ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค (์ž์‹ ${children}, ํด๋ฆฌ๊ณค ${polygonRefs}). ์ฐธ์กฐ ์ œ๊ฑฐ ํ›„ ์‚ญ์ œํ•˜์„ธ์š”.`)\n }\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any, areaId })\n return true\n }\n\n /* โ”€โ”€ Representation โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Create/update a representation (map|image|model). Returns {id}.' })\n async saveSpaceRepresentation(\n @Arg('spaceId') spaceId: string,\n @Arg('rep', type => ScalarObject) rep: any,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `space not found: ${spaceId}` }\n const repo = getRepository(TwinSpaceRepresentation)\n const existing = rep?.id ? await repo.findOne({ where: { id: rep.id } }) : null\n const saved = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, space: { id: space.id } as any, type: rep.type, name: rep.name, seq: rep.seq ?? 0, isPrimary: !!rep.isPrimary, config: rep.config }))\n return { ok: true, id: saved.id }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a representation and its areas.' })\n async deleteSpaceRepresentation(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, id } as any)\n return true\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Set the primary representation of a space.' })\n async setPrimaryRepresentation(@Arg('spaceId') spaceId: string, @Arg('repId') repId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return false\n await spaceRepo.save(spaceRepo.create({ ...space, primaryRepresentationId: repId }))\n const repRepo = getRepository(TwinSpaceRepresentation)\n const reps = await repRepo.find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) if (!!rep.isPrimary !== (rep.id === repId)) await repRepo.save(repRepo.create({ ...rep, isPrimary: rep.id === repId }))\n return true\n }\n\n /* โ”€โ”€ Area (map/image ํด๋ฆฌ๊ณค) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Create/update a polygon area (geometry + drillTo model + binding). Returns {id}.' })\n async saveSpaceArea(\n @Arg('representationId') representationId: string,\n @Arg('area', type => ScalarObject) area: any,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinSpaceArea)\n const existing = area?.id ? await repo.findOne({ where: { id: area.id } }) : null\n /* drillTo/binding ์€ ์„ ํƒ์  ๋งํฌ โ€” ํด๋ผ๊ฐ€ ํ•ด์ œ(undefined)๋กœ ๋ณด๋‚ด๋ฉด JSON ์—์„œ ํ‚ค๊ฐ€ ๋น ์ ธ TypeORM ์ด \"๋ณ€๊ฒฝ ์—†์Œ\"์œผ๋กœ\n * ๋ฌด์‹œํ•˜๋ฏ€๋กœ ๊ธฐ์กด ๊ฐ’์ด ๋‚จ๋Š”๋‹ค. null ๋กœ ๊ฐ•์ œํ•ด ๋ช…์‹œ์ ์œผ๋กœ ์ปฌ๋Ÿผ์„ ๋น„์šด๋‹ค(์ €์žฅ์€ ๋Š˜ ์ „์ฒด ํ•„๋“œ๋ฅผ ๋ณด๋ƒ„ โ†’ ๋ฎ์–ด์“ฐ๊ธฐ ์•ˆ์ „). */\n const saved = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, representation: { id: representationId } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style }))\n return { ok: true, id: saved.id }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a polygon area.' })\n async deleteSpaceArea(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n await getRepository(TwinSpaceArea).delete({ domain: { id: context.state.domain.id } as any, id } as any)\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"twin-space-resolver.js","sourceRoot":"","sources":["../../../server/service/twin-space/twin-space-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { twinError } from '../../engine/log.js'\nimport { Arg, Ctx, Mutation, Query, Resolver, Directive} from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { TwinSpace } from './twin-space.js'\nimport { TwinSpaceRepresentation } from './twin-space-representation.js'\nimport { TwinSpaceArea } from './twin-space-area.js'\nimport { TwinArea } from './twin-area.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinAuditEvent } from '../twin-audit/twin-audit-event.js'\nimport { TwinEngine } from '../../engine/index.js'\nimport { judgeMoveTwinSpace, judgeDetachTwinSpace } from './move-space.js'\nimport { checkSpaceIntegrity, sortFindings, type IntegrityPolygon } from './space-integrity.js'\n\n/*\n * ๊ณต๊ฐ„ ๊ตฌ์„ฑ ์ฑ„๋„(design/ui/space-composition.md) โ€” Site(Space) + ๋ณต์ˆ˜ ํ‘œํ˜„(Representation) + ์˜์—ญ(Area).\n * model ๋‚ด์šฉ์€ board-service Board ์—(ํ‘œํ˜„ config.boardId ์ฐธ์กฐ, ์ค‘๋ณต ์ €์žฅ ๊ธˆ์ง€). ๋ชจ๋‘ domain ์Šค์ฝ”ํ”„.\n */\n@Resolver()\nexport class TwinSpaceResolver {\n /* โ”€โ”€ Space(Site) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n /**\n * ์ด ํ…Œ๋„ŒํŠธ์˜ ํ˜„์žฅ ๋ชฉ๋ก.\n *\n * โ”€โ”€ ์„ธ ๋ฒˆ๋งŒ ๋ฌป๋Š”๋‹ค (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” ํ˜„์žฅ๋งˆ๋‹ค ํ‘œํ˜„ ์ˆ˜๋ฅผ ์„ธ๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ์กฐํšŒํ–ˆ๋‹ค โ€” ํ˜„์žฅ 13๊ณณ์ด๋ฉด **์งˆ์˜ 27๋ฒˆ**์ด๊ณ , ์ฒซ\n * ํ˜ธ์ถœ์ด 2.4์ดˆ์˜€๋‹ค(ํ—ค๋”๊ฐ€ ๋œฐ ๋•Œ๋งˆ๋‹ค ์ด ๋ชฉ๋ก์„ ์ฝ๋Š”๋‹ค). ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ๊ทธ๋Œ€๋กœ ์ž๋ž€๋‹ค.\n *\n * ์ด์ œ ์„ธ ๋ฒˆ ๋ฌป๊ณ  ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋งž์ถ˜๋‹ค: ํ˜„์žฅ ยท ํ‘œํ˜„(๊ณต๊ฐ„ id ๋งŒ) ยท ์ธ์Šคํ„ด์Šค(ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ).\n * ํ‘œํ˜„์€ **id ๋งŒ ์‹ค์–ด ์˜จ๋‹ค**(`loadRelationIds`) โ€” ์„ค์ • blob ์„ ์ฝ์–ด ์„ธ๋Š” ๊ฒƒ์€ ๋‚ญ๋น„๋‹ค.\n */\n @Query(returns => [ScalarObject], { description: 'List tenant Spaces (Sites) in the current domain.' })\n async twinSpaces(@Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const [rows, reps, insts] = await Promise.all([\n getRepository(TwinSpace).find({ where: { domain: { id: domainId } }, order: { createdAt: 'ASC' } }),\n /* ๊ด€๊ณ„๋ฅผ **์กฐ์ธํ•ด์„œ** ์ฝ๋Š”๋‹ค โ€” `loadRelationIds`+`select` ์กฐํ•ฉ์€ ๊ด€๊ณ„ ์ž๋ฆฌ๋ฅผ ๋น„์›Œ ๋‘์–ด\n ํ‘œํ˜„ ์ˆ˜๊ฐ€ ์ „๋ถ€ 0 ์ด ๋๋‹ค(2026-08-13 ์‹ค์ธก์œผ๋กœ ์žก์Œ). ์กฐ์ธ ํ•œ ๋ฒˆ์ด ํ˜„์žฅ๋งˆ๋‹ค ์„ธ๋Š” ๊ฒƒ๋ณด๋‹ค ์‹ธ๋‹ค. */\n getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId } }, relations: { space: true } }),\n getRepository(TwinInstance).find({ where: { domain: { id: domainId } }, select: { instanceId: true, spaceId: true, purpose: true, copyOf: true } })\n ])\n\n const repCount = new Map<string, number>()\n for (const rep of reps) {\n const sid = rep.space?.id\n if (sid) repCount.set(sid, (repCount.get(sid) ?? 0) + 1)\n }\n /* ๋ฒค์น˜ ์—ฌ๋ถ€ยท์›๋ณธ ์ฐธ์กฐ โ€” ์ธ์Šคํ„ด์Šค purpose ๊ทผ๊ฑฐ(1๊ธ‰). ์‚ฌ๋ณธ ํ˜„์žฅ์„ ํ—ค๋” ์„ ํƒ๊ธฐ์—์„œ ๊ตฌ๋ณ„ยท์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ. */\n const benchOf = new Map<string, { copyOf?: string }>()\n for (const i of insts) if ((i as any).purpose === 'bench' && i.spaceId && !benchOf.has(i.spaceId)) benchOf.set(i.spaceId, { copyOf: i.copyOf ?? undefined })\n\n return rows.map(r => {\n const bench = benchOf.get(r.spaceId)\n return {\n spaceId: r.spaceId,\n name: r.name,\n description: r.description,\n geo: r.geo,\n timezone: r.timezone,\n primaryRepresentationId: r.primaryRepresentationId,\n extentX: r.extentX,\n extentY: r.extentY,\n representationCount: repCount.get(r.id) ?? 0,\n bench: !!bench,\n copyOf: bench?.copyOf\n }\n })\n }\n\n /** ๋‹จ๊ฑด โ€” ํ‘œํ˜„(+์˜์—ญ) ํŠธ๋ฆฌ ํฌํ•จ. */\n @Query(returns => ScalarObject, { nullable: true, description: 'Get one Space with its representations (and their areas).' })\n async twinSpace(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any | null> {\n const domainId = context.state.domain.id\n const r = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!r) return null\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: r.id } }, order: { seq: 'ASC' } })\n const representations: any[] = []\n for (const rep of reps) {\n const areas = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId }, representation: { id: rep.id } }, order: { createdAt: 'ASC' } })\n representations.push({ id: rep.id, type: rep.type, name: rep.name, seq: rep.seq, isPrimary: rep.isPrimary, config: rep.config, areas: areas.map(a => ({ id: a.id, name: a.name, type: a.type, geometry: a.geometry, drillTo: a.drillTo, binding: a.binding, style: a.style })) })\n }\n return { spaceId: r.spaceId, name: r.name, description: r.description, geo: r.geo, timezone: r.timezone, primaryRepresentationId: r.primaryRepresentationId, extentX: r.extentX, extentY: r.extentY, representations }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Create or update a Space (name/description/geo/timezone/primaryRepresentationId).' })\n async saveTwinSpace(\n @Arg('spaceId') spaceId: string,\n @Arg('patch', type => ScalarObject) patch: any,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const repo = getRepository(TwinSpace)\n const domainId = context.state.domain.id\n const existing = await repo.findOne({ where: { domain: { id: domainId }, spaceId } })\n /* ์ง„์งœ ๋ถ€๋ถ„ ๋ณ‘ํ•ฉ โ€” patch ์— ์ค€ ํ‚ค๋งŒ ๊ฐฑ์‹ (๋‚˜๋จธ์ง€ ํ•„๋“œ ๋ณด์กด). id ๋Š” ๊ด€๊ณ„๋กœ ์žฌ์„ค์ •ํ•˜์ง€ ์•Š๋„๋ก ์ œ์™ธ. */\n const { id: _drop, ...clean } = patch ?? {}\n await repo.save(repo.create({ ...(existing ?? {}), ...clean, domain: { id: domainId } as any, spaceId }))\n return true\n }\n\n /**\n * ๊ณต๊ฐ„ ์‚ญ์ œ โ€” **์ด ๊ณต๊ฐ„์˜ ํŠธ์œˆ์ด ์žˆ์œผ๋ฉด ๊ฑฐ์ ˆํ•œ๋‹ค.** ๊ทธ๋ž˜์„œ ํŠธ์œˆ์ด ํ˜„์žฅ์„ ์žƒ๋Š” ์ผ์€ ์—†๋‹ค.\n *\n * โ”€โ”€ ์™œ ๋ชจ์–‘์„ ๋ฐ”๊ฟจ๋‚˜ (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” `Boolean` ์„ ๋Œ๋ ค์ฃผ๊ณ  ๊ฑฐ์ ˆ์€ **ํ•œ๊ตญ์–ด ๋ฌธ์žฅ์„ ๋ƒˆ๋‹ค.** ๋‘ ๊ฐ€์ง€๊ฐ€ ํ‹€๋ ธ๋‹ค:\n * โ‘  ์„œ๋ฒ„๊ฐ€ ํ™”๋ฉด์˜ ๋ง์„ ์ •ํ–ˆ๋‹ค โ€” ์ผ๋ณธ์–ดยท์ŠคํŽ˜์ธ์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•œ๊ตญ์–ด๊ฐ€ ์ƒˆ์–ด ๋‚˜๊ฐ„๋‹ค.\n * โ‘ก ์˜ค๋ฅ˜๋ฅผ ๋‚ธ ์˜ˆ์™ธ๋ฅผ ํ™”๋ฉด์ด ๋ฐ›์ง€ ์•Š์•„ **์•„๋ฌด ์ผ๋„ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ** ๋ณด์˜€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์‚ญ์ œ๋ฅผ ๋ˆŒ๋ €๊ณ \n * ํ™”๋ฉด์€ ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ๊ฑฐ์ ˆ์„ ์กฐ์šฉํžˆ ํ•˜๋Š” ๊ฒƒ์€ ์‹คํŒจ๋ณด๋‹ค ๋‚˜์˜๋‹ค.\n * ์ด์ œ `{ok, errorCode, errorParams}` ๋กœ ๋‚ธ๋‹ค โ€” ํ™”๋ฉด์ด `twin.compose.del.<code>` ๋กœ ๋ง์„ ๋งŒ๋“ ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Delete a Space and its representations/areas. Refused while twins still live in it (a twin never loses its site this way). Returns {ok, errorCode, errorParams}.'\n })\n async deleteTwinSpace(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n // ๋ผ์ดํ”„์‚ฌ์ดํด ๊ฐ€๋“œ โ€” ์ด ๊ณต๊ฐ„์— ๋ฐ”์ธ๋”ฉ๋œ ํŠธ์œˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์œผ๋ฉด ์‚ญ์ œ ์ฐจ๋‹จ(dangling ๋ฐฉ์ง€).\n // spaceId ์ปฌ๋Ÿผ(space #3) ๋กœ ์ง์ ‘ ์งˆ์˜ โ€” ์ „ ์ธ์Šคํ„ด์Šค ๋กœ๋“œ+JSํ•„ํ„ฐ ์ œ๊ฑฐ(ํšจ์œจยท1๊ธ‰ ์งˆ์˜).\n const bound = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n if (bound.length) {\n const twins = bound.map(i => i.name || i.instanceId)\n return {\n ok: false,\n errorCode: 'space-has-twins',\n errorParams: { spaceId, count: bound.length, twins: twins.slice(0, 5).join(', ') },\n error: `space \"${spaceId}\" still has ${bound.length} twin(s) โ€” remove or move them first (${twins.join(', ')})`\n }\n }\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 }) // ๋…ผ๋ฆฌ area ๋„ ํ•จ๊ป˜ ์ •๋ฆฌ\n }\n await getRepository(TwinSpace).delete({ domain: { id: domainId } as any, spaceId })\n return { ok: true }\n }\n\n /**\n * ์ด๋ฏธ ์žˆ๋Š” ํŠธ์œˆ์„ ์ด ํ˜„์žฅ์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค โ€” **์†Œ์† ๊ฐฑ์‹ **(์ด๋ ฅ ์ด์ „์ด ์•„๋‹ˆ๋‹ค).\n *\n * ์ €๋„ยทํˆฌ์˜ ํ–‰์€ `instanceId` ๋กœ ๋งค์—ฌ ์žˆ์–ด ํŠธ์œˆ์„ ๋”ฐ๋ผ์˜ค๊ณ , ๊ตฌ์—ญยทํ‘œํ˜„์€ ๊ณต๊ฐ„์˜ ๊ฒƒ์ด๋ผ ๋‚จ๋Š”๋‹ค\n * (๊ทผ๊ฑฐยทํŒ์ •: `move-space.ts`). ๊ทธ๋ž˜์„œ ์ด ๋ฎคํ…Œ์ด์…˜์ด ์“ฐ๋Š” ๊ฒƒ์€ ๋‘ ๊ณณ๋ฟ์ด๋‹ค โ€”\n * ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ `spaceId` ์™€ ์ €์žฅ๋œ model ์˜ `spaceId`(์ปค๋„ยท๋ณด๋“œ๊ฐ€ ๊ฐ™์€ ๊ณต๊ฐ„์„ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ•œ๋‹ค).\n * ์ƒˆ ๊ณต๊ฐ„์˜ ์‹œ๊ฐ„๋Œ€๋กœ `utcOffsetMinutes` ๋„ ๋‹ค์‹œ ํŒŒ์ƒํ•œ๋‹ค(๊ณต๊ฐ„์ด ์‹œ๊ฐ„์˜ ๊ธฐ์ค€์ด๋‹ค).\n *\n * `dryRun` ์€ **๊ฐ™์€ ํŒ์ •์„ ๋ฏธ๋ฆฌ** ๋ณด์—ฌ ์ค€๋‹ค โ€” ํ™”๋ฉด์ด ์žƒ์„ ๊ฒƒ์„ ๋จผ์ € ๋งํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ •ํ•œ๋‹ค.\n * ํŒ์ •์„ ๋‘ ๋ฒŒ๋กœ ๋‘๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ์™€ ์‹ค์ œ๊ฐ€ ์–ด๊ธ‹๋‚˜๋ฏ€๋กœ ํ•œ ํ•จ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ ๋ถ€๋ฅธ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Move an existing twin into a space (co-locate it as another lens). The journal and projected rows follow the twin; areas and representations stay with the old space. dryRun returns the same judgement without writing. Returns {ok, warnings, errorCode}.'\n })\n async moveTwinToSpace(\n @Arg('instanceId') instanceId: string,\n @Arg('spaceId') spaceId: string,\n @Ctx() context: ResolverContext,\n @Arg('dryRun', { nullable: true, description: 'Judge only โ€” report refusal/warnings without moving.' }) dryRun?: boolean\n ): Promise<any> {\n const domainId = context.state.domain.id\n const instRepo = getRepository(TwinInstance)\n const spaceRepo = getRepository(TwinSpace)\n\n const inst = await instRepo.findOne({ where: { domain: { id: domainId }, instanceId } })\n const from = inst?.spaceId ? await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } }) : null\n const to = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n\n /* ํŒ์ •์— ํ•„์š”ํ•œ ์‚ฌ์‹ค๋งŒ ๋ชจ์•„ ๋„˜๊ธด๋‹ค โ€” ํŒ์ • ์ž์ฒด๋Š” ์ˆœ์ˆ˜ ๋ชจ๋“ˆ์ด ํ•œ๋‹ค. */\n const toAreaIds = to\n ? (await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any, space: { id: to.id } as any } })).map(a => a.areaId)\n : []\n const fromRepresentationCount = from\n ? await getRepository(TwinSpaceRepresentation).count({ where: { domain: { id: domainId } as any, space: { id: from.id } as any } })\n : 0\n const model: any = inst?.model ?? {}\n const areaRefs: (string | undefined)[] = (model.locations ?? []).map((l: any) => l?.parentId)\n\n const judgement = judgeMoveTwinSpace({\n instanceId: inst?.instanceId,\n fromSpaceId: inst?.spaceId,\n toSpaceId: spaceId,\n toSpaceExists: !!to,\n purpose: (inst as any)?.purpose,\n running: !!inst && !!TwinEngine.runtime(domainId, instanceId),\n fromTimezone: from?.timezone ?? undefined,\n toTimezone: to?.timezone ?? undefined,\n areaRefs,\n toAreaIds,\n fromRepresentationCount\n })\n if (judgement.refusal) {\n const r = judgement.refusal\n return { ok: false, error: r.message, errorCode: r.code, errorParams: r.params, warnings: [] }\n }\n if (dryRun) return { ok: true, dryRun: true, warnings: judgement.warnings }\n\n /* ๋‘ ๊ณณ์„ ํ•จ๊ป˜ ์“ด๋‹ค โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ model ์ด ๋‹ค๋ฅธ ๊ณต๊ฐ„์„ ๊ฐ€๋ฆฌํ‚ค๋ฉด ๋ณด๋“œยท์ปค๋„์ด ๊ฐˆ๋ผ์ง„๋‹ค. */\n const moved = { ...model, spaceId }\n const withTime = await TwinEngine.withSpaceTimeBase(moved, domainId, spaceId)\n await instRepo.save(instRepo.create({ ...(inst as any), spaceId, model: withTime }))\n\n /*\n * ๊ฐ์‚ฌ ๊ธฐ๋ก โ€” ์†Œ์†์„ ๋ฐ”๊พผ ๊ฒƒ์€ ์‚ฌ๋žŒ์˜ ๊ฒฐ์ •์ด๊ณ , ๋‚˜์ค‘์— \"์™œ ์ด ํŠธ์œˆ์ด ์ € ํ˜„์žฅ์— ์žˆ๋‚˜\" ๋ฅผ ๋ฌป๊ฒŒ ๋œ๋‹ค.\n * ๊ธฐ๋ก์ด ์‹คํŒจํ•ด๋„ ์ด์ „ ๊ฒฐ๊ณผ๋Š” ๋Œ๋ ค์ค€๋‹ค(๊ฐ์‚ฌ๊ฐ€ ๋ณธ์—…์„ ๋ง‰์ง€ ์•Š๋Š”๋‹ค). ๋‹ค๋งŒ ์‚ผํ‚ค์ง€ ์•Š๊ณ  ๋กœ๊ทธ์— ๋‚จ๊ธด๋‹ค.\n */\n try {\n const repo = getRepository(TwinAuditEvent)\n await repo.save(\n repo.create({\n domain: context.state.domain,\n instanceId,\n commandType: 'twin.moveToSpace',\n accepted: true,\n origin: 'user',\n actorId: context.state.user?.id,\n args: { from: inst?.spaceId ?? null, to: spaceId, warnings: judgement.warnings.map(w => w.code) }\n } as any)\n )\n } catch (err) {\n twinError(`[twin-space] move audit not recorded for \"${instanceId}\"`, err)\n }\n\n return { ok: true, warnings: judgement.warnings }\n }\n\n /**\n * ํŠธ์œˆ์„ ํ˜„์žฅ์—์„œ ๋—€๋‹ค โ€” **์–ด๋А ํ˜„์žฅ์—๋„ ์†ํ•˜์ง€ ์•Š์Œ**์œผ๋กœ ๋˜๋Œ๋ฆฐ๋‹ค.\n *\n * ๋”ํ•˜๊ธฐยท์˜ฎ๊ธฐ๊ธฐ๋งŒ ์žˆ์œผ๋ฉด ์ž˜๋ชป ๋„ฃ์€ ๊ฒƒ์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋‹ค. ๋–ผ๋„ ์ €๋„ยท๋กœ์ผ€์ด์…˜ยท์„ค๋น„๋Š” ํŠธ์œˆ์— ๋‚จ๊ณ \n * (`instanceId` ๋กœ ๋งค์—ฌ ์žˆ๋‹ค), ๊ตฌ์—ญยทํ‘œํ˜„์€ ์˜› ํ˜„์žฅ์— ๋‚จ๋Š”๋‹ค. ์žƒ๋Š” ๊ฒƒ์€ **๋ณผ ๋ฌด๋Œ€**๋‹ค โ€”\n * ํŒ์ •์ด ๊ทธ๊ฒƒ์„ ๋งํ•œ๋‹ค(`judgeDetachTwinSpace`). `dryRun` ์€ ๊ฐ™์€ ํŒ์ •์„ ๋ฏธ๋ฆฌ ๋‚ธ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Detach a twin from its space (it ends up on no site). The journal and projected rows stay with the twin; areas and representations stay with the space. dryRun returns the same judgement without writing. Returns {ok, warnings, errorCode}.'\n })\n async detachTwinFromSpace(\n @Arg('instanceId') instanceId: string,\n @Ctx() context: ResolverContext,\n @Arg('dryRun', { nullable: true, description: 'Judge only โ€” report refusal/warnings without detaching.' }) dryRun?: boolean\n ): Promise<any> {\n const domainId = context.state.domain.id\n const instRepo = getRepository(TwinInstance)\n const inst = await instRepo.findOne({ where: { domain: { id: domainId }, instanceId } })\n const from = inst?.spaceId\n ? await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId: inst.spaceId } })\n : null\n const fromRepresentationCount = from\n ? await getRepository(TwinSpaceRepresentation).count({ where: { domain: { id: domainId } as any, space: { id: from.id } as any } })\n : 0\n\n const judgement = judgeDetachTwinSpace({\n instanceId: inst?.instanceId,\n fromSpaceId: inst?.spaceId,\n purpose: (inst as any)?.purpose,\n fromRepresentationCount,\n fromTimezone: from?.timezone ?? undefined\n })\n if (judgement.refusal) {\n const r = judgement.refusal\n return { ok: false, error: r.message, errorCode: r.code, errorParams: r.params, warnings: [] }\n }\n if (dryRun) return { ok: true, dryRun: true, warnings: judgement.warnings }\n\n /* ๋‘ ๊ณณ์„ ํ•จ๊ป˜ ๋น„์šด๋‹ค โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ model ์ด ์–ด๊ธ‹๋‚˜๋ฉด ์–ด๋А ์ชฝ์ด ์‚ฌ์‹ค์ธ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.\n ์‹œ๊ฐ„ ๊ธฐ์ค€(utcOffsetMinutes)์€ **๋‚จ๊ธด๋‹ค**: ์ง€์šฐ๋ฉด ์กฐ์šฉํžˆ UTC ๋กœ ์ฝํžŒ๋‹ค(ํŒ์ •์ด ๊ทธ๋ ‡๊ฒŒ ๋งํ–ˆ๋‹ค). */\n const { spaceId: _dropped, ...model } = (inst?.model as any) ?? {}\n await instRepo.update({ id: (inst as any).id }, { spaceId: null as any, model })\n\n try {\n const repo = getRepository(TwinAuditEvent)\n await repo.save(\n repo.create({\n domain: context.state.domain,\n instanceId,\n commandType: 'twin.detachFromSpace',\n accepted: true,\n origin: 'user',\n actorId: context.state.user?.id,\n args: { from: inst?.spaceId ?? null, warnings: judgement.warnings.map(w => w.code) }\n } as any)\n )\n } catch (err) {\n twinError(`[twin-space] detach audit not recorded for \"${instanceId}\"`, err)\n }\n\n return { ok: true, warnings: judgement.warnings }\n }\n\n /**\n * ๊ณต๊ฐ„ โ†” ํŠธ์œˆ โ†” ๊ฐ€์‹œํ™” ์ •ํ•ฉ์„ฑ ์ ๊ฒ€ โ€” **์‚ฌ์‹ค์„ ๋ชจ์•„ ์ˆœ์ˆ˜ ํŒ์ •์— ๋„˜๊ธด๋‹ค.**\n *\n * ์„ธ ์ถ•์€ ์„œ๋กœ๋ฅผ id ๋กœ๋งŒ ๊ฐ€๋ฆฌํ‚ค๊ณ  DB ๊ฐ€ ๊ทธ ์ฐธ์กฐ๋ฅผ ์ง€์ผœ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ํŠธ์œˆ์„ ์˜ฎ๊ธฐ๊ฑฐ๋‚˜ ๋–ผ๊ฑฐ๋‚˜ ์›๋ณธ์„\n * ๋‹ค์‹œ ์ฝ์œผ๋ฉด ์•„๋ฌด ์˜ค๋ฅ˜ ์—†์ด **๊ฐ€๋ฆฌํ‚ฌ ๊ฒƒ์ด ์—†๋Š” ๋„ํ˜•**๊ณผ **์†Œ์† ์—†๋Š” ๋กœ์ผ€์ด์…˜**์ด ๋‚จ๋Š”๋‹ค. ์‚ฌ๋žŒ์ด\n * ๋ˆˆ์œผ๋กœ ๋Œ€์กฐํ•˜๋˜ ์ผ์„ ๊ธฐ๊ณ„๊ฐ€ ํ•œ๋‹ค(ํŒ์ •ยท๊ทผ๊ฑฐ: `space-integrity.ts`).\n *\n * `spaceId` ๋ฅผ ์ฃผ๋ฉด ๊ทธ ํ˜„์žฅ๋งŒ, ์—†์œผ๋ฉด ํ…Œ๋„ŒํŠธ ์ „์ฒด๋ฅผ ๋ณธ๋‹ค.\n */\n @Query(returns => [ScalarObject], {\n description:\n 'Check space โ†” twin โ†” visualization integrity: dangling site refs, registry/model mismatch, polygons binding areas or entities that are not there, primary representation, unbound board representations. Pass spaceId to check one site.'\n })\n async twinSpaceIntegrity(\n @Ctx() context: ResolverContext,\n @Arg('spaceId', { nullable: true }) spaceId?: string\n ): Promise<any[]> {\n const domainId = context.state.domain.id\n const spaceRows = await getRepository(TwinSpace).find({ where: { domain: { id: domainId } } })\n const instRows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })\n const repRows = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId } }, relations: ['space'] })\n const areaRows = await getRepository(TwinArea).find({ where: { domain: { id: domainId } }, relations: ['space'] })\n const polyRows = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId } }, relations: ['representation'] })\n\n const areasBySpace: Record<string, string[]> = {}\n for (const a of areaRows) {\n const sid = (a as any).space?.spaceId\n if (!sid) continue\n ;(areasBySpace[sid] ??= []).push(a.areaId)\n }\n\n /*\n * ํด๋ฆฌ๊ณค ๋ฐ”์ธ๋”ฉ์˜ ์‹ค์ œ ๋ชจ์–‘์€ `{ groupId?, locationId?, locationIds? }` ๋‹ค(์ง€๋„ ์ €์ž‘๊ธฐ ๊ธฐ์ค€).\n * ์—ฌ๋Ÿฌ ๋กœ์ผ€์ด์…˜์„ ๋ฌถ์€ ๋„ํ˜•์€ **๊ฐ๊ฐ์„ ๋”ฐ๋กœ** ๋ณธ๋‹ค โ€” ํ•˜๋‚˜๋งŒ ๋Š๊ฒจ๋„ ๊ทธ ๋„ํ˜•์€ ๋ฐ˜์ฏค ๊ฑฐ์ง“์ด ๋œ๋‹ค.\n */\n const polysByRep: Record<string, IntegrityPolygon[]> = {}\n for (const p of polyRows) {\n const rid = (p as any).representation?.id\n if (!rid) continue\n const b: any = p.binding ?? {}\n const list = polysByRep[rid] ??= []\n if (b.groupId) list.push({ id: p.id, groupId: b.groupId })\n const targets: string[] = [...(b.locationId ? [b.locationId] : []), ...(Array.isArray(b.locationIds) ? b.locationIds : [])]\n for (const t of targets) list.push({ id: p.id, targetKind: 'location', targetId: t })\n }\n\n /* ๋ณด๋“œ id ๋Š” ํ‘œํ˜„ config ๊ฐ€ ๋“ค๊ณ  ์žˆ๋‹ค โ€” ์กด์žฌ ํ™•์ธ์€ ๋ณด๋“œ ์„œ๋น„์Šค์˜ ์ผ์ด๋ฏ€๋กœ, ์—ฌ๊ธฐ์„œ๋Š” ํ‘œํ˜„์ด\n ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’์ด ์žˆ๋Š”์ง€๋งŒ ๋ณธ๋‹ค(์—†๋Š” ๋ณด๋“œ๊นŒ์ง€ ๋ณด๋ ค๋ฉด board-service ๋ฅผ ๋ฌผ์–ด์•ผ ํ•œ๋‹ค: ์•„๋ž˜ ์ฃผ์„). */\n const boardIds = repRows.map(r => (r.config as any)?.boardId).filter(Boolean) as string[]\n\n const findings = checkSpaceIntegrity({\n spaces: spaceRows.map(s => ({ spaceId: s.spaceId, primaryRepresentationId: s.primaryRepresentationId })),\n instances: instRows.map(i => {\n const model: any = i.model ?? {}\n /*\n * ์–ดํœ˜๊ฐ€ ๋งž๋Š”์ง€๋Š” **์‹คํ–‰ ์ค‘์ธ ํŠธ์œˆ๋งŒ** ๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์ปค๋„์ด ๋ฌด์—‡์„ ๋ฒ„๋ ธ๋Š”์ง€๋Š” ๋Ÿฐํƒ€์ž„์˜ ์‚ฌ์‹ค์ด๋‹ค.\n * ์ •์ง€ํ•œ ํŠธ์œˆ์€ `undefined`(๋ชจ๋ฅธ๋‹ค)๋กœ ๋‘”๋‹ค. ์ €๋„์„ ๋‹ค์‹œ ์ ‘์–ด ์•Œ์•„๋‚ด์ง€๋Š” ์•Š๋Š”๋‹ค: ์ด ์งˆ์˜๋Š”\n * ํ…Œ๋„ŒํŠธ ์ „์ฒด๋ฅผ ํ›‘์œผ๋ฏ€๋กœ ํŠธ์œˆ๋งˆ๋‹ค ํด๋“œ๋ฅผ ๊ฑธ๋ฉด ์ •ํ•ฉ์„ฑ ์ ๊ฒ€์ด ๊ฐ€์žฅ ๋ฌด๊ฑฐ์šด ์งˆ์˜๊ฐ€ ๋œ๋‹ค.\n */\n const live: any = TwinEngine.isRunning(domainId, i.instanceId)\n ? TwinEngine.snapshot(domainId, i.instanceId)\n : undefined\n return {\n instanceId: i.instanceId,\n spaceId: i.spaceId,\n modelSpaceId: model.spaceId,\n purpose: (i as any).purpose,\n locationIds: (model.locations ?? []).map((l: any) => l?.id).filter(Boolean),\n equipmentIds: (model.equipment ?? []).map((e: any) => e?.id).filter(Boolean),\n areaRefs: (model.locations ?? []).map((l: any) => l?.parentId),\n ...(Array.isArray(live?.unhandled) ? { unhandled: live.unhandled } : {})\n }\n }),\n representations: repRows.map(r => ({\n id: r.id,\n spaceId: (r as any).space?.spaceId ?? '',\n type: r.type,\n boardId: (r.config as any)?.boardId ?? null,\n polygons: polysByRep[r.id] ?? []\n })),\n areasBySpace,\n boardIds\n })\n\n const scoped = spaceId ? findings.filter(f => f.spaceId === spaceId || (!f.spaceId && !spaceId)) : findings\n return sortFindings(scoped)\n }\n\n /**\n * ๊ธฐ๊ณ„์ ์œผ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ์–ด๊ธ‹๋‚จ๋งŒ ๊ณ ์นœ๋‹ค โ€” **์‚ฌ๋žŒ์˜ ํŒ๋‹จ์ด ํ•„์š”ํ•œ ๊ฒƒ์€ ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค.**\n *\n * ์ง€๊ธˆ ๊ณ ์น˜๋Š” ๊ฒƒ์€ ํ•˜๋‚˜๋‹ค: **๋Œ€ํ‘œ ํ‘œํ˜„ ํฌ์ธํ„ฐ**. ๊ณต๊ฐ„์ด ์—†๋Š” ํ‘œํ˜„ id ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์œผ๋ฉด, ํ–‰์˜\n * `isPrimary` ๊ฐ€ ์ผœ์ง„ ํ‘œํ˜„(์—†์œผ๋ฉด ์ฒซ ํ‘œํ˜„)์œผ๋กœ ๋‹ค์‹œ ๊ฐ€๋ฆฌํ‚ค๊ณ , ํ‘œํ˜„์ด ์—†์œผ๋ฉด ๋น„์šด๋‹ค. ๊ทผ๊ฑฐ๊ฐ€ ์žˆ๊ณ \n * ๋‹ต์ด ํ•˜๋‚˜๋ฟ์ธ ๋ถ€๋ฅ˜๋ผ ์ž๋™์œผ๋กœ ๊ณ ์ณ๋„ ์‚ฌ์‹ค์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ํด๋ฆฌ๊ณค์ด ์—†๋Š” ๊ตฌ์—ญยท๊ฐœ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์€ **๊ณ ์น˜์ง€ ์•Š๋Š”๋‹ค.** ๊ทธ ๋„ํ˜•์„ ์ง€์›Œ์•ผ ํ•˜๋Š”์ง€, ํŠธ์œˆ์„ ๋‹ค์‹œ\n * ๋ฐ๋ ค์™€์•ผ ํ•˜๋Š”์ง€, ๊ตฌ์—ญ์„ ๋‹ค์‹œ ๊ทธ๋ ค์•ผ ํ•˜๋Š”์ง€๋Š” ์‚ฌ๋žŒ์ด ์ •ํ•  ์ผ์ด๋‹ค โ€” ๊ธฐ๊ณ„๊ฐ€ ๊ณ ๋ฅด๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋ฆฐ\n * ๋„ํ˜•์ด ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Repair mechanically fixable space integrity findings (currently: a primary representation pointer that points nowhere). Dangling polygon bindings are left alone โ€” that is a human decision. Returns {repaired:[{spaceId, code}], skipped}.'\n })\n async repairTwinSpaceIntegrity(\n @Ctx() context: ResolverContext,\n @Arg('spaceId', { nullable: true }) spaceId?: string\n ): Promise<any> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const repRepo = getRepository(TwinSpaceRepresentation)\n const spaces = await spaceRepo.find({\n where: spaceId ? { domain: { id: domainId }, spaceId } : { domain: { id: domainId } }\n })\n const repaired: any[] = []\n for (const space of spaces) {\n const reps = await repRepo.find({ where: { domain: { id: domainId } as any, space: { id: space.id } as any }, order: { seq: 'ASC' } })\n const pointer = (space.primaryRepresentationId ?? '').trim()\n if (pointer && reps.some(r => r.id === pointer)) continue /* ์ด๋ฏธ ์˜ณ๋‹ค */\n const primary = reps.find(r => r.isPrimary) ?? reps[0]\n const next = primary?.id ?? null\n if (pointer === (next ?? '')) continue\n await spaceRepo.save(spaceRepo.create({ ...space, primaryRepresentationId: next }))\n if (primary) for (const r of reps) if (!!r.isPrimary !== (r.id === primary.id)) await repRepo.save(repRepo.create({ ...r, isPrimary: r.id === primary.id }))\n repaired.push({ spaceId: space.spaceId, code: 'primary-representation-missing', from: pointer || null, to: next })\n }\n return { ok: true, repaired, count: repaired.length }\n }\n\n /* โ”€โ”€ Area(๋…ผ๋ฆฌ ๊ตฌ์—ญ, ํ‘œํ˜„ ๋ฌด๊ด€ยท๊ณต์œ ยท๊ณ„์ธต) โ€” area ๋‹จ์ผํ™” space #2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Query(returns => [ScalarObject], { description: 'List logical areas (representation-agnostic hierarchy) of a space. (area unification)' })\n async twinAreas(@Arg('spaceId') spaceId: string, @Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const rows = await getRepository(TwinArea).find({ where: { domain: { id: domainId }, space: { spaceId } }, order: { createdAt: 'ASC' } })\n return rows.map(a => ({ areaId: a.areaId, name: a.name, type: a.type, parentId: a.parentId, layout: a.layout }))\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Create/update a logical area (shared across representations). (area unification)' })\n async saveTwinArea(\n @Arg('spaceId') spaceId: string,\n @Arg('areaId') areaId: string,\n @Arg('patch', type => ScalarObject) patch: any,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) throw new Error(`space \"${spaceId}\" not found`)\n const repo = getRepository(TwinArea)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, space: { id: space.id }, areaId } })\n await repo.save(\n repo.create({\n ...(existing ?? {}),\n domain: { id: domainId } as any,\n space: { id: space.id } as any,\n areaId,\n name: patch?.name ?? existing?.name ?? areaId,\n type: patch?.type ?? existing?.type,\n parentId: patch?.parentId !== undefined ? patch.parentId : existing?.parentId,\n layout: patch?.layout ?? existing?.layout\n })\n )\n return true\n }\n\n /*\n * ์ฐธ์กฐ๊ธฐ๋ฐ˜ ํšŒ์ˆ˜(reference-counted) โ€” area ๋Š” ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„ ์žˆ์œผ๋ฉด ์‚ญ์ œ ์ฐจ๋‹จ, ๊ณ ์•„๋ฉด ์ œ๊ฑฐ.\n * ์ฐธ์กฐ: ์ž์‹ area(parentId) ยท ํ‘œํ˜„๋ณ„ ํด๋ฆฌ๊ณค(TwinSpaceArea binding.groupId/areaId).\n * (๋…ธ๋“œ/์—”ํ‹ฐํ‹ฐ ๋‹ด๊น€ยทdrillTo ์ฐธ์กฐ๋Š” P2 areaId ๋ฐฐ์„  ํ›„ ํ™•์žฅ.)\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a logical area only if unreferenced (reference-counted). Throws if referenced. (area unification)' })\n async deleteTwinArea(@Arg('spaceId') spaceId: string, @Arg('areaId') areaId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return false\n // ์ฐธ์กฐ 1: ์ž์‹ area\n const children = await getRepository(TwinArea).count({ where: { domain: { id: domainId }, space: { id: space.id }, parentId: areaId } })\n // ์ฐธ์กฐ 2: ํ‘œํ˜„๋ณ„ ํด๋ฆฌ๊ณค(์ด ๊ณต๊ฐ„์˜ ํ‘œํ˜„๋“ค์— ์ด area ๋ฅผ ๊ทธ๋ฆฐ ๊ฒƒ). binding.groupId/areaId ๋Š” JSON โ†’ ๋กœ๋“œ ํ›„ JS ํ•„ํ„ฐ(๋ฉ€ํ‹ฐDB).\n const reps = await getRepository(TwinSpaceRepresentation).find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n let polygonRefs = 0\n for (const rep of reps) {\n const polys = await getRepository(TwinSpaceArea).find({ where: { domain: { id: domainId }, representation: { id: rep.id } } })\n polygonRefs += polys.filter(p => (p.binding as any)?.groupId === areaId || (p.binding as any)?.areaId === areaId).length\n }\n if (children > 0 || polygonRefs > 0) {\n throw new Error(`area \"${areaId}\" ๋Š” ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค (์ž์‹ ${children}, ํด๋ฆฌ๊ณค ${polygonRefs}). ์ฐธ์กฐ ์ œ๊ฑฐ ํ›„ ์‚ญ์ œํ•˜์„ธ์š”.`)\n }\n await getRepository(TwinArea).delete({ domain: { id: domainId } as any, space: { id: space.id } as any, areaId })\n return true\n }\n\n /* โ”€โ”€ Representation โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Create/update a representation (map|image|model). Returns {id}.' })\n async saveSpaceRepresentation(\n @Arg('spaceId') spaceId: string,\n @Arg('rep', type => ScalarObject) rep: any,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const space = await getRepository(TwinSpace).findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return { ok: false, error: `space not found: ${spaceId}` }\n const repo = getRepository(TwinSpaceRepresentation)\n const existing = rep?.id ? await repo.findOne({ where: { id: rep.id } }) : null\n const saved = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, space: { id: space.id } as any, type: rep.type, name: rep.name, seq: rep.seq ?? 0, isPrimary: !!rep.isPrimary, config: rep.config }))\n return { ok: true, id: saved.id }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a representation and its areas.' })\n async deleteSpaceRepresentation(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n await getRepository(TwinSpaceArea).delete({ domain: { id: domainId } as any, representation: { id } as any })\n await getRepository(TwinSpaceRepresentation).delete({ domain: { id: domainId } as any, id } as any)\n return true\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Set the primary representation of a space.' })\n async setPrimaryRepresentation(@Arg('spaceId') spaceId: string, @Arg('repId') repId: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const domainId = context.state.domain.id\n const spaceRepo = getRepository(TwinSpace)\n const space = await spaceRepo.findOne({ where: { domain: { id: domainId }, spaceId } })\n if (!space) return false\n await spaceRepo.save(spaceRepo.create({ ...space, primaryRepresentationId: repId }))\n const repRepo = getRepository(TwinSpaceRepresentation)\n const reps = await repRepo.find({ where: { domain: { id: domainId }, space: { id: space.id } } })\n for (const rep of reps) if (!!rep.isPrimary !== (rep.id === repId)) await repRepo.save(repRepo.create({ ...rep, isPrimary: rep.id === repId }))\n return true\n }\n\n /* โ”€โ”€ Area (map/image ํด๋ฆฌ๊ณค) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Create/update a polygon area (geometry + drillTo model + binding). Returns {id}.' })\n async saveSpaceArea(\n @Arg('representationId') representationId: string,\n @Arg('area', type => ScalarObject) area: any,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinSpaceArea)\n const existing = area?.id ? await repo.findOne({ where: { id: area.id } }) : null\n /* drillTo/binding ์€ ์„ ํƒ์  ๋งํฌ โ€” ํด๋ผ๊ฐ€ ํ•ด์ œ(undefined)๋กœ ๋ณด๋‚ด๋ฉด JSON ์—์„œ ํ‚ค๊ฐ€ ๋น ์ ธ TypeORM ์ด \"๋ณ€๊ฒฝ ์—†์Œ\"์œผ๋กœ\n * ๋ฌด์‹œํ•˜๋ฏ€๋กœ ๊ธฐ์กด ๊ฐ’์ด ๋‚จ๋Š”๋‹ค. null ๋กœ ๊ฐ•์ œํ•ด ๋ช…์‹œ์ ์œผ๋กœ ์ปฌ๋Ÿผ์„ ๋น„์šด๋‹ค(์ €์žฅ์€ ๋Š˜ ์ „์ฒด ํ•„๋“œ๋ฅผ ๋ณด๋ƒ„ โ†’ ๋ฎ์–ด์“ฐ๊ธฐ ์•ˆ์ „). */\n const saved = await repo.save(repo.create({ ...(existing ?? {}), domain: { id: domainId } as any, representation: { id: representationId } as any, name: area.name, type: area.type, geometry: area.geometry, drillTo: area.drillTo ?? null, binding: area.binding ?? null, style: area.style }))\n return { ok: true, id: saved.id }\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a polygon area.' })\n async deleteSpaceArea(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n await getRepository(TwinSpaceArea).delete({ domain: { id: context.state.domain.id } as any, id } as any)\n return true\n }\n}\n"]}
@@ -19,11 +19,31 @@ export declare const personsTag: (instanceId: string) => string;
19
19
  export declare const assetsTag: (instanceId: string) => string;
20
20
  export declare const energyTag: (instanceId: string) => string;
21
21
  /**
22
- * ๋ฌผํ’ˆ ์ง‘์•ฝ์˜ ์ƒํ•œ โ€” ํฐ ํ˜„์žฅ์€ ๋ฌผํ’ˆ์ด ์ˆ˜๋งŒ ๊ฐœ๋ผ, ์ „๋Ÿ‰์„ ๋งค ๋ฐฉ์†ก์— ์‹ค์œผ๋ฉด ์ „๋‹ฌ์ด ํ˜„์žฅ์„ ๋А๋ฆฌ๊ฒŒ ํ•œ๋‹ค.
22
+ * ๋ฌผํ’ˆ ์ง‘์•ฝ์˜ ์ƒํ•œ โ€” ํฐ ํ˜„์žฅ์€ ๋ฌผํ’ˆ์ด ์ˆ˜๋งŒ ๊ฐœ๋ผ, ์ „๋Ÿ‰์„ ๋งค ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…์— ์‹ค์œผ๋ฉด ์ „๋‹ฌ์ด ํ˜„์žฅ์„ ๋А๋ฆฌ๊ฒŒ ํ•œ๋‹ค.
23
23
  *
24
24
  * **์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค**: ๋„˜์น˜๋ฉด `total`(์ „์ฒด ์ˆ˜)๊ณผ `truncated`(์ž˜๋ฆฐ ์ˆ˜)๋ฅผ ํ•จ๊ป˜ ์‹ค์–ด, ์†Œ๋น„์ฒ˜๊ฐ€
25
25
  * "์ด๊ฒŒ ์ „๋ถ€" ๋ผ๊ณ  ์˜คํ•ดํ•˜์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค. ๊ฐœ๋ณ„ ๋ฌผํ’ˆ์€ ํƒœ๊ทธ๋ณ„ delta ๋กœ ๋”ฐ๋กœ ๋‚˜๊ฐ€๊ณ  ๊ทธ์ชฝ์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜ dedup
26
- * ์ด ๊ฑธ๋ ค **๋ณ€ํ•œ ๊ฒƒ๋งŒ** ์žฌ๋ฐฉ์†ก๋œ๋‹ค.
26
+ * ์ด ๊ฑธ๋ ค **๋ณ€ํ•œ ๊ฒƒ๋งŒ** ์žฌ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…๋œ๋‹ค.
27
27
  */
28
28
  export declare const ITEMS_AGGREGATE_LIMIT = 500;
29
- export declare function buildEntityDeltas(state: any, instanceId: string): EntityDelta[];
29
+ /**
30
+ * ๋ฌผํ’ˆ ์ถ•๋งŒ **๋ฒ”์œ„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค** (2026-08-21).
31
+ *
32
+ * โ”€โ”€ ์™œ ์ด ์ธ์ž๊ฐ€ ์ƒ๊ฒผ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
33
+ * ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ… ํ•œ ๋ฒˆ์ด ๋งŒ๋“œ๋Š” payload ๋Š” ์—”ํ‹ฐํ‹ฐ ์ˆ˜๋งŒํผ์ด๊ณ  ๊ทธ ๋Œ€๋ถ€๋ถ„์ด ๋ฌผํ’ˆ์ด๋‹ค(์‹ค์ธก: ์—”ํ‹ฐํ‹ฐ 3,611 ์ค‘
34
+ * ๋ฌผํ’ˆ 2,400 ยท ๋งŒ๋“œ๋Š” ๋ฐ 1.8ms ยท ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พธ๋Š” ๋ฐ 1.0ms). ๋ฐ”๋€ ๊ฒƒ์ด ๋ฌผํ’ˆ ํ•˜๋‚˜์—ฌ๋„ ์ „๋ถ€ ๋งŒ๋“ค์–ด
35
+ * ใ€Œ๊ฐ™๋‹คใ€๋ฅผ ํ™•์ธํ•˜๊ณ  ๋ฒ„๋ ธ๋‹ค.
36
+ *
37
+ * `items` ๋ฅผ ์ฃผ๋ฉด **๊ทธ ํƒœ๊ทธ์˜ ๋ฌผํ’ˆ๋งŒ** ๊ฐœ๋ณ„ payload ๋ฅผ ๋งŒ๋“ ๋‹ค. ์ฃผ์ง€ ์•Š์œผ๋ฉด(`undefined`) ์ „๋ถ€ ๋งŒ๋“ ๋‹ค โ€”
38
+ * ๋ถ€๋ฅด๋Š” ์ชฝ์ด ๋ฌด์—‡์ด ๋ฐ”๋€Œ์—ˆ๋Š”์ง€ ๋งํ•  ์ˆ˜ ์—†์„ ๋•Œ์˜ ๋‹ต์ด๋‹ค.
39
+ *
40
+ * **์ง‘์•ฝ ๋ทฐ๋Š” ๋ฒ”์œ„๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.** ์ง‘์•ฝ์€ ๋ชฉ๋ก ์ „์ฒด๊ฐ€ ํ•œ payload ๋ผ์„œ, ํ•œ ๋ฌผํ’ˆ์ด ๋ฐ”๋€Œ๋ฉด ๊ทธ payload ๋Š”
41
+ * ํ†ต์งธ๋กœ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค(์ƒํ•œ 500์œผ๋กœ ์ด๋ฏธ ๋ฌถ์—ฌ ์žˆ๋‹ค). ์ž๋ฆฌยท์„ค๋น„ยท์ธ์›ยท์ž์‚ฐยท์ž‘์—…ยท์˜ค๋”๋„ ๋ฒ”์œ„๋ฅผ ๋ฐ›์ง€
42
+ * ์•Š๋Š”๋‹ค โ€” ์ˆ˜๊ฐ€ ์ ๊ณ , ์ž˜๋ชป ๊ฑธ๋Ÿฌ์„œ ์žƒ๋Š” ๊ฒƒ์ด ํฌ๋‹ค(์ž๋ฆฌ ์ ์œ ๋Š” ๋ฌผํ’ˆ์ด ๋– ๋‚œ ์ž๋ฆฌ์™€ ๋„์ฐฉํ•œ ์ž๋ฆฌ๊ฐ€ ํ•จ๊ป˜
43
+ * ๋ฐ”๋€Œ๋Š”๋ฐ ์‚ฌ๊ฑด์€ ํ•œ ์ง€์ ๋งŒ ๋งํ•œ๋‹ค).
44
+ */
45
+ export interface EntityDeltaScope {
46
+ /** ๊ฐœ๋ณ„ payload ๋ฅผ ๋งŒ๋“ค ๋ฌผํ’ˆ ํƒœ๊ทธ. ์—†์œผ๋ฉด ์ „๋ถ€. */
47
+ items?: ReadonlySet<string>;
48
+ }
49
+ export declare function buildEntityDeltas(state: any, instanceId: string, scope?: EntityDeltaScope): EntityDelta[];
@@ -73,7 +73,7 @@ exports.energyTag = energyTag;
73
73
  const EXCLUDED = new Set(['id', 'epc', 'oee']);
74
74
  /**
75
75
  * OEE ์›์‹œ ๋น„์œจ/์นด์šดํŠธ โ†’ ํ‘œ์‹œ์šฉ ์ •์ˆ˜ ํผ์„ผํŠธ + ์นด์šดํŠธ.
76
- * ์›์‹œ ๋ˆ„์  ms(idleMs ๋“ฑ)๋Š” ๋งค delta ์ฆ๊ฐ€ํ•ด ๋ฌด๋ณ€ํ™”-์ƒ๋žต์„ ๋ฌด๋ ฅํ™”ํ•˜๋ฏ€๋กœ ์ œ์™ธ(์œ ํœด ์ž์›์˜ ๋งค์ดˆ ์žฌ๋ฐฉ์†ก ์–ต์ œ).
76
+ * ์›์‹œ ๋ˆ„์  ms(idleMs ๋“ฑ)๋Š” ๋งค delta ์ฆ๊ฐ€ํ•ด ๋ฌด๋ณ€ํ™”-์ƒ๋žต์„ ๋ฌด๋ ฅํ™”ํ•˜๋ฏ€๋กœ ์ œ์™ธ(์œ ํœด ์ž์›์˜ ๋งค์ดˆ ์žฌ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ… ์–ต์ œ).
77
77
  * oee ๋ฏธ์ธก์ •์ด๋ฉด undefined.
78
78
  */
79
79
  function shapeOee(o) {
@@ -121,11 +121,11 @@ function aggregateItem(entity, idKey) {
121
121
  return out;
122
122
  }
123
123
  /**
124
- * ๋ฌผํ’ˆ ์ง‘์•ฝ์˜ ์ƒํ•œ โ€” ํฐ ํ˜„์žฅ์€ ๋ฌผํ’ˆ์ด ์ˆ˜๋งŒ ๊ฐœ๋ผ, ์ „๋Ÿ‰์„ ๋งค ๋ฐฉ์†ก์— ์‹ค์œผ๋ฉด ์ „๋‹ฌ์ด ํ˜„์žฅ์„ ๋А๋ฆฌ๊ฒŒ ํ•œ๋‹ค.
124
+ * ๋ฌผํ’ˆ ์ง‘์•ฝ์˜ ์ƒํ•œ โ€” ํฐ ํ˜„์žฅ์€ ๋ฌผํ’ˆ์ด ์ˆ˜๋งŒ ๊ฐœ๋ผ, ์ „๋Ÿ‰์„ ๋งค ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…์— ์‹ค์œผ๋ฉด ์ „๋‹ฌ์ด ํ˜„์žฅ์„ ๋А๋ฆฌ๊ฒŒ ํ•œ๋‹ค.
125
125
  *
126
126
  * **์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค**: ๋„˜์น˜๋ฉด `total`(์ „์ฒด ์ˆ˜)๊ณผ `truncated`(์ž˜๋ฆฐ ์ˆ˜)๋ฅผ ํ•จ๊ป˜ ์‹ค์–ด, ์†Œ๋น„์ฒ˜๊ฐ€
127
127
  * "์ด๊ฒŒ ์ „๋ถ€" ๋ผ๊ณ  ์˜คํ•ดํ•˜์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค. ๊ฐœ๋ณ„ ๋ฌผํ’ˆ์€ ํƒœ๊ทธ๋ณ„ delta ๋กœ ๋”ฐ๋กœ ๋‚˜๊ฐ€๊ณ  ๊ทธ์ชฝ์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜ dedup
128
- * ์ด ๊ฑธ๋ ค **๋ณ€ํ•œ ๊ฒƒ๋งŒ** ์žฌ๋ฐฉ์†ก๋œ๋‹ค.
128
+ * ์ด ๊ฑธ๋ ค **๋ณ€ํ•œ ๊ฒƒ๋งŒ** ์žฌ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…๋œ๋‹ค.
129
129
  */
130
130
  exports.ITEMS_AGGREGATE_LIMIT = 500;
131
131
  /**
@@ -176,7 +176,7 @@ function energyByLocation(state) {
176
176
  }
177
177
  return out;
178
178
  }
179
- function buildEntityDeltas(state, instanceId) {
179
+ function buildEntityDeltas(state, instanceId, scope) {
180
180
  const out = [];
181
181
  const locEnergy = energyByLocation(state);
182
182
  for (const n of state?.locations ?? []) {
@@ -208,9 +208,13 @@ function buildEntityDeltas(state, instanceId) {
208
208
  out.push({ tag: t.id, data: payloadOf('task', t) });
209
209
  }
210
210
  for (const it of state?.items ?? []) {
211
- /* ๋ฌผํ’ˆ์˜ ํƒœ๊ทธ๋Š” epc(๊ฐœ์ฒด ์‹๋ณ„์ž) โ€” ๋…ธ๋“œยท๋ฌด๋ฒ„์™€ ๋‹ฌ๋ฆฌ id ๊ฐ€ ์•„๋‹ˆ๋‹ค. */
212
- if (it?.epc)
213
- out.push({ tag: it.epc, data: payloadOf('item', it) });
211
+ /* ๋ฌผํ’ˆ์˜ ํƒœ๊ทธ๋Š” epc(๊ฐœ์ฒด ์‹๋ณ„์ž) โ€” ์ž๋ฆฌยท์„ค๋น„์™€ ๋‹ฌ๋ฆฌ id ๊ฐ€ ์•„๋‹ˆ๋‹ค. */
212
+ if (!it?.epc)
213
+ continue;
214
+ /* ๋ฒ”์œ„๊ฐ€ ์ฃผ์–ด์กŒ์œผ๋ฉด ๊ทธ ์•ˆ์˜ ๋ฌผํ’ˆ๋งŒ ๋งŒ๋“ ๋‹ค โ€” ๋‚˜๋จธ์ง€๋Š” ๊ฐ’์ด ๊ทธ๋Œ€๋กœ์ด๋ฏ€๋กœ ๋ณด๋‚ผ ๊ฒƒ์ด ์—†๋‹ค. */
215
+ if (scope?.items && !scope.items.has(it.epc))
216
+ continue;
217
+ out.push({ tag: it.epc, data: payloadOf('item', it) });
214
218
  }
215
219
  /* โ”€โ”€ ์ง‘์•ฝ ๋ทฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
216
220
  * ๋Ÿฐํƒ€์ž„์— ์ƒ๊ธฐ๊ณ  ์‚ฌ๋ผ์ง€๋Š” ์—”ํ‹ฐํ‹ฐ(์˜ค๋”ยท์ž‘์—…ยท๋ฌผํ’ˆ)๋Š” ๋ณด๋“œ์— ๊ฐœ๋ณ„ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์—†๋‹ค โ†’ ํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€
@@ -275,7 +279,7 @@ function buildEntityDeltas(state, instanceId) {
275
279
  ...(energy.contractKW !== undefined ? { contractKW: energy.contractKW } : {}),
276
280
  ...(energy.open ? { open: energy.open } : {}),
277
281
  ...(energy.peakSince ? { peakSince: energy.peakSince } : {}),
278
- /* ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„์€ **์ตœ๊ทผ ๊ฒƒ๋งŒ** ๋‚ธ๋‹ค โ€” ํ•˜๋ฃจ์น˜๋ฅผ ๋งค ๋ฐฉ์†ก์— ์‹ค์œผ๋ฉด ์ฑ„๋„์ด ๊ทธ๊ฒƒ์œผ๋กœ ์ฐฌ๋‹ค.
282
+ /* ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„์€ **์ตœ๊ทผ ๊ฒƒ๋งŒ** ๋‚ธ๋‹ค โ€” ํ•˜๋ฃจ์น˜๋ฅผ ๋งค ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…์— ์‹ค์œผ๋ฉด ์ฑ„๋„์ด ๊ทธ๊ฒƒ์œผ๋กœ ์ฐฌ๋‹ค.
279
283
  ์ „์ฒด ์ˆ˜๋Š” ํ•จ๊ป˜ ๋‚ธ๋‹ค(์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค). */
280
284
  recent: (energy.closed ?? []).slice(-8),
281
285
  closedTotal: energy.closedTotal ?? 0