@things-factory/headless-twin 10.1.278 โ†’ 10.1.280

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 (614) hide show
  1. package/package.json +21 -7
  2. package/dist-server/engine/attention-digest.js.map +0 -1
  3. package/dist-server/engine/canonical-ingest.js.map +0 -1
  4. package/dist-server/engine/checkpoint-fold.js.map +0 -1
  5. package/dist-server/engine/command-routing.js.map +0 -1
  6. package/dist-server/engine/declared-stimulus.js.map +0 -1
  7. package/dist-server/engine/energy-topology.js.map +0 -1
  8. package/dist-server/engine/event-time.js.map +0 -1
  9. package/dist-server/engine/index.js.map +0 -1
  10. package/dist-server/engine/ingest-dedupe.js.map +0 -1
  11. package/dist-server/engine/ingest-health.js.map +0 -1
  12. package/dist-server/engine/integration-coverage.js.map +0 -1
  13. package/dist-server/engine/integration-probes.js.map +0 -1
  14. package/dist-server/engine/integration-runner.js.map +0 -1
  15. package/dist-server/engine/integration-target-profile.js.map +0 -1
  16. package/dist-server/engine/kpi-baseline.js.map +0 -1
  17. package/dist-server/engine/kpi-fold.js.map +0 -1
  18. package/dist-server/engine/kpi-query.js.map +0 -1
  19. package/dist-server/engine/kpi-target.js.map +0 -1
  20. package/dist-server/engine/live-attentions.js.map +0 -1
  21. package/dist-server/engine/live-feed-registry.js.map +0 -1
  22. package/dist-server/engine/load-meter.js.map +0 -1
  23. package/dist-server/engine/local-declarations.js.map +0 -1
  24. package/dist-server/engine/log.js.map +0 -1
  25. package/dist-server/engine/loop-lag.js.map +0 -1
  26. package/dist-server/engine/measured-estimator.js.map +0 -1
  27. package/dist-server/engine/measured-yield.js.map +0 -1
  28. package/dist-server/engine/model-basis.js.map +0 -1
  29. package/dist-server/engine/model-gap.js.map +0 -1
  30. package/dist-server/engine/model-refusal.js.map +0 -1
  31. package/dist-server/engine/model-vocabulary.js.map +0 -1
  32. package/dist-server/engine/oee-accumulator.js.map +0 -1
  33. package/dist-server/engine/operation-basis.js.map +0 -1
  34. package/dist-server/engine/producer-guard.js.map +0 -1
  35. package/dist-server/engine/property-effects.js.map +0 -1
  36. package/dist-server/engine/read-time.js.map +0 -1
  37. package/dist-server/engine/restart-policy.js.map +0 -1
  38. package/dist-server/engine/runtime-key.js.map +0 -1
  39. package/dist-server/engine/spec-coverage.js.map +0 -1
  40. package/dist-server/engine/stage-path.js.map +0 -1
  41. package/dist-server/engine/state-axes.js.map +0 -1
  42. package/dist-server/engine/structure-diff.js.map +0 -1
  43. package/dist-server/engine/travel-estimator.js.map +0 -1
  44. package/dist-server/engine/twin-engine.js.map +0 -1
  45. package/dist-server/engine/twin-state-channel.js.map +0 -1
  46. package/dist-server/engine/warm-start.js.map +0 -1
  47. package/dist-server/index.js.map +0 -1
  48. package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +0 -1
  49. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +0 -1
  50. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +0 -1
  51. package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +0 -1
  52. package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +0 -1
  53. package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +0 -1
  54. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js.map +0 -1
  55. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js.map +0 -1
  56. package/dist-server/migrations/1786800000000-CreateTwinReferenceReconciliations.js.map +0 -1
  57. package/dist-server/migrations/index.js.map +0 -1
  58. package/dist-server/routes.js.map +0 -1
  59. package/dist-server/service/actuation/actuation-advisor.js.map +0 -1
  60. package/dist-server/service/actuation/actuation-outcome.js.map +0 -1
  61. package/dist-server/service/actuation/actuation-rule-resolver.js.map +0 -1
  62. package/dist-server/service/actuation/actuation-rule.js.map +0 -1
  63. package/dist-server/service/actuation/approval-gateway.js.map +0 -1
  64. package/dist-server/service/actuation/catch-up-effects.js.map +0 -1
  65. package/dist-server/service/actuation/command-dispatcher.js.map +0 -1
  66. package/dist-server/service/actuation/command-store.js.map +0 -1
  67. package/dist-server/service/actuation/dispatch-after-approval.js.map +0 -1
  68. package/dist-server/service/actuation/effect-match.js.map +0 -1
  69. package/dist-server/service/actuation/index.js.map +0 -1
  70. package/dist-server/service/actuation/retry-plan.js.map +0 -1
  71. package/dist-server/service/actuation/rule-evaluate.js.map +0 -1
  72. package/dist-server/service/actuation/rule-loop.js.map +0 -1
  73. package/dist-server/service/actuation/rule-runner.js.map +0 -1
  74. package/dist-server/service/actuation/rule-wiring.js.map +0 -1
  75. package/dist-server/service/actuation/settle-effects.js.map +0 -1
  76. package/dist-server/service/actuation/sweep-dispatch.js.map +0 -1
  77. package/dist-server/service/actuation/twin-command-resolver.js.map +0 -1
  78. package/dist-server/service/actuation/twin-command.js.map +0 -1
  79. package/dist-server/service/actuation/twin-now.js.map +0 -1
  80. package/dist-server/service/index.js.map +0 -1
  81. package/dist-server/service/reference/actuation-routing.js.map +0 -1
  82. package/dist-server/service/reference/actuation-target.js.map +0 -1
  83. package/dist-server/service/reference/actuation-verification.js.map +0 -1
  84. package/dist-server/service/reference/attention-lane.js.map +0 -1
  85. package/dist-server/service/reference/connection-portability-resolver.js.map +0 -1
  86. package/dist-server/service/reference/connection-portability.js.map +0 -1
  87. package/dist-server/service/reference/control-routing.js.map +0 -1
  88. package/dist-server/service/reference/discovery-result.js.map +0 -1
  89. package/dist-server/service/reference/fill-cadence.js.map +0 -1
  90. package/dist-server/service/reference/fill-dedupe.js.map +0 -1
  91. package/dist-server/service/reference/fill-loop.js.map +0 -1
  92. package/dist-server/service/reference/fill-span.js.map +0 -1
  93. package/dist-server/service/reference/hook-contract.js.map +0 -1
  94. package/dist-server/service/reference/hook-rejected.js.map +0 -1
  95. package/dist-server/service/reference/hook-store.js.map +0 -1
  96. package/dist-server/service/reference/index.js.map +0 -1
  97. package/dist-server/service/reference/ingest-space.js.map +0 -1
  98. package/dist-server/service/reference/knob-defaults.js.map +0 -1
  99. package/dist-server/service/reference/live-cadence.js.map +0 -1
  100. package/dist-server/service/reference/live-feed-lease.js.map +0 -1
  101. package/dist-server/service/reference/live-ingest.js.map +0 -1
  102. package/dist-server/service/reference/reference-adapter.js.map +0 -1
  103. package/dist-server/service/reference/reference-assessment.js.map +0 -1
  104. package/dist-server/service/reference/reference-fill-run.js.map +0 -1
  105. package/dist-server/service/reference/reference-fill.js.map +0 -1
  106. package/dist-server/service/reference/reference-hook.js.map +0 -1
  107. package/dist-server/service/reference/reference-link-groups.js.map +0 -1
  108. package/dist-server/service/reference/reference-links.js.map +0 -1
  109. package/dist-server/service/reference/reference-live.js.map +0 -1
  110. package/dist-server/service/reference/reference-master.js.map +0 -1
  111. package/dist-server/service/reference/reference-probe.js.map +0 -1
  112. package/dist-server/service/reference/reference-progress-channel.js.map +0 -1
  113. package/dist-server/service/reference/reference-progress-subscription.js.map +0 -1
  114. package/dist-server/service/reference/reference-progress.js.map +0 -1
  115. package/dist-server/service/reference/reference-reconciliation-query.js.map +0 -1
  116. package/dist-server/service/reference/reference-reconciliation-writer.js.map +0 -1
  117. package/dist-server/service/reference/reference-reconciliation.js.map +0 -1
  118. package/dist-server/service/reference/reference-registry.js.map +0 -1
  119. package/dist-server/service/reference/reference-resolver.js.map +0 -1
  120. package/dist-server/service/reference/template-registry.js.map +0 -1
  121. package/dist-server/service/reference/twin-reference-reconciliation.js.map +0 -1
  122. package/dist-server/service/reference/twin-reference.js.map +0 -1
  123. package/dist-server/service/twin-attention/index.js.map +0 -1
  124. package/dist-server/service/twin-attention/twin-attention-query.js.map +0 -1
  125. package/dist-server/service/twin-audit/command-audit.js.map +0 -1
  126. package/dist-server/service/twin-audit/index.js.map +0 -1
  127. package/dist-server/service/twin-audit/twin-audit-event.js.map +0 -1
  128. package/dist-server/service/twin-audit/twin-audit-query.js.map +0 -1
  129. package/dist-server/service/twin-backfill/backfill-period-facts.js.map +0 -1
  130. package/dist-server/service/twin-backfill/backfill-shape.js.map +0 -1
  131. package/dist-server/service/twin-backfill/index.js.map +0 -1
  132. package/dist-server/service/twin-backfill/twin-backfill-resolver.js.map +0 -1
  133. package/dist-server/service/twin-control/index.js.map +0 -1
  134. package/dist-server/service/twin-control/twin-control-mutation.js.map +0 -1
  135. package/dist-server/service/twin-event/index.js.map +0 -1
  136. package/dist-server/service/twin-event/journal-count.js.map +0 -1
  137. package/dist-server/service/twin-event/twin-event-keys.js.map +0 -1
  138. package/dist-server/service/twin-event/twin-event-type.js.map +0 -1
  139. package/dist-server/service/twin-event/twin-event.js.map +0 -1
  140. package/dist-server/service/twin-forecast/forecast-metrics.js.map +0 -1
  141. package/dist-server/service/twin-forecast/forecast-tuning.js.map +0 -1
  142. package/dist-server/service/twin-forecast/gap-analytics.js.map +0 -1
  143. package/dist-server/service/twin-forecast/index.js.map +0 -1
  144. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +0 -1
  145. package/dist-server/service/twin-ingest-window/index.js.map +0 -1
  146. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +0 -1
  147. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +0 -1
  148. package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +0 -1
  149. package/dist-server/service/twin-instance/index.js.map +0 -1
  150. package/dist-server/service/twin-instance/twin-instance.js.map +0 -1
  151. package/dist-server/service/twin-journal/event-type-split-shape.js.map +0 -1
  152. package/dist-server/service/twin-journal/event-type-split.js.map +0 -1
  153. package/dist-server/service/twin-journal/index.js.map +0 -1
  154. package/dist-server/service/twin-journal/journal-order.js.map +0 -1
  155. package/dist-server/service/twin-journal/twin-journal-query.js.map +0 -1
  156. package/dist-server/service/twin-lifecycle/domain-catalog.js.map +0 -1
  157. package/dist-server/service/twin-lifecycle/index.js.map +0 -1
  158. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +0 -1
  159. package/dist-server/service/twin-metrics/index.js.map +0 -1
  160. package/dist-server/service/twin-metrics/twin-metrics-query.js.map +0 -1
  161. package/dist-server/service/twin-model/axis-journal-evidence.js.map +0 -1
  162. package/dist-server/service/twin-model/choose-recipe.js.map +0 -1
  163. package/dist-server/service/twin-model/epcis-coverage.js.map +0 -1
  164. package/dist-server/service/twin-model/external-resolver.js.map +0 -1
  165. package/dist-server/service/twin-model/iec61850-coverage.js.map +0 -1
  166. package/dist-server/service/twin-model/index.js.map +0 -1
  167. package/dist-server/service/twin-model/isa95-coverage.js.map +0 -1
  168. package/dist-server/service/twin-model/item-ref.js.map +0 -1
  169. package/dist-server/service/twin-model/name-index.js.map +0 -1
  170. package/dist-server/service/twin-model/project-structure.js.map +0 -1
  171. package/dist-server/service/twin-model/standard-coverage.js.map +0 -1
  172. package/dist-server/service/twin-model/status-tally.js.map +0 -1
  173. package/dist-server/service/twin-model/twin-equipment.js.map +0 -1
  174. package/dist-server/service/twin-model/twin-lineage-query.js.map +0 -1
  175. package/dist-server/service/twin-model/twin-location.js.map +0 -1
  176. package/dist-server/service/twin-model/twin-model-item-query.js.map +0 -1
  177. package/dist-server/service/twin-model/twin-model-mutation.js.map +0 -1
  178. package/dist-server/service/twin-model/twin-model-query.js.map +0 -1
  179. package/dist-server/service/twin-model/twin-model-tree-query.js.map +0 -1
  180. package/dist-server/service/twin-model/twin-operation.js.map +0 -1
  181. package/dist-server/service/twin-readiness/index.js.map +0 -1
  182. package/dist-server/service/twin-readiness/twin-readiness-query.js.map +0 -1
  183. package/dist-server/service/twin-space/area-resolver.js.map +0 -1
  184. package/dist-server/service/twin-space/index.js.map +0 -1
  185. package/dist-server/service/twin-space/move-space.js.map +0 -1
  186. package/dist-server/service/twin-space/representation-role.js.map +0 -1
  187. package/dist-server/service/twin-space/space-integrity.js.map +0 -1
  188. package/dist-server/service/twin-space/twin-area.js.map +0 -1
  189. package/dist-server/service/twin-space/twin-space-area.js.map +0 -1
  190. package/dist-server/service/twin-space/twin-space-representation.js.map +0 -1
  191. package/dist-server/service/twin-space/twin-space-resolver.js.map +0 -1
  192. package/dist-server/service/twin-space/twin-space.js.map +0 -1
  193. package/dist-server/service/twin-state/index.js.map +0 -1
  194. package/dist-server/service/twin-state/twin-state-subscription.js.map +0 -1
  195. package/dist-server/service/twin-structure/index.js.map +0 -1
  196. package/dist-server/service/twin-structure/twin-structure.js.map +0 -1
  197. package/dist-server/service/twin-subject/event-subjects.js.map +0 -1
  198. package/dist-server/service/twin-subject/index.js.map +0 -1
  199. package/dist-server/service/twin-subject/item-resolver.js.map +0 -1
  200. package/dist-server/service/twin-subject/subject-query-shape.js.map +0 -1
  201. package/dist-server/service/twin-subject/twin-subject-backfill.js.map +0 -1
  202. package/dist-server/service/twin-subject/twin-subject-event.js.map +0 -1
  203. package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +0 -1
  204. package/dist-server/service/twin-subject/twin-subject-query.js.map +0 -1
  205. package/dist-server/service/twin-subject/twin-subject-writer.js.map +0 -1
  206. package/dist-server/service/twin-target/index.js.map +0 -1
  207. package/dist-server/service/twin-target/twin-target-resolver.js.map +0 -1
  208. package/dist-server/service/twin-target/twin-target.js.map +0 -1
  209. package/dist-shared/axis-read.js.map +0 -1
  210. package/dist-shared/entity-delta.js.map +0 -1
  211. package/dist-shared/kpi-broadcast.js.map +0 -1
  212. package/dist-shared/touched-items.js.map +0 -1
  213. package/dist-shared/twin-level.js.map +0 -1
  214. package/server/engine/attention-digest.ts +0 -102
  215. package/server/engine/canonical-ingest.ts +0 -511
  216. package/server/engine/checkpoint-fold.ts +0 -12
  217. package/server/engine/command-routing.ts +0 -67
  218. package/server/engine/declared-stimulus.ts +0 -66
  219. package/server/engine/energy-topology.ts +0 -189
  220. package/server/engine/event-time.ts +0 -96
  221. package/server/engine/index.ts +0 -51
  222. package/server/engine/ingest-dedupe.ts +0 -24
  223. package/server/engine/ingest-health.ts +0 -24
  224. package/server/engine/integration-coverage.ts +0 -147
  225. package/server/engine/integration-probes.ts +0 -144
  226. package/server/engine/integration-runner.ts +0 -95
  227. package/server/engine/integration-target-profile.ts +0 -103
  228. package/server/engine/kpi-baseline.ts +0 -202
  229. package/server/engine/kpi-fold.ts +0 -1516
  230. package/server/engine/kpi-query.ts +0 -1210
  231. package/server/engine/kpi-target.ts +0 -248
  232. package/server/engine/live-attentions.ts +0 -30
  233. package/server/engine/live-feed-registry.ts +0 -59
  234. package/server/engine/load-meter.ts +0 -393
  235. package/server/engine/local-declarations.ts +0 -779
  236. package/server/engine/log.ts +0 -72
  237. package/server/engine/loop-lag.ts +0 -120
  238. package/server/engine/measured-estimator.ts +0 -91
  239. package/server/engine/measured-yield.ts +0 -89
  240. package/server/engine/model-basis.ts +0 -162
  241. package/server/engine/model-gap.ts +0 -168
  242. package/server/engine/model-refusal.ts +0 -31
  243. package/server/engine/model-vocabulary.ts +0 -82
  244. package/server/engine/oee-accumulator.ts +0 -195
  245. package/server/engine/operation-basis.ts +0 -131
  246. package/server/engine/producer-guard.ts +0 -64
  247. package/server/engine/property-effects.ts +0 -216
  248. package/server/engine/read-time.ts +0 -77
  249. package/server/engine/restart-policy.ts +0 -55
  250. package/server/engine/runtime-key.ts +0 -58
  251. package/server/engine/spec-coverage.ts +0 -105
  252. package/server/engine/stage-path.ts +0 -172
  253. package/server/engine/state-axes.ts +0 -60
  254. package/server/engine/structure-diff.ts +0 -88
  255. package/server/engine/travel-estimator.ts +0 -138
  256. package/server/engine/twin-engine.ts +0 -4979
  257. package/server/engine/twin-state-channel.ts +0 -39
  258. package/server/engine/warm-start.ts +0 -265
  259. package/server/index.ts +0 -90
  260. package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +0 -43
  261. package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +0 -54
  262. package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +0 -53
  263. package/server/migrations/1786300000000-IndexEventTypeByTime.ts +0 -48
  264. package/server/migrations/1786400000000-IndexEventCreatedAt.ts +0 -38
  265. package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +0 -93
  266. package/server/migrations/1786600000000-RenameOperatoMesAdapterType.ts +0 -66
  267. package/server/migrations/1786700000000-AddDispatchRetryColumns.ts +0 -82
  268. package/server/migrations/1786800000000-CreateTwinReferenceReconciliations.ts +0 -39
  269. package/server/migrations/index.ts +0 -25
  270. package/server/routes.ts +0 -75
  271. package/server/service/actuation/actuation-advisor.ts +0 -131
  272. package/server/service/actuation/actuation-outcome.ts +0 -97
  273. package/server/service/actuation/actuation-rule-resolver.ts +0 -147
  274. package/server/service/actuation/actuation-rule.ts +0 -139
  275. package/server/service/actuation/approval-gateway.ts +0 -44
  276. package/server/service/actuation/catch-up-effects.ts +0 -152
  277. package/server/service/actuation/command-dispatcher.ts +0 -474
  278. package/server/service/actuation/command-store.ts +0 -236
  279. package/server/service/actuation/dispatch-after-approval.ts +0 -71
  280. package/server/service/actuation/effect-match.ts +0 -124
  281. package/server/service/actuation/index.ts +0 -27
  282. package/server/service/actuation/retry-plan.ts +0 -145
  283. package/server/service/actuation/rule-evaluate.ts +0 -352
  284. package/server/service/actuation/rule-loop.ts +0 -160
  285. package/server/service/actuation/rule-runner.ts +0 -216
  286. package/server/service/actuation/rule-wiring.ts +0 -84
  287. package/server/service/actuation/settle-effects.ts +0 -115
  288. package/server/service/actuation/sweep-dispatch.ts +0 -179
  289. package/server/service/actuation/twin-command-resolver.ts +0 -387
  290. package/server/service/actuation/twin-command.ts +0 -232
  291. package/server/service/actuation/twin-now.ts +0 -97
  292. package/server/service/index.ts +0 -100
  293. package/server/service/reference/actuation-routing.ts +0 -192
  294. package/server/service/reference/actuation-target.ts +0 -163
  295. package/server/service/reference/actuation-verification.ts +0 -85
  296. package/server/service/reference/attention-lane.ts +0 -21
  297. package/server/service/reference/connection-portability-resolver.ts +0 -171
  298. package/server/service/reference/connection-portability.ts +0 -329
  299. package/server/service/reference/control-routing.ts +0 -62
  300. package/server/service/reference/discovery-result.ts +0 -95
  301. package/server/service/reference/fill-cadence.ts +0 -29
  302. package/server/service/reference/fill-dedupe.ts +0 -66
  303. package/server/service/reference/fill-loop.ts +0 -153
  304. package/server/service/reference/fill-span.ts +0 -31
  305. package/server/service/reference/hook-contract.ts +0 -364
  306. package/server/service/reference/hook-rejected.ts +0 -53
  307. package/server/service/reference/hook-store.ts +0 -28
  308. package/server/service/reference/index.ts +0 -18
  309. package/server/service/reference/ingest-space.ts +0 -104
  310. package/server/service/reference/knob-defaults.ts +0 -59
  311. package/server/service/reference/live-cadence.ts +0 -129
  312. package/server/service/reference/live-feed-lease.ts +0 -56
  313. package/server/service/reference/live-ingest.ts +0 -94
  314. package/server/service/reference/reference-adapter.ts +0 -985
  315. package/server/service/reference/reference-assessment.ts +0 -250
  316. package/server/service/reference/reference-fill-run.ts +0 -179
  317. package/server/service/reference/reference-fill.ts +0 -223
  318. package/server/service/reference/reference-hook.ts +0 -479
  319. package/server/service/reference/reference-link-groups.ts +0 -21
  320. package/server/service/reference/reference-links.ts +0 -77
  321. package/server/service/reference/reference-live.ts +0 -420
  322. package/server/service/reference/reference-master.ts +0 -999
  323. package/server/service/reference/reference-probe.ts +0 -264
  324. package/server/service/reference/reference-progress-channel.ts +0 -26
  325. package/server/service/reference/reference-progress-subscription.ts +0 -78
  326. package/server/service/reference/reference-progress.ts +0 -95
  327. package/server/service/reference/reference-reconciliation-query.ts +0 -28
  328. package/server/service/reference/reference-reconciliation-writer.ts +0 -38
  329. package/server/service/reference/reference-reconciliation.ts +0 -55
  330. package/server/service/reference/reference-registry.ts +0 -17
  331. package/server/service/reference/reference-resolver.ts +0 -969
  332. package/server/service/reference/template-registry.ts +0 -85
  333. package/server/service/reference/twin-reference-reconciliation.ts +0 -27
  334. package/server/service/reference/twin-reference.ts +0 -190
  335. package/server/service/twin-attention/index.ts +0 -3
  336. package/server/service/twin-attention/twin-attention-query.ts +0 -70
  337. package/server/service/twin-audit/command-audit.ts +0 -114
  338. package/server/service/twin-audit/index.ts +0 -5
  339. package/server/service/twin-audit/twin-audit-event.ts +0 -158
  340. package/server/service/twin-audit/twin-audit-query.ts +0 -72
  341. package/server/service/twin-backfill/backfill-period-facts.ts +0 -168
  342. package/server/service/twin-backfill/backfill-shape.ts +0 -86
  343. package/server/service/twin-backfill/index.ts +0 -3
  344. package/server/service/twin-backfill/twin-backfill-resolver.ts +0 -35
  345. package/server/service/twin-control/index.ts +0 -3
  346. package/server/service/twin-control/twin-control-mutation.ts +0 -150
  347. package/server/service/twin-event/index.ts +0 -3
  348. package/server/service/twin-event/journal-count.ts +0 -53
  349. package/server/service/twin-event/twin-event-keys.ts +0 -215
  350. package/server/service/twin-event/twin-event-type.ts +0 -68
  351. package/server/service/twin-event/twin-event.ts +0 -250
  352. package/server/service/twin-forecast/forecast-metrics.ts +0 -106
  353. package/server/service/twin-forecast/forecast-tuning.ts +0 -40
  354. package/server/service/twin-forecast/gap-analytics.ts +0 -139
  355. package/server/service/twin-forecast/index.ts +0 -3
  356. package/server/service/twin-forecast/twin-forecast-query.ts +0 -486
  357. package/server/service/twin-ingest-window/index.ts +0 -7
  358. package/server/service/twin-ingest-window/twin-ingest-window-query.ts +0 -125
  359. package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +0 -57
  360. package/server/service/twin-ingest-window/twin-ingest-window.ts +0 -113
  361. package/server/service/twin-instance/index.ts +0 -3
  362. package/server/service/twin-instance/twin-instance.ts +0 -199
  363. package/server/service/twin-journal/event-type-split-shape.ts +0 -112
  364. package/server/service/twin-journal/event-type-split.ts +0 -144
  365. package/server/service/twin-journal/index.ts +0 -3
  366. package/server/service/twin-journal/journal-order.ts +0 -20
  367. package/server/service/twin-journal/twin-journal-query.ts +0 -615
  368. package/server/service/twin-lifecycle/domain-catalog.ts +0 -51
  369. package/server/service/twin-lifecycle/index.ts +0 -3
  370. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +0 -285
  371. package/server/service/twin-metrics/index.ts +0 -3
  372. package/server/service/twin-metrics/twin-metrics-query.ts +0 -172
  373. package/server/service/twin-model/axis-journal-evidence.ts +0 -57
  374. package/server/service/twin-model/choose-recipe.ts +0 -31
  375. package/server/service/twin-model/epcis-coverage.ts +0 -251
  376. package/server/service/twin-model/external-resolver.ts +0 -173
  377. package/server/service/twin-model/iec61850-coverage.ts +0 -111
  378. package/server/service/twin-model/index.ts +0 -25
  379. package/server/service/twin-model/isa95-coverage.ts +0 -320
  380. package/server/service/twin-model/item-ref.ts +0 -80
  381. package/server/service/twin-model/name-index.ts +0 -94
  382. package/server/service/twin-model/project-structure.ts +0 -213
  383. package/server/service/twin-model/standard-coverage.ts +0 -35
  384. package/server/service/twin-model/status-tally.ts +0 -37
  385. package/server/service/twin-model/twin-equipment.ts +0 -191
  386. package/server/service/twin-model/twin-lineage-query.ts +0 -327
  387. package/server/service/twin-model/twin-location.ts +0 -147
  388. package/server/service/twin-model/twin-model-item-query.ts +0 -1029
  389. package/server/service/twin-model/twin-model-mutation.ts +0 -503
  390. package/server/service/twin-model/twin-model-query.ts +0 -792
  391. package/server/service/twin-model/twin-model-tree-query.ts +0 -211
  392. package/server/service/twin-model/twin-operation.ts +0 -157
  393. package/server/service/twin-readiness/index.ts +0 -3
  394. package/server/service/twin-readiness/twin-readiness-query.ts +0 -96
  395. package/server/service/twin-space/area-resolver.ts +0 -75
  396. package/server/service/twin-space/index.ts +0 -8
  397. package/server/service/twin-space/move-space.ts +0 -262
  398. package/server/service/twin-space/representation-role.ts +0 -15
  399. package/server/service/twin-space/space-integrity.ts +0 -293
  400. package/server/service/twin-space/twin-area.ts +0 -63
  401. package/server/service/twin-space/twin-space-area.ts +0 -66
  402. package/server/service/twin-space/twin-space-representation.ts +0 -99
  403. package/server/service/twin-space/twin-space-resolver.ts +0 -582
  404. package/server/service/twin-space/twin-space.ts +0 -148
  405. package/server/service/twin-state/index.ts +0 -3
  406. package/server/service/twin-state/twin-state-subscription.ts +0 -62
  407. package/server/service/twin-structure/index.ts +0 -3
  408. package/server/service/twin-structure/twin-structure.ts +0 -96
  409. package/server/service/twin-subject/event-subjects.ts +0 -162
  410. package/server/service/twin-subject/index.ts +0 -10
  411. package/server/service/twin-subject/item-resolver.ts +0 -92
  412. package/server/service/twin-subject/subject-query-shape.ts +0 -84
  413. package/server/service/twin-subject/twin-subject-backfill.ts +0 -196
  414. package/server/service/twin-subject/twin-subject-event.ts +0 -101
  415. package/server/service/twin-subject/twin-subject-fast-path.ts +0 -346
  416. package/server/service/twin-subject/twin-subject-query.ts +0 -210
  417. package/server/service/twin-subject/twin-subject-writer.ts +0 -189
  418. package/server/service/twin-target/index.ts +0 -5
  419. package/server/service/twin-target/twin-target-resolver.ts +0 -142
  420. package/server/service/twin-target/twin-target.ts +0 -97
  421. package/server/types/global.d.ts +0 -22
  422. package/shared/axis-read.ts +0 -28
  423. package/shared/entity-delta.ts +0 -335
  424. package/shared/kpi-broadcast.ts +0 -13
  425. package/shared/touched-items.ts +0 -73
  426. package/shared/twin-level.ts +0 -48
  427. package/test/ack-shape-alignment.test.ts +0 -97
  428. package/test/actuation-advisor.test.ts +0 -55
  429. package/test/actuation-approval-door.test.ts +0 -411
  430. package/test/actuation-dispatch.test.ts +0 -209
  431. package/test/actuation-effect.test.ts +0 -162
  432. package/test/actuation-outcome.test.ts +0 -152
  433. package/test/actuation-rule-runner.test.ts +0 -281
  434. package/test/actuation-rule.test.ts +0 -266
  435. package/test/actuation-seam.test.ts +0 -255
  436. package/test/actuation-settle.test.ts +0 -164
  437. package/test/actuation-target.test.ts +0 -145
  438. package/test/actuation-verification-state.test.ts +0 -139
  439. package/test/adopt-structure-live.test.ts +0 -133
  440. package/test/aggregate-not-findone.test.ts +0 -112
  441. package/test/area-resolver-db.test.ts +0 -110
  442. package/test/attention-digest.test.ts +0 -161
  443. package/test/axis-declaration-passthrough-db.test.ts +0 -152
  444. package/test/axis-journal-evidence.test.ts +0 -71
  445. package/test/axis-read.test.ts +0 -188
  446. package/test/backfill-shape.test.ts +0 -89
  447. package/test/boot-resume.test.ts +0 -287
  448. package/test/broadcast-cost-baseline.test.ts +0 -201
  449. package/test/broadcast-period.test.ts +0 -58
  450. package/test/broadcast-queue-overflow.test.ts +0 -244
  451. package/test/canonical-ingest-vocabularies.test.ts +0 -451
  452. package/test/canonical-quantity-door.test.ts +0 -61
  453. package/test/capability-mapping.test.ts +0 -89
  454. package/test/checkpoint-refuses-empty.test.ts +0 -103
  455. package/test/choose-recipe.test.ts +0 -117
  456. package/test/column-type-portability.test.ts +0 -122
  457. package/test/command-routing.test.ts +0 -61
  458. package/test/command-store-writes-columns.test.ts +0 -126
  459. package/test/connection-portability-doors.test.ts +0 -87
  460. package/test/connector-capability-declaration.test.ts +0 -195
  461. package/test/contract-layer-guard.test.ts +0 -48
  462. package/test/control-capability.test.ts +0 -98
  463. package/test/cursor-stall-not-read-failure.test.ts +0 -126
  464. package/test/declaration-reaches-model.test.ts +0 -226
  465. package/test/declared-location-types.test.ts +0 -89
  466. package/test/declared-stimulus.test.ts +0 -88
  467. package/test/dedupe-transformation.test.ts +0 -112
  468. package/test/discovery-result.test.ts +0 -75
  469. package/test/dispatch-after-approval-source.test.ts +0 -81
  470. package/test/duration-estimators.test.ts +0 -144
  471. package/test/energy-topology.test.ts +0 -113
  472. package/test/entity-delta.test.ts +0 -352
  473. package/test/equipment-identity-reaches.test.ts +0 -57
  474. package/test/event-subjects.test.ts +0 -148
  475. package/test/event-time-column.test.ts +0 -67
  476. package/test/event-type-split.test.ts +0 -178
  477. package/test/external-resolver.test.ts +0 -177
  478. package/test/fact-scope-wiring.test.ts +0 -96
  479. package/test/fill-dedupe.test.ts +0 -59
  480. package/test/fill-loop.test.ts +0 -35
  481. package/test/first-envelope.test.ts +0 -153
  482. package/test/fold-gap-speaks.test.ts +0 -53
  483. package/test/fold-shift-dst.test.ts +0 -110
  484. package/test/forecast-metrics.test.ts +0 -157
  485. package/test/forecast-tuning.test.ts +0 -42
  486. package/test/gap-analytics.test.ts +0 -113
  487. package/test/generated-not-counted.test.ts +0 -99
  488. package/test/guard-roots.ts +0 -76
  489. package/test/home-in-area.test.ts +0 -90
  490. package/test/hook-address.test.ts +0 -28
  491. package/test/hook-rejected-shape.test.ts +0 -86
  492. package/test/hook-response-sum.test.ts +0 -193
  493. package/test/hook-sequence.test.ts +0 -333
  494. package/test/ingest-bench.test.ts +0 -70
  495. package/test/ingest-dedupe.test.ts +0 -56
  496. package/test/ingest-expected-quiet.test.ts +0 -111
  497. package/test/ingest-health-engine.test.ts +0 -248
  498. package/test/ingest-health-wiring.test.ts +0 -120
  499. package/test/ingest-health.test.ts +0 -306
  500. package/test/ingest-history.test.ts +0 -247
  501. package/test/ingest-idempotent.test.ts +0 -211
  502. package/test/ingest-reconcile-four-ways.test.ts +0 -97
  503. package/test/ingest-rules-header.test.ts +0 -100
  504. package/test/ingest-running-guard.test.ts +0 -136
  505. package/test/ingest-space.test.ts +0 -78
  506. package/test/ingest-window-rolls-unobserved.test.ts +0 -72
  507. package/test/ingest-wiring-guard.test.ts +0 -197
  508. package/test/instance-cache-lifecycle.test.ts +0 -110
  509. package/test/intake-mapping-parity.test.ts +0 -175
  510. package/test/integration-probes.test.ts +0 -103
  511. package/test/integration-runner.test.ts +0 -95
  512. package/test/item-ref.test.ts +0 -78
  513. package/test/journal-order-axis.test.ts +0 -80
  514. package/test/journal-read-discipline.test.ts +0 -186
  515. package/test/journal-retention.test.ts +0 -275
  516. package/test/journal-sort-axis.test.ts +0 -142
  517. package/test/journal-write-door.test.ts +0 -110
  518. package/test/journal-write-trend.test.ts +0 -115
  519. package/test/kernel-kind-guard.test.ts +0 -98
  520. package/test/knob-defaults.test.ts +0 -72
  521. package/test/kpi-baseline-db.test.ts +0 -216
  522. package/test/kpi-baseline.test.ts +0 -196
  523. package/test/kpi-fold.test.ts +0 -1456
  524. package/test/kpi-query-bench.test.ts +0 -130
  525. package/test/lens-own-places.test.ts +0 -50
  526. package/test/lineage-survives-restart.test.ts +0 -234
  527. package/test/live-cadence.test.ts +0 -170
  528. package/test/live-cursor-wiring.test.ts +0 -87
  529. package/test/live-feed-lease.test.ts +0 -63
  530. package/test/live-feed-registry.test.ts +0 -75
  531. package/test/live-kernel-facts.test.ts +0 -161
  532. package/test/live-mirror-parity.test.ts +0 -286
  533. package/test/load-meter.test.ts +0 -328
  534. package/test/local-declarations.test.ts +0 -662
  535. package/test/log-stamp.test.ts +0 -59
  536. package/test/loop-lag.test.ts +0 -82
  537. package/test/master-to-twin.test.ts +0 -279
  538. package/test/measured-yield.test.ts +0 -90
  539. package/test/merge-streams.test.ts +0 -70
  540. package/test/mirror-resumes-from-checkpoint.test.ts +0 -192
  541. package/test/model-basis.test.ts +0 -141
  542. package/test/model-gap.test.ts +0 -153
  543. package/test/model-refusal.test.ts +0 -75
  544. package/test/model-vocabulary.test.ts +0 -114
  545. package/test/move-space.test.ts +0 -149
  546. package/test/mutation-gate.test.ts +0 -122
  547. package/test/oee-accumulator.test.ts +0 -204
  548. package/test/oee-site-calendar.test.ts +0 -146
  549. package/test/open-doors.test.ts +0 -197
  550. package/test/operation-basis.test.ts +0 -127
  551. package/test/operational-vocabulary.test.ts +0 -108
  552. package/test/operations-capability-db.test.ts +0 -165
  553. package/test/order-and-transaction-split.test.ts +0 -107
  554. package/test/order-fold-host.test.ts +0 -112
  555. package/test/producer-guard.test.ts +0 -66
  556. package/test/project-structure-db.test.ts +0 -226
  557. package/test/projection-reaches-screen.test.ts +0 -277
  558. package/test/projection-reads-declared.test.ts +0 -109
  559. package/test/property-effects.test.ts +0 -128
  560. package/test/provenance-promotion.test.ts +0 -99
  561. package/test/read-failure-ledger.test.ts +0 -106
  562. package/test/read-failure-visible.test.ts +0 -145
  563. package/test/read-time.test.ts +0 -118
  564. package/test/reference-fill.test.ts +0 -235
  565. package/test/reference-grounding.test.ts +0 -70
  566. package/test/reference-hook.test.ts +0 -177
  567. package/test/reference-links.test.ts +0 -56
  568. package/test/reference-reconciliation.test.ts +0 -39
  569. package/test/registry-key-guard.test.ts +0 -80
  570. package/test/rejection-carries-event-id.test.ts +0 -101
  571. package/test/rename-twin.test.ts +0 -89
  572. package/test/resolve-ts-siblings.mjs +0 -52
  573. package/test/restart-policy.test.ts +0 -111
  574. package/test/resync-origin-site.test.ts +0 -83
  575. package/test/retry-plan.test.ts +0 -139
  576. package/test/revision-axis.test.ts +0 -110
  577. package/test/runtime-key.test.ts +0 -66
  578. package/test/save-intake-collision.test.ts +0 -91
  579. package/test/scale-twin-bench.test.ts +0 -103
  580. package/test/secrets-at-rest.test.ts +0 -135
  581. package/test/snapshot-freshness.test.ts +0 -60
  582. package/test/source-outcome-audit.test.ts +0 -104
  583. package/test/space-integrity.test.ts +0 -223
  584. package/test/space-representation.test.ts +0 -66
  585. package/test/space-scope-includes-stopped.test.ts +0 -55
  586. package/test/spec-coverage.test.ts +0 -113
  587. package/test/stage-path.test.ts +0 -95
  588. package/test/standard-coverage.test.ts +0 -148
  589. package/test/state-axes.test.ts +0 -74
  590. package/test/status-tally.test.ts +0 -55
  591. package/test/streamline-e2e.test.ts +0 -76
  592. package/test/structure-revision-db.test.ts +0 -315
  593. package/test/subject-fast-path.test.ts +0 -148
  594. package/test/subject-read-model.test.ts +0 -175
  595. package/test/sweep-dispatch.test.ts +0 -191
  596. package/test/tenant-registry-db.test.ts +0 -149
  597. package/test/time-range.test.ts +0 -152
  598. package/test/touched-items.test.ts +0 -61
  599. package/test/twin-audit.test.ts +0 -83
  600. package/test/twin-event-keys.test.ts +0 -193
  601. package/test/twin-model-item-db.test.ts +0 -319
  602. package/test/twin-model-parent-relation-db.test.ts +0 -125
  603. package/test/twin-model-tree-db.test.ts +0 -209
  604. package/test/twin-origin-resync.test.ts +0 -133
  605. package/test/twin-state-channel.test.ts +0 -111
  606. package/test/vocabulary-guard.test.ts +0 -43
  607. package/test/warm-start-seam.test.ts +0 -162
  608. package/test/warm-start.test.ts +0 -297
  609. package/test/withheld-door.test.ts +0 -95
  610. package/test/yield-loop.test.ts +0 -199
  611. package/tsconfig.json +0 -15
  612. package/tsconfig.shared.json +0 -23
  613. package/tsconfig.shared.tsbuildinfo +0 -1
  614. package/tsconfig.tsbuildinfo +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"reference-resolver.js","sourceRoot":"","sources":["../../../server/service/reference/reference-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { pubsub } from '@things-factory/shell'\nimport { HOST_STEPS, type ReferenceProgress } from './reference-progress.js'\nimport { REFERENCE_PROGRESS_TOPIC, referenceProgressPayload } from './reference-progress-channel.js'\nimport { assessMaster } from './reference-assessment.js'\nimport { Arg, Ctx, Int, Mutation, Query, Resolver, Directive } from 'type-graphql'\n\nimport { Refusal, ScalarObject, getRepository, refusalKey } from '@things-factory/shell'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { readRestartPolicy } from '../../engine/restart-policy.js'\nimport { readBoardEquipment } from '@operato/ops-contract'\n\nimport { applyKnobDefaults, filledKnobKeys } from './knob-defaults.js'\nimport type { KnobDef } from './template-registry.js'\nimport { knobDefaultsFilled, pickOriginSite, siteEquipmentAdopted } from './reference-master.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinReference } from './twin-reference.js'\nimport { runFill, seqReportOf } from './reference-fill-run.js'\nimport { listReferences, getReference } from './reference-registry.js'\nimport { getAdapter, listAdapterTypes, listAdapters } from './reference-adapter.js'\nimport {\n discovered, failed, detailOf,\n referenceNotFound, adapterUnknown, discoveryFailed, discoveryTimedOut\n} from './discovery-result.js'\nimport { refuseImportSpace } from './ingest-space.js'\nimport { actuationAddressed, actuationResetPatch } from './actuation-verification.js'\nimport { refuseIntakeCollision } from './connection-portability.js'\nimport { startReferenceLiveFeed } from './reference-live.js'\nimport { listTemplates, getTemplate } from './template-registry.js'\n\n/*\n * Face2 ๋ ˆํผ๋Ÿฐ์Šค ์ธ์ œ์ŠคํŠธ ์ฑ„๋„(ADR-0018) โ€” ๋“ฑ๋ก๋œ ๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค๋ฅผ ์—ด๊ฑฐํ•˜๊ณ , ๊ณจ๋ผ์„œ ํŠธ์œˆ์œผ๋กœ ์ธ์ œ์ŠคํŠธ.\n * \"์—ฐ๊ฒฐํ•˜๊ณ  ๋‚ด ๊ฒƒ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค\" โ€” ์—”ํ‹ฐํ‹ฐ๋Š” ๋ ˆํผ๋Ÿฐ์Šค์—์„œ ์˜ค์ง€ ์†๋ฐฐ์„ /๋ฐœ๋ช…์ด ์•„๋‹ˆ๋‹ค.\n */\n\n/**\n * ๋ฐœ๊ฒฌ ์กฐํšŒ์˜ ์‹œ๊ฐ„ ์ƒํ•œ โ€” 15์ดˆ.\n *\n * ์–ด๋Œ‘ํ„ฐ ๊ณ„์•ฝ์— ์‹œ๊ฐ„ ์ œํ•œ์ด ์—†๋‹ค. ์ฃผ์†Œ๊ฐ€ ํ‹€๋ฆฐ ์—”๋“œํฌ์ธํŠธ๋Š” ๋‹ตํ•˜์ง€ ์•Š๊ณ , ๊ทธ๋Ÿฌ๋ฉด ํ™”๋ฉด์ด ๋ฌดํ•œํžˆ ๋กœ๋”ฉ๋œ๋‹ค โ€”\n * ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” \"์‹คํŒจ\" ๋ณด๋‹ค ๋ชปํ•œ ์ƒํƒœ๋‹ค(๋ฌด์—‡์„ ๊ธฐ๋‹ค๋ฆฌ๋Š”์ง€ ๋ชจ๋ฅธ ์ฑ„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค). ์‹ค ์‹œ์Šคํ…œ ์กฐํšŒ๊ฐ€ ๋ช‡ ์ดˆ\n * ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์€ ์ •์ƒ์ด๋ฏ€๋กœ ๋„‰๋„‰ํžˆ ๋‘๋˜, ๋์€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.\n */\nconst DISCOVER_TIMEOUT_MS = 15_000\nconst TIMEOUT = 'discover-timeout'\n\nfunction withTimeout<T>(work: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(Object.assign(new Error('timeout'), { code: TIMEOUT })), ms)\n work.then(\n v => { clearTimeout(timer); resolve(v) },\n e => { clearTimeout(timer); reject(e) }\n )\n })\n}\n\n/**\n * ๊ฑฐ์ ˆ์„ **์‚ฌ์šฉ์ž ์–ธ์–ด๋กœ ์˜ฎ๊ฒจ ๋ณด๋‚ธ๋‹ค** โ€” ๋ฒˆ์—ญ์€ ํ•œ ๊ณณ์—์„œ ํ•œ๋‹ค.\n *\n * โ”€โ”€ ์™œ ์„œ๋ฒ„์ธ๊ฐ€ (2026-08-14) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์‹ค์ธก: ์‹คํ–‰ ์ค‘์ธ ํŠธ์œˆ์„ ๋‹ค์‹œ ํ”„๋กœ๋น„์ €๋‹ํ•˜๋ฉด ใ€Œinstance \"order-check\" is running โ€” stop before\n * re-provisioningใ€ ์ด๋ผ๋Š” **์˜์–ด ํ•œ ์ค„์ด ํ† ์ŠคํŠธ๋กœ** ๋–ด๋‹ค(๋‹ค์„ฏ ์–ธ์–ด ์ œํ’ˆ์—์„œ).\n *\n * ์„œ๋ฒ„์™€ ์•ฑ์€ **๊ฐ™์€ ์‚ฌ์ „**์„ ์“ฐ๊ณ , ์‚ฌ์šฉ์ž์˜ ํ˜„์žฌ ์–ธ์–ด๊ฐ€ ๋ฐฑ์—”๋“œ์— ๋ฐ˜์˜๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ๋ฌธ๊ตฌ๋Š” ์„œ๋ฒ„๊ฐ€\n * ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์ด ๋งž๋‹ค โ€” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋ฏธ ๊ฐ™์€ ๊ทœ์•ฝ์ด๋‹ค(`authenticate-401-middleware` ๊ฐ€\n * `context.t('error.' + errorCode, detail)` ๋กœ ์˜ฎ๊ธด๋‹ค).\n *\n * โ”€โ”€ ๊ทธ๋Ÿฌ๋ฉด ์ฝ”๋“œ๋Š” ์™œ ํ•จ๊ป˜ ๋ณด๋‚ด๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ํ™”๋ฉด์ด **๊ตฌ์กฐ๋กœ** ๋‹ค๋ค„์•ผ ํ•˜๋Š” ๊ฑฐ์ ˆ์ด ๋”ฐ๋กœ ์žˆ๋‹ค(์ •ํ•ฉ์„ฑ ํ‘œ์˜ ํ–‰ยท์‹ฌ๊ฐ๋„ยท์ˆ˜๋ฆฌ ๋ฒ„ํŠผ โ€” ๊ทธ๊ฒƒ๋“ค์€\n * `twin.compose.chk.*` ์ฒ˜๋Ÿผ ํ™”๋ฉด์ด ์˜ฎ๊ธด๋‹ค). ๊ทธ๋ฆฌ๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ ์†Œ๋น„์ž(AIยท์Šคํฌ๋ฆฝํŠธยทAPI)์—๊ฒŒ๋Š”\n * ์ฝ”๋“œ๊ฐ€ ๊ณ„์•ฝ์ด๋‹ค. ๋ฌธ์žฅ๊ณผ ์ฝ”๋“œ๋Š” ์„œ๋กœ๋ฅผ ๋Œ€์‹ ํ•˜์ง€ ์•Š๋Š”๋‹ค.\n *\n * **๋‘ ๊ณณ์—์„œ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ธฐ์ง€ ์•Š๋Š”๋‹ค** โ€” ๋ฌธ์žฅ์ด ๋‘ ๋ฒŒ์ด ๋˜๋ฉด ๋ฐ˜๋“œ์‹œ ์–ด๊ธ‹๋‚œ๋‹ค.\n */\nfunction refusal(context: ResolverContext, e: any, fallback: string): Record<string, unknown> {\n const code = typeof e?.code === 'string' ? e.code : undefined\n const params = e?.params && typeof e.params === 'object' ? e.params : undefined\n /* ์˜์–ด canonical ์€ ํ•ญ์ƒ ๋‚จ๊ธด๋‹ค โ€” ๋ฒˆ์—ญ ํ‚ค๊ฐ€ ์—†์œผ๋ฉด ๊ทธ๊ฒƒ์ด ๋ณด์ด๊ณ , ๋กœ๊ทธ์—๋Š” ๊ทธ๊ฒƒ์ด ๋‚จ๋Š”๋‹ค. */\n const canonical = e?.message || fallback\n /* A shell `Refusal` (a kernel refusal of the model, `asModelRefusal`) has one sentence, under `error.<code>`\n โ€” the same key `SpeakRefusals` reads on every other road, so it is not written twice. */\n const key = e instanceof Refusal ? refusalKey(e.code) : `twin.provision.err.${code}`\n const message =\n code && typeof context.t === 'function'\n ? String(context.t(key, { ...(params ?? {}), defaultValue: canonical }))\n : canonical\n return { ok: false, error: message, ...(code ? { errorCode: code } : {}), ...(params ? { errorParams: params } : {}) }\n}\n\n/**\n * `siteEquipmentIds` ๋…ธ๋ธŒ๋ฅผ ์ด ํ˜„์žฅ์˜ ์„ค๋น„๋กœ ์ฑ„์šด๋‹ค โ€” **๋น„์–ด ์žˆ์„ ๋•Œ๋งŒ.**\n *\n * ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฉ๋ก์„ ์ง์ ‘ ์ค€ ๊ฒฝ์šฐ์—๋Š” ์†๋Œ€์ง€ ์•Š๋Š”๋‹ค(๊ณ ๋ฅธ ๊ฒƒ์ด ์ •๋ณธ์ด๋‹ค). ํ˜„์žฅ์ด ์—†์œผ๋ฉด ์ฑ„์šธ ๊ฒƒ๋„ ์—†๋‹ค.\n * ๋“ฑ๋ก๋ถ€์˜ ๋ชจ๋ธ์—์„œ ์ฝ๋Š”๋‹ค(๋Ÿฐํƒ€์ž„์ด ์•„๋‹ˆ๋‹ค) โ€” ํŠธ์œˆ์ด ๋„๋Š” ์ค‘์ด ์•„๋‹ˆ์–ด๋„ ๊ทธ ํ˜„์žฅ์˜ ์„ค๋น„๋Š” ์‚ฌ์‹ค์ด๋‹ค.\n */\nasync function resolveSiteEquipmentKnobs(\n knobs: readonly KnobDef[] | undefined,\n effective: Record<string, any>,\n domainId: string,\n spaceId?: string\n): Promise<{ key: string; count: number }[]> {\n const targets = (knobs ?? []).filter(k => k?.type === 'siteEquipment')\n if (!targets.length) return []\n const out: { key: string; count: number }[] = []\n let ids: { id: string; kind: string }[] | undefined\n for (const k of targets) {\n const given = effective[k.key]\n if (Array.isArray(given) && given.length) continue // ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ๋ฅธ ๊ฒƒ์ด ์ •๋ณธ์ด๋‹ค\n if (!spaceId) {\n effective[k.key] = []\n continue\n }\n if (ids === undefined) {\n const rows = await getRepository(TwinInstance).find({ where: { domain: { id: domainId }, spaceId } })\n const seen = new Map<string, { id: string; kind: string }>()\n for (const r of rows) {\n for (const e of readBoardEquipment((r.model as any) ?? {})) {\n if (!e?.id || seen.has(String(e.id))) continue\n seen.set(String(e.id), { id: String(e.id), kind: String((e as any).kind ?? '') })\n }\n }\n ids = [...seen.values()]\n }\n effective[k.key] = ids\n out.push({ key: k.key, count: ids.length })\n }\n return out\n}\n\n@Resolver()\nexport class TwinReferenceResolver {\n /** ๋“ฑ๋ก๋œ ๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ๋ชฉ๋ก(์š”์•ฝ + ์ด๋ฏธ ์ธ์ œ์ŠคํŠธ๋๋Š”์ง€). */\n @Query(returns => [ScalarObject], { description: 'List registered reference sources (virtual or real adapters) available to ingest.' })\n async referenceSources(@Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const out: any[] = []\n for (const m of listReferences()) {\n const reg = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId: m.source } })\n out.push({\n source: m.source,\n system: m.system,\n siteName: m.siteName,\n locationCount: m.locations.filter(l => l.role === 'location' || l.role === 'both').length,\n areaCount: m.locations.filter(l => l.role === 'area' || l.role === 'both').length,\n equipmentCount: (m.equipment ?? []).length,\n imported: !!reg,\n running: TwinEngine.owns(domainId, m.source)\n })\n }\n return out\n }\n\n /** ์†Œ์Šค๋ฅผ ์ธ์ œ์ŠคํŠธ โ†’ ๊ณต๊ฐ„ + ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ(provision). start ๋ฉด ๊ธฐ๋™๊นŒ์ง€. */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Ingest a registered reference source into a twin (space + instance). Optionally start it. restartPolicy declares how the new twin treats its own past on reboot: 'resync' (read the source again) | 'resume' (continue its journal) | 'reset' (wipe and replay from the seed). It has no default โ€” a twin cannot exist without the declaration.\"\n })\n async importFromReference(\n @Arg('source') source: string,\n @Arg('restartPolicy') restartPolicy: string,\n @Ctx() context: ResolverContext,\n @Arg('start', { nullable: true }) start?: boolean\n ): Promise<any> {\n const master = getReference(source)\n if (!master) return { ok: false, error: `unknown reference source: ${source}` }\n const domainId = context.state.domain.id\n try {\n /* ์–ด๋””์„œ ์™”๋Š”์ง€ ๋‚จ๊ธด๋‹ค โ€” ์ด๊ฒƒ์ด ์—†์œผ๋ฉด ์ด ํŠธ์œˆ์€ ๋‘ ๋ฒˆ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์—†๋‹ค.\n ์ด ๊ฒฝ๋กœ๋Š” **๋ฉ”๋ชจ๋ฆฌ์— ๋“ฑ๋ก๋œ ๋งˆ์Šคํ„ฐ ํ•˜๋‚˜**๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฏ€๋กœ ์‚ฌ์ดํŠธ ์„œ์ˆ ์ž๊ฐ€ ์—†๋‹ค(์‚ฌ์ดํŠธ ์ •์ฒด๋ฅผ\n ์ ์„ ๊ฒƒ์ด ์—†๋‹ค). ๋‹ค์‹œ ์ฝ๊ธฐ๋„ ๊ฐ™์€ ๋“ฑ๋ก๋ณธ์„ ์ง‘์œผ๋ฏ€๋กœ ์‚ฌ์ดํŠธ๋ฅผ ์ฐพ์„ ํ•„์š”๊ฐ€ ์—†๋‹ค. */\n const res = await TwinEngine.ingestMaster(\n domainId,\n { ...master, origin: { kind: 'reference', source } },\n readRestartPolicy(restartPolicy, 'importFromReference'),\n undefined,\n context.state.user\n )\n if (start) await TwinEngine.startFromRegistry(domainId, res.instanceId)\n return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings: res.warnings }\n } catch (e: any) {\n return refusal(context, e, 'ingest failed')\n }\n }\n\n /**\n * **์›๋ณธ์—์„œ ๋‹ค์‹œ ์ฝ๋Š”๋‹ค** โ€” ์ด ํŠธ์œˆ์˜ ๊ตฌ์กฐ๋ฅผ ์ง€๊ธˆ์˜ ์›๋ณธ ๋ชจ์Šต์œผ๋กœ ๊ฐฑ์‹ ํ•œ๋‹ค.\n *\n * โ”€โ”€ ์™œ ์ง„์ž…์ ์ด ํ•˜๋‚˜์—ฌ์•ผ ํ•˜๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ง€๊ธˆ๊นŒ์ง€ ๋‹ค์‹œ ์ฝ๊ธฐ๋Š” **๋งŒ๋“œ๋Š” ๊ฒฝ๋กœ์— ์–นํ˜€ ์žˆ์—ˆ๋‹ค**(`importFromReference`ยท`createFromTemplate`).\n * ๊ทธ๋ž˜์„œ ์ด๋ฏธ ์žˆ๋Š” ํŠธ์œˆ์„ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด ๋งŒ๋“ค ๋•Œ ๋ฌด์—‡์„ ๊ณจ๋ž๋Š”์ง€ ์‚ฌ๋žŒ์ด ๊ธฐ์–ตํ•ด ๊ฐ™์€ ํ™”๋ฉด์„ ๋‹ค์‹œ\n * ๊ฑฐ์ณ์•ผ ํ–ˆ๊ณ , ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์„ธ์šด ํŠธ์œˆ์€ ๋…ธ๋ธŒ๋ฅผ ์–ด๋””์—๋„ ์•ˆ ๋‚จ๊ฒจ์„œ **์•„์˜ˆ ๊ฐฑ์‹ ํ•  ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค.**\n * ์›์ฒœ์ด ๋ฌด์—‡์ด๋“  ํŠธ์œˆ ์ž์‹ ์ด ๊ธฐ์–ตํ•˜๊ฒŒ ํ•˜๊ณ (`TwinInstance.origin`), ์—ฌ๊ธฐ ํ•œ ๊ณณ์—์„œ ๊ทธ๊ฒƒ์„ ๋”ฐ๋ฅธ๋‹ค.\n *\n * โ”€โ”€ ๋ฌด์—‡์ด ์ผ์–ด๋‚˜๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์›๋ณธ์—์„œ ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ์–ป์–ด ์ธ์ œ์ŠคํŠธ์— ๊ทธ๋Œ€๋กœ ํƒœ์šด๋‹ค. ๊ทธ๋‹ค์Œ์€ ์ธ์ œ์ŠคํŠธ๊ฐ€ ์•„๋Š” ์ผ์ด๋‹ค โ€”\n * ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ผ์กŒ์œผ๋ฉด ์ƒˆ ๋ฆฌ๋น„์ „์ด ๋‚จ๊ณ , ๊ตฌ์กฐ ํ–‰์ด ๋‹ค์‹œ ๊ทธ๋ ค์ง€๊ณ , **์‹คํ–‰ ์ค‘์ธ ๋ฏธ๋Ÿฌ๋Š” ๋ฉˆ์ถ”์ง€ ์•Š๊ณ \n * ์ „ํ™˜ํ•œ๋‹ค.** ์‹คํ–‰ ์ค‘์ธ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์€ ๊ฑฐ์ ˆ๋œ๋‹ค(์กฐ๊ฑด์ด ๋ฐ”๋€ ์‹คํ—˜์€ ๋‹ค๋ฅธ ์‹คํ—˜์ด๋‹ค).\n *\n * โ”€โ”€ ๋ชป ํ•  ๋•Œ๋Š” ๋ชป ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `origin` ์ด ์—†๋Š” ํŠธ์œˆ(์ด ์ž๋ฆฌ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ์ „์— ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ)์€ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์—†๋‹ค. ์ง์ž‘์œผ๋กœ\n * ํ…œํ”Œ๋ฆฟ์„ ๊ณ ๋ฅด๊ฑฐ๋‚˜ ์ฒซ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ง‘์ง€ ์•Š๋Š”๋‹ค โ€” ์—‰๋šฑํ•œ ์›๋ณธ์œผ๋กœ ํ˜„์žฅ์„ ๋ฎ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋‚˜์˜๋‹ค.\n */\n /**\n * **๊ทธ ๋ฒˆํ˜ธ๋“ค์ด ๋ฌด์—‡์ด์—ˆ๋‚˜** โ€” ๊ตฌ๋ฉ์„ ๋งŒ๋‚ฌ์„ ๋•Œ ์›๋ณธ์— ๋ฌป๋Š”๋‹ค.\n *\n * `fillTwinScope` ๊ฐ€ ใ€Œ418 ๋‹ค์Œ์ด 420ใ€์ด๋ผ๊ณ  ๋ฉˆ์ถ”๋ฉด, ๊ทธ 419 ๊ฐ€ ๋ฌด์—‡์ด์—ˆ๋Š”์ง€ ์•Œ์•„์•ผ ๋‹ค์Œ์„\n * ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ๊ธธ์ด ์—†์–ด์„œ ์‚ฌ๋žŒ์ด ์›๋ณธ DB ๋ฅผ ์†์œผ๋กœ ๋’ค์กŒ๋‹ค.\n *\n * **ํŒ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.** ์›๋ณธ์ด ์•„๋Š” ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋‚ธ๋‹ค โ€” `lost` ๋Š” ใ€Œ๋ฒˆํ˜ธ๋Š” ๋‚˜๊ฐ”๋Š”๋ฐ ํ–‰์ด ์—†๋‹คใ€์ด์ง€\n * ใ€Œํฌ๊ธฐํ•ด๋„ ๋œ๋‹คใ€๊ฐ€ ์•„๋‹ˆ๋‹ค. ๊ทธ ํŒ๋‹จ์€ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์–ด์„œ(์ปค์„œ๊ฐ€ ์ง€๋‚˜๊ฐ€๋ฉด ๋์ด๋‹ค) ์‚ฌ๋žŒ์˜ ๋ชซ์ด๋‹ค.\n */\n /*\n * **์ฝ๊ธฐ์ธ๋ฐ ์“ฐ๊ธฐ์™€ ๊ฐ™์€ ๋ฌธ์„ ์“ด๋‹ค.** ์ด ๋ฌธ์€ ์›๋ณธ์˜ ๋ด‰ํˆฌ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ƒ…๋‹ˆ๋‹ค โ€” ๊ทธ ์‹œ์Šคํ…œ์ด ๋ฌด์—‡์„\n * ์–ธ์ œ ๋ณด๋ƒˆ๋Š”์ง€๊ฐ€ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. `twinConnectionBundle` ๊ณผ ๊ฐ™์€ ๋ฌด๊ฒŒ์ด๊ณ , ์ด ์ €์žฅ์†Œ๋Š” ๊ทธ ๋ฌด๊ฒŒ๋ฅผ\n * ใ€Œ์“ฐ๊ธฐ๋Š” GATE ํ•˜๋‚˜ใ€๋กœ ํ†ต์ผํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค(ADR-0027).\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => ScalarObject, {\n description:\n 'Ask the source what it knows about a range of sequence numbers. Each number comes back as present ยท lost ยท unissued ยท unknown โ€” the source reports, the human decides.'\n })\n async twinSeqReport(\n @Arg('instanceId') instanceId: string,\n @Arg('scope') scope: string,\n @Arg('from', type => Int) from: number,\n @Arg('to', type => Int) to: number,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n return seqReportOf({ domainId: context.state.domain.id, instanceId, scope, from, to })\n }\n\n /**\n * **๋น ์ง„ ๊ตฌ๊ฐ„์„ ๋‹ค์‹œ ๋ฐ›๋Š”๋‹ค** โ€” ํ›…์€ ๋ฐ˜๋“œ์‹œ ๋†“์นฉ๋‹ˆ๋‹ค: ์šฐ๋ฆฌ๊ฐ€ ๋‚ด๋ ค๊ฐ€ ์žˆ์„ ๋•Œ, ๊ทธ์ชฝ์ด ๋ชป ๋ณด๋ƒˆ์„ ๋•Œ.\n *\n * โ”€โ”€ ์™œ ๋ฌธ์ด ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ฒˆํ˜ธ๊ฐ€ ๋น„๋ฉด `takeInSequence` ๊ฐ€ ์•Œ์•„์ฑ•๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ **์•Œ์•„์ฑˆ ๋’ค ๊ทธ ์‚ฌ์ด๋ฅผ ์ฑ„์šฐ๋Š” ๊ธธ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.**\n * `fillSince` ๋Š” 2026-08-31 ๋ถ€ํ„ฐ ์žˆ์—ˆ๊ณ  ๋ถ€๋ฅด๋Š” ๊ณณ์ด 0๊ณณ์ด์—ˆ์Šต๋‹ˆ๋‹ค.\n *\n * ์‹ค์ œ๋กœ plant ์•„์›ƒ๋ฐ•์Šค์˜ 1~20 ์„ ์žƒ๊ณ  ๋˜์ฐพ์„ ๋ฐฉ๋ฒ•์ด ์—†๋Š” ์ƒํƒœ๋ฅผ ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค.\n *\n * โ”€โ”€ `from` ์€ ์žƒ์€ ๊ตฌ๊ฐ„์„ ๋˜์ฐพ์„ ๋•Œ๋งŒ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ฃผ์ง€ ์•Š์œผ๋ฉด ์ปค์„œ๋ถ€ํ„ฐ ์ด์–ด ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ฃผ๋ฉด **๊ทธ ๋ฒˆํ˜ธ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ฌป์Šต๋‹ˆ๋‹ค** โ€” ์ด๋ฏธ ๋“ค์–ด๊ฐ„ ๊ฒƒ์€ ์œ ์ž…\n * ๊ฒฝ๊ณ„๊ฐ€ ๋˜ํ’€์ด๋กœ ๊ฑฐ๋ฅด๋ฏ€๋กœ ๋‘ ๋ฒˆ ์•‰์ง€ ์•Š์Šต๋‹ˆ๋‹ค.\n *\n * ์ €์žฅ๋œ ์ปค์„œ๋ฅผ ๋˜๋Œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `fillSince` ๋Š” ๋ฒˆํ˜ธ ๊ฒ€์‚ฌ๋ฅผ ์ง€๋‚œ ๋งŒํผ๋งŒ ์ ์œผ๋ฏ€๋กœ, ๋˜์ฐพ์€ ๋’ค\n * ์ปค์„œ๊ฐ€ ์›๋ž˜ ์ž๋ฆฌ๋ณด๋‹ค ์•ž์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Fetch the stretch this twin missed for one scope and ingest it through the same checks as the push path. Without `from` it continues from the cursor; with `from` it asks again from that number โ€” already-ingested facts are filtered as duplicates.'\n })\n async fillTwinScope(\n @Arg('instanceId') instanceId: string,\n @Arg('scope', { description: 'The unit the source numbers by โ€” the same name its envelopes carry (e.g. EVENTS).' }) scope: string,\n @Ctx() context: ResolverContext,\n @Arg('from', type => Int, { nullable: true, description: 'Ask again from this sequence number. Omit to continue from the cursor.' })\n from?: number,\n @Arg('maxPages', type => Int, { nullable: true, description: 'Page limit for one run. Default 50.' }) maxPages?: number\n ): Promise<any> {\n return runFill({ domainId: context.state.domain.id, instanceId, scope, from: from ?? undefined, maxPages: maxPages ?? undefined })\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Re-read a twin's structure from the source it remembers (TwinInstance.origin). Works for both reference- and template-born twins. A running mirror adopts the new structure without stopping; a running simulation is refused.\"\n })\n async resyncTwin(@Arg('instanceId') instanceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain.id\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return { ok: false, error: `unknown twin: ${instanceId}` }\n\n const origin = inst.origin as any\n if (!origin?.kind)\n return {\n ok: false,\n error: `twin \"${instanceId}\" does not remember where it came from โ€” it cannot be re-read. Re-create it from its template or reference so the origin is recorded.`\n }\n\n /*\n * ์ง„ํ–‰์„ ์•Œ๋ฆฌ๋Š” ํ†ต๋กœ โ€” ๋งŒ๋“ค ๋•Œ์™€ **๊ฐ™์€ ๊ฒƒ**์ด๋‹ค. ๋ ˆํผ๋Ÿฐ์Šค์—์„œ ์˜จ ํŠธ์œˆ๋งŒ ์•Œ๋ฆฐ๋‹ค(ํ…œํ”Œ๋ฆฟ์—์„œ ์˜จ\n * ํŠธ์œˆ์€ ์›๋ณธ์„ ์ฝ์ง€ ์•Š์œผ๋ฏ€๋กœ ์•Œ๋ฆด ๋‹จ๊ณ„๊ฐ€ ์—†๋‹ค).\n *\n * ๋ถ„๋ชจ๋Š” ๊ทธ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์„ ์–ธํ•œ ๋‹จ๊ณ„ ์ˆ˜๋‹ค(`masterSteps`) + ํ˜ธ์ŠคํŠธ ๋‹จ๊ณ„. ์„ ์–ธํ•˜์ง€ ์•Š์€ ์–ด๋Œ‘ํ„ฐ๋Š”\n * `total` ์ด ์—†๊ณ , ๊ทธ๋•Œ ํ™”๋ฉด์€ ํผ์„ผํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค โ€” ๋ชจ๋ฅด๋Š” ์ง„ํ–‰๋ฅ ์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.\n */\n const progressSource: string | undefined = origin.kind === 'reference' ? origin.source : undefined\n const refRow = progressSource\n ? await getRepository(TwinReference).findOne({ where: { domain: { id: domainId }, source: progressSource } })\n : null\n const adapterForSteps = refRow ? getAdapter(refRow.adapterType) : undefined\n const declaredSteps = adapterForSteps?.masterSteps?.length\n const stepTotal = declaredSteps === undefined ? undefined : declaredSteps + HOST_STEPS.length\n const siteId = origin.siteId ?? instanceId\n let lastDone = 0\n let lastStep: ReferenceProgress['step'] = (adapterForSteps?.masterSteps?.[0] ?? 'provision') as ReferenceProgress['step']\n const emit = (p: Omit<ReferenceProgress, 'siteCount' | 'siteId' | 'siteIndex'>) => {\n if (!progressSource) return\n lastDone = p.done\n lastStep = p.step\n pubsub.publish(\n REFERENCE_PROGRESS_TOPIC,\n referenceProgressPayload(domainId, { ...p, siteId, siteIndex: 0, siteCount: 1, total: p.total ?? stepTotal, source: progressSource })\n )\n }\n\n try {\n const master = await this.masterFromOrigin(domainId, origin, instanceId, st =>\n emit({ step: st.key, done: st.done, total: stepTotal, detail: st.detail })\n )\n emit({ step: 'provision', done: declaredSteps ?? 0, total: stepTotal })\n /*\n * **์–ด๋А ํ˜„์žฅ์˜ ํŠธ์œˆ์ด์—ˆ๋‚˜๋ฅผ ์ง€ํ‚จ๋‹ค** โ€” ๋‹ค์‹œ ์ฝ๊ธฐ๋Š” ๊ตฌ์กฐ๋งŒ ์ƒˆ๋กœ ๊ทธ๋ฆฌ๋Š” ์ผ์ด๊ณ , ํ˜„์žฅ ์†Œ์†์€ ๊ทธ๋•Œ\n * ์‚ฌ๋žŒ์ด ๊ณ ๋ฅธ ๊ฒƒ์ด๋‹ค. ๊ธฐ์–ต์ด ์—†๋Š” ์˜› ํŠธ์œˆ์€ **์ง€๊ธˆ ์žˆ๋Š” ํ˜„์žฅ**์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค(๋นˆ์†์œผ๋กœ ๋‘๋ฉด ํ…œํ”Œ๋ฆฟ\n * ๊ธฐ๋ณธ ๊ณต๊ฐ„์œผ๋กœ ์˜ฎ๊ฒจ ๊ฐ„๋‹ค โ€” ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ํ˜„์žฅ์„ ๋– ๋‚˜๊ณ  ๊ทธ ํ˜„์žฅ์˜ ๊ฐ’๋„ ์žƒ๋Š”๋‹ค).\n */\n const keepSpace = origin.spaceId || inst.spaceId\n /* ๋‹ค์‹œ ์ฝ๊ธฐ๋Š” **๊ตฌ์กฐ๋งŒ** ์ƒˆ๋กœ ๊ทธ๋ฆฐ๋‹ค โ€” ์žฌ๊ธฐ๋™ ์ •์ฑ…์€ ๊ทธ ํŠธ์œˆ์˜ ์„ ์–ธ์ด๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ์ง€ํ‚จ๋‹ค. */\n const res = await TwinEngine.ingestMaster(\n domainId,\n master,\n readRestartPolicy(inst.restartPolicy, `resync of twin \"${instanceId}\"`),\n keepSpace ? { spaceId: keepSpace } : undefined,\n context.state.user\n )\n emit({ step: 'start', done: (declaredSteps ?? 0) + 1, total: stepTotal })\n /*\n * **์ดํ‰๋„ ์ƒˆ๋กœ ๋‚จ๊ธด๋‹ค.** ๋‹ค์‹œ ์ฝ์—ˆ๋Š”๋ฐ ์ดํ‰์ด ์˜›๊ฒƒ์ด๋ฉด ํ™”๋ฉด์ด ์ง€๋‚œ ์ฝ๊ธฐ๋ฅผ ํ˜„์žฌ๋กœ ๋ณด์—ฌ ์ค€๋‹ค โ€”\n * ๊ทธ ํ‘œ๋ฅผ ๋ณด๊ณ  ์‚ฌ๋žŒ์ด ์›๋ณธ์„ ๊ณ ์น˜๋Ÿฌ ๊ฐ„๋‹ค.\n */\n if (refRow && progressSource) {\n const prevSpec = (refRow.scopeSpec as any) ?? {}\n await getRepository(TwinReference).update(\n { id: refRow.id },\n {\n scopeSpec: { ...prevSpec, assessments: { ...(prevSpec.assessments ?? {}), [siteId]: assessMaster(master, siteId) } },\n /*\n * โ”€โ”€ ์ฝ์€ ์‹œ๊ฐ๊ณผ ๊ฒฝ๊ณ  ์ˆ˜๋„ ์ƒˆ๋กœ ๋‚จ๊ธด๋‹ค (2026-09-06) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ฒ˜์Œ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒฝ๋กœ๋Š” ์ด ๋‘˜์„ ์“ฐ๋Š”๋ฐ(ยง`connectReference`) ๋‹ค์‹œ ์ฝ๋Š” ๊ฒฝ๋กœ๋Š” ์ดํ‰๋งŒ\n * ์ผ๋‹ค. ๊ทธ๋ž˜์„œ `lastSyncedAt` ์ด ใ€Œ์ฒ˜์Œ ํŠธ์œˆ์„ ๋งŒ๋“  ์‹œ๊ฐใ€์— ๋จธ๋ฌผ๋ €๋‹ค.\n *\n * ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ ์ž˜๋ชป๋œ ํŒ๋‹จ์„ ๋งŒ๋“ค์—ˆ๋‹ค. ์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๋ ˆ์ธ์ด ์ปค๋„ฅํ„ฐ๋ฅผ ๊ณ ์น˜๊ณ  ์žฌ๋™๊ธฐํ™”๋ฅผ\n * ์ฒญํ•œ ๋’ค ์ด ์นธ์œผ๋กœ ํ™•์ธํ–ˆ๋Š”๋ฐ, ๊ฐ’์ด ๊ทธ๋Œ€๋กœ์—ฌ์„œ ใ€Œ์•ˆ ๋Œ์•˜๋‹คใ€๊ณ  ๊ฒฐ๋ก  ๋‚ด๋ ธ๋‹ค. ์‹ค์ œ๋กœ๋Š”\n * ๋Œ์•˜๊ณ  ํ’ˆ๋ชฉ 106๊ฑด์ด ๋“ค์–ด์™€ ์žˆ์—ˆ๋‹ค.\n *\n * ๊ฒฝ๊ณ  ์ˆ˜๋„ ๊ฐ™๋‹ค. ๋‹ค์‹œ ์ฝ์œผ๋ฉด์„œ ๊ฒฝ๊ณ ๊ฐ€ ์ค„๊ฑฐ๋‚˜ ๋Š˜์—ˆ๋Š”๋ฐ ํ™”๋ฉด์€ ์ง€๋‚œ ์ˆ˜๋ฅผ ๋ณด์ธ๋‹ค.\n */\n lastSyncedAt: new Date().toISOString(),\n lastWarningCount: Array.isArray(res.warnings) ? res.warnings.length : null\n } as any\n )\n }\n return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings: res.warnings }\n } catch (e: any) {\n /* ๋ง‰ํžŒ ์ž๋ฆฌ๋ฅผ ๊ทธ๋Œ€๋กœ ์•Œ๋ฆฐ๋‹ค โ€” ใ€Œ๋๋‚ธ ์ˆ˜ใ€์˜ ๋‹ค์Œ ๋‹จ๊ณ„๋‹ค(๋งŒ๋“ค ๋•Œ์™€ ๊ฐ™์€ ๊ทœ์น™). */\n emit({\n step: (adapterForSteps?.masterSteps?.[lastDone] ?? lastStep) as ReferenceProgress['step'],\n done: lastDone,\n total: stepTotal,\n failed: true,\n error: e?.message ?? String(e)\n })\n return refusal(context, e, 'resync failed')\n }\n }\n\n /** ๊ธฐ์–ตํ•ด ๋‘” ์›์ฒœ์—์„œ ๋งˆ์Šคํ„ฐ๋ฅผ ๋‹ค์‹œ ์–ป๋Š”๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๋“  ํ…œํ”Œ๋ฆฟ์ด๋“  ์ด ํ•œ ๊ณณ์—์„œ ๊ฐˆ๋ฆฐ๋‹ค. */\n private async masterFromOrigin(\n domainId: string,\n origin: any,\n instanceId: string,\n /*\n * **๋‹ค์‹œ ์ฝ๊ธฐ๋„ ์ง„ํ–‰์„ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค** (2026-08-22).\n *\n * ๋งŒ๋“ค ๋•Œ๋Š” 8๋‹จ๊ณ„๊ฐ€ ํ™”๋ฉด์— ํ๋ฅด๋Š”๋ฐ ๋‹ค์‹œ ์ฝ์„ ๋•Œ๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†์—ˆ๋‹ค โ€” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ \n * ใ€Œ์ง„ํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์—†๋‹คใ€๊ณ  ํ–ˆ๋‹ค. ์‹ค์ œ๋กœ chef ๋Š” ์›๋ณธ ์ฝ๊ธฐ๊ฐ€ 14~21์ดˆ์ด๊ณ  ๊ทธ ์‚ฌ์ด\n * ํ™”๋ฉด์— ์•„๋ฌด ๋ณ€ํ™”๊ฐ€ ์—†๋‹ค.\n *\n * ํ†ต๋กœ๋Š” ๋งŒ๋“ค ๋•Œ์™€ **๊ฐ™์€ ๊ฒƒ**์ด๋‹ค(`twin-reference-progress`). ํ™”๋ฉด๋„ ๊ฐ™์€ ํ‘œ์‹œ๋ฅผ ์“ด๋‹ค โ€”\n * ๋‘ ๋ฒŒ์„ ๋งŒ๋“ค๋ฉด ํ•œ์ชฝ๋งŒ ๊ณ ์ณ์ง€๊ณ  ์‚ฌ๋žŒ์€ ๊ฐ™์€ ์ผ์ด ๋‹ค๋ฅด๊ฒŒ ๋ณด์ด๋Š” ๊ฒƒ์„ ๊ฒฐํ•จ์œผ๋กœ ์ฝ๋Š”๋‹ค.\n */\n onStep?: (s: { key: any; done: number; total?: number; detail?: string }) => void\n ): Promise<any> {\n if (origin.kind === 'template') {\n const tpl = getTemplate(origin.templateId)\n if (!tpl) throw new Error(`unknown template: ${origin.templateId} โ€” this twin cannot be rebuilt`)\n /* ์ €์žฅํ•ด ๋‘” ๋…ธ๋ธŒ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ์ง“๋Š”๋‹ค. ๊ธฐ๋ณธ๊ฐ’์„ ๋‹ค์‹œ ์ž…ํžˆ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ทธ ์‚ฌ์ด ํ…œํ”Œ๋ฆฟ์˜ ๊ธฐ๋ณธ๊ฐ’์ด\n ๋ฐ”๋€Œ์—ˆ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ๋ฅด์ง€ ์•Š์€ ๊ฐ’์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ํ˜„์žฅ์„ ๋ฐ”๊พธ๊ฒŒ ๋œ๋‹ค. */\n const { master } = tpl.build(origin.params ?? {})\n master.origin = origin\n return master\n }\n\n /* ๋ ˆํผ๋Ÿฐ์Šค โ€” ๋ฉ”๋ชจ๋ฆฌ ๋“ฑ๋ก๋ณธ์ด ์žˆ์œผ๋ฉด ๊ทธ๊ฒƒ, ์—†์œผ๋ฉด ์ €์žฅ๋œ ์–ด๋Œ‘ํ„ฐ ์—ฐ๊ฒฐ๋กœ ๋‹ค์‹œ ๊ฐ€์ ธ์˜จ๋‹ค.\n (๋ถ€ํŒ… ๋’ค์—๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋“ฑ๋ก๋ณธ์ด ๋น„์–ด ์žˆ์œผ๋ฏ€๋กœ ์–ด๋Œ‘ํ„ฐ ๊ฒฝ๋กœ๊ฐ€ ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ๊ธธ์ด๋‹ค.) */\n const inMemory = getReference(origin.source)\n if (inMemory) return { ...inMemory, origin }\n\n const ref = await getRepository(TwinReference).findOne({ where: { domain: { id: domainId }, source: origin.source } })\n if (!ref) throw new Error(`reference \"${origin.source}\" is no longer registered โ€” nothing to re-read from`)\n const adapter = getAdapter(ref.adapterType)\n if (!adapter) throw new Error(`no adapter for type: ${ref.adapterType}`)\n const cfg = ref.connectionConfig ?? {}\n const sites = await adapter.discoverSites(cfg)\n\n /*\n * โ”€โ”€ ๋ฌด์—‡์„ ๋ฌด์—‡๊ณผ ๊ฒฌ์ฃผ๋‚˜ (2026-08-18 ์‹ค์ธก์œผ๋กœ ๊ณ ์นจ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n *\n * ์˜ˆ์ „์—๋Š” `master.source === origin.source` ๋กœ ์‚ฌ์ดํŠธ๋ฅผ ์ฐพ์•˜๋‹ค. ๊ทธ๋Ÿฐ๋ฐ `origin.source` ๋Š” **๋ ˆํผ๋Ÿฐ์Šค\n * ๋“ฑ๋ก ์ด๋ฆ„**์ด๊ณ (๊ทธ ์ฐธ์กฐ์˜ ์‚ฌ์ดํŠธ ์ „๋ถ€์— ๊ฐ™๋‹ค) `master.source` ๋Š” **์‚ฌ์ดํŠธ๋ณ„ ์ธ์Šคํ„ด์Šค id** ๋‹ค โ€”\n * ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์„ ๊ฒฌ์คฌ์œผ๋‹ˆ ์‚ฌ์ดํŠธ๊ฐ€ ๋ฉ€์ฉกํžˆ ์žˆ์–ด๋„ ใ€Œ๋” ์ด์ƒ ๋ณด๊ณ ํ•˜์ง€ ์•Š๋Š”๋‹คใ€๋กœ ๊ฑฐ์ ˆํ–ˆ๋‹ค. ์‚ฌ์ดํŠธ๊ฐ€\n * ์—ฌ๋Ÿฟ์ธ ์ฐธ์กฐ์—์„œ ์˜จ ํŠธ์œˆ์€ ๊ทธ๋ž˜์„œ **์ „๋ถ€** ์žฌ๋™๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€ํ–ˆ๊ณ , ์˜ค๋ฅ˜ ๋ฌธ์žฅ์€ ์›์ธ์„ ์ฐธ์กฐ ์ชฝ์œผ๋กœ\n * ์ž˜๋ชป ๊ฐ€๋ฆฌ์ผฐ๋‹ค.\n *\n * ์ด์ œ โ‘  ๊ธฐ์–ตํ•ด ๋‘” ์‚ฌ์ดํŠธ๋กœ ๊ณง์žฅ ๊ฐ„๋‹ค(`origin.siteId`) โ‘ก ๊ธฐ์–ต์ด ์—†๋Š” ์˜› ํŠธ์œˆ์€ ์‚ฌ์ดํŠธ๋ฅผ ์‚ดํŽด\n * **๋งˆ์Šคํ„ฐ์˜ ์ •์ฒด(=์ด ์ธ์Šคํ„ด์Šค id)** ์™€ ๊ฒฌ์ค€๋‹ค. ์–ด๋А ์ชฝ๋„ ๋ชป ์ฐพ์œผ๋ฉด **์ฒซ ์‚ฌ์ดํŠธ๋กœ ๋•Œ์šฐ์ง€ ์•Š๋Š”๋‹ค** โ€”\n * ๋‹ค๋ฅธ ํ˜„์žฅ์˜ ๊ตฌ์กฐ๋ฅผ ์ด ํŠธ์œˆ์— ๋ฎ๋Š” ๊ฒƒ์€ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ค๋ฅ˜ ์—†์ด ํ‹€๋ฆฐ ๊ณต์žฅ์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค.\n */\n const picked = pickOriginSite(sites, origin)\n if (picked.site) return { ...(await adapter.fetchMaster(cfg, picked.site, onStep)), origin }\n if (picked.reason === 'site-gone')\n throw new Error(\n `reference \"${origin.source}\" no longer reports site \"${origin.siteId}\" โ€” refusing to overwrite this twin with a different site`\n )\n\n for (const site of sites) {\n const master = await adapter.fetchMaster(cfg, site)\n if (master.source === instanceId) return { ...master, origin: { ...origin, siteId: site.siteId } }\n }\n throw new Error(\n `reference \"${origin.source}\" does not report a site that rebuilds twin \"${instanceId}\" ` +\n `(this twin was imported before the site identity was recorded, and no site's master carries its id) โ€” refusing to overwrite it with a different site`\n )\n }\n\n /** ๋“ฑ๋ก๋œ ํŠธ์œˆ ํ…œํ”Œ๋ฆฟ(ํŒŒ๋ผ๋ฏธํ„ฐํ™” ์•„ํ‚คํƒ€์ž…) ๋ชฉ๋ก โ€” ๋…ธ๋ธŒ ์Šคํ‚ค๋งˆ ํฌํ•จ(ํด๋ผ์ด์–ธํŠธ ํผ์šฉ). */\n @Query(returns => [ScalarObject], { description: 'List registered twin templates (parameterized archetypes) with their knob schema.' })\n async twinTemplates(@Ctx() _context: ResolverContext): Promise<any[]> {\n return listTemplates().map(t => ({ id: t.id, label: t.label, system: t.system, description: t.description, detail: t.detail, knobs: t.knobs }))\n }\n\n /** ํ…œํ”Œ๋ฆฟ + ๋…ธ๋ธŒ โ†’ ํ•ฉ์„ฑ ๋งˆ์Šคํ„ฐ โ†’ ์ธ์ œ์ŠคํŠธ(+๊ธฐ๋™+์‹œ๋‚˜๋ฆฌ์˜ค). ๋ ˆํผ๋Ÿฐ์Šค import ์™€ ๊ฐ™์€ ๊ฒฝ๋กœ, ์›์ฒœ๋งŒ ํ•ฉ์„ฑ. */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Instantiate a twin template with params โ†’ synthetic master โ†’ ingest (+start+scenario). restartPolicy declares how the new twin treats its own past on reboot ('resync' | 'resume' | 'reset') โ€” there is no default. Returns {ok, instanceId, spaceId}.\"\n })\n async createFromTemplate(\n @Arg('templateId') templateId: string,\n @Arg('params', type => ScalarObject) params: any,\n @Arg('restartPolicy') restartPolicy: string,\n @Ctx() context: ResolverContext,\n @Arg('start', { nullable: true }) start?: boolean,\n @Arg('spaceId', { nullable: true, description: 'Existing space to co-locate this twin into (add a lens to a site). Omit to create its own space.' }) spaceId?: string\n ): Promise<any> {\n const tpl = getTemplate(templateId)\n if (!tpl) return { ok: false, error: `unknown template: ${templateId}` }\n const domainId = context.state.domain.id\n try {\n /*\n * **๋น ์ง„ ๋…ธ๋ธŒ๋ฅผ ์„œ๋ฒ„๊ฐ€ ์ฑ„์šด๋‹ค.** ๊ธฐ๋ณธ๊ฐ’์„ ์•„๋Š” ๊ณณ์€ ๋…ธ๋ธŒ ์Šคํ‚ค๋งˆ(๊ณ„์•ฝ)์ธ๋ฐ ๊ทธ๊ฒƒ์„ ์ ์šฉํ•˜๋Š” ๊ณณ์ด\n * ์œ„์ž๋“œ๋ฟ์ด์—ˆ๋‹ค โ€” ๊ทธ๋ž˜์„œ ํ™”๋ฉด์„ ๊ฑฐ์น˜์ง€ ์•Š๋Š” ํ˜ธ์ถœ์ž(AIยท์Šคํฌ๋ฆฝํŠธยทAPI)๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ผ๋ถ€๋งŒ ์ฃผ๋ฉด\n * ํ…œํ”Œ๋ฆฟ ์•ˆ์—์„œ ๋ฐœ์ƒ๋ฅ ์ด 0 ์ด ๋˜๊ณ  **์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š” ํŠธ์œˆ**์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋งŒ๋“ค์–ด์กŒ๋‹ค.\n * ์ฑ„์šด ๋…ธ๋ธŒ ์ด๋ฆ„์€ ๊ฒฝ๊ณ ๋กœ ํ•จ๊ป˜ ๋Œ๋ ค์ค€๋‹ค โ€” ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ฑ„์šฐ๋Š” ๊ฒƒ๋„ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋น„์šฐ๋Š” ๊ฒƒ๋งŒํผ ์œ„ํ—˜ํ•˜๋‹ค.\n */\n const filled = filledKnobKeys(tpl.knobs, params)\n const effective = applyKnobDefaults(tpl.knobs, params)\n /*\n * **์ด ํ˜„์žฅ์— ์ด๋ฏธ ์žˆ๋Š” ์„ค๋น„๋ฅผ ๋…ธ๋ธŒ ๊ฐ’์œผ๋กœ ํ™•์ •ํ•œ๋‹ค** (`siteEquipmentIds`).\n *\n * ์—๋„ˆ์ง€ ํŠธ์œˆ์ด ใ€Œ๊ณต์žฅ์ด ๋Œ๋ฉด ์ „๊ธฐ๊ฐ€ ์˜ค๋ฅธ๋‹คใ€๋ฅผ ๋งํ•˜๋ ค๋ฉด ๋ถ€ํ•˜๋ฅผ **์ด์›ƒ ํŠธ์œˆ์˜ ์„ค๋น„ id ๋กœ**\n * ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค(์„ค๋น„ ํ•˜๋‚˜์— ์‚ฌ์‹ค ๋‘˜). ๊ทธ ๋ชฉ๋ก์„ ๋นŒ๋“œํ•  ๋•Œ๋งˆ๋‹ค ํ˜„์žฅ์—์„œ ๋‹ค์‹œ ์ฝ์œผ๋ฉด, ์‚ฌ์ด์—\n * ์„ค๋น„๊ฐ€ ๋Š˜๊ฑฐ๋‚˜ ์ค€ ๋งŒํผ **๋‹ค์‹œ ์ง€์„ ๋•Œ ๋‹ค๋ฅธ ํŠธ์œˆ**์ด ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์„œ ํ•œ ๋ฒˆ ํ•ด์„ํ•˜๊ณ \n * ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋…ธ๋ธŒ ๊ฐ’์œผ๋กœ ๋‚จ๊ธด๋‹ค(์•„๋ž˜ `origin.params` ์— ๊ทธ๋Œ€๋กœ ์ €์žฅ๋œ๋‹ค).\n */\n const adopted = await resolveSiteEquipmentKnobs(tpl.knobs, effective, domainId, spaceId)\n const { master, scenario } = tpl.build(effective)\n /* **๋ฌด์—‡์œผ๋กœ ์ง€์—ˆ๋Š”์ง€ ๋‚จ๊ธด๋‹ค.** ํ•ฉ์„ฑ์€ ๊ฒฐ์ •์ ์ด๋ฏ€๋กœ ๊ฐ™์€ ๋…ธ๋ธŒ๋ฉด ๊ฐ™์€ ๋งˆ์Šคํ„ฐ๊ฐ€ ๋‹ค์‹œ ๋‚˜์˜จ๋‹ค โ€”\n ๊ทธ๋ž˜์„œ ํ…œํ”Œ๋ฆฟ ํŠธ์œˆ๋„ ์–ด๋Œ‘ํ„ฐ ํŠธ์œˆ๊ณผ ๋˜‘๊ฐ™์ด ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. ๋‚จ๊ธฐ์ง€ ์•Š์œผ๋ฉด ๊ทธ ํŠธ์œˆ์€\n ์ฒซ๋‚ ์˜ ๋ชจ์Šต์— ์˜์›ํžˆ ๋จธ๋ฌธ๋‹ค(์›๋ณธ์„ ์žƒ์€ ํŠธ์œˆ). */\n /* ๊ณ ๋ฅธ ํ˜„์žฅ๋„ ๋‚จ๊ธด๋‹ค โ€” ์—†์œผ๋ฉด ๋‹ค์‹œ ์ฝ๊ธฐ๊ฐ€ ํŠธ์œˆ์„ ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ณธ ๊ณต๊ฐ„์œผ๋กœ ์˜ฎ๊ฒจ ๋ฒ„๋ฆฐ๋‹ค(ํ˜„์žฅ ๊ฐ’๋„ ์žƒ๋Š”๋‹ค). */\n master.origin = { kind: 'template', templateId, params: effective, ...(spaceId ? { spaceId } : {}) }\n /* ๊ณต๊ฐ„ ์„ ํƒ์€ ํ…œํ”Œ๋ฆฟ์„ ๊ฑฐ์น˜์ง€ ์•Š๋Š”๋‹ค โ€” ํ…œํ”Œ๋ฆฟ๋งˆ๋‹ค ์ด ๋…ธ๋ธŒ๋ฅผ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋ฉด ์ƒˆ ํ…œํ”Œ๋ฆฟ์ด\n ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋ฌด์‹œํ•˜๊ฒŒ ๋œ๋‹ค. ํ•ฉ์„ฑ๋œ ๋งˆ์Šคํ„ฐ์— ํ•œ ๊ณณ์—์„œ ์–น๋Š”๋‹ค(๋ ˆํผ๋Ÿฐ์Šค ์ธ์ œ์ŠคํŠธ์™€ ๊ฐ™์€ ๊ฒฝ๋กœ). */\n const res = await TwinEngine.ingestMaster(\n domainId,\n master,\n readRestartPolicy(restartPolicy, `createFromTemplate(\"${templateId}\")`),\n { spaceId },\n context.state.user\n )\n if (start !== false) {\n await TwinEngine.startFromRegistry(domainId, res.instanceId)\n if (scenario) {\n const runtime = TwinEngine.runtime(domainId, res.instanceId)\n if (runtime) {\n runtime.scenario.load(scenario)\n runtime.scenario.start()\n }\n }\n }\n const warnings = [\n ...(filled.length ? [knobDefaultsFilled(filled)] : []),\n ...adopted.filter(a => a.count > 0).map(a => siteEquipmentAdopted(a.key, a.count)),\n ...res.warnings\n ]\n return { ok: true, instanceId: res.instanceId, spaceId: res.spaceId, warnings }\n } catch (e: any) {\n return refusal(context, e, 'template instantiation failed')\n }\n }\n\n /* โ”€โ”€ ๋ ˆํผ๋Ÿฐ์Šค ๊ด€๋ฆฌ(์—”ํ‹ฐํ‹ฐ ๊ธฐ๋ฐ˜ยทํ…Œ๋„ŒํŠธ ์Šค์ฝ”ํ”„) โ€” reference-management P1 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ „์—ญ ์ธ๋ฉ”๋ชจ๋ฆฌ(referenceSources/importFromReference)์™€ ๊ณต์กด. ์ด์ชฝ์€ TwinReference ํ–‰ + ์–ด๋Œ‘ํ„ฐ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ.\n */\n\n @Query(returns => [ScalarObject], { description: 'List tenant-scoped persisted twin references (adapter-backed).' })\n async twinReferences(@Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const rows = await getRepository(TwinReference).find({ where: { domain: { id: domainId } } })\n /*\n * provenance ๋ผ์ด๋ธŒ ๋Œ€์กฐ โ€” ์ง€์›Œ์ง„ ํŠธ์œˆ์€ producedCount ์—์„œ ์ž๋™ ์ œ์™ธ(์ƒํƒœ ๋™๊ธฐ์˜ lazy ๋ฐฉ์‹).\n *\n * **id ๋งŒ ์ฝ๋Š”๋‹ค** (2026-08-21). ์˜ˆ์ „์—๋Š” ์ธ์Šคํ„ด์Šค ํ–‰ ์ „์ฒด๋ฅผ ์ฝ์—ˆ๊ณ , ๊ทธ ํ–‰์—๋Š” **๋ชจ๋ธ JSON** ์ด\n * ๋“ค์–ด ์žˆ๋‹ค(์ž๋ฆฌ ์ˆ˜๋ฐฑ ๊ฐœ + ๋ฐœ์ž๊ตญ ์ขŒํ‘œ). ๊ทธ๋ž˜์„œ ์ด ๋ชฉ๋ก์„ ์—ฌ๋Š” ๋ฐ ์ˆ˜ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ๋ฅผ ์ฝ๊ณ  ํŒŒ์‹ฑํ–ˆ๊ณ ,\n * ํ™”๋ฉด์€ ๊ทธ๋™์•ˆ ใ€Œ์•„์ง ์—ฐ๊ฒฐ๋œ ์‹œ์Šคํ…œ์ด ์—†์Šต๋‹ˆ๋‹คใ€๋ฅผ ๋ณด์ด๊ณ  ์žˆ์—ˆ๋‹ค โ€” ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ใ€Œ์—†๋‹คใ€๋Š” ๋‹ต์œผ๋กœ\n * ์ฝํžŒ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•„์š”ํ•œ ๊ฒƒ์€ ์‚ด์•„ ์žˆ๋Š” id ์ง‘ํ•ฉ ํ•˜๋‚˜๋‹ค.\n */\n const liveIds = new Set(\n (await getRepository(TwinInstance).find({ where: { domain: { id: domainId } }, select: ['instanceId'] })).map(\n i => i.instanceId\n )\n )\n return rows.map(r => {\n const produced = (((r.scopeSpec as any)?.produced ?? []) as any[]).filter(p => liveIds.has(p.instanceId))\n return {\n source: r.source, system: r.system, siteName: r.siteName, description: r.description,\n adapterType: r.adapterType, status: r.status, lastSyncedAt: r.lastSyncedAt, lastError: r.lastError,\n producedCount: produced.length, produced,\n /*\n * **์กฐ์น˜๊ฐ€ ์ €์ชฝ์— ๋‹ฟ์•„ ๋ดค๋‚˜** (ADR-0046 โ‘ก). ์นธ ์…‹์€ 2026-09 ๋ถ€ํ„ฐ ์„œ ์žˆ์—ˆ๋Š”๋ฐ ๋ชฉ๋ก๋„ ์ƒ์„ธ๋„\n * ์ด ๊ฐ’์„ ์‹ฃ์ง€ ์•Š์•„ **ํ™”๋ฉด์ด ๋ณผ ๊ธธ์ด ์—†์—ˆ๋‹ค** โ€” ์ €์žฅ๋œ ์‚ฌ์‹ค์ด ์•„๋ฌด์—๊ฒŒ๋„ ๋‹ฟ์ง€ ์•Š์•˜๋‹ค.\n *\n * ๋ณด๋‚ผ ์ฃผ์†Œ๊ฐ€ ์ ํžŒ ์—ฐ๊ฒฐ์—๋งŒ ์‹ฃ๋Š”๋‹ค. ์ฝ๊ธฐ๋งŒ ํ•˜๋Š” ์—ฐ๊ฒฐ์— ใ€Œ์•„์ง ํ™•์ธ ์•ˆ ๋จใ€์ด ์„œ๋ฉด ํ•  ์ผ์ด ์—†๋Š”\n * ์‚ฌ๋žŒ์—๊ฒŒ ํ•  ์ผ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.\n */\n ...(actuationAddressed(r.connectionConfig as any)\n ? {\n actuationState: r.actuationState ?? 'unverified',\n actuationVerifiedAt: r.actuationVerifiedAt ?? null,\n actuationFailure: r.actuationFailure ?? null\n }\n : {})\n }\n })\n }\n\n @Query(returns => [String], { description: 'List registered reference adapter type keys.' })\n referenceAdapterTypes(): string[] {\n return listAdapterTypes()\n }\n\n /**\n * ์ธํ‹ฐ๊ทธ๋ ˆ์ด์…˜ ๊ทธ๋ฃนํ•‘ (reference-management ยง2.3ยทD11) โ€” ์‚ฐ์ถœ๋ฌผ์„ ์ปค๋„ฅํ„ฐ ํƒ€์ž… โ–ธ Connection โ–ธ ์ธ์Šคํ„ด์Šค 2๋‹จ์œผ๋กœ.\n * ํŠธ์œˆ-๋„ค์ดํ‹ฐ๋ธŒ ์˜จํ†จ๋กœ์ง€(integration ๋ฌด์˜์กด): TwinReference ๊ฐ€ ๊ทธ๋ฃนํ•‘ ๋…ธ๋“œ(source=connectionName),\n * scopeSpec.connectorType ๋กœ ์ƒ์œ„ ๋ถ„๋ฅ˜. producedCount ๋Š” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋กœ ๋Œ€์กฐ(์ง€์›Œ์ง„ ํŠธ์œˆ ์ œ์™ธ).\n */\n @Query(returns => [ScalarObject], { description: 'Group integration items 2-tier: connector type โ–ธ connection โ–ธ produced twins. (reference-management ยง2.3)' })\n async twinConnections(@Ctx() context: ResolverContext): Promise<any[]> {\n const domainId = context.state.domain.id\n const rows = await getRepository(TwinReference).find({ where: { domain: { id: domainId } } })\n const liveIds = new Set((await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })).map(i => i.instanceId))\n const groups = new Map<string, any[]>()\n for (const r of rows) {\n const connectorType = (r.scopeSpec as any)?.connectorType ?? r.adapterType\n const producedCount = (((r.scopeSpec as any)?.produced ?? []) as any[]).filter(p => liveIds.has(p.instanceId)).length\n const conn = { source: r.source, name: r.siteName, status: r.status, adapterType: r.adapterType, producedCount, lastSyncedAt: r.lastSyncedAt }\n if (!groups.has(connectorType)) groups.set(connectorType, [])\n groups.get(connectorType)!.push(conn)\n }\n return [...groups.entries()].map(([connectorType, connections]) => ({\n connectorType,\n connectionCount: connections.length,\n instanceCount: connections.reduce((s, c) => s + c.producedCount, 0),\n connections\n }))\n }\n\n /** ํ•œ Connection ๊ทธ๋ฃน ๋…ธ๋“œ ์ƒ์„ธ โ€” ๊ทธ ์•„๋ž˜ ์ƒ์„ฑ๋œ ํŠธ์œˆ ์ธ์Šคํ„ด์Šค(๋ผ์ด๋ธŒ ๋Œ€์กฐยท์ƒํƒœยท๊ธฐ๋™์—ฌ๋ถ€). */\n @Query(returns => ScalarObject, { nullable: true, description: 'One connection grouping location with its produced twin instances (live-checked). (reference-management ยง2.3)' })\n async twinConnection(@Arg('source') source: string, @Ctx() context: ResolverContext): Promise<any | null> {\n const domainId = context.state.domain.id\n const r = await getRepository(TwinReference).findOne({ where: { domain: { id: domainId }, source } })\n if (!r) return null\n const produced = ((r.scopeSpec as any)?.produced ?? []) as any[]\n const instMap = new Map((await getRepository(TwinInstance).find({ where: { domain: { id: domainId } } })).map(i => [i.instanceId, i]))\n const instances = produced\n .filter(p => instMap.has(p.instanceId))\n .map(p => {\n const inst = instMap.get(p.instanceId) as any\n return { instanceId: p.instanceId, spaceId: p.spaceId, siteId: p.siteId, kind: inst.kind, status: inst.status, running: TwinEngine.owns(domainId, p.instanceId) }\n })\n return {\n source: r.source,\n connectorType: (r.scopeSpec as any)?.connectorType ?? r.adapterType,\n name: r.siteName,\n status: r.status,\n system: r.system,\n lastSyncedAt: r.lastSyncedAt,\n instanceCount: instances.length,\n instances\n }\n }\n\n /** ๋‹จ๊ฑด ์ƒ์„ธ(๋ทฐ/ํŽธ์ง‘) โ€” connectionConfig ํฌํ•จ, ์–ด๋Œ‘ํ„ฐ ์Šคํ‚ค๋งˆ์˜ secret ํ•„๋“œ๋Š” ๋งˆ์Šคํ‚น(์žˆ์œผ๋ฉด 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'). */\n @Query(returns => ScalarObject, { nullable: true, description: 'Get one tenant-scoped reference with its connection config (secret fields masked) for view/edit.' })\n async twinReference(@Arg('source') source: string, @Ctx() context: ResolverContext): Promise<any | null> {\n const r = await getRepository(TwinReference).findOne({ where: { domain: { id: context.state.domain.id }, source } })\n if (!r) return null\n const secretKeys = new Set((getAdapter(r.adapterType)?.meta?.configSchema ?? []).filter(f => f.secret).map(f => f.key))\n const cfg: any = {}\n for (const [k, v] of Object.entries((r.connectionConfig as any) ?? {})) cfg[k] = secretKeys.has(k) ? (v ? 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ข' : '') : v\n /*\n * **์ด ์—ฐ๊ฒฐ์ด ๋งŒ๋“  ํŠธ์œˆ id ๋ฅผ ํ•จ๊ป˜ ๋‚ธ๋‹ค.** ์ƒ์„ธ ํ™”๋ฉด์ด ใ€Œ์ด ์—ฐ๊ฒฐ์ด ์ž˜ ๋™๊ธฐํ™”๋˜๊ณ  ์žˆ๋‚˜ใ€๋ฅผ ๋ฌผ์œผ๋ ค๋ฉด\n * ์–ด๋А ํŠธ์œˆ์„ ๋ฌผ์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•œ๋‹ค. ์˜ˆ์ „์—๋Š” ๊ฐœ์ˆ˜(`producedCount`)๋งŒ ์žˆ์–ด์„œ ํ™”๋ฉด์ด id ๋ฅผ\n * ์•Œ ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค.\n */\n const producedInstanceIds = [\n ...new Set(\n ((r.scopeSpec as any)?.produced ?? [])\n .map((p: any) => p?.instanceId)\n .filter((x: any): x is string => typeof x === 'string' && !!x)\n )\n ]\n return {\n source: r.source, system: r.system, siteName: r.siteName, description: r.description,\n adapterType: r.adapterType, connectionConfig: cfg, status: r.status, lastSyncedAt: r.lastSyncedAt, lastError: r.lastError,\n producedInstanceIds,\n /* ๋ชฉ๋ก๊ณผ ๊ฐ™์€ ๊ทœ์น™ โ€” ๋ณด๋‚ผ ์ฃผ์†Œ๊ฐ€ ์ ํžŒ ์—ฐ๊ฒฐ๋งŒ ๊ฒ€์ฆ ์ƒํƒœ๋ฅผ ์‹ฃ๋Š”๋‹ค(ADR-0046 โ‘ก). */\n ...(actuationAddressed(r.connectionConfig as any)\n ? {\n actuationState: r.actuationState ?? 'unverified',\n actuationVerifiedAt: r.actuationVerifiedAt ?? null,\n actuationFailure: r.actuationFailure ?? null\n }\n : {})\n }\n }\n\n @Query(returns => [ScalarObject], { description: 'List reference connector metadata (label, domain, config schema, availability, capabilities) for the connect UI.' })\n referenceAdapters(): any[] {\n /*\n * **๋Šฅ๋ ฅ์„ ํ•จ๊ป˜ ๋‚ธ๋‹ค** (2026-08-21).\n *\n * `capabilities` ๋Š” ์–ด๋Œ‘ํ„ฐ ๋ฟŒ๋ฆฌ์— ์žˆ๊ณ  `meta` ์—๋Š” ์—†์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์—ฐ๊ฒฐ ํ™”๋ฉด์ด ใ€Œ์ด ์›๋ณธ์ด ๋ผ์ด๋ธŒ๋ฅผ\n * ๋‚ผ ์ˆ˜ ์žˆ๋‚˜ใ€๋ฅผ ์•Œ ์ˆ˜ ์—†์—ˆ๊ณ , ํŠธ์œˆ์„ ๋งŒ๋“ค ๋•Œ `live` ๋ฅผ ๋งํ•˜์ง€ ๋ชปํ•ด **์žฌ๊ธฐ๋™ ์ •์ฑ…์ด ์—†๋‹ค๊ณ  ๊ฑฐ์ ˆ**๋๋‹ค\n * (์‹ค ์—ฐ๋™์—์„œ ๊ทธ๊ฒƒ์— ๋ง‰ํ˜”๋‹ค โ€” ๋ฏธ๋Ÿฌ๋Š” ์ •์˜์ƒ `resync` ์ด๋ฏ€๋กœ `live` ํ•˜๋‚˜๋กœ ์ •ํ•ด์ง„๋‹ค).\n *\n * ํ™”๋ฉด์ด ๊ทธ ์‚ฌ์‹ค์„ ์•Œ์•„์•ผ ์ •์ฑ…์„ ์‚ฌ๋žŒ์—๊ฒŒ ๋ฌผ์„์ง€ ์Šค์Šค๋กœ ์ •ํ• ์ง€ ๊ฐ€๋ฅผ ์ˆ˜ ์žˆ๋‹ค.\n */\n return listAdapters().map(a => ({ type: a.type, ...(a.meta ?? {}), capabilities: a.capabilities ?? [] }))\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Create or update a tenant-scoped twin reference (persisted).' })\n async saveTwinReference(\n @Arg('source') source: string,\n @Arg('patch', type => ScalarObject) patch: any,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinReference)\n const existing = await repo.findOne({ where: { domain: { id: domainId }, source } })\n // ํ•„๋“œ ๋‹จ์œ„ ๋ณ‘ํ•ฉ โ€” ํŽธ์ง‘ ์‹œ ์ƒ๋žต๋œ ํ‚ค(์˜ˆ: ๋งˆ์Šคํ‚น๋œ secret)๋Š” ๊ธฐ์กด ๊ฐ’ ์œ ์ง€.\n const connectionConfig = patch.connectionConfig\n ? { ...((existing?.connectionConfig as any) ?? {}), ...patch.connectionConfig }\n : existing?.connectionConfig\n\n /*\n * ๊ฐ™์€ ๋ฐ›๋Š” ์‚ฌ์ดํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์—ฐ๊ฒฐ ๋‘˜์€ **์ €์žฅํ•˜๋Š” ์ˆœ๊ฐ„ ๊ฑฐ๋ถ€ํ•œ๋‹ค** (ADR-0046 โ‘ก-1).\n * ๋“ค์—ฌ์˜ค๊ธฐ(planImport)์—๋Š” ์žˆ๋˜ ๊ฒ€์‚ฌ๊ฐ€ ํ™”๋ฉด ์ €์žฅ์—๋Š” ์—†์–ด์„œ, ์—ฐ๊ฒฐ์„ ๋ฒ ๊ปด ์ด๋ฆ„๋งŒ ๋ฐ”๊พธ๋ฉด ๋‘ ํŠธ์œˆ์˜\n * ์กฐ์น˜๊ฐ€ ํ•œ ๊ณต์žฅ์œผ๋กœ ๊ฐ”๋‹ค โ€” ์ €์ชฝ์€ 200 ์œผ๋กœ ๋ฐ›๊ณ  ์‹ค์ œ๋กœ ๋งŒ๋“ ๋‹ค. ์ง(intakeEndpointยทintakeSiteId)์€\n * ์•”ํ˜ธํ™”๋œ ์นธ ์•ˆ์— ์žˆ์–ด DB ์œ ๋‹ˆํฌ๋กœ ๋ชป ์žก์œผ๋‹ˆ ์—ฌ๊ธฐ์„œ ์žก๋Š”๋‹ค(ํŒ์ •: connection-portability.ts).\n */\n const others = await repo.find({ where: { domain: { id: domainId } } })\n const taken = refuseIntakeCollision(source, connectionConfig as any, others as any)\n if (taken) return { ok: false, source, error: taken.message, errorCode: taken.code, errorParams: taken.params }\n\n /*\n * **์ฃผ์†Œ๋ฅผ ๋ฐ”๊พธ๋Š” ์ €์žฅ์€ ๊ฒ€์ฆ์„ ๋˜๋Œ๋ฆฐ๋‹ค** (ADR-0046 โ‘ก). ์ง€๋‚œ ์™•๋ณต์€ ์ง€๋‚œ ์ฃผ์†Œ์˜ ์ด์•ผ๊ธฐ๋ผ ์ƒˆ\n * ์ฃผ์†Œ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ฌด ๋ง๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ™”๋ฉด์ด ๊ทธ ์ดˆ๋ก์„ ๊ทธ๋Œ€๋กœ ๋‘๋ฉด ๋‹ค๋ฅธ ๊ณต์žฅ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์—ฐ๊ฒฐ์ด\n * ใ€Œํ™•์ธ๋จใ€์œผ๋กœ ๋ณด์ธ๋‹ค. ๋˜๋Œ๋ฆฐ ์ƒํƒœ๋Š” ์‹คํŒจ๊ฐ€ ์•„๋‹ˆ๋‹ค โ€” ์•„์ง ์•ˆ ํ•ด ๋ณธ ๊ฒƒ์ด๋‹ค.\n */\n const reset = actuationResetPatch(existing?.connectionConfig as any, connectionConfig as any)\n\n const saved = await repo.save(\n repo.create({\n ...(existing ?? {}),\n ...(reset ?? {}),\n domain: { id: domainId } as any,\n source,\n system: patch.system ?? existing?.system,\n siteName: patch.siteName ?? existing?.siteName,\n description: patch.description ?? existing?.description,\n adapterType: patch.adapterType ?? existing?.adapterType,\n connectionConfig,\n mappingSpec: patch.mappingSpec ?? existing?.mappingSpec,\n scopeSpec: patch.scopeSpec ?? existing?.scopeSpec,\n status: patch.status ?? existing?.status ?? 'draft'\n })\n )\n return { ok: true, source: saved.source }\n }\n\n /** ์—ฐ๊ฒฐ ํ•ด์ œ โ€” removeTwins=true ๋ฉด ์ด ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋งŒ๋“  ํŠธ์œˆ(provenance)๋„ ํ•จ๊ป˜ ์ œ๊ฑฐ(๋ผ์ดํ”„์‚ฌ์ดํด ์—ฐ์‡„). ๊ธฐ๋ณธ์€ ํŠธ์œˆ ๋ณด์กด(๋ถ„๋ฆฌ). */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete a tenant-scoped reference. If removeTwins, also remove the twin instances it produced (provenance cascade); otherwise twins are kept (detached).' })\n async deleteTwinReference(\n @Arg('source') source: string,\n @Ctx() context: ResolverContext,\n @Arg('removeTwins', { nullable: true }) removeTwins?: boolean\n ): Promise<boolean> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinReference)\n const ref = await repo.findOne({ where: { domain: { id: domainId }, source } })\n if (removeTwins && ref) {\n for (const p of (((ref.scopeSpec as any)?.produced ?? []) as any[])) {\n try {\n await TwinEngine.remove(domainId, p.instanceId)\n } catch {\n /* ์ด๋ฏธ ์—†๊ฑฐ๋‚˜ ์‹คํŒจ โ€” ์—ฐ์‡„๋Š” best-effort. */\n }\n }\n }\n await repo.delete({ domain: { id: domainId } as any, source })\n return true\n }\n\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'Test a reference connection via its adapter; updates status.' })\n async testReferenceConnection(@Arg('source') source: string, @Ctx() context: ResolverContext): Promise<any> {\n const repo = getRepository(TwinReference)\n const ref = await repo.findOne({ where: { domain: { id: context.state.domain.id }, source } })\n if (!ref) return { ok: false, error: `unknown reference: ${source}` }\n const adapter = getAdapter(ref.adapterType)\n if (!adapter) return { ok: false, error: `no adapter for type: ${ref.adapterType}` }\n try {\n const res = await adapter.testConnection(ref.connectionConfig ?? {})\n await repo.update({ id: ref.id }, { status: res.ok ? 'connected' : 'error', lastError: res.error ?? null } as any)\n return res\n } catch (e: any) {\n return { ok: false, error: e?.message ?? 'test failed' }\n }\n }\n\n /**\n * ์–ด๋Œ‘ํ„ฐ ๊ธฐ๋ฐ˜ ์ธ์ œ์ŠคํŠธ โ€” discoverSites โ†’ ์‚ฌ์ดํŠธ๋ณ„ fetchMaster โ†’ ingestMaster (fan-out, ยง2.2ยทยง4.2).\n * P1 ์€ ๋Œ€๊ฐœ N=1(virtual/๋‹จ์ผ). start ๋ฉด ๊ฐ ์ธ์Šคํ„ด์Šค ๊ธฐ๋™. ๋ผ์ด๋ธŒ ํ”ผ๋“œยทmode ๋Š” face2-inbound-live ์†Œ์œ .\n */\n /** ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋…ธ์ถœํ•˜๋Š” ์‚ฌ์ดํŠธ/๊ณต์žฅ ๋ฐœ๊ฒฌ โ€” ํŠธ์œˆ ์ƒ์„ฑ ์‹œ \"์–ด๋А ๊ณต์žฅ\" ์„ ํƒ์šฉ(ยง2.2). */\n @Query(returns => ScalarObject, { description: 'Discover sites/factories exposed by a reference. Returns { sites, error? } โ€” an empty list with no error means the system genuinely has none, which is different from a failure.' })\n async discoverReferenceSites(@Arg('source') source: string, @Ctx() context: ResolverContext): Promise<any> {\n /*\n * **\"๋ชป ์ฐพ์•˜๋‹ค\" ์™€ \"์—†๋‹ค\" ๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.** ์˜ˆ์ „์—๋Š” ๋„ท์„ ๋นˆ ๋ฐฐ์—ด ํ•˜๋‚˜๋กœ ํ•ฉ์ณค๊ณ (๋ ˆํผ๋Ÿฐ์Šค ์—†์Œยท์–ด๋Œ‘ํ„ฐ\n * ๋ฏธ์ƒยท์กฐํšŒ ์‹คํŒจยท์ •๋ง 0๊ฑด), ํ™”๋ฉด์€ ๊ทธ ๋ชจ๋‘๋ฅผ \"์‚ฌ์ดํŠธ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค\" ๋ผ๊ณ ๋งŒ ๋งํ–ˆ๋‹ค. ์‹ค ์‹œ์Šคํ…œ\n * ์—ฐ๊ฒฐ์—์„œ ๊ฐ€์žฅ ์ž์ฃผ ๋ง‰ํžˆ๋Š” ์ž๋ฆฌ์ธ๋ฐ ์ž๊ฒฉ์ด ํ‹€๋ ธ๋Š”์ง€ ์ฃผ์†Œ๊ฐ€ ํ‹€๋ ธ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์—ˆ๋‹ค.\n * ํŒ์ •๊ณผ ๋ฌธ์žฅ ํ˜•ํƒœ๋Š” `discovery-result`(์ˆœ์ˆ˜)๊ฐ€ ๊ฐ–๋Š”๋‹ค.\n */\n const ref = await getRepository(TwinReference).findOne({ where: { domain: { id: context.state.domain.id }, source } })\n if (!ref) return failed(referenceNotFound(source))\n const adapter = getAdapter(ref.adapterType)\n if (!adapter) return failed(adapterUnknown(ref.adapterType, source))\n try {\n /*\n * **๊ธฐ๋‹ค๋ ค๋„ ๋‹ต์ด ์—†์œผ๋ฉด ์‚ฌ์œ ๋ฅผ ์ค€๋‹ค.** ์–ด๋Œ‘ํ„ฐ ๊ณ„์•ฝ์— ์‹œ๊ฐ„ ์ œํ•œ์ด ์—†์–ด์„œ, ์ฃผ์†Œ๊ฐ€ ํ‹€๋ฆฐ ์—”๋“œํฌ์ธํŠธ๋Š”\n * ํ™”๋ฉด์„ ๋ฌดํ•œํžˆ ๋Œ๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค โ€” ๋ฌดํ•œํžˆ ๋„๋Š” ํ™”๋ฉด์€ ๋“ค์–ด์˜จ ๊ฒƒ์ด ์—†๋Š” ์‹คํŒจ์˜ ๋‹ค๋ฅธ ์–ผ๊ตด์ด๋‹ค.\n * ์ƒํ•œ์€ ์—ฌ๊ธฐ์„œ ์ •ํ•œ๋‹ค(์–ด๋Œ‘ํ„ฐ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๋‘๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋А ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค).\n */\n const sites = await withTimeout(adapter.discoverSites(ref.connectionConfig ?? {}), DISCOVER_TIMEOUT_MS)\n return discovered(sites)\n } catch (e: any) {\n if (e?.code === TIMEOUT) return failed(discoveryTimedOut(source, DISCOVER_TIMEOUT_MS / 1000))\n return failed(discoveryFailed(source, detailOf(e)))\n }\n }\n\n /**\n * ํŠธ์œˆ ์ƒ์„ฑ โ€” ๋ ˆํผ๋Ÿฐ์Šค์—์„œ ์‚ฌ์ดํŠธ ๋ฐœ๊ฒฌ โ†’ (siteIds ์žˆ์œผ๋ฉด ๊ทธ ๊ณต์žฅ๋งŒ) โ†’ fetchMaster โ†’ provision. ์‚ฌ์ดํŠธ๋ณ„ resilient.\n * ์—ฌ๋Ÿฌ ๊ณต์žฅ์„ ๊ด€ํ• ํ•˜๋Š” ์†Œ์Šค๋Š” siteIds ๋กœ \"์–ด๋А ๊ณต์žฅ\"์„ ๊ณจ๋ผ ์ƒ์„ฑ(1:N, ยง2.1ยทยง2.2).\n *\n * โ”€โ”€ ํ˜„์žฅ ์„ ํƒ์ด ์ด ๊ฒฝ๋กœ์—๋„ ์žˆ๋‹ค (2026-08-13) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ํ•œ ํ˜„์‹ค์„ ์—ฌ๋Ÿฌ ๋ Œ์ฆˆ๊ฐ€ ๋น„์ถ˜๋‹ค(WMSยทMESยทYMS). ๊ทธ๋Ÿฐ๋ฐ **๊ทธ ์„ ํƒ์ด ํ…œํ”Œ๋ฆฟ ๊ฒฝ๋กœ์—๋งŒ** ์žˆ์–ด์„œ\n * (`createFromTemplate(spaceId)`), ์‹ค ์‹œ์Šคํ…œ์—์„œ ๊ฐ€์ ธ์˜จ ํŠธ์œˆ์€ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ํŒŒ์ƒํ•œ ๊ณต๊ฐ„ id ๊ฐ€ ์šฐ์—ฐํžˆ\n * ์ผ์น˜ํ•  ๋•Œ๋งŒ ํ•œ ํ˜„์žฅ์— ๋ชจ์˜€๋‹ค โ€” ์‚ฌ๋žŒ์ด \"์ด MES ์™€ ๊ฐ™์€ ํ˜„์žฅ์— ๋„ฃ์–ด๋ผ\" ๋ฅผ ๋งํ•  ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค.\n * ๋ฐ์ดํ„ฐ๋กœ๋Š” ๊ฐ€๋Šฅํ•œ ์ผ์ด ์ €์ž‘์œผ๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•œ, `ingest-space` ๊ฐ€ ์ด๋ฏธ ์ง€์ ํ•œ ๊ทธ ๋น„๋Œ€์นญ์ด๋‹ค.\n *\n * ํŒ์ •์€ ๊ทธ ์ˆœ์ˆ˜ ๋ชจ๋“ˆ์ด ๊ฐ–๋Š”๋‹ค: ์—†๋Š” ๊ณต๊ฐ„์€ ๊ฑฐ์ ˆ(`resolveIngestSpace`), ์‚ฌ์ดํŠธ ์—ฌ๋Ÿฟ์„ ํ•œ ๊ณต๊ฐ„์—\n * ๋„ฃ๋Š” ๊ฒƒ๋„ ๊ฑฐ์ ˆ(`refuseImportSpace`) โ€” ์„œ๋กœ ๋‹ค๋ฅธ ํ˜„์žฅ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ํ•ฉ์ณ์ง€๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Create twins from a reference: discover sites โ†’ filter by siteIds (if given) โ†’ fetch master(s) โ†’ provision. spaceId co-locates the twin into an existing space (one site only). start=false to only provision; live=true to run as a mirror (adapter openLiveFeed โ†’ live projector) instead of sim. restartPolicy declares how each new twin treats its own past on reboot ('resync' | 'resume' | 'reset'); omit it and live=true implies 'resync' โ€” a mirror reads the source again โ€” while a simulation must declare 'resume' or 'reset' for itself.\"\n })\n async importTwinReference(\n @Arg('source') source: string,\n @Ctx() context: ResolverContext,\n @Arg('siteIds', type => [String], { nullable: true }) siteIds?: string[],\n @Arg('start', { nullable: true }) start?: boolean,\n @Arg('live', { nullable: true }) live?: boolean,\n @Arg('spaceId', { nullable: true, description: 'Existing space to co-locate this twin into (add a lens to a site). Only when importing a single site. Omit to give each site its own space.' }) spaceId?: string,\n @Arg('restartPolicy', { nullable: true, description: \"How each new twin treats its own past on reboot: 'resync' | 'resume' | 'reset'. Required unless live=true (a mirror is 'resync' by definition).\" }) restartPolicy?: string\n ): Promise<any> {\n const domainId = context.state.domain.id\n const repo = getRepository(TwinReference)\n const ref = await repo.findOne({ where: { domain: { id: domainId }, source } })\n if (!ref) return { ok: false, error: `unknown reference: ${source}` }\n const adapter = getAdapter(ref.adapterType)\n if (!adapter) return { ok: false, error: `no adapter for type: ${ref.adapterType}` }\n const cfg = ref.connectionConfig ?? {}\n try {\n let sites = await adapter.discoverSites(cfg)\n if (siteIds?.length) sites = sites.filter(s => siteIds.includes(s.siteId))\n /* ์•„๋ฌด๊ฒƒ๋„ ์“ฐ๊ธฐ ์ „์— ๊ฑฐ์ ˆํ•œ๋‹ค โ€” ํ•œ ์‚ฌ์ดํŠธ๋ฅผ ๋„˜์œผ๋ฉด \"์ด ํ˜„์žฅ์— ๋”ํ•œ๋‹ค\" ๊ฐ€ ์„ฑ๋ฆฝํ•˜์ง€ ์•Š๋Š”๋‹ค. */\n const refusal = refuseImportSpace(sites.length, spaceId)\n if (refusal) return { ok: false, error: refusal.message, errorCode: refusal.code, errorParams: refusal.params }\n const instances: any[] = []\n const failed: any[] = []\n /*\n * **์ง„ํ–‰์„ ๊ตฌ๋…์œผ๋กœ ํ˜๋ฆฐ๋‹ค** (2026-08-21).\n *\n * ๋งˆ์Šคํ„ฐ ์ฝ๊ธฐ๋Š” ์›๋ณธ์— ์—ฌ๋Ÿฌ ์งˆ์˜๋ฅผ ๋ณด๋‚ด๋Š” ๊ธด ์ž‘์—…์ด๊ณ , ํ™”๋ฉด์€ ๊ทธ ์‚ฌ์ด ์•„๋ฌด๊ฒƒ๋„ ์•Œ ์ˆ˜ ์—†์—ˆ๋‹ค.\n * ๋‹จ๊ณ„๋ฅผ ์•„๋Š” ๊ฒƒ์€ ์–ด๋Œ‘ํ„ฐ๋ฟ์ด๋ฏ€๋กœ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋งํ•˜๊ณ (ํ‘œ์ค€ ๋‚ฑ๋ง), ํ˜ธ์ŠคํŠธ๊ฐ€ ์ž๊ธฐ ๋‘ ๋‹จ๊ณ„(์ƒ์„ฑยท๊ธฐ๋™)๋ฅผ\n * ๋”ํ•ด ํ˜๋ฆฐ๋‹ค.\n *\n * **๋ถ„๋ชจ๋Š” ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์„ ์–ธํ•œ ๊ฒƒ**์ด๋‹ค(`masterSteps`). ์„ ์–ธํ•˜์ง€ ์•Š์€ ์–ด๋Œ‘ํ„ฐ๋Š” `total` ์ด ์—†๊ณ , ๊ทธ๋•Œ\n * ํ™”๋ฉด์€ ํผ์„ผํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค โ€” ๋ชจ๋ฅด๋Š” ์ง„ํ–‰๋ฅ ์„ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.\n */\n const declared = adapter.masterSteps?.length\n const stepTotal = declared === undefined ? undefined : declared + HOST_STEPS.length\n const emit = (p: Omit<ReferenceProgress, 'siteCount'>) =>\n pubsub.publish(REFERENCE_PROGRESS_TOPIC, referenceProgressPayload(domainId, { ...p, siteCount: sites.length, total: p.total ?? stepTotal, source }))\n\n /*\n * **์ฝ์€ ๋’ค์˜ ์ดํ‰์„ ์‚ฌ์ดํŠธ๋งˆ๋‹ค ๋‚จ๊ธด๋‹ค** (2026-08-22).\n *\n * ์ดํ‰์€ ์ฝ๋Š” ์ˆœ๊ฐ„์—๋งŒ ์žˆ์—ˆ๋‹ค โ€” ๋Œ€ํ™”์ƒ์ž๋ฅผ ๋‹ซ์œผ๋ฉด ์‚ฌ๋ผ์ง€๊ณ , ๋‹ค์‹œ ๋ณด๋ ค๋ฉด ๊ฐ™์€ ์ฝ๊ธฐ๋ฅผ ๋˜ ํ•ด์•ผ ํ–ˆ๋‹ค.\n * ๊ทธ๋Ÿฐ๋ฐ ์‚ฌ๋žŒ์ด ๊ทธ๊ฒƒ์„ ๋ฌป๋Š” ์ž๋ฆฌ๋Š” ใ€Œ๋ชจ๋ธ ์‚ดํŽด๋ณด๊ธฐใ€๋‹ค(ํŠธ์œˆ์„ ๋ณด๋‹ค๊ฐ€ ใ€Œ์ด๊ฑด ์™œ ๋น„์—ˆ๋‚˜ใ€๋ฅผ ๋ฌป๋Š”๋‹ค).\n * ๊ทธ๋ž˜์„œ ๋ ˆํผ๋Ÿฐ์Šค ํ–‰์— ๋‚จ๊ฒจ ๊ทธ ํ™”๋ฉด์ด ์–ธ์ œ๋“  ์ฝ๊ฒŒ ํ•œ๋‹ค.\n *\n * ์‚ฌ์‹ค๋งŒ ๋‹ด๋Š”๋‹ค(`assessMaster`) โ€” ๋ฌธ์žฅ์€ ํ™”๋ฉด์ด ๋งŒ๋“ค๊ณ , ๋” ์•Œ๊ณ  ์‹ถ์„ ๋•Œ AI ๊ฐ€ ์ด ์‚ฌ์‹ค๋งŒ ๊ทผ๊ฑฐ๋กœ\n * ์„œ์ˆ ํ•œ๋‹ค. ๋‹ค์‹œ ์ฝ์œผ๋ฉด ๊ทธ ์‚ฌ์ดํŠธ์˜ ์ดํ‰์ด ์ƒˆ๊ฒƒ์œผ๋กœ ๋ฐ”๋€๋‹ค(์ง€๋‚œ ์ฝ๊ธฐ์˜ ์ดํ‰์„ ํ˜„์žฌ๋กœ ๋ณด์ด๊ฒŒ\n * ๋‘์ง€ ์•Š๋Š”๋‹ค).\n */\n const assessments: Record<string, unknown> = {}\n\n for (const [siteIndex, site] of sites.entries()) {\n /*\n * **์‹คํŒจ๋ฅผ ์‹ค์ œ๋กœ ๋ง‰ํžŒ ๋‹จ๊ณ„์— ์ ๋Š”๋‹ค** (2026-08-22).\n *\n * ์˜ˆ์ „์—๋Š” ์‹คํŒจ๋ฅผ ๋ฌด์กฐ๊ฑด `provision` ์œผ๋กœ ์ ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์›๋ณธ์„ ์ฝ๋‹ค ๋Š๊ธด ๊ฒƒ๋„ ํ™”๋ฉด์—๋Š”\n * ใ€ŒํŠธ์œˆ ์ƒ์„ฑ์—์„œ ์‹คํŒจใ€๋กœ ๋–ด๋‹ค โ€” ์‚ฌ๋žŒ์ด ์›์ธ์„ ์—‰๋šฑํ•œ ์ž๋ฆฌ์—์„œ ์ฐพ๋Š”๋‹ค(์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ๋๋‹ค).\n *\n * ๊ทœ์•ฝ์ด ๋‹ต์„ ์ค€๋‹ค: `done` ์€ **๋๋‚ธ ๋‹จ๊ณ„ ์ˆ˜**๋‹ค(`ReferenceProgress.done`). ๊ทธ๋Ÿฌ๋ฉด ์ง€๊ธˆ ๋ง‰ํžŒ ๊ฒƒ์€\n * ๊ทธ ๋‹ค์Œ ๋‹จ๊ณ„, ์ฆ‰ `masterSteps[done]` ์ด๋‹ค. ๊ทธ ํ‘œ๋ฅผ ๋„˜์–ด์„œ๋ฉด(ํ˜ธ์ŠคํŠธ ๋‹จ๊ณ„) ๋งˆ์ง€๋ง‰์œผ๋กœ ์•Œ๋ฆฐ ๊ฒƒ์„ ์“ด๋‹ค.\n *\n * ์ด ๊ทœ์น™์€ ๋‘ ๊ฐ€์ง€ ๋ณด๊ณ  ๋ฐฉ์‹์— ํ•จ๊ป˜ ๋งž๋Š”๋‹ค โ€” ๋‹จ๊ณ„ **์‹œ์ž‘**์— ์•Œ๋ฆฌ๋Š” ์–ด๋Œ‘ํ„ฐ(`done` ์ด ์•„์ง 0)์™€\n * ๋‹จ๊ณ„ **์™„๋ฃŒ**์— ์•Œ๋ฆฌ๋Š” ์–ด๋Œ‘ํ„ฐ(`done` ์ด 1 ๋Š˜์–ด๋‚œ๋‹ค) ๋ชจ๋‘ ใ€Œ๋๋‚ธ ์ˆ˜ใ€๋งŒ ์ง€ํ‚ค๋ฉด ๋œ๋‹ค.\n */\n let lastDone = 0\n let lastStep: ReferenceProgress['step'] = (adapter.masterSteps?.[0] ?? 'provision') as ReferenceProgress['step']\n const track = (p: Omit<ReferenceProgress, 'siteCount'>) => {\n lastDone = p.done\n lastStep = p.step\n emit(p)\n }\n try {\n const master = await adapter.fetchMaster(cfg, site, st =>\n track({ siteId: site.siteId, siteIndex, step: st.key, done: st.done, total: stepTotal, detail: st.detail })\n )\n /* ์–ด๋А ๋ ˆํผ๋Ÿฐ์Šค์˜ **์–ด๋А ์‚ฌ์ดํŠธ**์—์„œ ์™”๋Š”์ง€ ๋‚จ๊ธด๋‹ค โ€” ๋‹ค์‹œ ์ฝ๊ธฐ๊ฐ€ ๊ฐ™์€ ์–ด๋Œ‘ํ„ฐยท๊ฐ™์€ ์‚ฌ์ดํŠธ๋กœ ๋Œ์•„์˜ค๋ ค๋ฉด\n ์‚ฌ์ดํŠธ ์ •์ฒด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค(`source` ๋Š” ์ฐธ์กฐ ์ด๋ฆ„์ด๋ผ ์‚ฌ์ดํŠธ ์ „๋ถ€์— ๊ฐ™๋‹ค). */\n /*\n * ์ •์ฑ…์€ **์„ ์–ธ์ด๊ฑฐ๋‚˜ ์˜๋„์—์„œ ๊ณง๋ฐ”๋กœ ๋”ฐ๋ผ์˜ค๋Š” ๊ฒƒ**์ด๋‹ค: `live=true` ๋Š” ๋ฏธ๋Ÿฌ๋ฅผ ๋„์šฐ๊ฒ ๋‹ค๋Š” ๋œป์ด๊ณ \n * ๋ฏธ๋Ÿฌ๋Š” ์ •์˜์ƒ `resync` ๋‹ค(์™ธ๋ถ€๊ฐ€ ์ง„์‹ค์ด๋ฏ€๋กœ ์šฐ๋ฆฌ ๊ณผ๊ฑฐ๋ฅผ ์ด์–ด ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค). ์‹œ๋ฎฌ๋กœ ๋„์šฐ๋ ค๋ฉด\n * ์Šค์Šค๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค โ€” ๊ทธ ์ž๋ฆฌ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ๊ณ ๋ฅด๋ฉด ์žฌ๊ธฐ๋™๋งˆ๋‹ค ์ด๋ ฅ์„ ์ง€์šฐ๋Š” ํŠธ์œˆ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ƒ๊ธด๋‹ค.\n */\n assessments[site.siteId] = assessMaster(master, site.siteId)\n const policy = readRestartPolicy(restartPolicy ?? (live ? 'resync' : undefined), `importTwinReference(\"${source}\")`)\n track({ siteId: site.siteId, siteIndex, step: 'provision', done: declared ?? 0, total: stepTotal })\n const res = await TwinEngine.ingestMaster(\n domainId,\n { ...master, origin: { kind: 'reference', source, siteId: site.siteId, ...(spaceId ? { spaceId } : {}) } },\n policy,\n { spaceId },\n context.state.user\n )\n track({ siteId: site.siteId, siteIndex, step: 'start', done: (declared ?? 0) + 1, total: stepTotal })\n if (start !== false) {\n // live=true + ์–ด๋Œ‘ํ„ฐ๊ฐ€ openLiveFeed ์ง€์› โ†’ mirror(์‹ค ์ด๋ฒคํŠธ ๋ฏธ๋Ÿฌ). ์•„๋‹ˆ๋ฉด sim ๊ธฐ๋™(fallback).\n /* ์ฝ๊ธฐ ์ปค์„œ๋ฅผ ์ €์žฅํ•  ์ž๋ฆฌ๋ฅผ ํ•จ๊ป˜ ๋„˜๊ธด๋‹ค โ€” ๋ ˆํผ๋Ÿฐ์Šค์˜ ์ด๋ฆ„์€ ํ˜ธ์ŠคํŠธ๊ฐ€ ๋ถ™์ด๋Š” ๊ฒƒ์ด๊ณ \n ์ปค๋„ฅํ„ฐ๋Š” ๊ทธ๊ฒƒ์„ ์•Œ ์ˆ˜ ์—†๋‹ค(ยง`startReferenceLiveFeed`). */\n const wentLive = live\n ? await startReferenceLiveFeed(domainId, ref.adapterType, cfg, site, res.instanceId, ref.source)\n : false\n if (!wentLive) await TwinEngine.startFromRegistry(domainId, res.instanceId)\n instances.push({ siteId: site.siteId, instanceId: res.instanceId, spaceId: res.spaceId, mode: wentLive ? 'live' : 'sim', warnings: res.warnings })\n } else {\n instances.push({ siteId: site.siteId, instanceId: res.instanceId, spaceId: res.spaceId, mode: 'provisioned', warnings: res.warnings })\n }\n } catch (e: any) {\n /*\n * **์‹คํŒจํ•œ ๋‹จ๊ณ„๋ฅผ ๊ทธ๋Œ€๋กœ ์•Œ๋ฆฐ๋‹ค.** ํ™”๋ฉด์ด ์ง„ํ–‰ ํ‘œ์‹œ๋ฅผ ์ง€์šฐ์ง€ ์•Š๊ณ  ๊ทธ ์ž๋ฆฌ๋ฅผ ๋ถ‰๊ฒŒ ๋‘์–ด์•ผ\n * ์‚ฌ๋žŒ์ด ใ€Œ์–ด๋””๊นŒ์ง€ ๊ฐ”๋Š”์ง€ใ€๋ฅผ ์•ˆ๋‹ค. ๋ง‰ํžŒ ์ž๋ฆฌ๋Š” ใ€Œ๋๋‚ธ ์ˆ˜ใ€์˜ ๋‹ค์Œ ๋‹จ๊ณ„๋‹ค(์œ„ ์ฃผ์„).\n */\n const at = (adapter.masterSteps?.[lastDone] ?? lastStep) as ReferenceProgress['step']\n emit({ siteId: site.siteId, siteIndex, step: at, done: lastDone, total: stepTotal, failed: true, error: e?.message ?? String(e) })\n\n failed.push({ siteId: site.siteId, error: e?.message ?? 'failed', ...(e?.code ? { errorCode: e.code, errorParams: e.params } : {}) })\n }\n }\n // provenance โ€” ์ด ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋งŒ๋“  ์ธ์Šคํ„ด์Šค ์ถ”์ (scopeSpec.produced). ์‚ญ์ œ ์—ฐ์‡„ยท์ƒํƒœ ๋™๊ธฐยท๋„ค๋น„๊ฒŒ์ด์…˜ ๊ทผ๊ฑฐ.\n const producedNew = instances.map(i => ({ siteId: i.siteId, instanceId: i.instanceId, spaceId: i.spaceId }))\n const prev: any[] = ((ref.scopeSpec as any)?.produced ?? []).filter((p: any) => !producedNew.some(n => n.instanceId === p.instanceId))\n await repo.update(\n { id: ref.id },\n {\n status: 'connected',\n lastSyncedAt: new Date().toISOString(),\n /* ๋ชป ์˜ฎ๊ธด ๊ฐ’์„ **์„ธ์–ด ๋‚จ๊ธด๋‹ค**. ์•„๋ฌด ์ธ์Šคํ„ด์Šค๋„ ๋ณด๊ณ ํ•˜์ง€ ์•Š์•˜์œผ๋ฉด `null` โ€” ใ€Œ์—†์—ˆ๋‹คใ€๋กœ ์œ„์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. */\n lastWarningCount: instances.some((i: any) => Array.isArray(i.warnings))\n ? instances.reduce((n: number, i: any) => n + (Array.isArray(i.warnings) ? i.warnings.length : 0), 0)\n : null,\n /*\n * **์˜์–ด canonical ๋กœ ๋‚จ๊ธด๋‹ค.** ์ด ๊ฐ’์€ DB ์— ์ €์žฅ๋˜๊ณ  ์—ฐ๊ฒฐ ํ™”๋ฉด์ด ๊ทธ๋Œ€๋กœ ๋ฟŒ๋ฆฐ๋‹ค โ€” ์˜ˆ์ „์—๋Š”\n * ํ•œ๊ธ€ ์‚ฐ๋ฌธ(`N๊ฐœ ์‚ฌ์ดํŠธ ์‹คํŒจ`)์ด๋ผ ๋‹ค์„ฏ ์–ธ์–ด ํ™”๋ฉด์— ํ•œ๊ธ€์ด ์ƒˆ์–ด ๋‚˜๊ฐ”๋‹ค. ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์ฃผ๋Š” ์‚ฌ์œ ๋„\n * ๊ฐ™์€ ํ•„๋“œ์— ๋“ค์–ด์˜ค๋ฏ€๋กœ(๊ทธ๊ฒƒ์€ ์› ์‹œ์Šคํ…œ์˜ ๋ง์ด๋‹ค) ํ‚ค๊ฐ€ ์•„๋‹ˆ๋ผ ์˜์–ด ๋ฌธ์žฅ์œผ๋กœ ํ†ต์ผํ•œ๋‹ค.\n * ์–ด๋А ์‚ฌ์ดํŠธ๊ฐ€ ์™œ ์‹คํŒจํ–ˆ๋Š”์ง€๋Š” `failed[]` ๊ฐ€ ๋‹ตํ•œ๋‹ค โ€” ํ™”๋ฉด์ด ๊ทธ๊ฒƒ์„ ๋ณด์—ฌ ์ค€๋‹ค.\n */\n lastError: failed.length ? `${failed.length} of ${sites.length} site(s) failed: ${failed.map((f: any) => f.siteId).join(', ')}` : null,\n /*\n * โ”€โ”€ ์‹คํŒจ ์‚ฌ์œ ๋ฅผ **๋‚จ๊ธด๋‹ค** (2026-08-21) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n *\n * ์‚ฌ์œ ๋Š” ๋Œ€ํ™”์ƒ์ž์—๋งŒ ์žˆ์—ˆ๋‹ค. ๋‹ซ์œผ๋ฉด ์‚ฌ๋ผ์ง€๊ณ , ๋‹ค์‹œ ๋ณด๋ ค๋ฉด ๊ฐ™์€ ์‹คํŒจ๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋‹ค โ€”\n * ์‹ค์ œ๋กœ ใ€Œ์Šนํ™”ํ‘ธ๋“œใ€ ์—ฐ๊ฒฐ์ด ๊ทธ ์ƒํƒœ์˜€๋‹ค(์š”์•ฝ ํ•œ ์ค„๋งŒ ๋‚จ๊ณ  ์›์ธ์€ ์–ด๋””์—๋„ ์—†์—ˆ๋‹ค).\n *\n * `scopeSpec` ์€ ์ด๋ฏธ ์ด ๋ ˆํผ๋Ÿฐ์Šค์˜ ๋ถ€์† ์‚ฌ์‹ค์„ ๋‹ด๋Š” ์ž๋ฆฌ์ด๋ฏ€๋กœ(`produced`) ์Šคํ‚ค๋งˆ๋ฅผ ๋Š˜๋ฆฌ์ง€ ์•Š๊ณ \n * ์—ฌ๊ธฐ ์ ๋Š”๋‹ค. ์„ฑ๊ณตํ•œ ํšŒ์ฐจ์—๋Š” **๋น„์šด๋‹ค** โ€” ์ง€๋‚˜๊ฐ„ ์‹คํŒจ๋ฅผ ํ˜„์žฌ ์ƒํƒœ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋‘์ง€ ์•Š๋Š”๋‹ค.\n */\n scopeSpec: {\n ...((ref.scopeSpec as any) ?? {}),\n produced: [...prev, ...producedNew],\n /* ์ด๋ฒˆ์— ์ฝ์€ ์‚ฌ์ดํŠธ์˜ ์ดํ‰๋งŒ ๊ฐˆ์•„ ๋ผ์šด๋‹ค โ€” ์ฝ์ง€ ์•Š์€ ์‚ฌ์ดํŠธ์˜ ๊ฒƒ์€ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค. */\n assessments: { ...(((ref.scopeSpec as any) ?? {}).assessments ?? {}), ...assessments },\n ...(failed.length\n ? { lastFailures: failed.map((f: any) => ({ siteId: f.siteId, error: f.error, at: new Date().toISOString() })) }\n : { lastFailures: [] })\n }\n } as any\n )\n return { ok: instances.length > 0, instances, failed }\n } catch (e: any) {\n /* ๋ ˆํผ๋Ÿฐ์Šค ํ–‰์—๋Š” **์˜์–ด canonical** ์„ ๋‚จ๊ธด๋‹ค โ€” ์ €์žฅ๋˜๋Š” ๊ฐ’์€ ์–ธ์–ด์ค‘๋ฆฝ์ด์–ด์•ผ ๋‹ค์‹œ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. */\n await repo.update({ id: ref.id }, { status: 'error', lastError: e?.message ?? 'ingest failed' } as any)\n return refusal(context, e, 'ingest failed')\n }\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"template-registry.js","sourceRoot":"","sources":["../../../server/service/reference/template-registry.ts"],"names":[],"mappings":";;AA4EA,4CAEC;AACD,sCAEC;AACD,kCAEC;AATD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAA;AACjD,SAAgB,gBAAgB,CAAC,GAAiB;IAChD,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;AAC5B,CAAC;AACD,SAAgB,aAAa;IAC3B,OAAO,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;AAChC,CAAC;AACD,SAAgB,WAAW,CAAC,EAAU;IACpC,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AAC1B,CAAC","sourcesContent":["/*\n * ํŠธ์œˆ ํ…œํ”Œ๋ฆฟ(์•„ํ‚คํƒ€์ž…) ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ โ€” ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋œ ํ•ฉ์„ฑ ๋ ˆํผ๋Ÿฐ์Šค ๋งˆ์Šคํ„ฐ ๋นŒ๋”.\n * ๋ ˆํผ๋Ÿฐ์Šค(reference-registry)๊ฐ€ \"๊ณ ์ • ๋งˆ์Šคํ„ฐ\"๋ผ๋ฉด, ํ…œํ”Œ๋ฆฟ์€ \"๋…ธ๋ธŒ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋œ ๋งˆ์Šคํ„ฐ ๋นŒ๋”\".\n * ๋‘˜ ๋‹ค ๊ฐ™์€ ์ธ์ œ์ŠคํŠธ ๊ฒฝ๋กœ(ingestMaster)๋กœ ํ๋ฅธ๋‹ค โ€” ์›์ฒœ์ด ๊ณ ์ •์ด๋ƒ ํ•ฉ์„ฑ์ด๋ƒ๋งŒ ๋‹ค๋ฅด๋‹ค(board-authoring ยง10).\n * ์•ฑ(operato-twin)์ด bootstrap ์—์„œ ์ž๊ธฐ ์•„ํ‚คํƒ€์ž…์„ registerTemplate ํ•œ๋‹ค. ํ‘œํ˜„(map/image/model) ๋ฌด๊ด€.\n */\nimport type { DomainSystem } from '@operato/ops-contract'\n\nimport type { ReferenceMaster } from './reference-master.js'\n\n/** ์‚ฌ์šฉ์ž ๋…ธ์ถœ ํŒŒ๋ผ๋ฏธํ„ฐ(๋…ธ๋ธŒ) ์ •์˜ โ€” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด ์Šคํ‚ค๋งˆ๋กœ ํผ์„ ๋ Œ๋”ํ•œ๋‹ค. */\nexport interface KnobDef {\n key: string\n /** 'geo' = ์œ„๊ฒฝ๋„ ์ง€์ (์ง€๋„์—์„œ ํด๋ฆญ ์„ ํƒ). ๊ฐ’์€ { lat, lon }. ์‚ฌ์šฉ์ž๊ฐ€ ์ขŒํ‘œ๋ฅผ ๋ชฐ๋ผ๋„ ์ง€๋„๋กœ ์ง€์ •. */\n label: string\n /**\n * 'siteEquipment' = **์ด ํ˜„์žฅ์— ์ด๋ฏธ ์žˆ๋Š” ์„ค๋น„๋“ค**(`{id, kind}`). ๊ฐ’์ด ๋น„์–ด ์žˆ์œผ๋ฉด ๋งŒ๋“ค ๋•Œ ํ•œ ๋ฒˆ\n * ํ•ด์„ํ•ด์„œ ์ฑ„์šฐ๊ณ , ์ฑ„์šด ๊ฒฐ๊ณผ๋ฅผ ๋…ธ๋ธŒ ๊ฐ’์œผ๋กœ **๋‚จ๊ธด๋‹ค**(`origin.params`). ๊ทธ๋ž˜์•ผ ๋‚˜์ค‘์— ๋‹ค์‹œ ์ง€์–ด๋„\n * ๊ฐ™์€ ํŠธ์œˆ์ด ๋‚˜์˜จ๋‹ค โ€” ๊ทธ๋•Œ๊ทธ๋•Œ ํ˜„์žฅ์„ ๋‹ค์‹œ ์ฝ์œผ๋ฉด ์‚ฌ์ด์— ์„ค๋น„๊ฐ€ ๋Š˜๊ณ  ์ค€ ๋งŒํผ ๋‹ค๋ฅธ ํŠธ์œˆ์ด ๋œ๋‹ค.\n *\n * ์ข…๋ฅ˜๋ฅผ ํ•จ๊ป˜ ์‹ฃ๋Š” ์ด์œ : ๋ฌด์—‡์„ ๋ฐ›์•„๋“ค์ผ์ง€๋Š” **ํ…œํ”Œ๋ฆฟ์ด ์ข…๋ฅ˜๋กœ ํŒ๋‹จ**ํ•œ๋‹ค(์ด๋ฆ„์œผ๋กœ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค).\n */\n type: 'number' | 'text' | 'select' | 'geo' | 'siteEquipment'\n default: any\n min?: number\n max?: number\n options?: { value: string; label: string }[]\n help?: string\n}\n\n/**\n * ํ…œํ”Œ๋ฆฟ ์ƒ์„ธ(์„ค๋ช… ํŽ˜์ด์ง€์šฉ, ์„ ํƒ) โ€” \"์ด ํ…œํ”Œ๋ฆฟ์ด ๋ฌด์—‡์„ ๋ชจ๋ธ๋งํ•˜๋‚˜\"๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ๋ณด์—ฌ์ค˜ ํ™•์‹ ์„ ์ค€๋‹ค.\n * ์ˆœ์ˆ˜ ํ‘œ์‹œ์šฉ ๋ฐ์ดํ„ฐ(๋นŒ๋“œ ๋กœ์ง๊ณผ ๋ฌด๊ด€). ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด ์Šคํ‚ค๋งˆ๋กœ ์ƒ์„ธ ๋ทฐ๋ฅผ ๋ Œ๋”ํ•œ๋‹ค.\n */\nexport interface TemplateDetail {\n /** ํ•œ ์ค„ ์š”์•ฝ(๋ˆ„๊ตฌ๋ฅผ ์œ„ํ•œ/๋ฌด์—‡). */\n summary?: string\n standards?: string[]\n /** ๋ฐธ๋ฅ˜์ฒด์ธ ๊ตญ๋ฉด(๋ฐ˜์ž…ยท๋ณด๊ด€ยท๋ณ€ํ™˜ยท๋ฐ˜์ถœ ๋“ฑ). */\n phases?: { key: string; label: string; system?: string; note?: string }[]\n /** ๊ณต์ • ๋ผ์šฐํŠธ(์˜คํผ๋ ˆ์ด์…˜ ์‹œํ€€์Šค). */\n route?: { op: string; label?: string; resource?: string; intent?: string; bizStep?: string }[]\n locationTypes?: { key: string; label?: string; standardClass?: string; capabilities?: string[] }[]\n resourceTypes?: { key: string; label?: string; standardClass?: string; capabilities?: string[] }[]\n /** BOM/๋ ˆ์‹œํ”ผ ์š”์•ฝ. */\n recipe?: {\n inputs: { material: string; qty: number; key?: string }[]\n outputs: { material: string; qty: number; key?: string }[]\n /** ์™„์„ฑ ๋ผ์šฐํŠธ ์ด๋ฆ„(๊ณต์ • ๋ผ์šฐํŠธ ์ฐธ์กฐ). */\n route?: string\n }\n /**\n * ํ‘œ์ค€ ์ •ํ•ฉ ๋งคํ•‘ โ€” ๊ฐœ๋…์ด **์–ด๋А ํ‘œ์ค€์˜ ๋ฌด์—‡์— ๋Œ€์‘ํ•˜๋‚˜.**\n *\n * ํ‘œ์ค€ ์นธ์ด EPCISยทISA-95 ๋‘˜๋กœ ๊ตณ์–ด ์žˆ์—ˆ๋‹ค. ์—๋„ˆ์ง€ ํ…œํ”Œ๋ฆฟ์€ ๊ทธ ๋‘˜์ด ์•ต์ปค๊ฐ€ ์•„๋‹ˆ๋ผ ์ ์„ ์ž๋ฆฌ๊ฐ€ ์—†์—ˆ๋‹ค โ€”\n * ์ปค๋„์˜ `StandardClass` ๋„ ๊ฐ™์€ ์ด์œ ๋กœ ์—ด์—ˆ๋‹ค(`iso50001`ยท`iec61850`). ๋Œ€์‘ํ•  ์ด๋ฆ„์ด ์—†์œผ๋ฉด **๋น„์šด๋‹ค**.\n */\n standardsMap?: { concept: string; epcis?: string; isa95?: string; iso50001?: string; iec61850?: string }[]\n /** \"์ด ํ…œํ”Œ๋ฆฟ์ด ๋งž๋‚˜?\" ํŒ๋‹จ ๋„์›€ ํ•ญ๋ชฉ. */\n fits?: string[]\n}\n\nexport interface TwinTemplate {\n id: string\n label: string\n /** ์ปค๋„ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ์ •๋ณธ โ€” ์ข…๋ฅ˜๊ฐ€ ๋Š˜๋ฉด ์—ฌ๊ธฐ ์†๋Œˆ ๊ฒƒ์ด ์—†๋‹ค(`DomainSystem`). */\n system: DomainSystem\n description?: string\n /** ์ƒ์„ธ ์„ค๋ช…(์„ ํƒ) โ€” ์„ค๋ช… ํŽ˜์ด์ง€/ํŒจ๋„์ด ๋ Œ๋”. */\n detail?: TemplateDetail\n knobs: KnobDef[]\n /** ๋…ธ๋ธŒ ๊ฐ’ โ†’ ํ•ฉ์„ฑ ๋งˆ์Šคํ„ฐ(+์˜ต์…˜ ์‹œ๋‚˜๋ฆฌ์˜ค). scenario ๋Š” runtime.scenario.load ๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ถˆํˆฌ๋ช… ๊ฐ’. */\n build(params: Record<string, any>): { master: ReferenceMaster; scenario?: any }\n}\n\nconst templates = new Map<string, TwinTemplate>()\nexport function registerTemplate(tpl: TwinTemplate): void {\n templates.set(tpl.id, tpl)\n}\nexport function listTemplates(): TwinTemplate[] {\n return [...templates.values()]\n}\nexport function getTemplate(id: string): TwinTemplate | undefined {\n return templates.get(id)\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-reference-reconciliation.js","sourceRoot":"","sources":["../../../server/service/reference/twin-reference-reconciliation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\nimport { Field, ID, Int, ObjectType } from 'type-graphql'\nimport { Domain } from '@things-factory/shell'\n\n/* ํ•œ ์—ฐ๊ฒฐยทTwinยท๋‹จ์œ„์˜ ์ตœ์‹  ๋ฒˆํ˜ธ ๋Œ€์‚ฌ ์ƒํƒœ. ๊ณผ๊ฑฐ ์ถ”์ด๋Š” ingest window๊ฐ€, ํ˜„์žฌ ์กฐ์น˜ ํŒ๋‹จ์€ ์ด ํ‘œ๊ฐ€ ๋‹ตํ•œ๋‹ค. */\n@Entity()\n@Index('uq_twin_reference_reconciliation_0', (e: TwinReferenceReconciliation) => [e.domain, e.instanceId, e.scope], { unique: true })\n@Index('ix_twin_reference_reconciliation_0', (e: TwinReferenceReconciliation) => [e.domain, e.instanceId, e.checkedAt], { unique: false })\n@ObjectType({ description: 'Latest durable sequence reconciliation for one connected source scope. It reports only what numbered source ranges can prove; it never substitutes replay-prone ingest-window counts for source facts.' })\nexport class TwinReferenceReconciliation {\n @PrimaryGeneratedColumn('uuid') @Field(type => ID) readonly id: string\n @ManyToOne(type => Domain) @Field(type => Domain, { nullable: true }) domain?: Domain\n @RelationId((e: TwinReferenceReconciliation) => e.domain) domainId?: string\n @Column() @Field() instanceId: string\n @Column() @Field() scope: string\n @Column() @Field() status: 'aligned' | 'gap' | 'unknown'\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) sourceFirst?: number\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) sourceLast?: number\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) cursorSeq?: number\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) firstSeqSeen?: number\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) headMissing?: number\n @Column({ type: 'int', nullable: true }) @Field(type => Int, { nullable: true }) behind?: number\n @Column({ nullable: true }) @Field({ nullable: true }) reason?: string\n @Column() @Field() checkedAt: Date\n @CreateDateColumn() createdAt?: Date\n @UpdateDateColumn() updatedAt?: Date\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-reference.js","sourceRoot":"","sources":["../../../server/service/reference/twin-reference.ts"],"names":[],"mappings":"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","sourcesContent":["import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { ObjectType, Field, ID, Int } from 'type-graphql'\n\nimport type { RefusalCode, RefusalParams } from '@operato/ops-contract'\n\nimport { Domain, ScalarObject, encryptedJsonColumn } from '@things-factory/shell'\n\n/** ์กฐ์น˜ ๊ฒ€์ฆ ์ƒํƒœ โ€” ใ€Œ์•„์ง ์•ˆ ํ•ด ๋ดค๋‹คใ€๋Š” ์‹คํŒจ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ ์ž์ฒด๋กœ ํ•˜๋‚˜์˜ ์‚ฌ์‹ค์ด๋‹ค. */\nexport type ActuationState = 'unverified' | 'verified' | 'failed'\n\n/** ๋งˆ์ง€๋ง‰ ๊ฑฐ์ ˆ โ€” ์–ธ์–ด ์ค‘๋ฆฝ ์ฝ”๋“œ์™€ ๊ทธ ๊ฐ’๋“ค. ์‚ฌ๋žŒ ๋ฌธ์žฅ์€ ๋‹ด์ง€ ์•Š๋Š”๋‹ค. */\nexport interface ActuationFailure {\n code: RefusalCode\n /** ๊ฑฐ์ ˆ๋œ ์‹œ๊ฐ (ISO 8601). */\n at: string\n params?: RefusalParams\n}\n\n/*\n * TwinReference โ€” ํ…Œ๋„ŒํŠธ ์Šค์ฝ”ํ”„์˜ ์™ธ๋ถ€ ์†Œ์Šค ์‹œ์Šคํ…œ ์—ฐ๊ฒฐ(์‹ค ๋˜๋Š” ๊ฐ€์ƒ). ํŠธ์œˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ธ์ œ์ŠคํŠธ๋˜๋Š” ์›์ฒœ(Face2, ADR-0018).\n * ์ „์—ญ ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ ˆํผ๋Ÿฐ์Šค ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ์˜์†ยท๋„๋ฉ”์ธ๋ณ„ยท์–ด๋Œ‘ํ„ฐ ๊ธฐ๋ฐ˜ ์—”ํ‹ฐํ‹ฐ.\n * inbound ์ „์šฉ(๊ตฌ์กฐยท์ƒํƒœ). ์•„์›ƒ๋ฐ”์šด๋“œ ์•ก์ถ”์—์ด์…˜์€ command-routing(ActuationAdapter) ์†Œ์œ .\n * mappingSpec/scopeSpec ๋Š” simple-json(๋ฉ€ํ‹ฐDB ์ด์‹ โ€” postgres/mysql/sqlite/mssql/oracle ๊ณตํ†ต).\n * connectionConfig ๋Š” ์ž๊ฒฉ ์ฆ๋ช…์„ ๋‹ด์œผ๋ฏ€๋กœ ์•”ํ˜ธํ™”๋˜๋Š” ํ…์ŠคํŠธ ์นธ์ด๋‹ค(์นธ ์ฃผ์„ ์ฐธ์กฐ).\n * ์„ค๊ณ„ SoT: operato-twin/design/plans/reference-management.md.\n * (CLAUDE.md: ๋ชจ๋“  @ObjectType/@Field ๋Š” ์˜๋ฌธ description ํ•„์ˆ˜.)\n */\n@Entity()\n@Index('ix_twin_reference_0', (e: TwinReference) => [e.domain, e.source], { unique: true })\n@ObjectType({ description: 'A tenant-scoped connection to an external source system โ€” the origin for ingesting twin instances (Face2).' })\nexport class TwinReference {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the reference record.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })\n domain?: Domain\n\n @RelationId((e: TwinReference) => e.domain)\n domainId?: string\n\n @Column()\n @Field({ description: 'Reference source id (unique within a domain).' })\n source: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Domain kernel system: wms | yms | mes.' })\n system?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Human-readable site/system name.' })\n siteName?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Optional description.' })\n description?: string\n\n @Column()\n @Field({ description: \"Adapter type registry key (e.g. 'virtual' | 'rest' | 'db' | 'epcis').\" })\n adapterType: string\n\n /**\n * ์ด ์—ฐ๊ฒฐ์— ํ•„์š”ํ•œ ๊ฐ’ โ€” **์ž๊ฒฉ ์ฆ๋ช…์ด ์—ฌ๊ธฐ ๋“ค์–ด์˜จ๋‹ค. ๊ทธ๋ž˜์„œ ์ €์žฅ๋  ๋•Œ ์•”ํ˜ธํ™”๋œ๋‹ค.**\n *\n * โ”€โ”€ ์™œ ํ‘œ์— ๋‘๋‚˜ (2026-09-09) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋น„๋ฐ€๊ฐ’์€ ํ™˜๊ฒฝ์— ๋‘๊ณ  ์ด๋ฆ„์œผ๋กœ ๊ณ ๋ฅด๋Š” ๊ฒƒ์ด ์›์น™์ด๋‹ค(ยง`webhookSecretCandidates`). ๊ทธ ์›์น™์€\n * **์„ค์น˜๋ณธ๋งˆ๋‹ค ํ•˜๋‚˜์ธ ํ‚ค**์— ๋งž๋Š”๋‹ค โ€” ๋ฐฐํฌํ•  ๋•Œ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.\n *\n * ํŠธ์œˆ์˜ ์—ฐ๊ฒฐ์€ ๊ทธ ๋ชจ์–‘์ด ์•„๋‹ˆ๋‹ค. **์‚ฌ๋žŒ์ด ํ™”๋ฉด์—์„œ ์—ฐ๊ฒฐ์„ ๋งŒ๋“ ๋‹ค.** ์ƒˆ ๊ณต์žฅ์„ ๋ถ™์ด๋ ค๊ณ  ์žฌ๋ฐฐํฌํ• \n * ์ˆ˜๋Š” ์—†์œผ๋ฏ€๋กœ, ์—ฐ๊ฒฐ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด ๊ฐ’์€ ํ‘œ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ ์ž๋ฆฌ์—์„œ ์›์น™์ด ๊ฐˆ๋ฆฐ๋‹ค:\n *\n * ์„ค์น˜๋ณธ๋งˆ๋‹ค ํ•˜๋‚˜์ธ ํ‚ค ํ™˜๊ฒฝ๋ณ€์ˆ˜. ์ด๋ฆ„์ด ์–ด๋А ์ƒ๋Œ€ ๊ฒƒ์ธ์ง€ ๋งํ•œ๋‹ค\n * ์—ฐ๊ฒฐ๋งˆ๋‹ค ๋‹ค๋ฅธ ๊ฐ’ ํ‘œ. ๋Œ€์‹  ์ €์žฅ๋  ๋•Œ ์•”ํ˜ธํ™”ํ•œ๋‹ค\n *\n * โ”€โ”€ ๋ฌด์—‡์„ ์ง€ํ‚ค๊ณ  ๋ฌด์—‡์„ ๋ชป ์ง€ํ‚ค๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ €์žฅ๋œ ๊ฒƒ์„ ์ง€ํ‚จ๋‹ค โ€” DB ํŒŒ์ผ ยท ๋ฐฑ์—… ยท ๋ณต์ œ๋ณธ. 2026-09-09 ์— ์ด ์นธ์—์„œ `hookSecret` ๊ณผ ์ ‘์†\n * ํ† ํฐ์„ ๋ช…๋ น ๋‘ ๊ฐœ๋กœ ์ฝ์—ˆ๋‹ค.\n *\n * **ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ์„œ๋Š” ๋ชป ์ง€ํ‚จ๋‹ค** โ€” ๊ทธ ์‚ฌ๋žŒ์€ ํ‚ค๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ’์ด\n * ํ™”๋ฉด์œผ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒƒ๋„ ์ด ์นธ์ด ๋ง‰์ง€ ์•Š๋Š”๋‹ค: ๋‚ด๋ณด๋‚ด๋Š” ์ชฝ์ด ์–ด๋Œ‘ํ„ฐ ์Šคํ‚ค๋งˆ์˜ `secret: true` ๋ฅผ ๋ณด๊ณ \n * ๊ฐ€๋ฆฐ๋‹ค(ยง`reference-resolver` ์˜ ์ƒ์„ธ ์กฐํšŒ). **๋‘ ๊ฐ€์ง€๊ฐ€ ๊ฐˆ๋ ค ์žˆ์œผ๋ฏ€๋กœ ํ•œ์ชฝ๋งŒ ํ•˜๋ฉด ๋ฐ˜์ชฝ์ด๋‹ค.**\n *\n * ๊ธฐ์กด ํ‰๋ฌธ ํ–‰์€ ์•ˆ ๊นจ์ง„๋‹ค โ€” ๋ณ€ํ™˜๊ธฐ๊ฐ€ ์•”ํ˜ธ๋ฌธ ๋ชจ์–‘์ด ์•„๋‹Œ ๊ฐ’์„ ์•Œ์•„๋ณด๊ณ  ํŒŒ์‹ฑํ•˜๋ฉฐ ๊ฒฝ๊ณ ๋ฅผ ๋‚จ๊ธฐ๊ณ ,\n * ๋‹ค์‹œ ์ €์žฅ๋  ๋•Œ ์•”ํ˜ธํ™”๋œ๋‹ค.\n */\n @Column({ nullable: true, ...encryptedJsonColumn() })\n @Field(type => ScalarObject, { nullable: true, description: 'Adapter-specific connection config (endpoint, credentials, params). Encrypted at rest; secret-declared fields are masked on the way out.' })\n connectionConfig?: any\n\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Declarative legacyโ†’canonical mapping rules (kernel face2-adapter AdapterRule[]).' })\n mappingSpec?: any\n\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: '1:N fan-out scope (discovered sites). Multiple sites โ†’ N instances.' })\n scopeSpec?: any\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Lifecycle status: draft | connected | error.' })\n status?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Last successful master sync time (ISO 8601 string; portable across DB drivers).' })\n lastSyncedAt?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Last connection/sync error message, if any.' })\n lastError?: string\n\n /**\n * **์กฐ์น˜๋ฅผ ์ด ์ฃผ์†Œ๋กœ ์‹ค์ œ๋กœ ๋„˜๊ฒจ ๋ดค๋‚˜** (ADR-0046 โ‘ก).\n *\n * โ”€โ”€ ์™œ ์„ธ ๊ฐ’์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์„ค์ •์ด ๋งž๋Š” ๊ฒƒ๊ณผ ์ €์ชฝ์ด ๋ฐ›๋Š” ๊ฒƒ์€ ๋‹ค๋ฅด๋‹ค. ์ฃผ์†Œ๋„ ๋น„๋ฐ€๊ฐ’๋„ ๋‹ค ์ ํ˜€ ์žˆ๋Š”๋ฐ ์ €์ชฝ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ทธ ๊ฐ’์„\n * ์žƒ์€ ์ผ์ด ์‹ค์ œ๋กœ ์žˆ์—ˆ๋‹ค(ยง`actuationReadiness`). ๊ทธ๊ฒƒ์€ **ํ•œ ๋ฒˆ ๋„˜๊ฒจ ๋ด์•ผ** ์•Œ ์ˆ˜ ์žˆ๊ณ , ๊ทธ๋ž˜์„œ\n * ใ€Œ์•„์ง ์•ˆ ํ•ด ๋ดค๋‹คใ€์™€ ใ€Œํ•ด ๋ดค๊ณ  ๋๋‹คใ€์™€ ใ€Œํ•ด ๋ดค๊ณ  ์•ˆ ๋๋‹คใ€๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋‹ค.\n *\n * unverified ์•„์ง ์™•๋ณต์ด ์—†๋‹ค โ€” ์‹คํŒจ๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ƒˆ ์—ฐ๊ฒฐ๊ณผ ์„ค์ •์ด ๋ฐ”๋€ ์—ฐ๊ฒฐ์ด ์—ฌ๊ธฐ ์„ ๋‹ค\n * verified `actuate` ๊ฐ€ ๋ฐ›์•„๋“ค์—ฌ์กŒ๋‹ค. ๊ทธ ์‹œ๊ฐ์ด `actuationVerifiedAt`\n * failed ๊ฑฐ์ ˆ๋๋‹ค. ์‚ฌ์œ ๋Š” `actuationFailure` ์— **์ฝ”๋“œ๋กœ**\n *\n * `unverified` ๋ฅผ `failed` ๋กœ ์ ‘์ง€ ์•Š๋Š”๋‹ค โ€” ์•ˆ ํ•ด ๋ณธ ๊ฒƒ์„ ์‹คํŒจ๋กœ ๊ทธ๋ฆฌ๋ฉด ์‚ฌ๋žŒ์ด ๊ณ ์น  ๊ฒƒ์„ ์ฐพ์œผ๋Ÿฌ\n * ๊ฐ€๊ณ , ๊ณ ์น  ๊ฒƒ์ด ์—†๋‹ค.\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"Whether an actuation has actually reached this peer: 'unverified' | 'verified' | 'failed'. Null means the same as unverified; a connection that has never been tried is not a failed one.\" })\n actuationState?: ActuationState\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When an actuation was last accepted by the peer (ISO 8601 string; portable across DB drivers). Null while unverified.' })\n actuationVerifiedAt?: string\n\n /**\n * ๋งˆ์ง€๋ง‰ ๊ฑฐ์ ˆ โ€” **์ฝ”๋“œ์™€ ๊ฐ’๋งŒ ์ €์žฅํ•œ๋‹ค. ๋ฌธ์žฅ์€ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.**\n *\n * `lastError` ๊ฐ€ ์‚ฌ๋žŒ ๋ฌธ์žฅ์„ ์ €์žฅํ•ด ๋‘๊ณ  ํ™”๋ฉด์ด ๊ทธ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋ฟŒ๋ ธ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฒˆ์—ญ์ด ์•ˆ ๋˜๊ณ , ๋ฌด์—‡์ด\n * ๋ช‡ ๋ฒˆ ๋‚ฌ๋Š”์ง€ ์„ธ์ง€๋„ ๋ชปํ•˜๊ณ , ์ปค๋„ฅํ„ฐ๊ฐ€ ๋ฌธ์žฅ์„ ๊ณ ์น˜๋Š” ๋‚  ์˜› ํ–‰๊ณผ ์ƒˆ ํ–‰์ด ์„œ๋กœ ๋‹ค๋ฅธ ๋ง์„ ํ•œ๋‹ค.\n * ์ฝ”๋“œ๋Š” `CommandAck.errorCode` ์™€ ๊ฐ™์€ ๋‚ฑ๋ง์ด๋‹ค(ADR-0042 โ‘ข) โ€” ํ‘œํ˜„์ธต์ด ๋ฌธ์žฅ์„ ๋งŒ๋“ ๋‹ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Why the last actuation was refused: { code, at, params? }. Language-neutral codes only โ€” the presentation layer builds the sentence. Null when the last attempt was accepted or none was made.' })\n actuationFailure?: ActuationFailure\n\n /**\n * ๋งˆ์ง€๋ง‰ ๋™๊ธฐ์—์„œ **๋ชป ์˜ฎ๊ธด ๊ฐ’์˜ ์ˆ˜**. `null` = ์„ธ์ง€ ์•Š์•˜๋‹ค(0 ๊ณผ ๋‹ค๋ฅด๋‹ค).\n *\n * ์„ธ์ง€ ์•Š์€ ๊ตฌ์กฐ ์ธ์ œ์ŠคํŠธ๋Š” ๋„ํฌ๋ฅผ ๋ž™์œผ๋กœ ๋ฐ”๊ฟ” ๋†“๊ณ ๋„ ์„ฑ๊ณต์ด๋ผ ๋‹ตํ•˜๋ฉด์„œ ์•„๋ฌด ์ผ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ ์‚ฌ์‹ค์„ ์‚ฌํ›„์— ๋ฌผ์„ ์ˆ˜\n * ์žˆ์–ด์•ผ ๋‹จ๊ณ„ ํŒ์ •์ด ใ€Œ๊ตฌ์กฐ๋Š” ๋๋‹คใ€๋ฅผ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์—†๋Š” ๋™์•ˆ ํŒ์ •์€ ๋Š˜ `unmeasured` ์˜€๋‹ค.\n * ๊ธฐ๋ณธ๊ฐ’์„ ๋‘์ง€ ์•Š๋Š”๋‹ค: 0 ์„ ๊ธฐ๋ณธ์œผ๋กœ ๊น”๋ฉด ใ€Œ๊ฒฝ๊ณ  ์—†์—ˆ๋‹คใ€์™€ ใ€Œ์„ธ์ง€ ์•Š์•˜๋‹คใ€๊ฐ€ ๊ฐ™์•„์ง„๋‹ค.\n */\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'Number of values the last sync could not carry over (mapping fallbacks). Null means they were not counted at all, which is different from zero.' })\n lastWarningCount?: number\n\n /**\n * **์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋‚˜** โ€” ๋ผ์ด๋ธŒ ํ”ผ๋“œ์˜ ์ฝ๊ธฐ ์ปค์„œ(ยง`LiveFeedContinuity`).\n *\n * โ”€โ”€ ์™œ ์ €์žฅํ•˜๋‚˜ (2026-08-23 ์‹ค์ธก) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋ถ™์„ ๋•Œ๋งˆ๋‹ค `Date.now() โˆ’ ๋˜๋Œ์•„๋ณผ ๋‚ ์ˆ˜` ๋กœ ์ฐฝ์„ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ **์žฌ๊ธฐ๋™๋งˆ๋‹ค\n * ๋ฏธ๋Ÿฌ์˜ ๊ณผ๊ฑฐ๊ฐ€ ์ž˜๋ ธ๋‹ค** โ€” ์ž‘์—… 2,855 โ†’ 2,820(8์‹œ๊ฐ„ ํ๋ฅธ ๋งŒํผ). ๋ฏธ๋Ÿฌ๊ฐ€ ์•„๋Š” ๊ฒƒ์ด ใ€Œ์›๋ณธ์˜ ์‚ฌ์‹คใ€์ด\n * ์•„๋‹ˆ๋ผ ใ€Œ์ฐฝ์˜ ํ•จ์ˆ˜ใ€์˜€๊ณ , ๊ทธ ์‚ฌ์‹ค์„ ์•„๋ฌด๋„ ๋งํ•˜์ง€ ์•Š์•˜๋‹ค.\n *\n * ์ปค๋„์ด ๊ทธ ๊ฐˆ๋ฆผ์„ ์ด๋ฏธ ์ ์–ด ๋‘์—ˆ๋‹ค(ยง`hydrateContinuity`): ใ€Œ์›์ฒœ์ด ์• ์ดˆ์— ๋‹ค์‹œ ๋งํ•ด ์ฃผ์ง€ ์•Š๋Š” ์ถ•ใ€์€\n * ์žฌ๊ธฐ๋™ ์—ฐ์†์„ฑ์œผ๋กœ ์ด์–ด๋ฐ›๋Š”๋‹ค. ใ€Œ์šฐ๋ฆฌ๊ฐ€ ์–ด๋””๊นŒ์ง€ ์ฝ์—ˆ๋‚˜ใ€๊ฐ€ ์ •ํ™•ํžˆ ๊ทธ ์„ฑ์งˆ์ด๋ฏ€๋กœ **์–ด๋Œ‘ํ„ฐ์˜ ์‚ฌ๋ฌผํ•จ์ด\n * ์•„๋‹ˆ๋ผ ์ด ์ธต**์— ์žˆ๋‹ค โ€” ์›๋ณธ์ด ๋Š˜ ๋•Œ๋งˆ๋‹ค ์ €์žฅ ๊ธฐ์ œ๊ฐ€ ๋Š˜๊ณ  ๊ทธ์ค‘ ํ•˜๋‚˜๊ฐ€ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜์ง€ ์•Š๊ฒŒ.\n *\n * โ”€โ”€ ์™œ ์บ์‹œ๊ฐ€ ์•„๋‹ˆ๋ผ ํ‘œ์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋งŒ๋ฃŒ๋˜๋ฉด ์ฐฝ์ด ๋‹ค์‹œ ๋ฏธ๋„๋Ÿฌ์ง€๊ณ , ๊ทธ ์†์‹ค์€ ์˜ค๋ฅ˜ ์—†์ด ๋“ค์–ด์˜จ ๊ฒƒ์ด ์—†๋‹ค. ์Šค๋ƒ…์ƒท ์ฒดํฌํฌ์ธํŠธ์™€ ์„ฑ์งˆ์ด ๋‹ค๋ฅด๋‹ค\n * (๊ทธ์ชฝ์€ ์žƒ์–ด๋„ ์›์ฒœ์ด ์ •์ •ํ•ด ์ค€๋‹ค โ€” ์ด ๊ฐ’์€ **์žƒ์œผ๋ฉด ์›์ฒœ์— ๋ฌป์ง€ ์•Š๊ฒŒ ๋œ๋‹ค**).\n *\n * ๋ชจ์–‘์€ `{ streams: { [ํ๋ฆ„]: { since?, seen[] } }, firstAttachedAt? }` ๋‹ค. **ํ๋ฆ„ ์ด๋ฆ„์€ ์–ด๋Œ‘ํ„ฐ๊ฐ€\n * ์ •ํ•œ๋‹ค** โ€” ์›๋ณธ๋งˆ๋‹ค ํ๋ฆ„ ์ˆ˜์™€ ๋œป์ด ๋‹ค๋ฅด๋ฏ€๋กœ ์ด ์ธต์€ ์—ด์‡ ๋กœ๋งŒ ๋‹ค๋ฃฌ๋‹ค. `simple-json` ์ด๋ผ ๋“œ๋ผ์ด๋ฒ„\n * ๋‹ค์„ฏ์„ ๊ทธ๋Œ€๋กœ ์ง€๋‚œ๋‹ค.\n *\n * `firstAttachedAt` ์€ ใ€Œ์–ธ์ œ๋ถ€ํ„ฐ ์•„๋Š”๊ฐ€ใ€๋‹ค. ์ปค๋„์€ ์ƒํ•œ๋งŒ ์•ˆ๋‹ค(`nowTime` = ๋งˆ์ง€๋ง‰์œผ๋กœ ๋“ค์€ ์‹œ๊ฐ).\n * ๋‘˜์ด ํ•จ๊ป˜ ใ€Œ์ด ํŠธ์œˆ์ด ์•„๋Š” ๊ตฌ๊ฐ„ใ€์ด๊ณ , ํ™”๋ฉด์ด ์ˆ˜๋ฅผ ๋ณด์ผ ๋•Œ ๊ทธ ๊ตฌ๊ฐ„์„ ๋งํ•ด์•ผ ํ•œ๋‹ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Live feed read cursor carried across restarts, keyed by adapter-defined stream. Null means the feed has never attached, and the next attach decides its first window.' })\n liveCursor?: any\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when the reference was first created.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when the reference row was last updated.' })\n updatedAt?: Date\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-attention/index.ts"],"names":[],"mappings":";;;AAAA,uEAA8D;AAEjD,QAAA,SAAS,GAAG,CAAC,4CAAkB,CAAC,CAAA","sourcesContent":["import { TwinAttentionQuery } from './twin-attention-query.js'\n\nexport const resolvers = [TwinAttentionQuery]\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-attention-query.js","sourceRoot":"","sources":["../../../server/service/twin-attention/twin-attention-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Int, Query, Resolver } from 'type-graphql'\n\nimport { ScalarObject } from '@things-factory/shell'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { digestAttentions } from '../../engine/attention-digest.js'\n\n/*\n * ์ฃผ๋ชฉ ์‹ ํ˜ธ(Attention) ์งˆ์˜ โ€” ํ˜„์žฌ ์Šค๋ƒ…์ƒท์˜ ์š”์•ฝ๋œ \"๋ด์•ผ ํ•  ๊ฒƒ\".\n * ์ปค๋„ computeAttentions() ํŒŒ์ƒ: severity(ISA-18.2/IEC 62682) ยท state(OPC UA A&C) ยท\n * anchor(locationId/moverId/orderId = ๊ณต๊ฐ„ ์œ„์น˜) ยท suggestedAction(์กฐ์น˜ ์ œ์•ˆ). kind ๋Š” ๋„๋ฉ”์ธ ์†Œ์œ (๋ฌด๋ฐฉ์–ธ).\n * full StateSnapshot ๋Œ€์‹  ์ด ๊ฒฝ๋Ÿ‰ ๋ชฉ๋ก์„ AI read ๋„๊ตฌยทinsight UI ๊ฐ€ ์†Œ์‹ฑ(๋Œ€์šฉ๋Ÿ‰ ๋คํ”„ ํšŒํ”ผ).\n * (์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆผ์€ twinState subscription ์ด attentions ๋ฅผ ํฌํ•จ. ์ด๊ฑด one-shot '์งˆ์˜' ํ‘œ๋ฉด.)\n */\n@Resolver()\nexport class TwinAttentionQuery {\n @Query(returns => [ScalarObject], {\n description: 'Active attention signals (things to look at) derived from the current twin snapshot โ€” severity (ISA-18.2), lifecycle state (OPC UA A&C), space anchor, and suggested action.'\n })\n async twinAttentions(\n @Ctx() context: ResolverContext,\n @Arg('instanceId', { nullable: true }) instanceId?: string,\n /*\n * **๊ณต๊ฐ„์œผ๋กœ ๋ฌผ์œผ๋ฉด ๊ทธ ํ˜„์žฅ์˜ ๋ชจ๋“  ๋ Œ์ฆˆ์—์„œ ๋ชจ์•„ ๋‹ตํ•œ๋‹ค** โ€” ํ•œ ํ˜„์‹ค์„ WMSยทMESยทYMS ๊ฐ€ ํ•จ๊ป˜ ๋น„์ถ”๋ฏ€๋กœ\n * \"์ด ํ˜„์žฅ์—์„œ ๋ด์•ผ ํ•  ๊ฒƒ\" ์€ ๋ Œ์ฆˆ ํ•˜๋‚˜๋กœ ๋‹ตํ•  ์ˆ˜ ์—†๋‹ค. ์˜ˆ์ „์—๋Š” ํ™”๋ฉด์ด ์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ๋ฌผ์–ด ์†์œผ๋กœ\n * ํ•ฉ์ณค๊ณ , ๊ทธ๋Ÿฌ๋ฉด ์ •๋ ฌ ๊ทœ์น™์ด ํ™”๋ฉด๋งˆ๋‹ค ๊ฐˆ๋ฆฐ๋‹ค.\n *\n * ๊ฒฝ๊ณ ๋Š” **ํ•ฉ์ง‘ํ•ฉ์ด ๊ทธ๋Œ€๋กœ ๋œป์ด ์žˆ๋Š” ์œ ์ผํ•œ ๋ Œ์ฆˆ**๋‹ค. ์˜ˆ์ธก์€ ํ•ฉ์น  ์ˆ˜ ์—†๋‹ค(P50 ๋‘ ๊ฐœ๋ฅผ ๋”ํ•  ์ˆ˜ ์—†๋‹ค) โ€”\n * ๊ทธ๋ž˜์„œ ์˜ˆ์ธก์€ ์—ฌ์ „ํžˆ ์ธ์Šคํ„ด์Šค๋ณ„๋กœ ๋‹ตํ•˜๊ณ  ํ™”๋ฉด์ด ๋‚˜๋ž€ํžˆ ๋†“๋Š”๋‹ค.\n */\n @Arg('spaceId', { nullable: true }) spaceId?: string\n /*\n * โ”€โ”€ ์ž๋ฅด๋Š” ์ธ์ž๋Š” ์—ฌ๊ธฐ ์—†๋‹ค (2026-09-19, ์ˆ˜์„ ์•„ํ‚คํ…ํŠธ ํŒ์ •) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n *\n * `limit` ์ด ์žˆ์—ˆ๋‹ค. ์ž๋ฅด๋ฉด์„œ **๋ช‡ ๊ฑด์„ ์ž˜๋ž๋Š”์ง€๋Š” ๋‹ต์— ์‹ฃ์ง€ ๋ชปํ–ˆ๋‹ค** โ€” ๋‹ต์ด ๋งจ ๋ชฉ๋ก์ด๋ผ ์‹ค์„\n * ์ž๋ฆฌ๊ฐ€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ž๋ฅผ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ด ์ž˜๋ฆฐ ์ˆ˜๋ฅผ ๋ชป ๋งํ•˜๋ฉด, ์Šค๋ฌด ๊ฑด๋งŒ ๋ฐ›์€ ํ™”๋ฉด์€ ๊ทธ๊ฒƒ์ด\n * ์ „๋ถ€์ธ์ง€ ์ด๋ฐฑ ์ค‘ ์Šค๋ฌด ๊ฑด์ธ์ง€ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์—†๋‹ค.\n *\n * ์ž๋ฅด๋ ค๋Š” ์†Œ๋น„์ž๋Š” `twinAttentionDigest` ๋ฅผ ์“ด๋‹ค โ€” ๊ทธ ๋ฌธ์€ `attentionTotal` ์„ ํ•จ๊ป˜ ๋‹ตํ•˜๊ณ ,\n * ์ž๋ฆฌ๋ณ„ ์ƒ‰์„ **์ „๋Ÿ‰์„ ๊ทผ๊ฑฐ๋กœ** ๊ณ„์‚ฐํ•œ๋‹ค. ์ด ๋ฌธ์€ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค.\n */\n ): Promise<any[]> {\n if (spaceId) return (await TwinEngine.attentionsOfSpace(context.state.domain.id, spaceId)).attentions\n if (!instanceId || !TwinEngine.owns(context.state.domain.id, instanceId)) return [] // ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ\n // ๋ผ์ด๋ธŒ ์ปค๋„ ์Šค๋ƒ…์ƒท(fresh) ์šฐ์„  โ€” snapshot()=resync() ๋Š” ์บ์‹œ๋ผ ์ปค๋งจ๋“œ ๋ธํƒ€ ์ง€์—ฐ(recover ์™€ ๋™์ผ ์›์ฒœ ์‚ฌ์šฉ).\n const kernel = TwinEngine.kernel(context.state.domain.id, instanceId)\n const snap = kernel?.getSnapshot?.() ?? TwinEngine.snapshot(context.state.domain.id, instanceId)\n return snap?.attentions ?? []\n }\n\n /**\n * ์ž˜๋ž๋‹ค๋ฉด **๋ช‡ ๊ฑด์„ ์ž˜๋ž๋Š”์ง€**์™€ ์ž๋ฆฌ ์ƒ‰ ์š”์•ฝ๊นŒ์ง€ โ€” ๋ชฉ๋ก๋งŒ ์ฃผ๋ฉด ํ™”๋ฉด์ด \"N๊ฑด ๋”\" ๋ฅผ ๋งํ•  ์ˆ˜ ์—†๋‹ค.\n * ์ž๋ฆฌ๋ณ„ ์ตœ๊ณ  ์‹ฌ๊ฐ๋„๋Š” **์ „๋Ÿ‰์„ ๊ทผ๊ฑฐ๋กœ** ๊ณ„์‚ฐํ•œ๋‹ค(์ƒ์œ„ N ์œผ๋กœ ์ค„์ด๋ฉด 20์œ„ ๋ฐ– ์‹ ํ˜ธ๋ฅผ ๊ฐ€์ง„ ์ž๋ฆฌ๊ฐ€ ์ƒ‰์„ ์žƒ๋Š”๋‹ค).\n */\n @Query(returns => ScalarObject, {\n description: 'Attention signals for a space (all its lenses) or one twin, with the total count and the per-location highest severity folded from all of them.'\n })\n async twinAttentionDigest(\n @Ctx() context: ResolverContext,\n @Arg('spaceId', { nullable: true }) spaceId?: string,\n @Arg('instanceId', { nullable: true }) instanceId?: string,\n @Arg('limit', type => Int, { nullable: true }) limit?: number\n ): Promise<any> {\n if (spaceId) return TwinEngine.attentionsOfSpace(context.state.domain.id, spaceId, limit ?? undefined)\n if (!instanceId || !TwinEngine.owns(context.state.domain.id, instanceId)) return { attentions: [], attentionTotal: 0, severityByLocation: {} }\n const kernel = TwinEngine.kernel(context.state.domain.id, instanceId)\n const snap = kernel?.getSnapshot?.() ?? TwinEngine.snapshot(context.state.domain.id, instanceId)\n return digestAttentions((snap?.attentions ?? []).map((a: any) => ({ ...a, instanceId })), limit ?? undefined)\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command-audit.js","sourceRoot":"","sources":["../../../server/service/twin-audit/command-audit.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAoDH,0CAEC;AAKD,8CAuBC;AAkBD,0CAGC;AApDD,4DAA4D;AAC5D,SAAgB,eAAe,CAAC,CAAU;IACxC,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzE,CAAC;AAED,0CAA0C;AAC1C,MAAM,QAAQ,GAAG,IAAI,CAAA;AAErB,SAAgB,iBAAiB,CAAC,KAAwB;IACxD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAA;IACjE,OAAO;QACL,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC;QAClC,WAAW,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;QAC/B,MAAM,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC;QACxC,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;QAC5B,2CAA2C;QAC3C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClH,4CAA4C;QAC5C,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,UAAU,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;QAC7B,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC;QAC3B,uDAAuD;QACvD,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ;QACzB,SAAS,EAAE,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC;QAC9B,4CAA4C;QAC5C,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,SAAS;QAC3E,aAAa,EAAE,SAAS;KACzB,CAAA;AACH,CAAC;AAED,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AAE5F,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA,CAAC,wCAAwC;IACtD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,MAA2C;IACzE,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxE,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1C,CAAC","sourcesContent":["/*\n * ์ปค๋งจ๋“œ ๊ฐ์‚ฌ ๊ธฐ๋ก ๋งŒ๋“ค๊ธฐ (์ˆœ์ˆ˜) โ€” **๋ˆ„๊ฐ€ ๋ฌด์—‡์„ ํ—ˆ๋ฝํ–ˆ๊ณ , ๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ๋๋‚˜.**\n *\n * ์Šน์ธ ๊ฒŒ์ดํŠธ๊ฐ€ ์•ž์„ ๋ง‰๊ณ , ์ด ๊ธฐ๋ก์ด ๋’ค๋ฅผ ์„ค๋ช…ํ•œ๋‹ค. ๋‘˜ ๋‹ค ์žˆ์–ด์•ผ \"์‚ฌ๋žŒ ์†์„ ๊ฑฐ์ณค๋‹ค\" ๋ฅผ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.\n *\n * ๋ฌด์—‡์„ ๋ฏฟ๋Š”๊ฐ€๊ฐ€ ์ด ๊ธฐ๋ก์˜ ์ „๋ถ€๋‹ค:\n * ยท **์‹ ์›ยท์‹œ๊ฐ์€ ์„œ๋ฒ„๊ฐ€ ์ค€๋‹ค.** ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋งํ•œ ์‹ ์›์„ ๊ทธ๋Œ€๋กœ ์ ์œผ๋ฉด ์œ„์กฐ๊ฐ€ ์ž์œ ๋กœ์›Œ ์•„๋ฌด๊ฒƒ๋„\n * ์ฆ๋ช…ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์„ธ์…˜์ด ์•„๋Š” ์‚ฌ์šฉ์ž์™€ ์„œ๋ฒ„ ์‹œ๊ฐ๋งŒ ์“ด๋‹ค.\n * ยท **์˜๋„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ค€๋‹ค** โ€” ์ถœ์ฒ˜(origin)ยท๊ทผ๊ฑฐ(reason). ์„œ๋ฒ„๊ฐ€ ์•Œ ์ˆ˜ ์—†๋Š” ์ •๋ณด์ด๊ณ ,\n * ์œ„์กฐ๋˜๋”๋ผ๋„ ์‹ ์› ์ฆ๋ช…์„ ํ›ผ์†ํ•˜์ง€ ์•Š๋Š”๋‹ค.\n */\n\nexport type CommandOrigin = 'user' | 'ai' | 'automation' | 'unknown'\n\nexport type CommandAuditInput = {\n /** ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹ค์–ด ๋ณด๋‚ธ ์ปค๋งจ๋“œ(์‹ ๋ขฐํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„์„ ํฌํ•จํ•œ ์›๋ณธ). */\n command: any\n /** ์ปค๋„ ํŒ์ •. */\n ack: { accepted?: boolean; errorCode?: string; error?: string }\n /**\n * **์›๋ณธ(์–ด๋Œ‘ํ„ฐ)์ด ์ค€ ๋‹ต** โ€” ํ—ˆ๋ฝ๊ณผ ์ผ์–ด๋‚จ ์‚ฌ์ด์— ๋ผ์–ด ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ™์€ ๊ธฐ๋ก์— ๋‹ซ๋Š”๋‹ค (ADR-0029 ยง1 ๊ฒฐ์ • C).\n *\n * โ”€โ”€ ์™œ ์ด ์นธ์ด ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ช…๋ น์ด ์›๋ณธ์œผ๋กœ ๊ฐ€๋ฉด ๊ฐ์‚ฌ๋Š” ใ€Œํ—ˆ๋ฝํ–ˆ๋‹คใ€๊นŒ์ง€๋งŒ ์ฆ๋ช…ํ•œ๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์˜ค๋ฅ˜ ์—†์ด ์‹คํŒจํ•˜๋ฉด ์›์žฅ์—๋Š” ์Šน์ธ๋งŒ\n * ๋‚จ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋Œ‘ํ„ฐ์˜ ๋‹ต์„ **๊ฐ™์€ ํ–‰**์— ๋˜์ ๋Š”๋‹ค.\n *\n * ์…‹์„ ๊ตฌ๋ณ„ํ•œ๋‹ค:\n * ยท ์—†์Œ(`undefined`) โ€” **์›๋ณธ์— ๋ฌป์ง€ ์•Š์•˜๋‹ค**(์ปค๋„์ด ๋ฐ›์€ ๋ช…๋ น์ด๋‹ค). ใ€Œ๋ชจ๋ฅธ๋‹คใ€์™€ ๋‹ค๋ฅด๋‹ค.\n * ยท `{ answered: false }` โ€” ๋ฌผ์—ˆ๋Š”๋ฐ **๋‹ต์„ ๋ชป ๋ฐ›์•˜๋‹ค** โ†’ `unknown` ์œผ๋กœ ๋‚จ๊ธด๋‹ค. ์„ฑ๊ณต์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค.\n * ยท `{ answered: true, ok, code? }` โ€” ์›๋ณธ์ด ๋‹ตํ–ˆ๋‹ค(์ ์šฉยท๊ฑฐ์ ˆ ๋ชจ๋‘ ์‚ฌ์‹ค์ด๋‹ค).\n */\n source?: { answered: boolean; ok?: boolean; code?: string }\n /** ์„ธ์…˜์ด ์•„๋Š” ์‚ฌ์šฉ์ž โ€” **์„œ๋ฒ„๋งŒ ์ฑ„์šด๋‹ค.** */\n actor?: { id?: string; email?: string; name?: string }\n /** ์„œ๋ฒ„ ์‹œ๊ฐ. ํ˜ธ์ถœ๋ถ€๊ฐ€ ์ฃผ์ž…ํ•ด ํ…Œ์ŠคํŠธ๊ฐ€ ์‹œ๊ฐ„์„ ๊ณ ์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. */\n at: Date\n}\n\n/** `TwinAuditEvent` ์— ๊ทธ๋Œ€๋กœ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๋ชจ์–‘(์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ชฐ๋ผ๋„ ๋˜๊ฒŒ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋‘”๋‹ค). */\nexport type CommandAuditRow = {\n eventTime: Date\n commandId?: string\n commandType?: string\n origin: CommandOrigin\n reason?: string\n actorId?: string\n actorEmail?: string\n actorName?: string\n accepted: boolean\n errorCode?: string\n /**\n * ์›๋ณธ์ด ๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ํ–ˆ๋‚˜ โ€” `applied` ยท `refused` ยท `unknown`(๋ฌผ์—ˆ์ง€๋งŒ ๋‹ต์ด ์—†๋‹ค).\n * **์—†์œผ๋ฉด ๋ฌป์ง€ ์•Š์€ ๊ฒƒ์ด๋‹ค**(์ปค๋„์ด ๋ฐ›์€ ๋ช…๋ น). 0 ์ด๋‚˜ ์„ฑ๊ณต์œผ๋กœ ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค.\n */\n sourceOutcome?: 'applied' | 'refused' | 'unknown'\n /** ์›๋ณธ์ด ์ค€ ์‚ฌ์œ  ์ฝ”๋“œ โ€” ์žˆ์œผ๋ฉด ๊ทธ๋Œ€๋กœ. ์šฐ๋ฆฌ๊ฐ€ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค. */\n sourceCode?: string\n args?: any\n argsTruncated: boolean\n}\n\n/** ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ถœ์ฒ˜ ํ‘œ๊ธฐ๋กœ ์ •๊ทœํ™” โ€” ๋ชจ๋ฅด๋Š” ๊ฐ’์€ ์ง€์–ด๋‚ด์ง€ ์•Š๊ณ  'unknown' ์œผ๋กœ ๋‘”๋‹ค. */\nexport function normalizeOrigin(v: unknown): CommandOrigin {\n return v === 'user' || v === 'ai' || v === 'automation' ? v : 'unknown'\n}\n\n/** args ์ง๋ ฌํ™” ์ƒํ•œ(๋ฌธ์ž). ๋„˜์œผ๋ฉด ์ž๋ฅด๋˜ ์ž˜๋ž๋‹ค๊ณ  ํ‘œ์‹œํ•œ๋‹ค. */\nconst ARGS_MAX = 4000\n\nexport function buildCommandAudit(input: CommandAuditInput): CommandAuditRow {\n const { command, ack, actor, at, source } = input\n const argsText = safeJson(command?.args)\n const truncated = argsText !== null && argsText.length > ARGS_MAX\n return {\n eventTime: at,\n commandId: str(command?.commandId),\n commandType: str(command?.type),\n origin: normalizeOrigin(command?.origin),\n reason: str(command?.reason),\n /* ์›๋ณธ์˜ ๋‹ต โ€” ๋ฌป์ง€ ์•Š์•˜์œผ๋ฉด ์นธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค(๋ชจ๋ฆ„๊ณผ ๊ตฌ๋ณ„ํ•œ๋‹ค). */\n ...(source ? { sourceOutcome: sourceOutcomeOf(source), ...(source.code ? { sourceCode: source.code } : {}) } : {}),\n /* ์‹ ์› โ€” ์„ธ์…˜ ๊ฐ’๋งŒ. ์ปค๋งจ๋“œ์— ์‹ค๋ ค ์˜จ ์‹ ์› ์ฃผ์žฅ์€ ์ณ๋‹ค๋ณด์ง€ ์•Š๋Š”๋‹ค. */\n actorId: str(actor?.id),\n actorEmail: str(actor?.email),\n actorName: str(actor?.name),\n /* ๊ฒฐ๊ณผ โ€” ์Šน์ธํ–ˆ๋Š”๋ฐ ์ปค๋„์ด ๊ฑฐ์ ˆํ•œ ๊ฒƒ๋„ ๊ฐ์‚ฌ ๋Œ€์ƒ์ด๋‹ค(๋ฌด์—‡์„ ์‹œ๋„ํ–ˆ๋Š”์ง€๊ฐ€ ๋‚จ์•„์•ผ ํ•œ๋‹ค). */\n accepted: !!ack?.accepted,\n errorCode: str(ack?.errorCode),\n /* ์ธ์ž๋Š” ์›ํ˜• ๊ทธ๋Œ€๋กœ. ๋„ˆ๋ฌด ํฌ๋ฉด ์ž˜๋ฆฐ ๋ฌธ์ž์—ด๋กœ ๋‘๋˜ ์ž˜๋ž๋‹ค๊ณ  ๋งํ•œ๋‹ค. */\n args: truncated ? argsText!.slice(0, ARGS_MAX) : command?.args ?? undefined,\n argsTruncated: truncated\n }\n}\n\nconst str = (v: unknown): string | undefined => (typeof v === 'string' && v ? v : undefined)\n\nfunction safeJson(v: unknown): string | null {\n try {\n return v === undefined ? null : JSON.stringify(v)\n } catch {\n return null /* ์ˆœํ™˜ ์ฐธ์กฐ ๋“ฑ โ€” ๋ชป ์žฌ๋ฉด ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค(์›๋ณธ์„ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค) */\n }\n}\n\n/**\n * ์›๋ณธ์˜ ๋‹ต์„ ์„ธ ๊ฐ’์œผ๋กœ โ€” **๋‹ต์ด ์—†์œผ๋ฉด `unknown`**(์„ฑ๊ณต์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค).\n *\n * ์ด ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ์ด์œ : ใ€Œ๋ฌผ์—ˆ์ง€๋งŒ ๋‹ต์ด ์—†๋‹คใ€๋ฅผ ์‹คํŒจ๋กœ๋„ ์„ฑ๊ณต์œผ๋กœ๋„ ์ ์„ ์ˆ˜ ์—†๋‹ค. ์‹คํŒจ๋กœ ์ ์œผ๋ฉด ์ผ์–ด๋‚œ ์ผ์„\n * ์—†๋˜ ์ผ๋กœ ๋งŒ๋“ค๊ณ , ์„ฑ๊ณต์œผ๋กœ ์ ์œผ๋ฉด ์—†๋˜ ์ผ์„ ์ผ์–ด๋‚œ ์ผ๋กœ ๋งŒ๋“ ๋‹ค. ์…‹์งธ ๊ฐ’์ด ์‚ฌ์‹ค์ด๋‹ค.\n */\nexport function sourceOutcomeOf(source: { answered: boolean; ok?: boolean }): 'applied' | 'refused' | 'unknown' {\n if (!source.answered || typeof source.ok !== 'boolean') return 'unknown'\n return source.ok ? 'applied' : 'refused'\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-audit/index.ts"],"names":[],"mappings":";;;AAAA,+DAAsD;AACtD,+DAAsD;AAEzC,QAAA,QAAQ,GAAG,CAAC,oCAAc,CAAC,CAAA;AAC3B,QAAA,SAAS,GAAG,CAAC,oCAAc,CAAC,CAAA","sourcesContent":["import { TwinAuditEvent } from './twin-audit-event.js'\nimport { TwinAuditQuery } from './twin-audit-query.js'\n\nexport const entities = [TwinAuditEvent]\nexport const resolvers = [TwinAuditQuery]\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-audit-event.js","sourceRoot":"","sources":["../../../server/service/twin-audit/twin-audit-event.ts"],"names":[],"mappings":";;;;AAAA,qCAAgH;AAChH,+CAAoD;AAEpD,iDAA4D;AAC5D,6CAA4C;AAE5C;;;GAGG;AACH,MAAM,aAAa,GAAG,YAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,CAAA;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AAOI,IAAM,cAAc,GAApB,MAAM,cAAc;CAuH1B,CAAA;AAvHY,wCAAc;AAGhB;IAFR,IAAA,gCAAsB,EAAC,MAAM,CAAC;IAC9B,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,EAAE,EAAE,WAAW,EAAE,wCAAwC,EAAE,CAAC;;0CAC1D;AAInB;IAFC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;IACzB,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;sCACvE,cAAM;8CAAA;AAGf;IADC,IAAA,oBAAU,EAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;;gDAC3B;AAIjB;IAFC,IAAA,gBAAM,GAAE;IACR,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;;kDACxD;AAYlB;IAFC,IAAA,gBAAM,GAAE;IACR,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;sCAC5D,IAAI;iDAAA;AAIf;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC;;iDACtF;AAIlB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC;;mDACxE;AAKpB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yEAAyE,EAAE,CAAC;;8CACnG;AAqBf;IAbC,IAAA,gBAAM,EAAC;QACN,QAAQ,EAAE,IAAI;QACd,IAAI,EACF,aAAa,IAAI,OAAO,IAAI,aAAa,IAAI,SAAS;YACpD,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,aAAa,IAAI,QAAQ;gBACzB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,aAAa,IAAI,OAAO;oBACxB,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,aAAa,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC;IACD,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC;;8CACvF;AAgBf;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2JAA2J,EAAE,CAAC;;qDAC9K;AAKtB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;;kDACvE;AAInB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4DAA4D,EAAE,CAAC;;+CACrF;AAIhB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC;;kDACrF;AAInB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;;iDACrF;AAKlB;IAFC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;;gDAClD;AAIjB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0DAA0D,EAAE,CAAC;;iDACjF;AAQlB;IAFC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;4CAClF;AAIV;IAFC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1B,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;;qDACxD;AAItB;IAFC,IAAA,0BAAgB,GAAE;IAClB,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;sCACxE,IAAI;iDAAA;yBAtHL,cAAc;IAN1B,IAAA,gBAAM,GAAE;IACT,mDAAmD;;IAClD,IAAA,eAAK,EAAC,iBAAiB,EAAE,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1G,oDAAoD;;IACnD,IAAA,eAAK,EAAC,iBAAiB,EAAE,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACzG,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,kFAAkF,EAAE,CAAC;GACnG,cAAc,CAuH1B","sourcesContent":["import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'\nimport { ObjectType, Field, ID } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\nimport { config } from '@things-factory/env'\n\n/*\n * ๊ธด ๊ธ€์˜ ์ปฌ๋Ÿผ ํƒ€์ž…์€ **๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค ์ด๋ฆ„์ด ๋‹ค๋ฅด๋‹ค** โ€” ์ด ๋ ˆํฌ์˜ ์ •๋ณธ ๊ด€ํ–‰๋Œ€๋กœ ์—ฌ๊ธฐ์„œ ๊ณ ๋ฅธ๋‹ค\n * (board-service ์˜ `Board.model` ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹). `text` ๋ฅผ ๊ทธ๋Œ€๋กœ ์ ์—ˆ๋”๋‹ˆ Oracle ์ด ๋ชจ๋ฅด๋Š” ์ด๋ฆ„์ด์—ˆ๋‹ค.\n */\nconst DATABASE_TYPE = config.get('ormconfig', {}).type\n\n/*\n * TwinAuditEvent โ€” **์‚ฌ๋žŒ์ด ๋ฌด์—‡์„ ํ—ˆ๋ฝํ–ˆ๋Š”๊ฐ€.**\n *\n * โ”€โ”€ ์™œ ์ €๋„(TwinEvent)์ด ์•„๋‹Œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ฒ˜์Œ์—๋Š” ์ €๋„์— ํ•จ๊ป˜ ๋„ฃ์—ˆ๋‹ค. \"๊ฐ์‚ฌ๋Š” ์›์žฅ์—์„œ ํ•˜๋‹ˆ๊นŒ\" ๋ผ๋Š” ์ด์œ ์˜€๋Š”๋ฐ, ๊ทธ๊ฑด **ํ™”๋ฉด์˜ ํŽธ์˜**์˜€๊ณ \n * ์ €์žฅ ๊ตฌ์กฐ๋ฅผ ์ •ํ•  ๊ทผ๊ฑฐ๊ฐ€ ๋ชป ๋๋‹ค. ๋„ฃ์ž๋งˆ์ž ์˜ˆ์™ธ๊ฐ€ ๋„ท ์ƒ๊ฒผ๋‹ค โ€” ๋ฆฌํ”Œ๋ ˆ์ด์—์„œ ๋นผ๊ณ , ๋ฐฑํ•„์—์„œ ๋นผ๊ณ ,\n * ์›์žฅ ๊ฑฐ๋ž˜ ๋ถ„๋ฅ˜์—์„œ ๋นผ๊ณ , ์›์žฅ ๋ Œ๋”์—์„œ ๊ฐˆ๋ž๋‹ค. **์˜ˆ์™ธ๊ฐ€ ๋„ท์ด๋ฉด ์„ค๊ณ„๊ฐ€ \"์—ฌ๊ธฐ ์•„๋‹ˆ๋‹ค\" ๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด๋‹ค.**\n *\n * ๊ฐˆ๋ผ ๋‘๋ฉด ์˜ˆ์™ธ๊ฐ€ 0 ์ด๊ณ , ์˜คํžˆ๋ ค ์–ป๋Š”๋‹ค:\n * ยท ํ–‰์œ„์ž๊ฐ€ **์ปฌ๋Ÿผ**์ด ๋œ๋‹ค โ€” \"๋ˆ„๊ฐ€ ์Šน์ธํ•œ ๊ฒƒ ์ „๋ถ€\" ๋Š” ๊ฐ์‚ฌ์˜ ๊ธฐ๋ณธ ์งˆ๋ฌธ์ธ๋ฐ payload ์•ˆ์—์„œ๋Š” ๋ชป ์ฐพ์•˜๋‹ค\n * ยท revision ์ด ์—†๋‹ค. ์ €๋„์—์„œ๋Š” ๊ทธ ์นธ์„ ๋น„์›Œ \"์ƒํƒœ๊ฐ€ ์•„๋‹˜\" ์„ ๋œปํ•˜๊ฒŒ ์ผ๋Š”๋ฐ, ์—†์Œ์„ ์ข…๋ฅ˜ ํ‘œ์‹œ๋กœ\n * ์“ฐ๋Š” ๊ฒƒ์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฌธ์ œ๋ฅผ ๋ƒˆ๋‹ค(๋ฐฑํ•„์˜ `bizStep IS NULL = ์˜› ํ–‰` ์ „์ œ๊ฐ€ ์ด๊ฒƒ ๋•Œ๋ฌธ์— ๊นจ์กŒ๋‹ค)\n * ยท bizStep ์˜ค์—ผ์ด ์—†๋‹ค โ€” ์ €๋„์˜ ํ‚ค ์ถ”์ถœ๊ธฐ๋Š” ๊ฐ’์ด ์—†์œผ๋ฉด ์ด๋ฒคํŠธ ํƒ€์ž…์œผ๋กœ ๋Œ€์ฒดํ•˜๋ฏ€๋กœ,\n * ๊ฐ์‚ฌ ํ–‰์„ ํƒœ์šฐ๋ฉด CBV ํ‘œ์ค€ ์–ดํœ˜ ์ปฌ๋Ÿผ์— `governance.command` ๊ฐ€ ๋ฐ•ํžŒ๋‹ค\n *\n * โ”€โ”€ ๋ฌด์—‡์„ ๋ฏฟ๋Š”๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * **์‹ ์›ยท์‹œ๊ฐ์€ ์„œ๋ฒ„๊ฐ€ ๊ฐ์ธํ•œ๋‹ค.** ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋งํ•œ ์‹ ์›์„ ๊ทธ๋Œ€๋กœ ์ ์œผ๋ฉด ์œ„์กฐ๊ฐ€ ์ž์œ ๋กœ์›Œ ๊ทธ ๊ธฐ๋ก์€\n * ์•„๋ฌด๊ฒƒ๋„ ์ฆ๋ช…ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์„ธ์…˜์ด ์•„๋Š” ์‚ฌ์šฉ์ž์™€ ์„œ๋ฒ„ ์‹œ๊ฐ๋งŒ ์‹ ๋ขฐํ•œ๋‹ค.\n * ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ›๋Š” ๊ฒƒ์€ **์˜๋„**๋ฟ์ด๋‹ค โ€” ์–ด๋””์„œ ์‹œ์ž‘๋๋‚˜(origin), ์™œ ํ•˜๋‚˜(reason).\n */\n@Entity()\n/* ๋ชฉ๋ก ๊ธฐ๋ณธ ์ •๋ ฌ โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ. ๊ฐ์‚ฌ๋Š” \"์š”์ฆ˜ ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜\" ๋กœ ์‹œ์ž‘ํ•œ๋‹ค. */\n@Index('ix_twin_audit_0', (e: TwinAuditEvent) => [e.domain, e.instanceId, e.eventTime], { unique: false })\n/* ํ–‰์œ„์ž๋กœ ์ฐพ๊ธฐ โ€” ์ €๋„์— ์žˆ์„ ๋•Œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋˜ ์งˆ๋ฌธ(\"๊น€ํ˜„์žฅ์ด ์Šน์ธํ•œ ๊ฒƒ ์ „๋ถ€\"). */\n@Index('ix_twin_audit_1', (e: TwinAuditEvent) => [e.domain, e.actorEmail, e.eventTime], { unique: false })\n@ObjectType({ description: 'Audit record of a twin command: who approved what, and what the kernel answered.' })\nexport class TwinAuditEvent {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the audit record.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })\n domain?: Domain\n\n @RelationId((e: TwinAuditEvent) => e.domain)\n domainId?: string\n\n @Column()\n @Field({ description: 'Twin runtime instance the command was aimed at.' })\n instanceId: string\n\n /*\n * ์„œ๋ฒ„ ์‹œ๊ฐ. ํด๋ผ์ด์–ธํŠธ ์‹œ๊ณ„๋ฅผ ๋ฏฟ์ง€ ์•Š๋Š”๋‹ค โ€” ๊ธฐ๋ก์˜ ์‹œ๊ฐ„์ถ•์ด ๋‹จ๋ง ์„ค์ •์— ์ขŒ์šฐ๋˜๋ฉด ์•ˆ ๋œ๋‹ค.\n *\n * **ํƒ€์ž… ์ด๋ฆ„์€ ์ ์ง€ ์•Š๋Š”๋‹ค** (2026-08-19 Postgres ๋ถ€ํŒ… ์‹คํŒจ๋กœ ๊ณ ์นจ).\n * `datetime` ์€ sqliteยทMySQL ์˜ ์ด๋ฆ„์ด๊ณ  Postgres ๋Š” `timestamp` ๋งŒ ์•ˆ๋‹ค โ€” ๊ฑฐ๊พธ๋กœ `timestamp` ๋Š”\n * sqlite ๊ฐ€ ๋ชจ๋ฅธ๋‹ค. **๋‹ค์„ฏ ๋“œ๋ผ์ด๋ฒ„์— ๋‹ค ํ†ตํ•˜๋Š” ์ด๋ฆ„์ด ์—†๋‹ค.** ๊ทธ๋ž˜์„œ ์ด๋ฆ„ ๊ณ ๋ฅด๋Š” ์ผ์„ TypeORM ์—\n * ๋งก๊ธด๋‹ค(`emitDecoratorMetadata` ๊ฐ€ ์ผœ์ ธ ์žˆ์–ด `Date` ์—์„œ ๋“œ๋ผ์ด๋ฒ„๋ณ„ ํƒ€์ž…์„ ๊ณ ๋ฅธ๋‹ค).\n */\n @Column()\n @Field({ description: 'Server time when the command was dispatched.' })\n eventTime: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Client-supplied command id, for correlating with kernel logs.' })\n commandId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Command type (e.g. order.hold, equipment.repair).' })\n commandType?: string\n\n /* 'user' | 'ai' | 'automation' | 'unknown'. ๋ชจ๋ฅด๋ฉด unknown ์ด์ง€ ์‚ฌ๋žŒ์ด ํ•œ ๊ฒƒ์œผ๋กœ ์น˜์ง€ ์•Š๋Š”๋‹ค. */\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"Where the command originated: 'user' | 'ai' | 'automation' | 'unknown'.\" })\n origin?: string\n\n /*\n * ์Šน์ธ ์‚ฌ์œ  โ€” ์‚ฌ๋žŒ์ด ์“ฐ๋Š” ๊ธ€์ด๋ผ ๊ธธ์ด๋ฅผ ๋ฏธ๋ฆฌ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค.\n *\n * ์ด๋ฆ„์„ ๋“œ๋ผ์ด๋ฒ„๋ณ„๋กœ ๊ณ ๋ฅธ๋‹ค(2026-08-19): `text` ๋Š” Oracle ์ด ๋ชจ๋ฅด๊ณ (๊ทธ์ชฝ์€ `clob`), MySQL ๊ณ„์—ด์€\n * ๊ธด ๊ธ€์— `longtext` ๋ฅผ, MSSQL ์€ `nvarchar(MAX)` ๋ฅผ ์“ด๋‹ค. ๋‹ค์ค‘ DB ๋ฅผ ์ง€ํ‚ค๋Š” ์ด ๋ ˆํฌ์˜ ๊ด€ํ–‰์ด ๊ทธ๋ ‡๋‹ค.\n */\n @Column({\n nullable: true,\n type:\n DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'\n ? 'longtext'\n : DATABASE_TYPE == 'oracle'\n ? 'clob'\n : DATABASE_TYPE == 'mssql'\n ? 'nvarchar'\n : 'text',\n length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined\n })\n @Field({ nullable: true, description: 'Why this action โ€” the rationale shown on the approval card.' })\n reason?: string\n\n /* โ”€โ”€ ์‹ ์›: ์„ธ์…˜์—์„œ๋งŒ ์˜จ๋‹ค โ”€โ”€ */\n /*\n * **์›๋ณธ์ด ๊ทธ๋ž˜์„œ ์–ด๋–ป๊ฒŒ ํ–ˆ๋‚˜** โ€” ํ—ˆ๋ฝ๊ณผ ์ผ์–ด๋‚จ ์‚ฌ์ด์— ๋ผ์–ด ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ™์€ ํ–‰์— ๋‹ซ๋Š”๋‹ค\n * (ADR-0029 ยง1 ๊ฒฐ์ • C, 2026-08-19).\n *\n * ๋ช…๋ น์ด ์›๋ณธ์œผ๋กœ ๊ฐ€๋ฉด ๊ฐ์‚ฌ๋Š” ใ€Œํ—ˆ๋ฝํ–ˆ๋‹คใ€๊นŒ์ง€๋งŒ ์ฆ๋ช…ํ•œ๋‹ค โ€” ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์˜ค๋ฅ˜ ์—†์ด ์‹คํŒจํ•˜๋ฉด ์›์žฅ์—๋Š” ์Šน์ธ๋งŒ\n * ๋‚จ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋Œ‘ํ„ฐ์˜ ๋‹ต์„ ๋˜์ ๋Š”๋‹ค.\n *\n * ยท ๋น„์–ด ์žˆ์Œ โ€” **์›๋ณธ์— ๋ฌป์ง€ ์•Š์•˜๋‹ค**(์ปค๋„์ด ๋ฐ›์€ ๋ช…๋ น์ด๋‹ค). ใ€Œ๋ชจ๋ฅธ๋‹คใ€์™€ ๋‹ค๋ฅด๋‹ค.\n * ยท `unknown` โ€” ๋ฌผ์—ˆ๋Š”๋ฐ **๋‹ต์„ ๋ชป ๋ฐ›์•˜๋‹ค**. ์„ฑ๊ณต์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค.\n * ยท `applied` ยท `refused` โ€” ์›๋ณธ์ด ๋‹ตํ–ˆ๋‹ค(๋‘˜ ๋‹ค ์‚ฌ์‹ค์ด๋‹ค).\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"What the source did with it: 'applied' | 'refused' | 'unknown' (asked but no answer). Empty means the source was not asked โ€” the kernel took the command.\" })\n sourceOutcome?: string\n\n /** ์›๋ณธ์ด ์ค€ ์‚ฌ์œ  ์ฝ”๋“œ โ€” ์žˆ์œผ๋ฉด ๊ทธ๋Œ€๋กœ ์ ๋Š”๋‹ค(์šฐ๋ฆฌ๊ฐ€ ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค). */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Reason code the source returned, as it gave it.' })\n sourceCode?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Approving user id, stamped by the server from the session.' })\n actorId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Approving user email, stamped by the server from the session.' })\n actorEmail?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Approving user name, stamped by the server from the session.' })\n actorName?: string\n\n /* โ”€โ”€ ๊ฒฐ๊ณผ: ๊ฑฐ์ ˆ๋„ ๋‚จ๊ธด๋‹ค โ”€โ”€ */\n @Column({ default: false })\n @Field({ description: 'Whether the kernel accepted the command.' })\n accepted: boolean\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Language-neutral rejection code when the kernel refused.' })\n errorCode?: string\n\n /**\n * ๋ช…๋ น ์ธ์ž โ€” **์›ํ˜• ๊ทธ๋Œ€๋กœ.** ๋ฌด์—‡์— ๋Œ€ํ•œ ๋ช…๋ น์ด์—ˆ๋Š”์ง€๊ฐ€ ๊ฐ์‚ฌ์˜ ํ•ต์‹ฌ์ด๋ผ ์š”์•ฝํ•˜์ง€ ์•Š๋Š”๋‹ค.\n * ์ง€๋‚˜์น˜๊ฒŒ ํฌ๋ฉด ์ž๋ฅด๋˜ `argsTruncated` ๋กœ ์ž˜๋ž๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋‚จ๊ธด๋‹ค(์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค).\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Command arguments as given.' })\n args?: any\n\n @Column({ default: false })\n @Field({ description: 'True when args were too large and stored truncated.' })\n argsTruncated: boolean\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when the audit row was written.' })\n createdAt?: Date\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-audit-query.js","sourceRoot":"","sources":["../../../server/service/twin-audit/twin-audit-query.ts"],"names":[],"mappings":";;;;AAAA,+CAAyD;AAEzD,iDAA6G;AAE7G,+DAAsD;AAEtD;;;;;;;;;GASG;AACH,+CAA+C;AAC/C,SAAS,WAAW,CAAC,CAAM;IACzB,MAAM,GAAG,GAAG,CAAC,CAAM,EAAE,EAAE;QACrB,IAAI,CAAC,YAAY,IAAI;YAAE,OAAO,CAAC,CAAA;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACrD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC,CAAA;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAC/C,CAAC;AAGM,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB;gEAC4D;IAMtD,AAAN,KAAK,CAAC,aAAa,CAGQ,MAAiB,EACnC,OAAwB;QAE/B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAA;QACzC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;QAE7C,MAAM,SAAS,GAAc;YAC3B,GAAG,CAAC,MAAM,IAAK,EAAgB,CAAC;YAChC,uCAAuC;YACvC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC1F,6DAA6D;YAC7D,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAChH,CAAA;QAED,MAAM,EAAE,GAAG,IAAA,qCAA6B,EAAC;YACvC,UAAU,EAAE,IAAA,qBAAa,EAAC,oCAAc,CAAC;YACzC,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;YAC5B,KAAK,EAAE,GAAG;YACV;;;eAGG;YACH,WAAW,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC;YACxF,SAAS,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC;YAC3E,gDAAgD;YAChD,YAAY,EAAE,EAAE;YAChB,QAAQ,EAAE,GAAG;SACd,CAAC,CAAA;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,eAAe,EAAE,CAAA;QACjD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;CACF,CAAA;AA5CY,wCAAc;AAQnB;IALL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,oBAAY,EAAE;QAC9B,QAAQ,EAAE,IAAI;QACd,WAAW,EACT,gJAAgJ;KACnJ,CAAC;IAIC,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;mDAgC3C;yBA3CU,cAAc;IAD1B,IAAA,uBAAQ,GAAE;GACE,cAAc,CA4C1B","sourcesContent":["import { Args, Ctx, Query, Resolver } from 'type-graphql'\n\nimport { ListParam, getQueryBuilderFromListParams, getRepository, ScalarObject } from '@things-factory/shell'\n\nimport { TwinAuditEvent } from './twin-audit-event.js'\n\n/*\n * ์Šน์ธ ๊ธฐ๋ก ์กฐํšŒ โ€” **๊ฐ์‚ฌ์˜ ๊ธฐ๋ณธ ์งˆ๋ฌธ์— ๋‹ตํ•œ๋‹ค.**\n *\n * \"์š”์ฆ˜ ๋ฌด์Šจ ์กฐ์น˜๊ฐ€ ๋‚˜๊ฐ”๋‚˜\" โ†’ ์ตœ๊ทผ์ˆœ ๋ชฉ๋ก\n * \"๊น€ํ˜„์žฅ์ด ์Šน์ธํ•œ ๊ฒƒ ์ „๋ถ€\" โ†’ ํ–‰์œ„์ž ๊ฒ€์ƒ‰(์ธ๋ฑ์Šค ์žˆ์Œ)\n * \"AI ๊ฐ€ ์ œ์•ˆํ•œ ๊ฒƒ๋งŒ\" โ†’ origin ํ•„ํ„ฐ\n * \"๊ฑฐ์ ˆ๋œ ์‹œ๋„\" โ†’ accepted ํ•„ํ„ฐ\n *\n * ์ €๋„์— ์„ž์—ฌ ์žˆ์„ ๋•Œ๋Š” ์ด ์ค‘ ์–ด๋А ๊ฒƒ๋„ ๋ชป ํ–ˆ๋‹ค โ€” ํ–‰์œ„์ž๊ฐ€ payload JSON ์•ˆ์ด๋ผ ์ธ๋ฑ์Šค๋ฅผ ๊ฑธ ์ˆ˜ ์—†์—ˆ๋‹ค.\n */\n/** ์‹œ๊ฐ ํ•„ํ„ฐ ๊ฐ’์„ ๋‚ ์งœ๋กœ โ€” ๋ชป ์ฝ๋Š” ๊ฐ’์€ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค(์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค). */\nfunction toDateValue(v: any): any {\n const one = (x: any) => {\n if (x instanceof Date) return x\n const t = typeof x === 'string' ? Date.parse(x) : NaN\n return Number.isNaN(t) ? x : new Date(t)\n }\n return Array.isArray(v) ? v.map(one) : one(v)\n}\n\n@Resolver()\nexport class TwinAuditQuery {\n /* ์กฐํšŒ ๊ฒŒ์ดํŠธ๋Š” ๋‹ฌ์ง€ ์•Š๋Š”๋‹ค โ€” ์ด ์ €์žฅ์†Œ์˜ ๊ทœ์•ฝ์ด๊ณ (mutation-gate ๊ฒ€์‚ฌ๊ฐ€ ์ •๋ณธ์„ ์ง€ํ‚จ๋‹ค),\n ๋„๋ฉ”์ธ ํ•„ํ„ฐ๊ฐ€ ํ…Œ๋„ŒํŠธ ๊ฒฝ๊ณ„๋ฅผ ์ด๋ฏธ ์ง€ํ‚จ๋‹ค. ํ…Œ๋„ŒํŠธ๋ฅผ ๋„˜์–ด ์ฝ๋Š” ๊ณ„๊ธฐํŒ๋งŒ OPS_GATE ๋ฅผ ์“ด๋‹ค. */\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'List twin command audit records (who approved what, and what the kernel answered) with the standard list contract, plus the total match count.'\n })\n async twinAuditList(\n /* ํ‘œ์ค€ ๋ชฉ๋ก ๊ณ„์•ฝ์€ `@Args` ๋กœ ํŽผ์ณ ๋ฐ›๋Š”๋‹ค โ€” `@Arg` ๋กœ ๋ฐ›์œผ๋ฉด type-graphql ์ด ์ž…๋ ฅ ํƒ€์ž…์„\n ๊ฒฐ์ •ํ•˜์ง€ ๋ชปํ•ด **์Šคํ‚ค๋งˆ ์กฐ๋ฆฝ ์ž์ฒด๊ฐ€ ์‹คํŒจ**ํ•œ๋‹ค(์„œ๋ฒ„๊ฐ€ ์•„์˜ˆ ์•ˆ ๋œฌ๋‹ค). */\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<any> {\n const domainId = context.state.domain?.id\n if (!domainId) return { items: [], total: 0 }\n\n const effective: ListParam = {\n ...(params ?? ({} as ListParam)),\n /* ๊ธฐ๋ณธ ์ •๋ ฌ โ€” ์ตœ๊ทผ ๊ฒƒ๋ถ€ํ„ฐ. ๊ฐ์‚ฌ๋Š” \"์š”์ฆ˜\" ์—์„œ ์‹œ์ž‘ํ•œ๋‹ค. */\n sortings: params?.sortings?.length ? params.sortings : [{ name: 'eventTime', desc: true }],\n /* ์‹œ๊ฐ ํ•„ํ„ฐ๋Š” ๋‚ ์งœ๋กœ ์˜ฎ๊ฒจ์„œ ๋„˜๊ธด๋‹ค โ€” ๋ฌธ์ž์—ด ๊ทธ๋Œ€๋กœ๋ฉด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  0๊ฑด์ด ๋œ๋‹ค(์ €๋„๊ณผ ๊ฐ™์€ ์ด์œ ). */\n filters: (params?.filters ?? []).map(f => (f.name === 'eventTime' ? { ...f, value: toDateValue(f.value) } : f))\n }\n\n const qb = getQueryBuilderFromListParams({\n repository: getRepository(TwinAuditEvent),\n params: effective,\n domain: context.state.domain,\n alias: 'a',\n /*\n * `searchables` ๋Š” ์ „๋ถ€ **์‹ค์ปฌ๋Ÿผ**์ด๋‹ค โ€” ํ”„๋ ˆ์ž„์›Œํฌ ์งˆ์˜ ๋นŒ๋”๋Š” ์—ฌ๊ธฐ ์—†๋Š” ์ปฌ๋Ÿผ์˜ LIKE ๋ฅผ\n * ๊ฒฝ๊ณ  ํ›„ ๋ฌด์‹œํ•œ๋‹ค(์ธ๋ฑ์Šค ์—†๋Š” ์ „์ฒด ์Šค์บ” ๋ฐฉ์ง€). ํ–‰์œ„์ž๋กœ ์ฐพ๋Š” ๊ฒƒ์ด ์ด ํ…Œ์ด๋ธ”์„ ๊ตฌ๋ถ„ํ•œ ์ด์œ ๋‹ค.\n */\n searchables: ['actorEmail', 'actorName', 'commandType', 'origin', 'errorCode', 'reason'],\n sortables: ['eventTime', 'commandType', 'actorEmail', 'origin', 'accepted'],\n /* ๊ฐ์‚ฌ ๋ชฉ๋ก์€ ์‚ฌ๋žŒ์ด ์ฝ๋Š” ์†๋„๋กœ ๋ณธ๋‹ค โ€” ํฌ๊ฒŒ ํผ ์˜ค๋Š” ๊ฒƒ์ด ์ด๋“์ด ์•„๋‹ˆ๋‹ค. */\n defaultLimit: 50,\n maxLimit: 200\n })\n\n const [items, total] = await qb.getManyAndCount()\n return { items, total }\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"backfill-period-facts.js","sourceRoot":"","sources":["../../../server/service/twin-backfill/backfill-period-facts.ts"],"names":[],"mappings":"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","sourcesContent":["import { getRepository } from '@things-factory/shell'\n\nimport { TwinEvent } from '../twin-event/twin-event.js'\nimport { TwinEngine } from '../../engine/twin-engine.js'\nimport { ingestCanonicalRecords } from '../../engine/canonical-ingest.js'\nimport { absoluteTime } from '../../engine/read-time.js'\nimport { judgeBackfill, splitAlreadyThere } from './backfill-shape.js'\n\n/*\n * ์ง€๋‚œ ๊ธฐ๋ก ์ฑ„์šฐ๊ธฐ โ€” **์ €๋„์—๋งŒ ์“ด๋‹ค. ํŠธ์œˆ์˜ ใ€Œ์ง€๊ธˆใ€์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.**\n *\n * โ”€โ”€ ์™œ ๋ผ์ด๋ธŒ ๋ฌธ์œผ๋กœ ๋„ฃ์„ ์ˆ˜ ์—†๋‚˜ (2026-08-30) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„์˜ ์ƒํƒœ๋Š” ใ€Œ์ง€๊ธˆใ€์ด๋‹ค. ๋Šฆ๊ฒŒ ์˜จ ์˜› ํ‘œ๋ณธ์€ ๊ฐ€๋“œ๊ฐ€ ๋ง‰๋Š”๋‹ค(๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค). ์ง€๋‚œ ๊ธฐ๋ก์„ ๋ผ์ด๋ธŒ\n * ๋ฌธ์œผ๋กœ ๋„ฃ์œผ๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋‹ค โ€” ๊ฐ€๋“œ์— ๋ง‰ํžˆ๊ฑฐ๋‚˜, ํŠธ์œˆ์˜ ์‹œ๊ณ„๊ฐ€ ๊ณผ๊ฑฐ๋กœ ๋Œ๋ฆฐ๋‹ค. ๋‘˜ ๋‹ค ๋‚˜์˜๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด ๊ธธ์€ ์ €๋„์—๋งŒ ์“ด๋‹ค. ์ƒํƒœ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ์ €๋„์„ ์ฝ๋Š” ์ชฝ(์„ฑ๊ณผ ๊ณ„์‚ฐยท์ด๋ ฅ ํ™”๋ฉด)๋งŒ ๊ทธ ์‚ฌ์‹ค์„\n * ๋ณด๊ฒŒ ๋œ๋‹ค.\n *\n * โ”€โ”€ ๋ฌด์—‡์„ ๋ฐ›๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * **๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„ ์‚ฌ์‹ค๋งŒ** ๋ฐ›๋Š”๋‹ค. ์‹œ์ ์˜ ๊ด€์ธก(๊ณ„๋Ÿ‰ ํ‘œ๋ณธยท์„ค๋น„ ์ƒํƒœยท๋ฐœ์ „ ์ ์‚ฐ)์€ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค โ€” ๊ทธ๊ฒƒ๋“ค์€\n * ์ปค๋„์˜ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ์‚ฌ์‹ค์ด๋ผ, ์ƒํƒœ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์ €๋„์—๋งŒ ๋„ฃ์œผ๋ฉด ์ƒํƒœ์™€ ์ €๋„์ด ๊ฐˆ๋ผ์ง„๋‹ค.\n *\n * โ”€โ”€ ๊ฐ™์€ ๊ธฐ๊ฐ„์„ ๋‘ ๋ฒˆ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„ ์‚ฌ์‹ค์€ ์ •์ฒด์„ฑ์ด ๋‚ด์šฉ์— ์žˆ๋‹ค(์ปค๋„ 0.7.81: ์ข…๋ฅ˜ยท๋Œ€์ƒยท์‹œ์ž‘ยท๋). ๊ทธ id ๋กœ ์ด๋ฏธ ์žˆ๋Š” ๊ฒƒ์„\n * ๊ฐ€๋ ค๋‚ธ๋‹ค. ์ €์žฅ์†Œ์˜ ์ œ์•ฝ์œผ๋กœ ๋ง‰์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๋‹ค์„ฏ์ด๊ณ  ์ถฉ๋Œ ์ฒ˜๋ฆฌ๊ฐ€ ์ œ๊ฐ๊ฐ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค โ€”\n * ๊ตฌ๊ฐ„ ๋‹จ์œ„๋กœ ํ•œ ๋ฒˆ ์ฝ์–ด ๊ฐ€๋ ค๋‚ด๋Š” ํŽธ์ด ์ด์‹์„ฑ์ด ์žˆ๊ณ  ๊ฐ’๋„ ์‹ธ๋‹ค(ํ•œ ์‹œ๊ฐ„์— ํ•œ ์ค„์ด๋ฉด ํ•˜๋ฃจ 24์ค„์ด๋‹ค).\n *\n * โ”€โ”€ ๋ณด์กด๋ณด๋‹ค ์˜ค๋ž˜๋œ ๊ฒƒ์€ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ €๋„์€ ๋ณด์กด ๊ธฐ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ง€์šด๋‹ค. ๊ทธ๋ณด๋‹ค ์˜ค๋ž˜๋œ ๊ฒƒ์„ ์ฑ„์šฐ๋ฉด ๋‹ค์Œ ์ •๋ฆฌ์—์„œ ์ง€์›Œ์ง„๋‹ค. ์กฐ์šฉํžˆ ๋„ฃ๊ณ \n * ์ง€์›Œ์ง€๋ฉด ์•„๋ฌด๋„ ๋ชจ๋ฅด๋ฏ€๋กœ, **๊ฑฐ์ ˆํ•˜๊ณ  ์ด์œ ๋ฅผ ๋งํ•œ๋‹ค.**\n */\n\nexport interface BackfillResult {\n /** ์ €๋„์— ์ƒˆ๋กœ ์ ์€ ์ˆ˜. */\n written: number\n /** ์ด๋ฏธ ์žˆ์–ด์„œ ๊ฑด๋„ˆ๋›ด ์ˆ˜ โ€” ๋‹ค์‹œ ์ฝ์–ด๋„ ์ค‘๋ณต์ด ์Œ“์ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๋œป์ด๋‹ค. */\n skipped: number\n /** ๋ฐ›์ง€ ์•Š์€ ๊ฒƒ๊ณผ ๊ทธ ์ด์œ . ์กฐ์šฉํžˆ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */\n refused: { record: unknown; reason: string }[]\n}\n\n/** ์ด ๋„๋ฉ”์ธ์˜ ๋ณด์กด ๊ธฐ๊ฐ„(์ผ). ์ •์ฑ…์ด ์—†์œผ๋ฉด `undefined` โ€” ๊ทธ๋•Œ๋Š” ์˜ค๋ž˜๋จ์„ ํŒ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. */\nasync function retentionDaysOf(domainId: string): Promise<number | undefined> {\n const perDomain = TwinEngine.retentionDaysOf ? await TwinEngine.retentionDaysOf(domainId).catch(() => undefined) : undefined\n const days = perDomain ?? TwinEngine.JOURNAL_RETENTION_DAYS\n return days && days > 0 ? days : undefined\n}\n\n/**\n * ์ง€๋‚œ ๊ธฐ๋ก์„ ์ €๋„์— ์ฑ„์šด๋‹ค.\n *\n * `records` ๋Š” ๋ผ์ด๋ธŒ์™€ **๊ฐ™์€ ๋ชจ์–‘**์ด๋‹ค โ€” ์ปค๋„ฅํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ์–ดํœ˜๋ฅผ ๋ฐฐ์šธ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ฒ€์ฆยท๊ฐˆ๋ฆผยทid ๋งŒ๋“ค๊ธฐ๋Š”\n * ์ปค๋„์˜ ์œ ์ž…์ด ๊ทธ๋Œ€๋กœ ํ•œ๋‹ค(ยง`ingestCanonicalRecords`).\n */\nexport async function backfillPeriodFacts(input: {\n domainId: string\n instanceId: string\n records: unknown[]\n /** ์ด ์‹œ๊ฐ์„ ใ€Œ์ง€๊ธˆใ€์œผ๋กœ ๋ณธ๋‹ค โ€” ๋ณด์กด ํŒ์ •์˜ ๊ธฐ์ค€. ์‹œํ—˜์ด ์‹œ๊ฐ์„ ์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฐ›๋Š”๋‹ค. */\n nowMs?: number\n}): Promise<BackfillResult> {\n const { domainId, instanceId, records } = input\n const nowMs = input.nowMs ?? Date.now()\n const refused: { record: unknown; reason: string }[] = []\n\n if (!Array.isArray(records) || !records.length) return { written: 0, skipped: 0, refused }\n\n /* ๊ฒ€์ฆ๊ณผ ๊ฐˆ๋ฆผ์€ ๋ผ์ด๋ธŒ์™€ ๊ฐ™์€ ๊ฒƒ์„ ์“ด๋‹ค โ€” ๋‘ ๋ฒŒ์ด ๋˜๋ฉด ์ฑ„์šด ์‚ฌ์‹ค๊ณผ ๊ด€์ธกํ•œ ์‚ฌ์‹ค์ด ๋‹ค๋ฅธ ๊ทœ์น™์„ ์ง€๋‚œ๋‹ค. */\n const { accepted, rejected } = ingestCanonicalRecords(\n records as any,\n domainId,\n new Date(nowMs).toISOString(),\n /* ์–ด๋А ํŠธ์œˆ์˜ ์‚ฌ์‹ค์ธ๊ฐ€ โ€” ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„์˜ ์ด๋ฆ„์ด ์ด๊ฒƒ์œผ๋กœ ๊ฐˆ๋ฆฐ๋‹ค(์ปค๋„ ยง`SubjectBasis`). */\n TwinEngine.factScope(domainId, instanceId)\n )\n for (const r of rejected) refused.push({ record: r.record, reason: (r.errors ?? []).join(' ยท ') })\n\n const days = await retentionDaysOf(domainId)\n\n const judged = judgeBackfill(accepted as any[], { nowMs, retentionDays: days })\n refused.push(...judged.refused)\n const keep = judged.keep\n\n if (!keep.length) {\n TwinEngine.recordIngestResult(\n domainId,\n instanceId,\n records.length,\n refused.map(r => ({ record: r.record, errors: [r.reason] })),\n nowMs,\n 0\n )\n return { written: 0, skipped: 0, refused }\n }\n\n /*\n * ์ด๋ฏธ ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ€๋ ค๋‚ธ๋‹ค โ€” ๊ทธ ๊ตฌ๊ฐ„์˜ ๊ทธ ์ข…๋ฅ˜๋งŒ ์ฝ๋Š”๋‹ค(์ƒ‰์ธ์ด ๋ฐ›์ณ ์ค€๋‹ค). ํŽ˜์ด๋กœ๋“œ์˜ id ๋กœ ๊ฒฌ์ฃผ๊ณ ,\n * ์ €์žฅ์†Œ ์ œ์•ฝ์— ๊ธฐ๋Œ€์ง€ ์•Š๋Š”๋‹ค(๋“œ๋ผ์ด๋ฒ„ ๋‹ค์„ฏ).\n */\n const times = keep.map(e => absoluteTime(e.eventTime)!.getTime())\n const fromAt = new Date(Math.min(...times))\n const toAt = new Date(Math.max(...times))\n const types = [...new Set(keep.map(e => String(e.eventType)))]\n\n const existing = await getRepository(TwinEvent)\n .createQueryBuilder('e')\n .select(['e.payload AS \"payload\"'])\n .where('e.domain = :domainId', { domainId })\n .andWhere('e.instanceId = :instanceId', { instanceId })\n .andWhere('e.eventType IN (:...types)', { types })\n .andWhere('e.eventTime BETWEEN :fromAt AND :toAt', { fromAt, toAt })\n .getRawMany<{ payload: unknown }>()\n\n const seen = new Set<string>()\n for (const row of existing) {\n const p: any = typeof row.payload === 'string' ? safeParse(row.payload) : row.payload\n const id = p?.eventId\n if (typeof id === 'string' && id) seen.add(id)\n }\n\n const { fresh, skipped } = splitAlreadyThere(keep, seen)\n if (!fresh.length) {\n TwinEngine.recordIngestResult(\n domainId,\n instanceId,\n records.length,\n refused.map(r => ({ record: r.record, errors: [r.reason] })),\n nowMs,\n skipped\n )\n return { written: 0, skipped, refused }\n }\n\n /*\n * ๋ฆฌ๋น„์ „์€ **์“ด ์ˆœ์„œ**๋‹ค(์ผ์–ด๋‚œ ์ˆœ์„œ๊ฐ€ ์•„๋‹ˆ๋‹ค). ์ง€๋‚œ ์‚ฌ์‹ค์ด ์ง€๊ธˆ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ด ๋งž๋‹ค โ€” ์ €๋„์„\n * ์‹œ๊ฐ์œผ๋กœ ์ฝ๋Š” ์ชฝ์€ `eventTime` ์„ ๋ณด๊ณ , ๋ฆฌ๋น„์ „์€ ๊ฐ™์€ ์‹œ๊ฐ์„ ๊ฐ€๋ฆด ๋•Œ๋งŒ ์“ด๋‹ค.\n */\n const start = TwinEngine.journalHead(domainId, instanceId)\n const items = fresh.map((event, i) => ({ event, revision: start + i + 1 }))\n\n await TwinEngine.persistCarried(domainId, instanceId, items)\n TwinEngine.advanceJournalHead(domainId, instanceId, items.length)\n\n /*\n * ์žฅ๋ถ€์— ์ ๋Š”๋‹ค โ€” **์œ ์ž…์„ ๋ถ€๋ฅด๋Š” ๊ณณ์€ ๋ชจ๋‘ ์ ๋Š”๋‹ค.** ํ•œ ๊ฒฝ๋กœ๋งŒ ๋น ์ง€๋ฉด ๊ทธ ํŠธ์œˆ์˜ ์œ ์ž… ๊ฑด๊ฐ•์ด\n * ใ€Œ๋ชจ๋ฆ„ใ€์œผ๋กœ ๋ณด์ธ๋‹ค(ยง`ingest-health-wiring`).\n *\n * ๊ฑด๋„ค๋ฐ›์ง€ ๋ชปํ•œ ์ˆ˜(`undelivered`)๋Š” **๊ฑฐ์ ˆํ•œ ๊ฒƒ๊ณผ ์ด๋ฏธ ์žˆ์–ด์„œ ๊ฑด๋„ˆ๋›ด ๊ฒƒ์˜ ํ•ฉ**์ด๋‹ค. ๊ฑด๋„ˆ๋›ด ๊ฒƒ์€\n * ๋ฒ„๋ ค์ง„ ๊ฒƒ์ด ์•„๋‹ˆ์ง€๋งŒ ์ด๋ฒˆ์— ์ƒˆ๋กœ ์ ํžˆ์ง€๋„ ์•Š์•˜๋‹ค โ€” ใ€Œํ†ต๊ณผใ€๋กœ ์„ธ๋ฉด ์ฑ„์šด ์–‘์ด ์‹ค์ œ๋ณด๋‹ค ์ปค ๋ณด์ธ๋‹ค.\n */\n TwinEngine.recordIngestResult(\n domainId,\n instanceId,\n records.length,\n refused.map(r => ({ record: r.record, errors: [r.reason] })),\n nowMs,\n skipped\n )\n return { written: items.length, skipped, refused }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return undefined\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"backfill-shape.js","sourceRoot":"","sources":["../../../server/service/twin-backfill/backfill-shape.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AA2BH,sCAyCC;AAQD,8CAGC;AA7ED,mCAAmC;AACtB,QAAA,YAAY,GAAsB;IAC7C,qBAAqB;IACrB,0BAA0B;IAC1B,yBAAyB;IACzB,qBAAqB;IACrB,aAAa;CACd,CAAA;AASD;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAC3B,SAAyB,EACzB,IAA+C;IAE/C,MAAM,IAAI,GAAU,EAAE,CAAA;IACtB,MAAM,OAAO,GAA0C,EAAE,CAAA;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,UAAU,CAAA;IAE7G,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,SAAS,IAAI,EAAE,CAAC,CAAA;QACzC,IAAI,CAAC,oBAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,GAAG;gBACX,MAAM,EACJ,GAAG,IAAI,yDAAyD;oBAChE,2BAA2B;aAC9B,CAAC,CAAA;YACF,SAAQ;QACV,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAA;YACvD,SAAQ;QACV,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,GAAG,EAAE,SAAS,gBAAgB,EAAE,CAAC,CAAA;YACtF,SAAQ;QACV,CAAC;QACD,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,GAAG,SAAS,EAAE,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,GAAG;gBACX,MAAM,EACJ,SAAS,IAAI,CAAC,aAAa,aAAa,GAAG,EAAE,SAAS,wBAAwB;oBAC9E,yBAAyB;aAC5B,CAAC,CAAA;YACF,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAoB,EAAE,WAAgC;IACtF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1G,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAA;AACvD,CAAC","sourcesContent":["/*\n * ์ง€๋‚œ ๊ธฐ๋ก ์ฑ„์šฐ๊ธฐ์˜ **ํŒ๋‹จ** โ€” ์ €์žฅ์†Œ๋ฅผ ๋ชจ๋ฅด๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜.\n *\n * ๋ฌด์—‡์„ ๋ฐ›๊ณ  ๋ฌด์—‡์„ ๊ฑฐ์ ˆํ•˜๋Š”์ง€๊ฐ€ ์ด ํŒŒ์ผ์— ๋‹ค ์žˆ๋‹ค. ์ €์žฅ์†Œ๋ฅผ ์•„๋Š” ์ฝ”๋“œ(`backfill-period-facts`)๋Š”\n * ์ด ํŒ๋‹จ์„ ๋ถ€๋ฅด๊ณ  ์“ฐ๊ธฐ๋งŒ ํ•œ๋‹ค. ๊ฐˆ๋ผ ๋‘๋Š” ์ด์œ ๋Š” ์ด ์ €์žฅ์†Œ๊ฐ€ ์ด๋ฏธ ์“ฐ๋Š” ๋ฐฉ์‹์ด๋‹ค โ€”\n * ํŒ๋‹จ์€ ์‹œํ—˜์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—†์ด ์ง€ํ‚ฌ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค(ยง`event-type-split-shape`).\n */\n\n/** ์ด ๊ธธ์ด ๋ฐ›๋Š” ์‚ฌ์‹ค โ€” ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„์„ ๋งํ•˜๋Š” ๊ฒƒ๋“ค. */\nexport const PERIOD_FACTS: readonly string[] = [\n 'energy.usage.period',\n 'energy.generation.period',\n 'energy.generation.price',\n 'energy.tariff.basis',\n 'energy.bill'\n]\n\nexport interface BackfillJudgement {\n /** ์ €๋„์— ๋„ฃ์–ด๋„ ๋˜๋Š” ๊ฒƒ. */\n keep: any[]\n /** ๋ฐ›์ง€ ์•Š์€ ๊ฒƒ๊ณผ ๊ทธ ์ด์œ  โ€” ์กฐ์šฉํžˆ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */\n refused: { record: unknown; reason: string }[]\n}\n\n/**\n * ๋ฌด์—‡์„ ์ฑ„์šธ ์ˆ˜ ์žˆ๋‚˜.\n *\n * ์„ธ ๊ฐ€์ง€๋กœ ๊ฑฐ์ ˆํ•œ๋‹ค.\n *\n * ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„์ด ์•„๋‹ˆ๋‹ค ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ์‚ฌ์‹ค์„ ์ €๋„์—๋งŒ ๋„ฃ์œผ๋ฉด ์ƒํƒœ์™€ ์ €๋„์ด ๊ฐˆ๋ผ์ง„๋‹ค\n * ์•„์ง ์˜ค์ง€ ์•Š์€ ์‹œ๊ฐ ์ง€๋‚œ ๊ธฐ๋ก์ด ์•„๋‹ˆ๋‹ค\n * ๋ณด์กด๋ณด๋‹ค ์˜ค๋ž˜๋๋‹ค ๋„ฃ์–ด๋„ ๋‹ค์Œ ์ •๋ฆฌ์—์„œ ์ง€์›Œ์ง„๋‹ค โ€” ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง€๋А๋‹ˆ ๊ฑฐ์ ˆํ•œ๋‹ค\n */\nexport function judgeBackfill(\n envelopes: readonly any[],\n opts: { nowMs: number; retentionDays?: number }\n): BackfillJudgement {\n const keep: any[] = []\n const refused: { record: unknown; reason: string }[] = []\n const horizonMs = opts.retentionDays === undefined ? undefined : opts.nowMs - opts.retentionDays * 86_400_000\n\n for (const env of envelopes) {\n const type = String(env?.eventType ?? '')\n if (!PERIOD_FACTS.includes(type)) {\n refused.push({\n record: env,\n reason:\n `${type} ๋Š” ๋งˆ๊ฐ๋œ ๊ตฌ๊ฐ„ ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋‹ค โ€” ์ด ๊ธธ์€ ์ €๋„์—๋งŒ ์“ฐ๋ฏ€๋กœ, ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ์‚ฌ์‹ค์„ ์—ฌ๊ธฐ๋กœ ๋„ฃ์œผ๋ฉด ` +\n '์ƒํƒœ์™€ ์ €๋„์ด ๊ฐˆ๋ผ์ง„๋‹ค. ๋ผ์ด๋ธŒ ๋ฌธ์œผ๋กœ ๋ณด๋‚ด๋ผ'\n })\n continue\n }\n const atMs = Date.parse(String(env?.eventTime ?? ''))\n if (!Number.isFinite(atMs)) {\n refused.push({ record: env, reason: '์‚ฌ๊ฑด ์‹œ๊ฐ์„ ์ฝ์„ ์ˆ˜ ์—†๋‹ค' })\n continue\n }\n if (atMs > opts.nowMs) {\n refused.push({ record: env, reason: `์•„์ง ์˜ค์ง€ ์•Š์€ ์‹œ๊ฐ์ด๋‹ค(${env?.eventTime}) โ€” ์ง€๋‚œ ๊ธฐ๋ก์ด ์•„๋‹ˆ๋‹ค` })\n continue\n }\n if (horizonMs !== undefined && atMs < horizonMs) {\n refused.push({\n record: env,\n reason:\n `๋ณด์กด ๊ธฐ๊ฐ„(${opts.retentionDays}์ผ)๋ณด๋‹ค ์˜ค๋ž˜๋๋‹ค(${env?.eventTime}) โ€” ๋„ฃ์–ด๋„ ๋‹ค์Œ ์ •๋ฆฌ์—์„œ ์ง€์›Œ์ง„๋‹ค. ` +\n '๋” ๋’ค๊นŒ์ง€ ๋ณด๋ ค๋ฉด ๋ณด์กด ๊ธฐ๊ฐ„์„ ๋Š˜๋ ค์•ผ ํ•œ๋‹ค'\n })\n continue\n }\n keep.push(env)\n }\n\n return { keep, refused }\n}\n\n/**\n * ์ด๋ฏธ ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ€๋ ค๋‚ธ๋‹ค โ€” **์ •์ฒด์„ฑ์€ ๋‚ด์šฉ์— ์žˆ๋‹ค**(์ปค๋„ 0.7.81).\n *\n * ์ €์žฅ์†Œ์˜ ์ œ์•ฝ์œผ๋กœ ๋ง‰์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๋‹ค์„ฏ์ด๊ณ  ์ถฉ๋Œ ์ฒ˜๋ฆฌ๊ฐ€ ์ œ๊ฐ๊ฐ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.\n * ๊ตฌ๊ฐ„ ๋‹จ์œ„๋กœ ํ•œ ๋ฒˆ ์ฝ์–ด ๊ฐ€๋ ค๋‚ด๋Š” ํŽธ์ด ์ด์‹์„ฑ์ด ์žˆ๊ณ  ๊ฐ’๋„ ์‹ธ๋‹ค.\n */\nexport function splitAlreadyThere(keep: readonly any[], existingIds: ReadonlySet<string>): { fresh: any[]; skipped: number } {\n const fresh = keep.filter(e => typeof e?.eventId === 'string' && e.eventId && !existingIds.has(e.eventId))\n return { fresh, skipped: keep.length - fresh.length }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-backfill/index.ts"],"names":[],"mappings":";;;AAAA,2EAAkE;AAErD,QAAA,SAAS,GAAG,CAAC,gDAAoB,CAAC,CAAA","sourcesContent":["import { TwinBackfillResolver } from './twin-backfill-resolver.js'\n\nexport const resolvers = [TwinBackfillResolver]\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-backfill-resolver.js","sourceRoot":"","sources":["../../../server/service/twin-backfill/twin-backfill-resolver.ts"],"names":[],"mappings":";;;;AAAA,+CAAsE;AACtE,iDAAoD;AAEpD,yEAAgE;AAEhE;;;;;;;;;;;;;GAaG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAC/B,0DAA0D;IAMpD,AAAN,KAAK,CAAC,uBAAuB,CACR,UAAkB,EACG,OAAkB,EACnD,OAAwB;QAE/B,OAAO,MAAM,IAAA,8CAAmB,EAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAA;IAC9F,CAAC;CACF,CAAA;AAdY,oDAAoB;AAOzB;IALL,IAAA,wBAAS,EAAC,uGAAuG,CAAC;IAClH,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,oBAAY,EAAE;QACjC,WAAW,EACT,ydAAyd;KAC5d,CAAC;IAEC,mBAAA,IAAA,kBAAG,EAAC,YAAY,CAAC,CAAA;IACjB,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,oBAAY,CAAC,CAAC,CAAA;IACtC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;mEAGP;+BAbU,oBAAoB;IADhC,IAAA,uBAAQ,GAAE;GACE,oBAAoB,CAchC","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { ScalarObject } from '@things-factory/shell'\n\nimport { backfillPeriodFacts } from './backfill-period-facts.js'\n\n/*\n * ์ง€๋‚œ ๊ธฐ๋ก ์ฑ„์šฐ๊ธฐ์˜ **๋ฌธ** โ€” ์ปค๋„ฅํ„ฐ๊ฐ€ ํŠธ์œˆ์ด ์—†๋˜ ๋™์•ˆ์˜ ๋‚ ๋“ค์„ ๋’ค๋Šฆ๊ฒŒ ๋„ฃ๋Š”๋‹ค.\n *\n * โ”€โ”€ ์™œ ๋ฌธ์„ ๋”ฐ๋กœ ๋‘๋‚˜ (2026-08-30) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ผ์ด๋ธŒ ์œ ์ž…๊ณผ ํŒ๋‹จ์ด ๋‹ค๋ฅด๋‹ค. ๋ผ์ด๋ธŒ๋Š” ํŠธ์œˆ์˜ ใ€Œ์ง€๊ธˆใ€์„ ๋ฐ”๊พธ๊ณ , ์ด์ชฝ์€ ์ €๋„์—๋งŒ ์“ด๋‹ค. ๊ฐ™์€ ๋ฌธ์œผ๋กœ\n * ๋ฐ›์œผ๋ฉด ์˜› ํ‘œ๋ณธ์ด ๊ฐ€๋“œ์— ๋ง‰ํžˆ๊ฑฐ๋‚˜ ํŠธ์œˆ์˜ ์‹œ๊ณ„๊ฐ€ ๊ณผ๊ฑฐ๋กœ ๋Œ๋ฆฐ๋‹ค(ยง`backfill-period-facts`).\n *\n * ๋ ˆ์ฝ”๋“œ์˜ **๋ชจ์–‘์€ ๋ผ์ด๋ธŒ์™€ ๊ฐ™๋‹ค** โ€” ์ปค๋„ฅํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ์–ดํœ˜๋ฅผ ๋ฐฐ์šธ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์€ ๋ฐ›๋Š” ์ข…๋ฅ˜๋ฟ์ด๊ณ ,\n * ๊ทธ ํŒ๋‹จ์€ ์ปค๋„์˜ ์œ ์ž…๊ณผ `judgeBackfill` ์ด ํ•œ๋‹ค.\n *\n * โ”€โ”€ ์™œ ์ด ํŒŒ์ผ์ด ๋Šฆ๊ฒŒ ์ƒ๊ฒผ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ฑ„์šฐ๊ธฐ ์ž์ฒด๋Š” ๋งŒ๋“ค์–ด ๋‘๊ณ  **๋ถ€๋ฅด๋Š” ๊ณณ์„ ๋งŒ๋“ค์ง€ ์•Š์•„** ์“ธ ์ˆ˜ ์—†๋Š” ์ฑ„๋กœ ์žˆ์—ˆ๋‹ค. 8์›” 29์ผ ๋ฐœ์ „๋Ÿ‰์„\n * ๋˜์‚ด๋ฆฌ๋ ค๋‹ค ๋“œ๋Ÿฌ๋‚ฌ๋‹ค. ๊ฐ™์€ ๋ถ€๋ฅ˜๋ฅผ ๊ทธ๋‚  ๋‘ ๋ฒˆ ๊ฒช์—ˆ๋‹ค(์ปค๋„์˜ ๋ฐœ์ „ ๊ธฐ๊ฐ„ ๋ฌธ๋„ ์—†์—ˆ๋‹ค).\n */\n@Resolver()\nexport class TwinBackfillResolver {\n /* ํŠธ์œˆ์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ๊ณผ ๊ฐ™์€ ๊ฒŒ์ดํŠธ๋‹ค(ADR-0027) โ€” ์ €๋„์— ์‚ฌ์‹ค์„ ์ ๋Š” ์ผ์ด๋ฏ€๋กœ ๋ณ€๊ฒฝ์ด๋‹ค. */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n 'Backfill closed-period facts into a twin journal without touching its live state. Records use the same shape as live ingest; only closed-period facts are accepted (usage/generation periods, generation price, tariff basis, bill). Point-in-time observations are refused with a reason, as are times beyond journal retention. Re-running is safe: a period already present is skipped, because a closed period is identified by its content. Returns { written, skipped, refused }.'\n })\n async backfillTwinPeriodFacts(\n @Arg('instanceId') instanceId: string,\n @Arg('records', type => [ScalarObject]) records: unknown[],\n @Ctx() context: ResolverContext\n ): Promise<{ written: number; skipped: number; refused: { record: unknown; reason: string }[] }> {\n return await backfillPeriodFacts({ domainId: context.state.domain.id, instanceId, records })\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-control/index.ts"],"names":[],"mappings":";;;AAAA,yEAAgE;AAEnD,QAAA,SAAS,GAAG,CAAC,8CAAmB,CAAC,CAAA","sourcesContent":["import { TwinControlMutation } from './twin-control-mutation.js'\n\nexport const resolvers = [TwinControlMutation]\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-control-mutation.js","sourceRoot":"","sources":["../../../server/service/twin-control/twin-control-mutation.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 { validateScenario } from '@operato/ops-contract'\n\nimport { ScalarObject } from '@things-factory/shell'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { TwinAuditEvent } from '../twin-audit/twin-audit-event.js'\nimport { buildCommandAudit } from '../twin-audit/command-audit.js'\n/* ๊ตฌ๋™์€ ์›๋ณธ์„ ์ง€๋‚œ๋‹ค(ADR-0029 ยง8) โ€” ํŠธ์œˆ ๋Ÿฐํƒ€์ž„์„ ์ง์ ‘ ์žก์ง€ ์•Š๋Š”๋‹ค. */\nimport { routeControl, controlCapabilityOf } from '../reference/control-routing.js'\n\n/*\n * ํŠธ์œˆ CommandยทScenario ์ฑ„๋„ โ€” ์ƒํ–ฅ mutation.\n * Command: runtime.dispatch(ํ–‰์œ„). Scenario: runtime.scenario.load/start/pause/setSpeed(์˜ˆ์ธก ์ž๊ทน).\n * (State ํ•˜ํ–ฅ์€ twin-state subscription. tick ์€ ์›Œ์ปค.)\n *\n * ์ธ๊ฐ€: data ๊ตฌ๋… ๋ฆฌ์กธ๋ฒ„์™€ ๋Œ€์นญ์œผ๋กœ, ๋Œ€์ƒ ์ธ์Šคํ„ด์Šค๊ฐ€ **ํ˜ธ์ถœ์ž ๋„๋ฉ”์ธ ์†Œ์†**์ธ์ง€ ๊ฒ€์ฆํ•œ๋‹ค(cross-tenant ์ปค๋งจ๋“œ ์ฃผ์ž… ์ฐจ๋‹จ).\n * command ์ฑ„๋„์€ sim ์ƒํƒœ๋ฅผ ๋ณ€์ดํ•˜๋ฏ€๋กœ ๋„๋ฉ”์ธ ์Šค์ฝ”ํ”„๊ฐ€ ํ•„์ˆ˜.\n */\n@Resolver()\nexport class TwinControlMutation {\n /** Command ์ฑ„๋„ โ€” ์˜ค๋” hold/resume/release ๋“ฑ. ์ปค๋„ dispatch ๋กœ ์œ„์ž„, ack{accepted,error} ๋ฐ˜ํ™˜. */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, { description: 'dispatch a twin command (order.hold/resume/release โ€ฆ). Returns {accepted, error?}.' })\n async dispatchTwinCommand(\n @Arg('instanceId') instanceId: string,\n @Arg('command', type => ScalarObject) command: any,\n @Ctx() context: ResolverContext\n ): Promise<{ accepted: boolean; error?: string; errorCode?: string; errorParams?: Record<string, string | number> }> {\n const domainId = context.state.domain?.id\n if (!domainId) return { accepted: false, error: 'no-domain', errorCode: 'no-domain' }\n /*\n * ๋ผ์šฐํŒ…์€ ์—”์ง„์ด ํ•œ๋‹ค โ€” ์˜ˆ์ „์—๋Š” ์—ฌ๊ธฐ์„œ `inst.runtime.dispatch` ๋ฅผ ๊ณง๋ฐ”๋กœ ๋ถˆ๋ €๊ณ , `runtime` ์ด\n * ์‹œ๋ฎฌ์—๋งŒ ์žˆ์–ด์„œ ๋ฏธ๋Ÿฌ ํŠธ์œˆ์—์„œ๋Š” ์ด ํ•œ ์ค„์ด TypeError ๋กœ ํ„ฐ์กŒ๋‹ค(๊น”๋”ํ•œ ๊ฑฐ์ ˆ์ด ์•„๋‹ˆ๋ผ ์‹คํŒจ).\n * ๊ถŒ์œ„(๋ชจ๋“œ) ร— ์„ฑ๊ฒฉ(์ฃผ์„/์•ก์ถ”์—์ด์…˜) ํŒ์ •์€ ํ•œ ๊ณณ์—๋งŒ ๋‘”๋‹ค.\n */\n /* ์›๋ณธ์„ ๊ทธ๋Œ€๋กœ ๊ฐ์‚ฌ์— ๋„˜๊ธด๋‹ค โ€” ๋ฌด์—‡์ด ๋“ค์–ด์™”๋Š”์ง€๊ฐ€ ๊ธฐ๋ก์˜ ๋Œ€์ƒ์ด๋‹ค(์ •๊ทœํ™”๋Š” ๊ฐ์‚ฌ ๋ชจ๋“ˆ์ด ํ•œ๋‹ค). */\n const cmdWithOrigin = command\n const ack = await TwinEngine.dispatchCommand(domainId, instanceId, command)\n /* ๋ผ์ด๋ธŒ ๊ตฌ์กฐ ๋ณ€์ด(resource.add)๋Š” ์ €์žฅ model ์—๋„ ๋ฐ˜์˜ โ€” ํ”„๋กœ๋น„์ €๋‹ ํŽธ์ง‘๊ธฐยท์žฌ๊ธฐ๋™์ด ์ถ”๊ฐ€๋ถ„์„ ์žƒ์ง€ ์•Š๊ฒŒ. */\n if (ack?.accepted && command?.type === 'resource.add') {\n await TwinEngine.syncBoardEquipment(domainId, instanceId).catch(err => twinError('twin syncBoardEquipment fail', err))\n }\n /*\n * ๊ฐ์‚ฌ ๊ธฐ๋ก โ€” ์Šน์ธ ๊ฒŒ์ดํŠธ๊ฐ€ ์•ž์„ ๋ง‰๊ณ , ์ด ์ค„์ด ๋’ค๋ฅผ ์„ค๋ช…ํ•œ๋‹ค. ๋‘˜ ๋‹ค ์žˆ์–ด์•ผ \"์‚ฌ๋žŒ ์†์„ ๊ฑฐ์ณค๋‹ค\" ๋ฅผ\n * ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปค๋„์ด ๊ฑฐ์ ˆํ•œ ๊ฒƒ๋„ ๋‚จ๊ธด๋‹ค โ€” ๋ฌด์—‡์„ ์‹œ๋„ํ–ˆ๋Š”์ง€๊ฐ€ ๊ฐ์‚ฌ์˜ ์ ˆ๋ฐ˜์ด๋‹ค.\n *\n * ๊ธฐ๋ก์ด ์‹คํŒจํ•ด๋„ ์ปค๋งจ๋“œ ๊ฒฐ๊ณผ๋Š” ๊ทธ๋Œ€๋กœ ๋Œ๋ ค์ค€๋‹ค. ๊ฐ์‚ฌ๊ฐ€ ๋ณธ์—…์„ ๋ง‰์œผ๋ฉด ์•ˆ ๋˜์ง€๋งŒ, ์‹คํŒจ๋ฅผ ์‚ผํ‚ค์ง€๋„\n * ์•Š๋Š”๋‹ค(๋กœ๊ทธ์— ๋‚จ๊ธด๋‹ค) โ€” ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์•ˆ ๋‚จ์œผ๋ฉด ๋‚˜์ค‘์— \"๊ธฐ๋ก์ด ์—†๋‹ค\" ์™€ \"์ผ์ด ์—†์—ˆ๋‹ค\" ๋ฅผ ๊ตฌ๋ถ„ ๋ชป ํ•œ๋‹ค.\n */\n try {\n const audit = buildCommandAudit({ command: cmdWithOrigin, ack, actor: context.state.user, at: new Date() })\n const repo = getRepository(TwinAuditEvent)\n await repo.save(repo.create({ domain: context.state.domain, instanceId, ...audit }))\n } catch (err) {\n twinError(`[twin-control] command audit not recorded for \"${instanceId}\"`, err)\n }\n\n /* ๊ฑฐ์ ˆ ์‚ฌ์œ ๋Š” **์–ธ์–ด ์ค‘๋ฆฝ ์ฝ”๋“œ**๋กœ ํ•จ๊ป˜ ๋Œ๋ ค์ค€๋‹ค โ€” ํ™”๋ฉด์ด `twin.cmderr.<code>` ๋กœ ์‚ฌ๋žŒ ๋ง์„ ๋งŒ๋“ ๋‹ค. */\n return { accepted: !!ack?.accepted, error: ack?.error, errorCode: ack?.errorCode, errorParams: ack?.errorParams }\n }\n\n /**\n * ๊ตฌ๋™ ์ฑ„๋„ โ€” **์›๋ณธ์„ ์ง€๋‚œ๋‹ค**(ADR-0029 ยง8).\n *\n * โ”€โ”€ ๋ฌด์—‡์ด ๋ฐ”๋€Œ์—ˆ๋‚˜ (2026-08-19) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” ์ด ๋ฌธ์ด `TwinEngine.runtime(...).scenario` ๋ฅผ **์ง์ ‘** ์žก์•˜๋‹ค. ์‹œ๋ฎฌ๋งŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ(์ž๊ทนยท๋ฐฐ์†ยท\n * ์ •์ง€)์ด ๊ณ„์•ฝ ๋ฐ–์˜ ์ง€๋ฆ„๊ธธ๋กœ ๋“ค์–ด์˜จ ์…ˆ์ด๊ณ , ์‹ค ์‹œ์Šคํ…œ์—๋Š” ๊ทธ ์ž๋ฆฌ๊ฐ€ ์•„์˜ˆ ์—†์—ˆ๋‹ค. ์ด์ œ ๊ธธ์€ ํ•˜๋‚˜๋‹ค:\n * ํŠธ์œˆ โ†’ ๊ทธ ํŠธ์œˆ์˜ ์›๋ณธ โ†’ ์–ด๋Œ‘ํ„ฐ๊ฐ€ **์„ ์–ธํ•œ** `control` ๋Šฅ๋ ฅ. ์„ ์–ธํ•˜์ง€ ์•Š์€ ์›๋ณธ์—๋Š” ๋ฌธ์ด ์—ด๋ฆฌ์ง€ ์•Š๊ณ ,\n * ๊ทธ ์‚ฌ์‹ค์„ ์‚ฌ์œ  ์ฝ”๋“œ๋กœ ๋งํ•œ๋‹ค(`not-declared`) โ€” ์‹ค WMS ๊ฐ€ ์ •์ง€๋˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ๊ฒฐ์†์ด ์•„๋‹ˆ๋‹ค.\n *\n * ๋ฐ˜ํ™˜์„ Boolean ์—์„œ ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟจ๋‹ค: ์˜ˆ์ „์—๋Š” ๊ฑฐ์ ˆ ์‚ฌ์œ ๋ฅผ ์‹ค์„ ์ž๋ฆฌ๊ฐ€ ์—†์–ด **๋กœ๊ทธ๋กœ๋งŒ** ๋‚จ๊ฒผ๋‹ค.\n * ํ™”๋ฉด์€ ์™œ ์•ˆ ๋˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์—ˆ๋‹ค.\n */\n @Directive('@privilege(category: \"twin\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ScalarObject, {\n description:\n \"Drive the source behind a twin: stimulus | start | pause | speed | reset. The command goes through the source adapter's declared control capability โ€” a source that does not declare it refuses with code 'not-declared' (a real system is not paused or seeded, and that is a fact rather than a gap). Returns { ok, code?, detail? }.\"\n })\n async controlTwinSource(\n @Arg('instanceId') instanceId: string,\n @Arg('action') action: string,\n @Ctx() context: ResolverContext,\n @Arg('scenario', type => ScalarObject, { nullable: true }) scenario?: any,\n @Arg('speed', { nullable: true }) speed?: number\n ): Promise<any> {\n const domainId = context.state.domain?.id\n if (!domainId) return { ok: false, code: 'no-domain' }\n const allowed = ['stimulus', 'start', 'pause', 'speed', 'reset']\n if (!allowed.includes(action)) return { ok: false, code: 'unsupported-action', detail: `one of ${allowed.join(' | ')}` }\n /*\n * **์ž˜๋ชป๋œ ์„ ์–ธ์€ ๋ฌธ ์•ž์—์„œ ๋ง‰๋Š”๋‹ค.** ์˜ˆ์ „์—๋Š” ๊ฒ€์ฆ ์—†์ด ์‹ค์—ˆ๊ณ , ๋‹ค์Œ tick ์—์„œ `rate.meanPerHour` ๋ฅผ\n * ์ฝ๋‹ค ํ„ฐ์ ธ **์„œ๋ฒ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‚ด๋ ค๊ฐ”๋‹ค**(ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ๊ฐ’ ํ•˜๋‚˜๋กœ ์•ฑ ์ „์ฒด๊ฐ€ ์ฃฝ์—ˆ๋‹ค). ๊ทœ์น™์€ ์ปค๋„์ด\n * ๋“ค๊ณ  ์žˆ๋‹ค(๊ณ„์•ฝ์˜ ์ฃผ์ธ) โ€” ํ˜ธ์ŠคํŠธ๊ฐ€ ๋”ฐ๋กœ ๋งŒ๋“ค๋ฉด ๋ฐฉ์–ธ์ด ์ƒ๊ธด๋‹ค.\n */\n if (action === 'stimulus') {\n const v = validateScenario(scenario)\n if (v.ok === false) return { ok: false, code: 'invalid', detail: v.errorCode, params: v.errorParams }\n }\n if (action === 'speed' && !(Number(speed) > 0)) return { ok: false, code: 'invalid', detail: 'speed must be greater than 0' }\n\n /*\n * **๊ตฌ๋™๋„ ์‚ฌ๋žŒ์ด ํ•œ ์ผ์ด๋‹ค โ€” ๋‚จ๊ธด๋‹ค** (ADR-0029 ยง1 ๊ฒฐ์ • C, 2026-08-19).\n *\n * ์ด ๋ฌธ์€ ๊ฐ์‚ฌ๋ฅผ ์•„์˜ˆ ๋‚จ๊ธฐ์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž๊ทน์„ ๋ฐ”๊พธ๊ณ  ๋ฐฐ์†์„ ์˜ฌ๋ฆฌ๊ณ  ์›๋ณธ์„ ๋ฉˆ์ถ”๋Š” ๊ฒƒ์€ ๊ทธ ํŠธ์œˆ์˜\n * ์‚ฌ์‹ค์„ ๋ฐ”๊พธ๋Š” ํ–‰์œ„๋‹ค โ€” ์ปค๋งจ๋“œ ์ฑ„๋„์€ ๋‚จ๊ธฐ๋Š”๋ฐ ์ด์ชฝ์ด ๋น„์–ด ์žˆ์œผ๋ฉด, ๋‚˜์ค‘์— ใ€Œ๋ฌด์—‡์ด ์ด ๊ณต์žฅ์„\n * ํ”๋“ค์—ˆ๋‚˜ใ€์— ๋‹ตํ•  ์ˆ˜ ์—†๋‹ค.\n *\n * ๊ฒฐ์ • C ๊ทธ๋Œ€๋กœ: ๊ฒŒ์ดํŠธ๋Š” ์—ฌ๊ธฐ ๋‚จ๊ณ (์œ„ `@privilege`), **์›๋ณธ์˜ ๋‹ต์„ ๊ฐ™์€ ํ–‰์— ๋‹ซ๋Š”๋‹ค.** ๋‹ต์„ ๋ชป ๋ฐ›์œผ๋ฉด\n * `unknown` ์ด๋‹ค โ€” ์„ฑ๊ณต์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค.\n */\n let result: { ok: boolean; code?: string; detail?: string }\n try {\n result = await routeControl(domainId, instanceId, { action: action as any, scenario, speed: speed != null ? Number(speed) : undefined })\n } catch (e: any) {\n result = { ok: false, code: 'failed', detail: e?.message ?? 'control failed' }\n }\n try {\n const audit = buildCommandAudit({\n /* ์ปค๋งจ๋“œ ์ฑ„๋„๊ณผ ๊ฐ™์€ ๋ชจ์–‘์œผ๋กœ ์ ๋Š”๋‹ค โ€” ๊ฐ์‚ฌ๋ฅผ ์ฝ๋Š” ์ชฝ์ด ๋‘ ์–ดํœ˜๋ฅผ ๋ฐฐ์šฐ์ง€ ์•Š๊ฒŒ. */\n command: { type: `source.${action}`, origin: 'user', args: { ...(scenario ? { scenario } : {}), ...(speed != null ? { speed } : {}) } },\n /* ๊ฒŒ์ดํŠธ๋Š” ํ†ต๊ณผํ–ˆ๋‹ค(์—ฌ๊ธฐ๊นŒ์ง€ ์™”๋‹ค) โ€” ๊ทธ ์‚ฌ์‹ค๊ณผ ์›๋ณธ์˜ ๋‹ต์€ ๋‹ค๋ฅธ ์นธ์ด๋‹ค. */\n ack: { accepted: true },\n source: { answered: typeof result?.ok === 'boolean', ok: result?.ok, code: result?.code },\n actor: context.state.user,\n at: new Date()\n })\n const repo = getRepository(TwinAuditEvent)\n await repo.save(repo.create({ domain: context.state.domain, instanceId, ...audit }))\n } catch (err) {\n /* ๊ธฐ๋ก์ด ์‹คํŒจํ•ด๋„ ๊ฒฐ๊ณผ๋Š” ๋Œ๋ ค์ค€๋‹ค โ€” ๋‹ค๋งŒ ์‚ผํ‚ค์ง€ ์•Š๋Š”๋‹ค(ใ€Œ๊ธฐ๋ก ์—†์Œใ€๊ณผ ใ€Œ์ผ ์—†์Œใ€์„ ๊ตฌ๋ณ„ํ•ด์•ผ ํ•œ๋‹ค). */\n twinError(`[twin-control] source control audit not recorded for \"${instanceId}\"`, err)\n }\n return result\n }\n\n /** ์ด ํŠธ์œˆ์˜ ์›๋ณธ์ด **๋ฌด์—‡์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‚˜** โ€” ํ™”๋ฉด์ด ๋ฒ„ํŠผ์„ ์—ด๊ธฐ ์ „์— ๋ฌป๋Š” ์ž๋ฆฌ. */\n @Query(returns => ScalarObject, {\n description: \"What the source behind this twin can do: its declared capabilities ('live', 'control'). Empty when the twin has no source or its adapter declares nothing.\"\n })\n async twinSourceCapability(@Arg('instanceId') instanceId: string, @Ctx() context: ResolverContext): Promise<any> {\n const domainId = context.state.domain?.id\n if (!domainId) return { capabilities: [] }\n return controlCapabilityOf(domainId, instanceId)\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/twin-event/index.ts"],"names":[],"mappings":";;;AAAA,mDAA2C;AAE9B,QAAA,QAAQ,GAAG,CAAC,yBAAS,CAAC,CAAA","sourcesContent":["import { TwinEvent } from './twin-event.js'\n\nexport const entities = [TwinEvent]\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"journal-count.js","sourceRoot":"","sources":["../../../server/service/twin-event/journal-count.ts"],"names":[],"mappings":";;;AAmCA,8BAOC;AAOD,sCAGC;AAhCD,iDAAiD;AACpC,QAAA,iBAAiB,GAAG,MAAM,CAAA;AASvC;;;;GAIG;AACI,KAAK,UAAU,SAAS,CAC7B,IAAmB,EACnB,KAAU,EACV,GAAG,GAAG,yBAAiB;IAEvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,CAAQ,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7E,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AACjG,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,aAAa,CAA0B,IAAmB,EAAE,KAAU;IAC1F,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,CAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IACvE,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;AACxB,CAAC","sourcesContent":["/*\n * ์ €๋„์„ **์ƒํ•œ๊นŒ์ง€๋งŒ ์„ผ๋‹ค** โ€” ์„ธ๋Š” ๊ฒƒ๋„ ์ฝ๋Š” ๊ฒƒ์ด๋‹ค (2026-08-22).\n *\n * โ”€โ”€ ์™œ (์‹ค์ธก) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์กฐ๊ฑด์— ๋งž๋Š” ํ–‰์„ ์ „๋ถ€ ์„ธ๋Š” ์งˆ์˜๋Š” ํ–‰์„ ์‹ค์–ด ์˜ค์ง€ ์•Š์•„๋„ ๋น„์‹ธ๋‹ค. ๊ฐœ๋ฐœ ์ €๋„์—์„œ ํŠธ์œˆ ํ•˜๋‚˜๊ฐ€ 358๋งŒ\n * ํ–‰์ด์—ˆ๊ณ  ๊ทธ ํ•œ ๋ฒˆ์ด **5.32์ดˆ**์˜€๋‹ค. ์ƒ‰์ธ๋งŒ ์ƒํ•œ๊นŒ์ง€ ์ฝ์œผ๋ฉด ๊ฐ™์€ ์กฐ๊ฑด์—์„œ **0.04์ดˆ**๋‹ค(130๋ฐฐ).\n *\n * ๊ทธ 5์ดˆ ๋™์•ˆ ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ๋‹ค๋ฅธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•œ๋‹ค โ€” ์ด๋ ฅ ํ™”๋ฉด ํ•œ ๋ฒˆ, ์ค€๋น„๋„ ํ™”๋ฉด ํ•œ ๋ฒˆ์ด\n * ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ใ€Œ๋ˆŒ๋ €๋Š”๋ฐ ์•„๋ฌด ๋ฐ˜์‘์ด ์—†๋‹คใ€๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. ์ค€๋น„๋„ ํ™”๋ฉด์€ ๊ทธ๋Ÿฐ ์„ธ๊ธฐ๋ฅผ **๋„ท** ํ–ˆ๋‹ค.\n *\n * โ”€โ”€ ๊ทœ์œจ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์„ธ๋Š” ๋ชฉ์ ์ด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋‹ค.\n * โ‘  **ํŒ์ •** โ€” ใ€Œํ•œ ๊ฑด์ด๋ผ๋„ ์žˆ๋‚˜ใ€. ๊ทธ๋•Œ๋Š” ํ•˜๋‚˜๋งŒ ์ฐพ์œผ๋ฉด ๋์ด๋‹ค(`anyJournalRow`).\n * โ‘ก **ํ‘œ์‹œ** โ€” ์‚ฌ๋žŒ์—๊ฒŒ ์ˆ˜๋ฅผ ๋ณด์ธ๋‹ค. ๊ทธ๋•Œ๋Š” ์ƒํ•œ๊นŒ์ง€ ์„ธ๊ณ , ๋„˜์œผ๋ฉด **๋ชจ๋ฅธ๋‹ค๊ณ  ๋งํ•œ๋‹ค**(`countUpTo`).\n *\n * ์ƒํ•œ์„ ๋„˜์—ˆ์„ ๋•Œ ์ƒํ•œ๊ฐ’์„ ์ „์ฒด๋กœ ์ ์œผ๋ฉด ํ™”๋ฉด์ด ๊ฑฐ์ง“์„ ๋งํ•œ๋‹ค. ๊ทธ๋ž˜์„œ `capped` ๋ฅผ ํ•จ๊ป˜ ๋‚ธ๋‹ค โ€”\n * ์—†๋Š” ๊ฒƒ๊ณผ ๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๊ฐ€๋ฅด๋Š” ์ด ํ”„๋กœ์ ํŠธ์˜ ๊ทœ์œจ์ด ์„ธ๊ธฐ์—๋„ ๊ฐ™์ด ์ ์šฉ๋œ๋‹ค.\n */\nimport type { ObjectLiteral, Repository } from 'typeorm'\n\n/** ํ‘œ์‹œ์šฉ ์„ธ๊ธฐ์˜ ๊ธฐ๋ณธ ์ƒํ•œ โ€” ํ™”๋ฉด์ด ํ•œ ๋ฒˆ์— ๋ณด์—ฌ ์ค„ ๋ฒ”์œ„๋ฅผ ํ›จ์”ฌ ๋„˜๋Š” ๊ฐ’. */\nexport const JOURNAL_COUNT_CAP = 10_000\n\nexport interface CappedCount {\n /** ์„ผ ์ˆ˜. `capped` ๋ฉด ์ƒํ•œ๊นŒ์ง€๋งŒ ์„ผ ๊ฐ’์ด๋ฏ€๋กœ **์ „์ฒด๊ฐ€ ์•„๋‹ˆ๋‹ค**. */\n count: number\n /** ์ƒํ•œ์„ ๋„˜์—ˆ๋‚˜ โ€” ๊ทธ๋•Œ ์ „์ฒด ์ˆ˜๋Š” ๋ชจ๋ฅด๋Š” ๊ฒƒ์ด ์‚ฌ์‹ค์ด๋‹ค. */\n capped: boolean\n}\n\n/**\n * ์ƒํ•œ๊นŒ์ง€๋งŒ ์„ธ๊ธฐ โ€” ํ‚ค ์ปฌ๋Ÿผ๋งŒ ์ฝ์œผ๋ฏ€๋กœ ํ–‰ ๋ณธ๋ฌธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.\n *\n * `count()` ๋ฅผ ์“ฐ์ง€ ์•Š๋Š” ์ด์œ : ๊ทธ๊ฒƒ์€ ์ƒํ•œ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค(์กฐ๊ฑด์— ๋งž๋Š” ์ „๋ถ€๋ฅผ ์„ผ๋‹ค).\n */\nexport async function countUpTo<T extends ObjectLiteral>(\n repo: Repository<T>,\n where: any,\n cap = JOURNAL_COUNT_CAP\n): Promise<CappedCount> {\n const rows = await repo.find({ where, select: ['id'] as any, take: cap + 1 })\n return rows.length > cap ? { count: cap, capped: true } : { count: rows.length, capped: false }\n}\n\n/**\n * ํ•œ ๊ฑด์ด๋ผ๋„ ์žˆ๋‚˜ โ€” **ํŒ์ •์—๋Š” ์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค.**\n *\n * ์˜ˆ์ „์—๋Š” ์ „๋ถ€ ์„ผ ๋’ค `> 0` ์„ ๋ดค๋‹ค. ๊ทธ ๋‹ต์„ ์–ป๋Š” ๋ฐ 358๋งŒ ํ–‰์„ ์„ธ๊ณ  ์žˆ์—ˆ๋‹ค.\n */\nexport async function anyJournalRow<T extends ObjectLiteral>(repo: Repository<T>, where: any): Promise<boolean> {\n const rows = await repo.find({ where, select: ['id'] as any, take: 1 })\n return rows.length > 0\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-event-keys.js","sourceRoot":"","sources":["../../../server/service/twin-event/twin-event-keys.ts"],"names":[],"mappings":"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","sourcesContent":["import { bizStepName } from '@operato/ops-contract'\n\nimport { twinWarn } from '../../engine/log.js'\n/*\n * ์ €๋„ ๊ฒ€์ƒ‰ ํ‚ค ์ถ”์ถœ โ€” **์ˆœ์ˆ˜**. ์ธ์ œ์ŠคํŠธ๊ฐ€ ๊ธฐ๋กํ•  ๋•Œ ํ•œ ๋ฒˆ ๋ฝ‘์•„ ์ธ๋ฑ์Šค ๊ฐ€๋Šฅํ•œ ์‹ค์ปฌ๋Ÿผ์œผ๋กœ ์Šน๊ฒฉํ•œ๋‹ค.\n *\n * โ”€โ”€ ์™œ ์Šน๊ฒฉํ•˜๋Š”๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์‚ฌ์šฉ์ž๊ฐ€ ์ €๋„์—์„œ ์‹ค์ œ๋กœ ์ฐพ๋Š” ๊ฒƒ์€ \"์ด ํŒ”๋ ˆํŠธ์˜ ์ด๋ ฅ\", \"์ด ์˜ค๋”๊ฐ€ ์–ด๋””๊นŒ์ง€ ๊ฐ”๋‚˜\", \"์ด ๋„ํฌ์—์„œ\n * ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜\" ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๊ฐ’๋“ค์€ ์ „๋ถ€ `payload`(simple-json = TEXT) **์•ˆ**์— ์žˆ์—ˆ๋‹ค.\n * things-factory ๋Š” 5๊ฐœ DB ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ง€์›ํ•ด์•ผ ํ•ด์„œ DB๋ณ„ JSON ์—ฐ์‚ฐ์ž๋ฅผ ์“ธ ์ˆ˜ ์—†๋‹ค โ€”\n * ์ฆ‰ ์Šน๊ฒฉ ์—†์ด๋Š” **์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ์„œ๋ฒ„์—์„œ ๊ทธ ์กฐ๊ฑด์œผ๋กœ ๊ฑฐ๋ฅผ ์ˆ˜ ์—†์—ˆ๋‹ค**. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ›์•„์˜จ\n * ๋ช‡ ์ฒœ ๊ฑด ์•ˆ์—์„œ๋งŒ ์ฐพ๋Š” ์‹œ๋Љ์ด ์ตœ์„ ์ด์—ˆ๊ณ , ์ €๋„์ด ์ปค์งˆ์ˆ˜๋ก ๊ทธ ์‹œ๋Љ์€ ๊ฑฐ์ง“๋ง์— ๊ฐ€๊นŒ์›Œ์ง„๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ๊ฒ€์ƒ‰ ์ถ•์ด ๋˜๋Š” ๊ฐ’๋งŒ ๊ณจ๋ผ ์ปฌ๋Ÿผ์œผ๋กœ ๊บผ๋‚ธ๋‹ค. payload ๋Š” ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค(์ •๋ณธ์€ ์—ฌ์ „ํžˆ payload โ€”\n * ์ด๊ฑด ํŒŒ์ƒ ์ƒ‰์ธ์ด์ง€ ์ƒˆ๋กœ์šด ์ง„์‹ค์ด ์•„๋‹ˆ๋‹ค).\n *\n * โ”€โ”€ ์™œ ์—ฌ๊ธฐ(์ˆœ์ˆ˜ ๋ชจ๋“ˆ)์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๊ธฐ๋ก ๊ฒฝ๋กœ๊ฐ€ ๋‘˜์ด๋‹ค(`persistBatch` ๋ผ์ด๋ธŒ ๋ฒŒํฌ ยท `persist` ์‹ฌ ๋‹จ๊ฑด). ๋‘ ๊ณณ์— ๊ฐ์ž ์ ์œผ๋ฉด\n * ๋ฐ˜๋“œ์‹œ ์–ด๊ธ‹๋‚˜๊ณ , ์–ด๊ธ‹๋‚œ ์ƒ‰์ธ์€ \"์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ด๋ฒคํŠธ\" ๋ฅผ ๋งŒ๋“ ๋‹ค โ€” ์ €๋„์—์„œ ๊ฐ€์žฅ ๋‚˜์œ ๊ฒฐํ•จ์ด๋‹ค.\n */\n\n/** ์Šน๊ฒฉ๋œ ๊ฒ€์ƒ‰ ํ‚ค โ€” ์ „๋ถ€ ์„ ํƒ์ . ๋ฝ‘ํžˆ์ง€ ์•Š์œผ๋ฉด **๋นˆ ๋ฌธ์ž์—ด์ด ์•„๋‹ˆ๋ผ undefined**(๊ฒฐ์ธกโ‰ ๋นˆ๊ฐ’). */\nexport interface TwinEventKeys {\n action?: string\n bizStep?: string\n epc?: string\n orderId?: string\n bizTransaction?: string\n locationId?: string\n moverId?: string\n /** `'actual'`, `'simulated'`, or absent โ€” absent means not declared, which is not `actual`. */\n provenance?: string\n}\n\n/*\n * ์ปฌ๋Ÿผ ๊ธธ์ด ์ƒํ•œ. GS1 ์‹๋ณ„์ž(EPC URNยทGDTIยทSGLN)๋Š” ๊ทœ๊ฒฉ์ƒ ์ด๋ณด๋‹ค ํ›จ์”ฌ ์งง๋‹ค.\n * ๋„˜์น˜๋Š” ๊ฐ’์ด ์˜ค๋ฉด **์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ž๋ฅด์ง€ ์•Š๊ณ ** ๊ฒฝ๊ณ ๋ฅผ ๋‚จ๊ธด๋‹ค โ€” ์ƒ‰์ธ์ด ์›๋ณธ๊ณผ ๋‹ค๋ฅด๋ฉด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๊ฑฐ์ง“์ด ๋˜๋Š”๋ฐ,\n * ๊ทธ ์‚ฌ์‹ค์ด ์–ด๋””์—๋„ ์•ˆ ๋‚จ์œผ๋ฉด ์•„๋ฌด๋„ ๋ชจ๋ฅธ๋‹ค.\n */\nconst MAX_KEY = 255\n\nfunction clip(v: unknown, field: string): string | undefined {\n if (v === undefined || v === null) return undefined\n const s = String(v)\n if (!s) return undefined\n if (s.length <= MAX_KEY) return s\n twinWarn(\n `[twin-event-keys] ${field} exceeds ${MAX_KEY} chars and was clipped for indexing โ€” ` +\n `search on this value may be incomplete. payload keeps the full value. (${s.slice(0, 60)}โ€ฆ)`\n )\n return s.slice(0, MAX_KEY)\n}\n\n/**\n * bizStep ์˜ ์งง์€ ์ด๋ฆ„ โ€” ์ž๋ฅด๋Š” ๊ทœ์น™์€ ๊ณ„์•ฝ์˜ `bizStepName` ํ•˜๋‚˜๋‹ค(CBV URN ๊ณผ ์‚ฌ์„ค ์ด๋ฆ„๊ณต๊ฐ„ URL ๋‘˜ ๋‹ค).\n * ์—†์œผ๋ฉด ์ด๋ฒคํŠธ ํƒ€์ž…์—์„œ ์œ ์ถ”(`epcis.` ์ ‘๋‘ ์ œ๊ฑฐ).\n */\nexport function bizStepOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n return bizStepName(d.bizStep) || String(envelope?.eventType ?? '').replace('epcis.', '') || undefined\n}\n\n/**\n * ํ’ˆ๋ชฉ ์‹๋ณ„์ž โ€” **์ „์ฒด ๊ฐ’**์„ ์ €์žฅํ•œ๋‹ค(๋๋งˆ๋””๋งŒ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค).\n *\n * ํ‘œ์‹œ์šฉ ์ถ•์•ฝ์€ ํ™”๋ฉด์ด ํ•˜๊ณ , ์ƒ‰์ธ์€ ์›๋ณธ์„ ๊ฐ–๋Š”๋‹ค. `search` ๋Š” ๋ถ€๋ถ„์ผ์น˜(contains)๋ผ\n * ์ „์ฒด๋ฅผ ์ €์žฅํ•ด ๋‘๋ฉด ๋๋งˆ๋””(\"402.2\")๋กœ๋„ URN ์ „์ฒด๋กœ๋„ ์ฐพํžŒ๋‹ค. ๋ฐ˜๋Œ€๋กœ ๋๋งˆ๋””๋งŒ ์ €์žฅํ•˜๋ฉด\n * URN ์œผ๋กœ ์ฐพ๋Š” ๊ฒฝ๋กœ๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.\n */\nexport function epcOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n return d.epcList?.[0] ?? d.parentID ?? d.quantityList?.[0]?.epcClass ?? undefined\n}\n\n/**\n * ์˜ค๋” ์‹๋ณ„์ž โ€” ์šด์˜ ๋ธํƒ€์˜ `orderId` ์šฐ์„ , EPCIS ๋Š” `bizTransactionList`.\n *\n * โ”€โ”€ ์‹ค์ธก (2026-08-24) โ€” ์ด ์ปฌ๋Ÿผ์ด **์ „๋ถ€ ๋น„์–ด ์žˆ์—ˆ๋‹ค** โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์—ฌ๊ธฐ๊ฐ€ ์ฐพ๋˜ ์ด๋ฆ„์ด `d.order` ์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ปค๋„์ด ๋‚ด๋Š” ์ด๋ฆ„์€ **`orderId`** ๋‹ค\n * (`OrderStatusDelta.orderId` ยท `TaskStatusDelta.orderId`). `d.order` ๋ฅผ ๋‚ด๋Š” ์ฝ”๋“œ๋Š” ์ปค๋„์— **ํ•œ ๊ณณ๋„\n * ์—†๋‹ค** โ€” ์ฃฝ์€ ๊ฐ€์ง€์˜€๋‹ค. ๊ทธ๋ž˜์„œ ์šด์˜ ๋ธํƒ€๋Š” ์ด ์ปฌ๋Ÿผ์„ ํ•œ ๋ฒˆ๋„ ์ฑ„์šฐ์ง€ ๋ชปํ–ˆ๋‹ค.\n *\n * order.status 29,403,565 ํ–‰ โ€” order_id ๋น„์–ด ์žˆ์Œ 29,403,565 (100%)\n * task.status 191,175 ํ–‰ โ€” ๋น„์–ด ์žˆ์Œ 191,175 (100%)\n *\n * ๊ทธ ๊ฒฐ๊ณผ ์ƒ‰์ธ `ix_twin_event_4` ๊ฐ€ **์ž๊ธฐ ์ฃผ์„์ด ์ ์–ด ๋‘” ์šฉ๋„**(ใ€Œ์ด ์˜ค๋”๊ฐ€ ์–ด๋””๊นŒ์ง€ ๊ฐ”๋‚˜ใ€)๋กœ ์“ธ ์ˆ˜\n * ์—†์—ˆ๋‹ค. ํ™”๋ฉด์€ ์˜ค๋”๋ฅผ ๋ˆŒ๋Ÿฌ๋„ ใ€Œ์—ฐ๊ฒฐ๋œ ์ด๋ฒคํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹คใ€๋ฅผ ๋ƒˆ๊ณ , ๊ทธ ๋‹ต์€ ์งˆ์˜ ๊ฒฐ๊ณผ๋กœ๋Š” ์ •์งํ–ˆ๋‹ค โ€”\n * ์‹œ์ ์„ ์–ด๋””๋กœ ์˜ฎ๊ฒจ๋„ 0 ์ด์—ˆ๋‹ค.\n *\n * **๊ณผ๊ฑฐ ํ–‰์€ ์ฑ„์›Œ์ง€์ง€ ์•Š๋Š”๋‹ค**(์‚ฌ์šฉ์ž ๊ฒฐ์ • 2026-08-24, `moverId` ๋•Œ์™€ ๊ฐ™์€ ๋ฐฉ์‹). ์•ž์œผ๋กœ ๋“ค์–ด์˜ค๋Š”\n * ์‚ฌ๊ฑด๋ถ€ํ„ฐ ์กฐํšŒ๋œ๋‹ค.\n *\n * โ”€โ”€ ํ•œ ์นธ์— ๋‘ ๋‚ฑ๋ง์ด ๋“ค์–ด ์žˆ์—ˆ๋‹ค (2026-09-05 ์‹ค์ธก) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์œ„ ์ฃผ์„์ด ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์—ˆ๋‹ค โ€” ใ€ŒEPCIS ์˜ `bizTransactionList` ๋Š” **๊ฑฐ๋ž˜**(PO/SO)์ด๊ณ  ์˜ค๋”์™€ ๊ฐ™์€\n * ๊ฒƒ์ด ์•„๋‹ ์ˆ˜ ์žˆ๋‹คใ€. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๋‘˜์„ **๊ฐ™์€ ์นธ์—** ๋„ฃ๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ ‡๊ฒŒ ๋๋‹ค.\n *\n * order.status order-1 ๋‚ด๋ถ€ ์˜ค๋” id\n * epcis.TransformationEvent urn:epc:id:gdti:9521321.403.1 GS1 ๊ฑฐ๋ž˜ ์‹๋ณ„์ž\n * epcis.TransactionEvent urn:epc:id:gdti:9521321.403.1\n *\n * ํ•œ ์˜ค๋”์˜ ์ด๋ ฅ์ด **์ƒ‰์ธ ์•ˆ์—์„œ ๋‘ ์ชฝ์œผ๋กœ ๊ฐˆ๋ผ์ง„๋‹ค.** ์–ด๋А ์ด๋ฆ„์œผ๋กœ ๋ฌผ์–ด๋„ ์ ˆ๋ฐ˜๋งŒ ๋‚˜์˜ค๊ณ ,\n * ์˜ค๋ฅ˜๋Š” ๋‚˜์ง€ ์•Š๋Š”๋‹ค. ์‹ค์ธก: ์–ดํœ˜๊ฐ€ ์„ž์ธ ํ–‰ 10,004๊ฐœ.\n *\n * ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ ๋ง‰์€ ๊ฒƒ โ€” ใ€Œ์ด ๊ฐœ์ฒด๋ฅผ ์–ด๋А ๋ ˆ์‹œํ”ผ๋กœ ๋งŒ๋“ค์—ˆ๋‚˜ใ€๋‹ค. ๋‹ต์€ ๊ธฐ๋ก๋˜์–ด ์žˆ๋‹ค(์˜ค๋” ์‚ฌ๊ฑด์ด\n * `recipeKey` ๋ฅผ ๋“ ๋‹ค, ์‹ค์ธก 328,021/328,021 = 100%). ๋ณ€ํ™˜ ์‚ฌ๊ฑด์€ ๊ทธ ์˜ค๋”๋ฅผ GDTI ๋กœ ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ\n * ์˜ค๋” ์‚ฌ๊ฑด์€ `order-1` ๋กœ ์ ํ˜€ ์žˆ์–ด **์ƒ‰์ธ์œผ๋กœ ์ด์„ ์ˆ˜๊ฐ€ ์—†์—ˆ๋‹ค.**\n *\n * ๊ทธ๋ž˜์„œ ์นธ์„ ๊ฐˆ๋ž๋‹ค(์‚ฌ์šฉ์ž ๊ฒฐ์ • 2026-09-05).\n *\n * orderId ๋‚ด๋ถ€ ์˜ค๋” id โ€” ์ฝ๊ธฐ ๋ชจ๋ธ์˜ ์ด์Œ์‡ \n * bizTransaction GS1 ๊ฑฐ๋ž˜ ์‹๋ณ„์ž โ€” ํ‘œ์ค€์ด ๋งํ•˜๋Š” ๊ทธ ๊ฑฐ๋ž˜\n *\n * ์˜ค๋” ์‚ฌ๊ฑด์€ **๋‘˜ ๋‹ค** ๋“ ๋‹ค(`order.status` ์˜ payload ์— `orderId` ์™€ `bizTransaction` ์ด ํ•จ๊ป˜\n * ์žˆ๋‹ค). ๊ทธ๋ž˜์„œ EPCIS ์‚ฌ๊ฑด์˜ ๊ฑฐ๋ž˜ ์‹๋ณ„์ž๋กœ ์˜ค๋”๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค โ€” ์ด ๋‘ ์นธ์ด ๊ทธ ๋‹ค๋ฆฌ๋‹ค.\n */\nexport function orderOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n return d.orderId ?? undefined\n}\n\n/**\n * **๊ทธ ์‚ฌ๊ฑด์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฑฐ๋ž˜** โ€” EPCIS `bizTransactionList` ์˜ ์ฒซ ํ•ญ๋ชฉ, ๋˜๋Š” ์šด์˜ ๋ธํƒ€๊ฐ€ ์ง์ ‘ ๋“  ๊ฐ’.\n *\n * ์˜ค๋”๊ฐ€ ์•„๋‹ˆ๋‹ค. ํ‘œ์ค€์ด ๋งํ•˜๋Š” ๊ฑฐ๋ž˜(PO/SO/์ƒ์‚ฐ์˜ค๋”)์ด๊ณ , ํ•œ ์˜ค๋”๊ฐ€ ์—ฌ๋Ÿฌ ๊ฑฐ๋ž˜์— ๊ฑธ๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค.\n * ๊ทธ ๊ตฌ๋ณ„์„ ์ง€ํ‚ค๋ ค๊ณ  `orderId` ์™€ ๊ฐˆ๋ผ ๋‘์—ˆ๋‹ค โ€” ํ•ฉ์น˜๋ฉด ์œ„ ์ฃผ์„์˜ ๊ทธ ์ผ์ด ๋‹ค์‹œ ๋‚œ๋‹ค.\n */\nexport function bizTransactionOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n return d.bizTransactionList?.[0]?.bizTransaction ?? d.bizTransaction ?? undefined\n}\n\n/**\n * ์œ„์น˜ โ€” EPCIS ๋Š” ์ฝ์€ ์ง€์ (readPoint) ์šฐ์„ , ์—†์œผ๋ฉด ์—…๋ฌด ์œ„์น˜(bizLocation).\n * ์šด์˜ ๋ธํƒ€(๋ฌด๋ฒ„ ์ด๋™ ๋“ฑ)๋Š” ๊ทธ ๋‘˜์ด ์—†๊ณ  ํ‰๋ฒ”ํ•œ `location` ์„ ์“ด๋‹ค โ€” ๋น ๋œจ๋ฆฌ๋ฉด ์„ค๋น„๊ฐ€ ์–ด๋””์„œ\n * ๋ฌด์—‡์„ ํ–ˆ๋Š”์ง€๊ฐ€ ์œ„์น˜ ์ถ•์—์„œ ํ†ต์งธ๋กœ ์‚ฌ๋ผ์ง„๋‹ค.\n */\nexport function locationOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n return d.readPoint?.id ?? d.bizLocation?.id ?? d.location ?? undefined\n}\n\n/**\n * ์„ค๋น„ยท๋ฌด๋ฒ„ โ€” ์šด์˜ ๋ธํƒ€(equipment.statusยทtask.status)๊ฐ€ ๋Œ€์ƒ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ถ•.\n *\n * EPCIS ์–ดํœ˜๊ฐ€ ์•„๋‹ˆ๋ผ์„œ ๋‹ค๋ฅธ ์ถ• ์–ด๋””์—๋„ ์•ˆ ์žกํžŒ๋‹ค. ์ด๊ฒŒ ์—†์œผ๋ฉด \"์ด ์ง€๊ฒŒ์ฐจ๊ฐ€ ์˜ค๋Š˜ ๋ฌด์—‡์„ ํ–ˆ๋‚˜\" ๋ฅผ\n * ์„œ๋ฒ„์—์„œ ๋ฌผ์„ ๋ฐฉ๋ฒ•์ด ์—†์–ด, ํ™”๋ฉด์ด ์ €๋„์„ ํ†ต์งธ๋กœ ๋ฐ›์•„ ์ „์ˆ˜ ์กฐํšŒํ•˜๋Š” ์ˆ˜๋ฐ–์— ์—†๋‹ค.\n */\nexport function equipmentIdOf(envelope: any): string | undefined {\n const d = envelope?.data ?? envelope ?? {}\n /*\n * โ”€โ”€ ์‹ค์ธก (2026-08-24) โ€” ๋‘ ๊ฐˆ๋ž˜๋ฅผ ๋†“์น˜๊ณ  ์žˆ์—ˆ๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์œ„ ์ฃผ์„์ด `task.status` ๋ฅผ ์ถœ์ฒ˜๋กœ **์ ์–ด ๋‘์—ˆ๋Š”๋ฐ** ์ด ํ•จ์ˆ˜๋Š” `d.moverId` ๋งŒ ๋ดค๋‹ค. ์ž‘์—…์ด ์ž์›์„\n * ๊ฐ€๋ฆฌํ‚ค๋Š” ์ด๋ฆ„์€ `resourceRef` ๋‹ค(`TaskStatusDelta.resourceRef`) โ€” ๊ทธ๋ž˜์„œ ์ž‘์—… 191,175 ํ–‰ ์ „๋ถ€\n * ์ด ์ปฌ๋Ÿผ์ด ๋น„์—ˆ๊ณ , ใ€Œ์ด ์ง€๊ฒŒ์ฐจ๊ฐ€ ์˜ค๋Š˜ ๋ฌด์—‡์„ ํ–ˆ๋‚˜ใ€์—์„œ **์ž‘์—…์ด ํ†ต์งธ๋กœ ๋น ์กŒ๋‹ค.**\n *\n * ๊ทธ๋ฆฌ๊ณ  ์—๋„ˆ์ง€ ์‚ฌ๊ฑด์€ `equipmentId` ๋ฅผ ์“ด๋‹ค(์–ดํœ˜๊ฐ€ `movers`โ†’`equipment` ๋กœ ๊ฐœ๋ช…๋œ ๋’ค์— ์ƒ๊ธด\n * ์ฑ„๋„์ด๋‹ค). ์‹ค์ธก `energy.equipment` 31,079 ํ–‰ ์ „๋ถ€ ๋น„์–ด ์žˆ์—ˆ๋‹ค โ€” ใ€Œ์ด ์„ค๋น„๊ฐ€ ์–ผ๋งˆ๋ฅผ ๋จน์—ˆ๋‚˜ใ€๋ฅผ\n * ์„ค๋น„ ์ถ•์œผ๋กœ ๋ฌผ์„ ์ˆ˜ ์—†์—ˆ๋‹ค.\n *\n * ์…‹์„ ํ•จ๊ป˜ ๋ณธ๋‹ค. ๊ฐœ๋ช… ์„ธ๋Œ€๊ฐ€ ์„ž์—ฌ ์žˆ๋Š” ๊ฒƒ์€ ์ €๋„์˜ ์„ฑ์งˆ์ด๊ณ , ์ฝ๋Š” ์ชฝ์ด ๊ทธ๊ฒƒ์„ ํก์ˆ˜ํ•œ๋‹ค.\n */\n return d.moverId ?? d.resourceRef ?? d.equipmentId ?? undefined\n}\n\n/**\n * EPCIS ํ–‰์œ„ โ€” `ADD`ยท`OBSERVE`ยท`DELETE`. ์„ธ ๊ฐ’์ด ์•„๋‹ˆ๋ฉด `undefined`(์›์ฒœ์˜ ์žก๊ฐ’์„ ์ƒ‰์ธ์— ๋„ฃ์ง€ ์•Š๋Š”๋‹ค).\n *\n * ์ด ํ‚ค๋Š” ๊ฒ€์ƒ‰ ์ถ•์ด ์•„๋‹ˆ๋ผ **ํŒ๋ณ„์‹**์ด๋‹ค: ๋˜ํ’€์–ด ์ฝ๋Š” ์Šค๋ƒ…์ƒท์€ ์›๋ฆฌ์ ์œผ๋กœ `DELETE` ๋ฅผ ๋ชป ๋‚ธ๋‹ค.\n * ๊ทธ๋ž˜์„œ ใ€Œ์ด ํŠธ์œˆ์ด ๋ฐ˜์ถœ์„ ํ•œ ๋ฒˆ์ด๋ผ๋„ ๊ณ„์‚ฐํ–ˆ๋Š”๊ฐ€ใ€๊ฐ€ ์ง„์งœ delta ํ”ผ๋“œ์˜ ์ฆ๊ฑฐ์ธ๋ฐ, payload ์•ˆ์— ์žˆ๋Š”\n * ๋™์•ˆ์—๋Š” 5๊ฐœ ๋“œ๋ผ์ด๋ฒ„ ์–ด๋””์—์„œ๋„ ๊ทธ ์งˆ๋ฌธ์„ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. ์šด์˜ ๋ธํƒ€์—๋Š” ํ–‰์œ„๊ฐ€ ์—†๋‹ค โ€” ๋น„์šด๋‹ค.\n */\nexport function actionOf(envelope: any): string | undefined {\n const a = (envelope?.data ?? envelope ?? {}).action\n return a === 'ADD' || a === 'OBSERVE' || a === 'DELETE' ? a : undefined\n}\n\n/**\n * **Whether the sender declared this fact as having actually happened** โ€” the envelope's\n * `provenance`, promoted to a column.\n *\n * โ”€โ”€ Why it is an indexed column (2026-09-09) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * The journal held 1,134 rows, all of them generator output, and there was nowhere to ask about\n * it. While the declaration sits inside `payload`, none of the five drivers can answer \"count\n * these without the invented ones\" โ€” the same reason `action` was promoted.\n *\n * โ”€โ”€ Only the two declared values are taken โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * Anything that is not `actual` or `simulated` becomes `undefined`. A source's stray value does\n * not reach the index (the discipline in `actionOf`).\n *\n * **`undefined` means \"not declared\", not \"it happened\".** A reader has to distinguish three\n * states โ€” declared simulated, declared actual, not declared. Folding the last two together\n * means a generator that omits the field has its output counted as production.\n */\nexport function provenanceOf(envelope: any): string | undefined {\n /*\n * Read from the envelope only. `data` is where the source system writes, and a source that\n * could declare its own facts actual would make this no longer the connecting side's statement.\n */\n const p = envelope?.provenance\n return p === 'actual' || p === 'simulated' ? p : undefined\n}\n\n/** Every promoted key for one event โ€” the write path calls this function and nothing else. */\nexport function twinEventKeys(envelope: any): TwinEventKeys {\n return {\n action: actionOf(envelope),\n bizStep: clip(bizStepOf(envelope), 'bizStep'),\n epc: clip(epcOf(envelope), 'epc'),\n orderId: clip(orderOf(envelope), 'orderId'),\n bizTransaction: clip(bizTransactionOf(envelope), 'bizTransaction'),\n locationId: clip(locationOf(envelope), 'locationId'),\n moverId: clip(equipmentIdOf(envelope), 'moverId'),\n provenance: provenanceOf(envelope)\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"twin-event-type.js","sourceRoot":"","sources":["../../../server/service/twin-event/twin-event-type.ts"],"names":[],"mappings":";;;;AAAA,+CAAqD;AAErD,mDAA2C;AAE3C;;;;;;GAMG;AAEI,IAAM,aAAa,GAAnB,MAAM,aAAa;CAuDzB,CAAA;AAvDY,sCAAa;AAExB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,yBAAS,CAAC,EAAE,EAAE,WAAW,EAAE,6FAA6F,EAAE,CAAC;;4CACzH;AAclB;IALC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE;QAClB,QAAQ,EAAE,IAAI;QACd,WAAW,EACT,iTAAiT;KACpT,CAAC;;4CACY;AAOd;IALC,IAAA,oBAAK,EAAC;QACL,QAAQ,EAAE,IAAI;QACd,WAAW,EACT,mMAAmM;KACtM,CAAC;;6CACc;AAMhB;IAJC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE;QAClB,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,6HAA6H;KAC3I,CAAC;;+CACe;AAQjB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,kQAAkQ,EAAE,CAAC;;iDACxR;AAiBnB;IALC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE;QAClB,QAAQ,EAAE,IAAI;QACd,WAAW,EACT,yUAAyU;KAC5U,CAAC;;qDACqB;wBAtDZ,aAAa;IADzB,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,mFAAmF,EAAE,CAAC;GACpG,aAAa,CAuDzB","sourcesContent":["import { Field, Int, ObjectType } from 'type-graphql'\n\nimport { TwinEvent } from './twin-event.js'\n\n/*\n * ์ €๋„ ๋ชฉ๋ก ๋ฐ˜ํ™˜ํ˜• โ€” things-factory ํ‘œ์ค€ `{ items, total }`(AttributeSetListยทDomainList ๋“ฑ๊ณผ ๋™ํ˜•).\n *\n * `total` ์ด ์ด ํƒ€์ž…์˜ ์กด์žฌ ์ด์œ ๋‹ค. ๊ธฐ์กด `twinEvents` ๋Š” ๋ฐฐ์—ด๋งŒ ๋Œ๋ ค์ค˜์„œ **ํ™”๋ฉด์ด ์ž๊ธฐ๊ฐ€ ์ „์ฒด๋ฅผ ๋ฐ›์€\n * ๊ฑด์ง€ ์ž˜๋ฆฐ ๊ฑด์ง€ ์•Œ ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค** โ€” ๊ทธ๋ž˜์„œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ž˜๋ฆฐ ์ฑ„๋กœ \"์ด๊ฒŒ ์ „๋ถ€\" ์ฒ˜๋Ÿผ ๋ณด์˜€๋‹ค.\n * ์ด๊ฑด์ˆ˜๋ฅผ ํ•จ๊ป˜ ์ฃผ๋ฉด ํ™”๋ฉด์€ \"48 / 12,904\" ๋ผ๊ณ  ์ •์งํ•˜๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ๊ณ , ์‚ฌ์šฉ์ž๋Š” ์ขํ˜€์•ผ ํ•œ๋‹ค๋Š” ๊ฑธ ์•ˆ๋‹ค.\n */\n@ObjectType({ description: 'A page of twin journal events together with the total number of matching records.' })\nexport class TwinEventList {\n @Field(type => [TwinEvent], { description: 'The events on this page, ordered by the requested sorting (revision descending by default).' })\n items: TwinEvent[]\n\n /*\n * ์ „์ฒด ์ˆ˜ โ€” **์ƒํ•œ์„ ๋„˜์œผ๋ฉด ๋น„์šด๋‹ค.**\n *\n * ์„ธ๋Š” ๋ฐ๋„ ๊ฐ’์ด ๋“ ๋‹ค(2026-08-22 ์‹ค์ธก: ์ €๋„ 358๋งŒ ํ–‰์ธ ํŠธ์œˆ์—์„œ ์ „๋Ÿ‰ ์„ธ๊ธฐ 5.32์ดˆ ยท ์ƒํ•œ 1๋งŒ๊นŒ์ง€\n * 0.04์ดˆ). ๊ทธ๋ž˜์„œ ์ƒํ•œ๊นŒ์ง€๋งŒ ์„ธ๊ณ , ๋„˜์œผ๋ฉด ใ€Œ๋ชจ๋ฅธ๋‹คใ€๋กœ ๋‘”๋‹ค. ๊ทธ๋•Œ ์ƒํ•œ๊ฐ’์„ ์ „์ฒด๋กœ ์ ์œผ๋ฉด ํ™”๋ฉด์ด\n * ๊ฑฐ์ง“์„ ๋งํ•œ๋‹ค โ€” ์—†๋Š” ๊ฒƒ๊ณผ ๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๊ฐ€๋ฅด๋Š” ๊ฒƒ์ด ์ด ํ•„๋“œ์˜ ๊ทœ์œจ์ด๋‹ค.\n */\n @Field(type => Int, {\n nullable: true,\n description:\n 'Total number of events matching the filters, ignoring pagination. Lets the caller show an honest \"shown of total\" count instead of silently truncating. NULL when the server stopped counting at countCap: the exact total is then unknown, and capped says so โ€” do not render the cap as if it were the total.'\n })\n total?: number\n\n @Field({\n nullable: true,\n description:\n 'True when there are more matching events than countCap, so total could not be established. The caller should say \"first N shown\" and offer narrowing rather than implying it received everything.'\n })\n capped?: boolean\n\n @Field(type => Int, {\n nullable: true,\n description: 'The counting limit the server applied. Reported so the screen can say how far the count is trustworthy instead of guessing.'\n })\n countCap?: number\n\n /*\n * ๋‹ค์Œ ํŽ˜์ด์ง€ ์ปค์„œ. ์ €๋„์€ **๋จธ๋ฆฌ์— ๊ณ„์† ์Œ“์ด๋Š” ๋ชฉ๋ก**์ด๋ผ offset ์œผ๋กœ ๋’ค๋ฅผ ์ฝ์œผ๋ฉด\n * ์ฝ๋Š” ์‚ฌ์ด ๋“ค์–ด์˜จ ์ด๋ฒคํŠธ๋งŒํผ ๋ฐ€๋ ค ๋ณธ ํ–‰์ด ๋˜ ๋‚˜์˜ค๊ฑฐ๋‚˜ ๋ชป ๋ณธ ํ–‰์ด ์‚ฌ๋ผ์ง„๋‹ค.\n * ์ด ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋‹ค์Œ ์š”์ฒญ์˜ `pagination.after` ๋กœ ๋Œ๋ ค์ฃผ๋ฉด ๊ทธ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค.\n */\n @Field({ nullable: true, description: 'Opaque cursor for the next page. Pass it back as pagination.after to continue exactly where this page ended, without the duplicate or skipped rows that offset paging produces on a journal that keeps growing at the head. Null when this page is the last one.' })\n nextCursor?: string\n\n /*\n * **์•ž๋ถ€๋ถ„์ด ์ง€์›Œ์กŒ๋‹ค** โ€” ๋ณด๊ด€ ๊ธฐ๊ฐ„ ์ •๋ฆฌ๊ฐ€ ์ด ํŠธ์œˆ์˜ ์˜ค๋ž˜๋œ ์‚ฌ๊ฑด์„ ์ง€์šด ๊ฒฝ์šฐ (2026-08-27).\n *\n * ์ •๋ฆฌ๋Š” ์„ ์–ธ๋œ ๋ณด๊ด€ ๊ธฐ๊ฐ„(๊ธฐ๋ณธ 7์ผ)๋ณด๋‹ค ์˜ค๋ž˜๋œ ์‚ฌ๊ฑด์„ ์ง€์šด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ด ๋ชฉ๋ก์˜ ์ฒซ ํŽ˜์ด์ง€ ๋’ค๋กœ ๋”\n * ๋‚ด๋ ค๊ฐ€๋„ ์–ด๋А ์ง€์ ์—์„œ ๊ธฐ๋ก์ด ๋๋‚œ๋‹ค. ํ™”๋ฉด์ด ๊ทธ๊ฒƒ์„ ๋งํ•˜์ง€ ์•Š์œผ๋ฉด ์‚ฌ๋žŒ์€ ใ€Œ์ด ํŠธ์œˆ์€ ๊ทธ๋•Œ๋ถ€ํ„ฐ\n * ์‹œ์ž‘ํ–ˆ๋‹คใ€๋กœ ์ฝ๋Š”๋‹ค. ์—†์—ˆ๋˜ ๊ฒƒ๊ณผ ์ง€์›Œ์ง„ ๊ฒƒ์€ ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋‹ค.\n *\n * ๊ฐ’์€ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ์กฐํšŒํ•  ๋•Œ ๊ตฌํ•œ๋‹ค(๋‚จ์•„ ์žˆ๋Š” ๊ฐ€์žฅ ์ž‘์€ ๋ฆฌ๋น„์ „). ์ €์žฅํ•˜๋ฉด ์‹ค์ œ ๋ฐ์ดํ„ฐ์™€ ์–ด๊ธ‹๋‚  ์ˆ˜\n * ์žˆ๊ณ , ์–ด๊ธ‹๋‚˜๋ฉด ์–ด๋А ์ชฝ์ด ์‚ฌ์‹ค์ธ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.\n */\n @Field(type => Int, {\n nullable: true,\n description:\n 'The oldest revision still stored for this twin. When it is greater than 1, older events were deleted by the journal retention policy: the screen must say the record starts here rather than implying the twin began at this point. NULL when the caller asked for more than one twin (the axis is per twin) or when nothing is stored.'\n })\n oldestRevision?: number\n}\n"]}