@things-factory/headless-twin 10.1.277 → 10.1.279

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,148 +0,0 @@
1
- import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
2
- import { ObjectType, Field, ID } from 'type-graphql'
3
-
4
- import { Domain, ScalarObject } from '@things-factory/shell'
5
-
6
- /*
7
- * TwinSpace — 테넌트 1급 공간(Site) 정의(ADR-0016). 트윈보다 먼저 세우는 몰입의 무대.
8
- * 공간이 보이는 방식(레이아웃·배경·영역)은 정규화됨: TwinSpaceRepresentation(map|image|model —
9
- * 이미지 배경은 attachment-base 참조 `config.imageUrl`) + TwinSpaceArea. 인스턴스는 model.spaceId 로 바인딩.
10
- * - geo = 사이트 지오레퍼런스, primaryRepresentationId = 홈/모니터 대표 표현.
11
- * - content(simple-json) 는 정규화 이전 레거시 단일 blob(@deprecated, P6 제거) — 신규 저작은 representation/area 로.
12
- * (CLAUDE.md: 모든 @ObjectType/@Field 영문 description 필수.)
13
- */
14
- @Entity()
15
- @Index('ix_twin_space_0', (e: TwinSpace) => [e.domain, e.spaceId], { unique: true })
16
- @ObjectType({ description: 'A tenant-level twin Space (Site) — the shared spatial stage set up before instances; its layout, backdrop and areas are normalized into representations (image backdrops via attachment-base) and areas.' })
17
- export class TwinSpace {
18
- @PrimaryGeneratedColumn('uuid')
19
- @Field(type => ID, { description: 'Unique identifier of the space record.' })
20
- readonly id: string
21
-
22
- @ManyToOne(type => Domain)
23
- @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })
24
- domain?: Domain
25
-
26
- @RelationId((e: TwinSpace) => e.domain)
27
- domainId?: string
28
-
29
- @Column()
30
- @Field({ description: 'Space id (unique within a domain).' })
31
- spaceId: string
32
-
33
- @Column({ nullable: true })
34
- @Field({ nullable: true, description: 'Human-readable space name.' })
35
- name?: string
36
-
37
- @Column({ nullable: true })
38
- @Field({ nullable: true, description: 'Space description.' })
39
- description?: string
40
-
41
- @Column({ type: 'simple-json', nullable: true })
42
- @Field(type => ScalarObject, { nullable: true, description: 'Site georeference { lat, lon, rotation } — pins the design frame to the earth so every representation lands in the same place. `rotation` is degrees clockwise from true north (bearing convention: 0 = north, 90 = east) by which the design frame is turned.' })
43
- geo?: any
44
-
45
- /*
46
- * 설계 좌표계의 범위 — **미터**. `geo` 와 한 쌍이다.
47
- *
48
- * 구역(TwinArea.layout)은 표현 중립 설계 좌표 `{x, y, w, h}` 로 놓인다. 그 좌표가 어디까지인지를
49
- * 이 둘이 정하고, `geo` 가 그것을 지구에 붙인다 — 지도로 보든 도면 이미지로 보든 보드로 보든
50
- * 구역이 같은 자리에 있어야 하므로, 범위도 지오레퍼런스도 **표현이 아니라 공간**이 갖는다.
51
- *
52
- * 설계 좌표 (x, y) ──[extentX/extentY 로 중심 이동]──▶ 미터 오프셋 ──[geo]──▶ 위경도
53
- *
54
- * `width`/`depth` 라 부르지 않는 이유: 컴포넌트 속성의 `depth` 는 높이 축(z)이다. 같은 화면에서
55
- * 한 낱말이 두 축을 가리키면 읽는 사람이 매번 어느 쪽인지 물어야 한다.
56
- * 단위 필드는 두지 않는다 — 미터로 고정이고, 있으면 "단위를 지원한다" 는 거짓 신호가 된다.
57
- */
58
- @Column({ type: 'float', nullable: true })
59
- @Field({ nullable: true, description: 'Extent of the design frame along the east-west axis, in metres. Area layouts are placed within this frame.' })
60
- extentX?: number
61
-
62
- @Column({ type: 'float', nullable: true })
63
- @Field({ nullable: true, description: 'Extent of the design frame along the north-south axis, in metres. Area layouts are placed within this frame.' })
64
- extentY?: number
65
-
66
- /**
67
- * 이 현장의 시각 기준 — IANA 이름(`'America/Tijuana'`).
68
- *
69
- * **테넌트가 아니라 공간이 갖는다.** 한 테넌트가 Rosarito(태평양)와 한국 공장을 함께 가질 수 있고,
70
- * 테넌트 단위(`Domain.timezone`)로 두면 둘 중 하나는 반드시 틀린다. 교대가 "06시" 라고 할 때 그것이
71
- * 어느 06시인가는 **물리 현장의 성질**이다.
72
- *
73
- * 오프셋 숫자가 아니라 이름으로 둔다: 숫자로는 일광절약시간을 표현할 수 없고, 나중에 절대 구간
74
- * (표준 `StartDateTime`)으로 옮길 때도 이름이 있어야 계산할 수 있다.
75
- */
76
- @Column({ nullable: true })
77
- @Field({ nullable: true, description: 'IANA time zone of this physical site (e.g. America/Tijuana) — the base for reading shift times. Belongs to the space, not the tenant, because one tenant can run plants in different zones.' })
78
- timezone?: string
79
-
80
- /**
81
- * **이 현장이 언제 도나** — 표준 `WorkCalendarEntry`(복수). 휴일 · 주말 · 정기보수가 여기 든다.
82
- *
83
- * ── 왜 공간에 있나 (2026-09-07) ──────────────────────────────────────────
84
- * 이 칸이 없던 동안 설비와 사람만 달력을 가질 수 있었다. 그래서 **현장이 언제 쉬는지가 어디에도
85
- * 없었고**, 계획 조업 시간이 「재기 시작한 뒤 흐른 시간 전부」였다 — 주말도 야간도 휴일도 계획 조업으로
86
- * 세었다. [산술] 8시간 × 주5일이면 168시간 중 40시간이 조업이니 그 수가 4.2배 크다.
87
- *
88
- * 시간대와 같은 축이라 같은 자리에 둔다. 「이 현장의 06:00 이 언제인가」와 「이 현장이 언제 도나」는
89
- * 둘 다 현장이 갖는 값이고, 테넌트가 아니다 — 한 테넌트가 다른 시간대·다른 조업일의 공장을 함께 가진다.
90
- *
91
- * `withSpaceTimeBase` 가 이 값을 모델에 얹고, 거기서 OEE 누적기가 계획 정지를 낸다. 얹는 자리를
92
- * 시간대와 하나로 둔 이유는 **한쪽만 채워진 상태**를 만들지 않기 위해서다.
93
- *
94
- * 없으면 아무것도 가정하지 않는다 — 종일 가동으로 보는 것은 「제약이 없다」가 아니라 「선언되지
95
- * 않았다」이고, 그 사실은 세어져야 한다(안 그러면 사람이 수를 되살리려고 아무 달력이나 채운다).
96
- */
97
- @Column({ type: 'simple-json', nullable: true })
98
- @Field(type => ScalarObject, {
99
- nullable: true,
100
- description:
101
- 'When this site runs — standard WorkCalendarEntry list (holidays, weekends, planned maintenance). Absent means undeclared, not unrestricted: planned busy time then counts the whole window.'
102
- })
103
- workCalendar?: any
104
-
105
- /**
106
- * 현장의 **우편 주소** — 사람이 읽고 서류에 적는 값.
107
- *
108
- * ── 왜 좌표와 따로 두나 (2026-09-07) ────────────────────────────────────
109
- * `geo` 는 도면을 지구에 붙이는 값이고 화면이 쓴다. 주소는 **사람과 서류의 값**이다 — 납품·통관·
110
- * 감사에 그 문자열이 그대로 들어가고, 좌표에서 되돌려 만들 수 없다(같은 좌표에 여러 주소가 있고
111
- * 동·호가 좌표에 없다).
112
- *
113
- * 고객이 준 것을 그대로 적는다. 우편번호·동·호를 우리가 지어내거나 좌표에서 유추하지 않는다.
114
- */
115
- @Column({ nullable: true })
116
- @Field({ nullable: true, description: 'Postal address of this site as the customer states it. Kept apart from `geo`: a floor or unit number has no coordinate, and paperwork carries this string verbatim.' })
117
- address?: string
118
-
119
- @Column({ nullable: true })
120
- @Field({ nullable: true, description: 'Id of the primary representation shown on the home/monitor.' })
121
- primaryRepresentationId?: string
122
-
123
- /**
124
- * 이 **현장**의 로컬 선언 겹 — 요금처럼 **트윈이 아니라 현장이 정하는 수**.
125
- *
126
- * ── 왜 트윈에 두면 안 되나 (2026-08-18) ────────────────────────────────────
127
- * 요금 단가·통화는 그 현장의 계약이므로, 같은 수전을 보는 EMS 트윈이 둘이면 **같은 값을 두 번**
128
- * 선언해야 했다. 두 번 적는 값은 반드시 갈라진다(하나만 고치는 날이 온다) — 그때 두 트윈이 다른
129
- * 금액을 말하고, 어느 쪽이 맞는지 화면으로는 알 수 없다.
130
- *
131
- * 적용 순서는 **현장 먼저, 트윈이 나중**이다. 더 좁은 선언이 이긴다 — 한 현장 안에서 특정 트윈만
132
- * 다른 값으로 실험하는 일이 있고(예: 인상된 단가로 what-if), 그때 현장 값을 고치게 만들면 나머지
133
- * 트윈이 함께 흔들린다.
134
- *
135
- * 모양은 트윈 겹과 같다(`LocalDeclaration`) — 같은 규칙(검사·기억·철회)을 두 벌로 만들지 않는다.
136
- */
137
- @Column({ type: 'simple-json', nullable: true })
138
- @Field(type => ScalarObject, { nullable: true, description: "Locally-declared values that belong to this facility rather than to one twin (tariff, currency). Applied to every twin in the space before the twin's own declarations, which win when both name the same property." })
139
- localDeclarations?: any
140
-
141
- @CreateDateColumn()
142
- @Field({ nullable: true, description: 'Timestamp when the space was created.' })
143
- createdAt?: Date
144
-
145
- @UpdateDateColumn()
146
- @Field({ nullable: true, description: 'Timestamp when the space was last updated.' })
147
- updatedAt?: Date
148
- }
@@ -1,3 +0,0 @@
1
- import { TwinStateSubscription } from './twin-state-subscription.js'
2
-
3
- export const resolvers = [TwinStateSubscription]
@@ -1,62 +0,0 @@
1
- import { filter, pipe } from 'graphql-yoga'
2
- import { Arg, Field, Int, ObjectType, Resolver, Root, Subscription } from 'type-graphql'
3
-
4
- import { assertDomainSubscribeAllowed, pubsub, ScalarObject } from '@things-factory/shell'
5
-
6
- import { TwinEngine } from '../../engine/index.js'
7
- import { TWIN_STATE_TOPIC, twinStateFilter, twinStatePayload, type TwinStatePayload } from '../../engine/twin-state-channel.js'
8
-
9
- /* State 채널 메시지 — snapshot | delta | clock 멀티플렉싱(커널 SubscriptionMessage 대응). */
10
- @ObjectType({ description: 'Twin State channel message multiplexing snapshot | delta | clock.' })
11
- export class TwinStateMessage {
12
- @Field({ description: 'Twin runtime instance id this message belongs to.' })
13
- instanceId: string
14
-
15
- @Field({ description: 'Message kind: snapshot | delta | clock.' })
16
- kind: string
17
-
18
- @Field(type => Int, { nullable: true, description: 'Monotonic state revision.' })
19
- revision?: number
20
-
21
- @Field(type => ScalarObject, { nullable: true, description: 'Payload — snapshot: StateSnapshot / delta: CanonicalEnvelope / clock: { simClockMs }.' })
22
- payload?: any
23
- }
24
-
25
- /*
26
- * 트윈 State 구독 — state-register/data-resolver 패턴 미러.
27
- * 구독 즉시 현재 snapshot 발행(process.nextTick) 후 delta/clock 스트림.
28
- *
29
- * The tenant is asked while streaming, not only at subscribe time (2026-09-24). Ownership used to be
30
- * checked once and the stream filtered on instanceId alone; the same id in two tenants is the normal
31
- * case (`runtime-key.ts`), so other tenants' deltas came through, and the snapshot sent to a new
32
- * subscriber reached every tenant subscribed to that id. Messages now carry their domain and the filter
33
- * compares it (`engine/twin-state-channel.ts`). A twin the caller does not own is refused rather than
34
- * given an empty stream — an empty stream cannot tell "nothing changed" from "you may not see this"
35
- * (shell's `data` throws too).
36
- */
37
- @Resolver()
38
- export class TwinStateSubscription {
39
- @Subscription(returns => TwinStateMessage, {
40
- subscribe: async ({ args, context }) => {
41
- const { instanceId } = args
42
- const { domain, user } = (context as any)?.state ?? {}
43
- await assertDomainSubscribeAllowed(domain, user, (d, u) => process.superUserGranted(d, u))
44
-
45
- /* One refusal for both cases, so the answer does not reveal whether another tenant has such a twin. */
46
- if (!TwinEngine.owns(domain.id, instanceId)) throw new Error(`twin instance not running in this tenant: ${instanceId}`)
47
-
48
- /* Current state first (a late subscriber still sees snapshot → delta). It reaches this tenant's subscribers only. */
49
- process.nextTick(() => {
50
- const snap = TwinEngine.snapshot(domain.id, instanceId)
51
- if (snap) {
52
- pubsub.publish(TWIN_STATE_TOPIC, twinStatePayload(domain.id, { instanceId, kind: 'snapshot', revision: snap.revision, payload: snap }))
53
- }
54
- })
55
-
56
- return pipe(pubsub.subscribe(TWIN_STATE_TOPIC), filter(twinStateFilter(domain.id, instanceId)))
57
- }
58
- })
59
- twinState(@Root() payload: TwinStatePayload, @Arg('instanceId') instanceId: string): TwinStateMessage {
60
- return payload.twinState as TwinStateMessage
61
- }
62
- }
@@ -1,3 +0,0 @@
1
- import { TwinStructure } from './twin-structure.js'
2
-
3
- export const entities = [TwinStructure]
@@ -1,96 +0,0 @@
1
- import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
2
- import { ObjectType, Field, ID, Int } from 'type-graphql'
3
-
4
- import { Domain, ScalarObject } from '@things-factory/shell'
5
- import { User } from '@things-factory/auth-base'
6
- import { modelColumnTransformer } from '../../engine/model-vocabulary.js'
7
-
8
- /*
9
- * TwinStructure — **한 트윈이 거쳐 온 공장 구조들.** 리비전 하나가 그 시절의 공장이다.
10
- *
11
- * ── 왜 필요한가: 역사를 잃거나 거짓말을 하거나 ──────────────────────────────
12
- * 공장은 바뀐다. 도장 부스를 넷 더 놓고, 라인 하나를 닫는다. 그런데 지금까지는 구조 서명이 바뀌면
13
- * **그 트윈의 저널을 통째로 지우는 것**이 유일한 길이었다. 안 지우면 옛 이벤트를 새 공장에 대고
14
- * 계산하게 되어 이력이 거짓말을 하기 때문이다 — 부스가 둘이던 시절의 사실을 여섯 개짜리 공장에 계산하면
15
- * 그때 없던 부스에서 일이 있었던 것처럼 보인다.
16
- *
17
- * 그래서 선택지가 둘뿐이었다: **역사를 잃거나, 거짓말을 하거나.**
18
- *
19
- * 셋째 길이 이 표다. 이벤트가 `structureRev` 로 자기 구조를 달고 다니고, 재생은 구조가 바뀌는
20
- * 지점에서 전환한 뒤 이어서 계산한다(`replaySegments`). 이력은 "그때 그 공장의 사실" 로 계속 읽힌다.
21
- *
22
- * ── 왜 model 를 통째로 담나 ─────────────────────────────────────────────────
23
- * 재생하려면 **그때의 토폴로지 전체**가 필요하다. 차이(diff)만 담으면 리비전 1부터 다시 계산해 쌓아야
24
- * 하고, 그 재계산 자체가 또 하나의 규칙이 되어 어긋난다. 구조는 이벤트에 비해 드물게 바뀌므로
25
- * 스냅샷을 통째로 두는 편이 싸고 정직하다(보드 이력 `BoardHistory` 와 같은 선택).
26
- *
27
- * ── audit 컬럼을 다 두지 않는 이유 ──────────────────────────────────────────
28
- * 리비전은 **한 번 쓰이면 바뀌지 않는다** — 그 시절의 사실이라 고칠 수가 없다. 그래서 updater·
29
- * deletedAt 이 없다(TwinEvent 와 같은 규율). 대신 **누가 구조를 바꿨는지**는 남긴다.
30
- *
31
- * (CLAUDE.md: 모든 @ObjectType/@Field 는 영문 description 필수.)
32
- */
33
- @Entity()
34
- @Index('ix_twin_structure_0', (e: TwinStructure) => [e.domain, e.instanceId, e.rev], { unique: true })
35
- @ObjectType({
36
- description:
37
- 'One structural revision of a twin — the plant as it stood for a stretch of its journal. Events carry the revision they were produced under, so history can be replayed against the structure that was actually in force instead of being deleted when the plant changes.'
38
- })
39
- export class TwinStructure {
40
- @PrimaryGeneratedColumn('uuid')
41
- @Field(type => ID, { description: 'Unique identifier of the structure revision record.' })
42
- readonly id: string
43
-
44
- @ManyToOne(type => Domain)
45
- @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })
46
- domain?: Domain
47
-
48
- @RelationId((e: TwinStructure) => e.domain)
49
- domainId?: string
50
-
51
- @Column()
52
- @Field({ description: 'Twin runtime instance this structure belongs to.' })
53
- instanceId: string
54
-
55
- /**
56
- * 리비전 번호 — 1부터. 이벤트의 `structureRev` 가 이것을 가리킨다.
57
- *
58
- * 0 을 안 쓰는 이유: 컬럼이 없던 시절의 행은 `structureRev` 가 비어 있고, 그 행들은 **가장 오래된
59
- * 리비전**에 속한다. 0 을 유효 번호로 쓰면 "모름" 과 "1번 구조" 가 같은 값이 된다.
60
- */
61
- @Column({ type: 'int' })
62
- @Field(type => Int, { description: 'Revision number, starting at 1. Events reference it via structureRev; absent on rows written before structure revisions existed, which belong to the oldest revision.' })
63
- rev: number
64
-
65
- /**
66
- * 구조 서명 — 이 리비전이 앞 리비전과 **정말 다른지** 판정한 근거.
67
- *
68
- * 서명이 같으면 새 리비전을 만들지 않는다. 프로비저닝은 자주 다시 도는데(부팅마다) 그때마다
69
- * 리비전이 하나씩 늘면 이력이 뜻 없는 마디로 잘게 쪼개진다.
70
- */
71
- @Column({ length: 64 })
72
- @Field({ description: 'Short hash of the structural signature (locations + equipment). A re-provision with the same signature does not create a new revision — otherwise every reboot would slice the history into meaningless segments.' })
73
- signature: string
74
-
75
- /* 읽을 때 어휘 세대를 흡수한다 — 옛 리비전의 모델로 지문을 다시 계산할 때 빈 공장으로 읽히면
76
- 구조 변경 감지가 죽는다(`engine/model-vocabulary.ts`). */
77
- @Column({ type: 'simple-json', transformer: modelColumnTransformer })
78
- @Field(type => ScalarObject, { description: 'The full TwinModelDef as it stood for this revision. Stored whole rather than as a diff: replay needs the entire topology, and rebuilding it from diffs would be a second rule that can drift.' })
79
- model: any
80
-
81
- /** 왜 바뀌었나 — 사람이 남기는 한 줄. 없을 수 있다(자동 프로비저닝은 이유를 모른다). */
82
- @Column({ nullable: true })
83
- @Field({ nullable: true, description: 'Why the structure changed — a human note, absent for automatic provisioning.' })
84
- comment?: string
85
-
86
- @ManyToOne(type => User, { nullable: true })
87
- @Field(type => User, { nullable: true, description: 'Who changed the structure, when known.' })
88
- creator?: User
89
-
90
- @RelationId((e: TwinStructure) => e.creator)
91
- creatorId?: string
92
-
93
- @CreateDateColumn()
94
- @Field({ nullable: true, description: 'When this revision took effect.' })
95
- createdAt?: Date
96
- }
@@ -1,162 +0,0 @@
1
- /*
2
- * **이 사건은 무엇에 대한 것인가** — 사건 하나에서 가리키는 대상들을 뽑는다.
3
- *
4
- * ── 왜 필요한가 (2026-08-27 실측) ───────────────────────────────────────────
5
- * 360 화면이 「이 대상의 이력」을 묻는다. 그 조회가 64초다. 대상으로 걸러 시각순으로 정렬하는 목차가
6
- * 없기 때문이고, 목차를 얹어도 풀리지 않는다.
7
- *
8
- * 부분일치(지금 화면) 63.998초 앞에 와일드카드가 붙어 목차를 쓸 수 없다
9
- * 정확일치로 바꾸면 67.316초 · 0건 품목 하나에 로트가 여럿이라 성립하지 않는다
10
- * 앞부분 범위로 바꾸면 68.402초 목차는 쓰지만 정렬 때문에 맞는 행을 다 가져온다
11
- *
12
- * 저장된 식별자에 품목과 로트가 한 문자열로 붙어 있는 것이 그 원인이다.
13
- *
14
- * https://seunghwa.net/class/product-M0000618-lot-L2604100071
15
- *
16
- * 그래서 문자열을 자르는 대신 **대상마다 한 줄**을 적는다. 같은 사건이 품목과 로트를 함께 가리키면
17
- * 두 줄이다. 자를 규칙이 필요 없다 — 넣는 쪽이 이미 둘을 안다.
18
- *
19
- * ── 왜 「뜻이 달라지는 키 칸」이 아닌가 ─────────────────────────────────────
20
- * `key01~05` 처럼 칸을 두고 사건 종류에 따라 뜻을 달리 쓰는 방식을 **이 표에는** 쓰지 않는다.
21
- *
22
- * 그 방식 자체가 틀린 것은 아니다. 데이터셋마다 정의가 따로 있는 프레임워크에서는 합리적이다 — 읽는
23
- * 쪽이 그 정의를 보고 해석한다. 우리 저널은 표 하나를 화면 여럿이 읽고 볼 정의가 없다. 그래서
24
- * 「M0000438 을 찾아 줘」가 어떤 줄에서는 품목, 다른 줄에서는 오더가 되고, 묻는 쪽이 사건 종류마다
25
- * 어느 칸에 무엇이 들어가는지 외워야 한다.
26
- *
27
- * **종류를 값으로 밝힌다.** 그러면 읽는 쪽이 사건 종류표를 들고 있지 않아도 된다.
28
- *
29
- * ── 왜 순수 모듈인가 ────────────────────────────────────────────────────────
30
- * 기록 경로에서 불리므로 DB·데코레이터를 알지 않는다. 그래야 테스트가 값으로 확인할 수 있다
31
- * (`twin-event-keys` 와 같은 이유다).
32
- *
33
- * 설계: `operato-twin/design/plans/read-models.md`
34
- */
35
- import { twinEventKeys } from '../twin-event/twin-event-keys.js'
36
-
37
- /**
38
- * 대상의 종류 — **닫힌 목록**이다.
39
- *
40
- * 열어 두면 넣는 쪽마다 다른 이름을 쓰게 되고(설비를 세 가지 이름으로 부르는 식), 그러면 조회가
41
- * 어느 이름으로 물어야 하는지 알 수 없다. 늘려야 하면 이 목록에 더한다.
42
- *
43
- * item 선언된 품목. 로트 여럿이 같은 품목을 가리킨다
44
- * lot 개체 하나. 저장된 식별자 그대로다
45
- * order 오더
46
- * location 자리
47
- * equipment 설비
48
- * task 작업
49
- * transaction 거래(PO/SO/생산오더) — 오더와 다르다. 전에는 오더 칸에 섞여 들어와 한 오더의
50
- * 이력이 두 쪽으로 갈라졌다(2026-09-05)
51
- */
52
- export const SUBJECT_KINDS = ['item', 'lot', 'order', 'location', 'equipment', 'task', 'transaction'] as const
53
- export type SubjectKind = (typeof SUBJECT_KINDS)[number]
54
-
55
- export interface EventSubject {
56
- kind: SubjectKind
57
- id: string
58
- }
59
-
60
- /**
61
- * 개체 식별자에서 **선언된 품목**을 찾아 주는 함수 — 부르는 쪽이 넘긴다.
62
- *
63
- * 이 모듈이 문자열을 자르지 않는 이유는 그 규칙이 연결된 시스템마다 다르기 때문이다. 어느 부호가
64
- * 로트를 가리키는지 커널 계약이 정한 적이 없고, chef 의 `-lot-` 을 여기에 굳히면 이 파일이 그
65
- * 시스템 위에 서게 된다(`item-ref.ts` 가 같은 판단을 적어 두었다).
66
- *
67
- * 그래서 판정은 **그 트윈의 선언**과 견주어 하고(`resolveByDeclaration`), 그 선언을 아는 것은
68
- * 부르는 쪽이다. 답하지 못하면 `undefined` — 그때는 품목 줄을 만들지 않는다. 짐작으로 이으면 남의
69
- * 품목 이력에 이 사건이 섞인다.
70
- */
71
- export type ItemResolver = (epc: string) => string | null | undefined
72
-
73
- /** 컬럼 길이 상한 — `twin-event-keys` 와 같은 값이다(같은 표에 나란히 서는 값이므로). */
74
- const MAX_ID = 255
75
-
76
- function put(out: EventSubject[], kind: SubjectKind, raw: unknown): void {
77
- if (raw === undefined || raw === null) return
78
- const id = String(raw).trim()
79
- if (!id || id.length > MAX_ID) return
80
- /* 같은 대상을 두 번 적지 않는다 — 사건 하나에 같은 자리가 두 번 실려 올 수 있다. */
81
- if (out.some(s => s.kind === kind && s.id === id)) return
82
- out.push({ kind, id })
83
- }
84
-
85
- /**
86
- * 사건 하나가 가리키는 대상들 — 없으면 빈 배열이다.
87
- *
88
- * 승격된 검색 키(`twinEventKeys`)를 그대로 쓴다. 그 함수가 이미 사건 종류별로 어디에서 값을 꺼낼지
89
- * 알고 있으므로, 여기서 다시 판단하면 두 곳이 어긋난다.
90
- *
91
- * **작업은 승격 키에 없어서 봉투에서 직접 읽는다.** 승격 컬럼을 늘리는 것은 이 작업의 범위가 아니다
92
- * (그것이 바로 이 파생 표로 대신하려는 일이다).
93
- */
94
- export function subjectsOf(envelope: any, opts?: { itemOf?: ItemResolver }): EventSubject[] {
95
- const keys = twinEventKeys(envelope)
96
- const out: EventSubject[] = []
97
-
98
- /*
99
- * ── 개체로 온 것과 클래스로 온 것을 갈라 적는다 (2026-08-27 실측) ────────────
100
- *
101
- * `epcOf` 는 셋을 한 칸에 담는다 — `epcList[0]` · `parentID` · `quantityList[0].epcClass`.
102
- * 승격 컬럼이 하나라서 그렇게 되어 있고, 그 칸으로는 「개체인가 클래스인가」를 알 수 없다.
103
- *
104
- * 실측한 chef 의 사건 하나가 그 경우다. 물건을 개체로 세지 않고 무게로 담는 현장이라 `epcList` 가
105
- * 비어 있고 `quantityList` 에 클래스가 있다.
106
- *
107
- * epcList []
108
- * quantityList [{ epcClass: 'https://…/product-M0000879', quantity: 11797.6, uom: 'KGM' }]
109
- *
110
- * 그것을 로트로 적으면 뜻이 틀린다 — 개체가 아니라 품목이다. 이 표는 종류를 값으로 밝히므로
111
- * 갈라 적을 수 있다.
112
- */
113
- const d = envelope?.data ?? envelope ?? {}
114
- const instanceEpc = d.epcList?.[0] ?? d.parentID
115
- const classEpc = d.quantityList?.[0]?.epcClass
116
-
117
- if (instanceEpc) {
118
- /* 개체는 저장된 식별자 그대로다 — 자르지 않는다. */
119
- put(out, 'lot', instanceEpc)
120
- /*
121
- * 품목은 선언과 견주어 찾는다. 답이 개체 식별자와 같으면 품목을 찾지 못한 것이므로 줄을 만들지
122
- * 않는다 — `itemRefOf` 는 URI 세계에서 문자열을 그대로 돌려주기 때문에 그 값이 그대로 올 수 있다.
123
- */
124
- const item = opts?.itemOf?.(String(instanceEpc))
125
- if (item && item !== instanceEpc) put(out, 'item', item)
126
- }
127
- if (classEpc) {
128
- /*
129
- * 클래스로 온 것은 개체 줄을 만들지 않는다 — 그 사건에 개체가 없다. 품목 줄만 만든다.
130
- *
131
- * 선언과 견주어 품목을 찾고, 찾지 못하면 클래스 문자열을 그대로 품목으로 쓴다. 클래스는 이미 품목을
132
- * 가리키는 값이므로 그것이 짐작이 아니다(개체 식별자를 그대로 품목으로 쓰는 것과 다르다).
133
- */
134
- const item = opts?.itemOf?.(String(classEpc)) ?? null
135
- put(out, 'item', item || classEpc)
136
- }
137
- put(out, 'order', keys.orderId)
138
- /*
139
- * 거래는 오더가 아니다 — 갈라 적는다. 합쳐 적으면 EPCIS 사건의 GDTI 가 오더 이름으로 앉고,
140
- * 그러면 한 오더의 이력이 두 쪽이 된다(`twin-event-keys.ts` 의 그 실측).
141
- */
142
- put(out, 'transaction', keys.bizTransaction)
143
- put(out, 'location', keys.locationId)
144
- put(out, 'equipment', keys.moverId)
145
-
146
- const data = envelope?.data
147
- put(out, 'task', data?.taskId)
148
- /*
149
- * ── 작업이 오간 두 자리도 적는다 ────────────────────────────────────────────
150
- *
151
- * 승격 컬럼(`locationId`)은 EPCIS 자리만 담는다(`readPoint` · `bizLocation` · `location`). 작업이
152
- * A 에서 B 로 갈 때 그 컬럼에는 **둘 중 하나만** 넣을 수 있어서 아무것도 넣지 않는다.
153
- *
154
- * 여기서는 둘 다 적는다. 이것이 승격 컬럼과의 어긋남이 아니라 **이 표가 할 수 있는 일**이다 —
155
- * 자리 하나에 줄 하나이므로 두 자리를 함께 담는다. 「그 자리에서 무슨 일이 있었나」를 묻는 화면은
156
- * 출발지와 도착지를 둘 다 그 자리의 사건으로 본다.
157
- */
158
- put(out, 'location', data?.fromNode)
159
- put(out, 'location', data?.toNode)
160
-
161
- return out
162
- }
@@ -1,10 +0,0 @@
1
- import { TwinSubjectEvent } from './twin-subject-event.js'
2
- import { TwinSubjectQuery, TwinSubjectMutation } from './twin-subject-query.js'
3
-
4
- export const entities = [TwinSubjectEvent]
5
- export const resolvers = [TwinSubjectQuery, TwinSubjectMutation]
6
- export { TwinSubjectEvent, TwinSubjectQuery, TwinSubjectMutation }
7
- export * from './event-subjects.js'
8
- export * from './item-resolver.js'
9
- export * from './twin-subject-writer.js'
10
- export * from './twin-subject-backfill.js'
@@ -1,92 +0,0 @@
1
- import { itemRefOf, resolveByDeclaration } from '../twin-model/item-ref.js'
2
- import type { ItemResolver } from './event-subjects.js'
3
-
4
- /*
5
- * **개체 식별자 → 선언된 품목** — 대상별 사건 목록에 품목 줄을 적기 위한 것.
6
- *
7
- * ── 왜 문자열을 자르지 않나 ─────────────────────────────────────────────────
8
- * 저장된 식별자에 품목과 로트가 붙어 있다.
9
- *
10
- * https://seunghwa.net/class/product-M0000438-lot-L2403090386
11
- *
12
- * 여기서 품목을 꺼내려면 `-lot-` 이 로트를 가리킨다는 것을 알아야 하는데, 그 부호는 연결된 시스템마다
13
- * 다르고 커널 계약이 정한 적이 없다. 한 시스템의 관습을 규칙으로 굳히면 이 코드가 그 시스템 위에 서게
14
- * 된다(`item-ref.ts` 가 같은 판단을 적어 두었다).
15
- *
16
- * 그래서 **그 트윈의 선언과 견주어** 판정한다. 선언된 품목 중 이 식별자가 가리키는 것을 찾고, 후보가
17
- * 둘 이상이면 답하지 않는다 — 짐작으로 이으면 남의 품목 이력에 이 사건이 섞인다.
18
- *
19
- * ── 왜 기억해 두나 ──────────────────────────────────────────────────────────
20
- * 사건마다 부르는 함수다(초당 130건). 같은 개체 식별자가 계속 되풀어 오므로, 한 번 판정한 것은 기억해
21
- * 둔다. 트윈의 선언이 바뀌면 그 기억을 버려야 하므로 **선언의 개수와 첫 항목으로 세대**를 만든다 —
22
- * 선언이 바뀌면 세대가 달라져 다시 판정한다.
23
- */
24
-
25
- /** 트윈마다 기억해 둔 판정 — 세대가 바뀌면 버린다. */
26
- const memo = new Map<string, { generation: string; declared: Map<string, string>; seen: Map<string, string | null> }>()
27
-
28
- /** 한 트윈이 기억할 개체 식별자 수 상한 — 넘으면 비우고 다시 채운다(무한히 자라지 않게). */
29
- const MEMO_LIMIT = 20_000
30
-
31
- /**
32
- * 선언된 품목의 식별자들을 모은다 — 트윈 모델이 말하는 것만.
33
- *
34
- * `materialDefinitions` 가 이 트윈이 다루는 품목의 선언이다. 그 항목의 `id` 와, 연결된 시스템의
35
- * 어휘로 이어 둔 값(`binding`)을 함께 후보로 둔다 — 개체 식별자는 후자를 앞부분으로 갖는다.
36
- */
37
- function declaredItems(model: any): Map<string, string> {
38
- const out = new Map<string, string>()
39
- const defs = model?.productionSpec?.materialDefinitions ?? model?.materialDefinitions
40
- if (!Array.isArray(defs)) return out
41
- for (const d of defs) {
42
- const id = String(d?.id ?? '').trim()
43
- if (!id) continue
44
- out.set(id, id)
45
- const binding = d?.binding
46
- const bound = typeof binding === 'string' ? binding : binding?.epcClass ?? binding?.id
47
- const b = String(bound ?? '').trim()
48
- if (b) out.set(b, id)
49
- }
50
- return out
51
- }
52
-
53
- /** 선언이 바뀌었는지 값싸게 가리는 표식 — 개수와 첫·끝 항목이면 실제 변경을 잡는다. */
54
- function generationOf(declared: Map<string, string>): string {
55
- const keys = [...declared.keys()]
56
- return `${keys.length}:${keys[0] ?? ''}:${keys[keys.length - 1] ?? ''}`
57
- }
58
-
59
- /**
60
- * 그 트윈의 품목 판정 함수 — 선언이 없으면 `undefined`(그때는 품목 줄을 만들지 않는다).
61
- *
62
- * 선언을 모르는 트윈에서 품목을 지어내지 않는다. 개체 줄(`lot`)은 그대로 적히므로 이력 조회는 로트로
63
- * 답할 수 있고, 품목 축만 비어 있다. 그 사실을 조회하는 쪽이 말한다.
64
- */
65
- export function itemResolverFor(domainId: string, instanceId: string, model: any): ItemResolver | undefined {
66
- const declared = declaredItems(model)
67
- if (!declared.size) return undefined
68
-
69
- const key = `${domainId}:${instanceId}`
70
- const generation = generationOf(declared)
71
- let entry = memo.get(key)
72
- if (!entry || entry.generation !== generation) {
73
- entry = { generation, declared, seen: new Map() }
74
- memo.set(key, entry)
75
- }
76
- const state = entry
77
-
78
- return (epc: string) => {
79
- const hit = state.seen.get(epc)
80
- if (hit !== undefined) return hit
81
- /* 판정은 선언이 한다 — 후보가 둘 이상이면 `undefined` 를 내고, 그것을 「모른다」로 기억한다. */
82
- const found = resolveByDeclaration(itemRefOf(epc), state.declared) ?? null
83
- if (state.seen.size >= MEMO_LIMIT) state.seen.clear()
84
- state.seen.set(epc, found)
85
- return found
86
- }
87
- }
88
-
89
- /** 시험이 쓰는 초기화 — 프로세스 안의 기억이므로 시험마다 비운다. */
90
- export function resetItemResolverMemo(): void {
91
- memo.clear()
92
- }