@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,226 +0,0 @@
1
- /*
2
- * 선언 적합성(경계 편) — **원본이 말한 사실은 모델까지 간다.**
3
- *
4
- * ── 왜 필요한가 ─────────────────────────────────────────────────────────────
5
- * 커널 쪽에는 같은 이름의 하네스가 있다(kernel/test/declaration-in-state: 선언 ⊆ 상태). 그런데 사실이
6
- * 새던 자리는 그 앞에도 있었다: **레퍼런스 마스터 → 커널 모델** 이라는 문 하나(`masterToTwin`).
7
- *
8
- * 여기서 새면 아무도 모른다. 원본은 말했고, 화면은 알리지 않고 id 를 보인다. 실제로 그렇게 잃었다 —
9
- * 자리의 이름(화면이 `cut-station` 을 찍었다), 사람의 이름, GS1 참조, 자원 속성, 시험 명세 참조,
10
- * 사람·설비의 시험 결과. 하루 사이에 여섯 번이고, 전부 **한 줄에서 필드 하나가 빠진** 것이었다.
11
- *
12
- * 타입 검사는 못 잡는다: 필드가 거의 다 선택(optional)이라 **안 옮기는 것이 합법**이다.
13
- *
14
- * ── 무엇을 검사하나 ─────────────────────────────────────────────────────────
15
- * `RefLocation`·`RefEquipment`·`RefPerson`·`RefAsset` 의 **모든 필드**가 셋 중 하나여야 한다:
16
- *
17
- * 1. 같은 이름으로 모델에 있다(대부분).
18
- * 2. `RENAMED` 에 적힌 다른 이름으로 모델에 있다(`homeLocationId → homeLocation`).
19
- * 3. `ELSEWHERE` 에 **다른 길이 무엇인지 적혀** 있다(좌표는 `layout` 으로, 역할은 분기에 쓰인다).
20
- *
21
- * 셋 중 어느 것도 아니면 실패한다 — 새 필드를 추가한 사람이 그때 분류해야 한다. 분류를 강제하는 것이
22
- * 이 검사의 전부다: 잊는 것이 기본값이면 잊는다.
23
- *
24
- * 필드 목록은 **소스에서 읽는다**(손으로 적지 않는다). 손으로 적으면 새 필드가 알리지 않고 빠지고, 그것이
25
- * 바로 이 검사가 막으려는 실패다.
26
- */
27
- import { test } from 'node:test'
28
- import assert from 'node:assert/strict'
29
- import { readFileSync } from 'node:fs'
30
-
31
- import { masterToTwin } from '../server/service/reference/reference-master.ts'
32
-
33
- /*
34
- * 주석을 먼저 걷어낸다 — **주석 속 예시가 필드로 세어졌다.**
35
- * 문서에 `effectivity: 'not-yet' | 'expired'` 라고 적어 둔 한 줄 때문에 없는 필드가 검사 대상에 들어왔다.
36
- * 검사가 없는 것을 요구하면 그 검사는 유지되지 않는다(사람이 예외를 늘려 입을 막는다).
37
- */
38
- const SOURCE = readFileSync(new URL('../server/service/reference/reference-master.ts', import.meta.url), 'utf8')
39
- .replace(/\/\*[\s\S]*?\*\//g, '')
40
- .replace(/\/\/[^\n]*/g, '')
41
-
42
- /** `export interface X { … }` 의 깊이 1 필드 이름 — 중첩 객체의 안쪽은 세지 않는다. */
43
- function fieldsOf(name: string): string[] {
44
- const start = SOURCE.indexOf(`export interface ${name}`)
45
- assert.ok(start >= 0, `선언 인터페이스를 못 찾았다: ${name} — 모양이 바뀌면 이 하네스도 따라가야 한다`)
46
- const body = SOURCE.slice(SOURCE.indexOf('{', start))
47
- const block = body.slice(0, body.indexOf('\n}') + 2)
48
- const out: string[] = []
49
- let depth = 0
50
- let token = ''
51
- for (const ch of block) {
52
- if (ch === '{') { depth++; token = ''; continue }
53
- if (ch === '}') { depth--; token = ''; continue }
54
- if (depth === 1 && /[A-Za-z0-9_?]/.test(ch)) { token += ch; continue }
55
- if (depth === 1 && ch === ':') { if (token) out.push(token.replace('?', '')); token = ''; continue }
56
- token = ''
57
- }
58
- return out
59
- }
60
-
61
- /** 경계에서 이름이 바뀌는 필드 — 바뀌는 이유는 커널 어휘를 따르기 때문이다(호스트 어휘를 밀어넣지 않는다). */
62
- const RENAMED: Record<string, string> = { homeLocationId: 'homeLocation' }
63
-
64
- /**
65
- * **다른 길로 가는 사실** — 모델의 그 자원 줄에는 없지만 잃지도 않는다. 길을 여기 적는다.
66
- * 적지 않고 넘기면 "원래 안 가는 것" 과 "새는 것" 이 같아 보인다.
67
- */
68
- const ELSEWHERE: Record<string, string> = {
69
- role: '자리인가 구역인가를 가르는 입력 — 모델의 locations 와 공간의 areas 로 갈라진다(값 자체는 나를 필요가 없다).',
70
- footprint: '좌표는 `model.layout`(중심점)과 구역 기하로 간다 — 자리 줄에 실리는 값이 아니다.',
71
- system: '이 렌즈의 자리인가 참조인가를 가르는 입력 — 다른 영역이면 `model.referencedLocations` 로 간다(ADR-0081 보탬, lens-own-places 시험).'
72
- }
73
-
74
- /** 모든 필드에 값을 실은 원본 — 값을 모르는 필드가 나오면 이 하네스는 실패한다(알리지 않고 건너뛰지 않는다). */
75
- const VALUE: Record<string, unknown> = {
76
- id: '__ID__',
77
- type: 'cut-station',
78
- kind: 'welder',
79
- name: '절단 스테이션',
80
- description: '강판을 자르는 자리',
81
- role: 'location',
82
- /* 픽스처 원본의 렌즈와 같은 영역 — 이 자리는 자기 자리로 선다(다른 영역이면 참조로 간다). */
83
- system: 'mes',
84
- parentId: 'zone-a',
85
- /* 전기 상류 — 공간 부모(`parentId`)와 다른 관계다. 값이 모델까지 가는지 이 하네스가 지킨다. */
86
- upstreamId: 'incoming-1',
87
- capacity: 40,
88
- parallelism: 2,
89
- level: 'WorkCenter',
90
- footprint: { x: 1, y: 2, w: 3, h: 4 },
91
- gs1Id: 'urn:epc:id:sgln:0614141.00001.0',
92
- /* 설비의 정체성 — **GS1 키가 아닌 것이 정상이다**(실측: 인버터 하드웨어 식별자). */
93
- identity: 'ES100000007d8d061d-1',
94
- /* 설비 등급 소속 — 2026-09-04 에 이 칸이 접수면에 없어서 원본이 채운 등급 22대가 문턱에서
95
- 버려졌다(인티그레이션 레인 실측). 사람·자산은 받는데 설비만 없었다. */
96
- equipmentClassIds: ['welding-robot'],
97
- homeLocationId: 'cut-station',
98
- mtbfMs: 600000,
99
- mttrMs: 60000,
100
- window: { startHour: 6, endHour: 22 },
101
- workCalendar: [{ id: 'day', entryType: 'production', startTime: '06:00', endTime: '22:00' }],
102
- properties: [{ id: 'speed', value: '1.2', uom: 'MTS' }],
103
- testSpecificationIds: ['weld-cert'],
104
- testResults: [{ specId: 'weld-cert', result: 'pass', expiresAt: '2099-01-01T00:00:00.000Z' }],
105
- effectiveStart: '2020-01-01T00:00:00.000Z',
106
- effectiveEnd: '2099-01-01T00:00:00.000Z',
107
- personnelClassIds: ['welder-op'],
108
- assetClassIds: ['euro-pallet']
109
- }
110
-
111
- interface Case {
112
- /** 선언 인터페이스 이름 */
113
- iface: string
114
- /** 모델의 배열 이름 */
115
- bucket: 'locations' | 'equipment' | 'persons' | 'assets'
116
- id: string
117
- }
118
-
119
- const CASES: Case[] = [
120
- { iface: 'RefLocation', bucket: 'locations', id: 'cut-station' },
121
- { iface: 'RefEquipment', bucket: 'equipment', id: 'cutter-1' },
122
- { iface: 'RefPerson', bucket: 'persons', id: 'cutter-op-1' },
123
- { iface: 'RefAsset', bucket: 'assets', id: 'pallet-1' }
124
- ]
125
-
126
- /** 그 인터페이스의 모든 필드에 값을 실은 항목. */
127
- function build(c: Case): any {
128
- const o: any = {}
129
- for (const f of fieldsOf(c.iface)) {
130
- assert.ok(
131
- f in VALUE,
132
- `픽스처가 "${c.iface}.${f}" 에 실을 값을 모른다 — VALUE 에 하나 적어라.\n` +
133
- '알리지 않고 건너뛰면 그 필드는 아무도 안 보는 필드가 되고, 그것이 이 하네스가 막으려는 실패다.'
134
- )
135
- o[f] = f === 'id' ? c.id : VALUE[f]
136
- }
137
- return o
138
- }
139
-
140
- function master(): any {
141
- return {
142
- source: 'decl-conformance',
143
- system: 'mes' as const,
144
- siteName: '선언 적합성 공장',
145
- space: { spaceId: 'decl-site', width: 100, depth: 60, unit: 'm' },
146
- locations: [build(CASES[0])],
147
- equipment: [build(CASES[1])],
148
- persons: [build(CASES[2])],
149
- assets: [build(CASES[3])]
150
- }
151
- }
152
-
153
- test('검사할 필드가 비어 있지 않다 — 비면 이 하네스는 아무것도 지키지 않는다', () => {
154
- for (const c of CASES) assert.ok(fieldsOf(c.iface).length > 2, `${c.iface}: 필드를 못 읽었다(파서가 낡았다)`)
155
- })
156
-
157
- for (const c of CASES) {
158
- test(`${c.iface} 의 사실이 하나도 잃지 않고 모델까지 간다`, () => {
159
- const src = build(c)
160
- const { model } = masterToTwin(master())
161
- const bucket = (model as any)[c.bucket]
162
- assert.ok(Array.isArray(bucket), `모델에 ${c.bucket} 이 없다`)
163
- const got = bucket.find((x: any) => x?.id === c.id)
164
- assert.ok(got, `선언한 ${c.iface} "${c.id}" 이 모델에 없다 — 사실 하나가 아니라 개체가 사라졌다`)
165
-
166
- const lost: string[] = []
167
- const mangled: string[] = []
168
- for (const f of Object.keys(src)) {
169
- if (f in ELSEWHERE) continue
170
- const key = RENAMED[f] ?? f
171
- if (got[key] === undefined) { lost.push(f); continue }
172
- try {
173
- assert.deepEqual(got[key], src[f])
174
- } catch {
175
- mangled.push(`${f}→${key}`)
176
- }
177
- }
178
- assert.deepEqual(
179
- { lost, mangled },
180
- { lost: [], mangled: [] },
181
- `${c.iface}: 잃은 사실=[${lost}] · 옮기다 값이 바뀐 사실=[${mangled}]\n` +
182
- '원본이 말한 것을 문에서 버리면 아무도 모른다 — 화면은 알리지 않고 id 를 보인다.\n' +
183
- '일부러 다른 길로 보내는 것이면 ELSEWHERE 에 그 길을 적어라(이름만 바뀌는 것은 RENAMED).'
184
- )
185
- })
186
- }
187
-
188
- /*
189
- * ── 공간의 시각 기준도 모델까지 간다 (2026-09-07) ────────────────────────────
190
- *
191
- * 위 검사는 **자원**의 필드만 본다. `space` 는 안 보고 있었고, 그래서 실제로 하나가 새고 있었다 —
192
- * `space.timezone` 이 오프셋으로만 풀려 모델에 실리고 **이름은 버려졌다.**
193
- *
194
- * 이름이 없으면 소비처가 순간마다 다시 풀 수 없다. 지난 구간을 교대별로 접을 때 그 구간 안의
195
- * 일광절약시간 전환이 사실을 한 시간 밀어 **다른 교대로** 세게 하고, 오류는 나지 않는다.
196
- * `America/Tijuana`(PST −480 / PDT −480 아닌 −420)가 이미 자료에 있다.
197
- *
198
- * 그리고 이 새는 자리를 잡은 것은 타입 검사도, 위 하네스도 아니라 **다른 레인의 물음**이었다
199
- * ("자료를 채운 뒤 이미 세워진 모델이 따라가나"). 그래서 여기 검사로 남긴다.
200
- */
201
- const withSpace = (space: Record<string, unknown>) => masterToTwin({ ...master(), space: { ...master().space, ...space } })
202
-
203
- test('공간의 시간대 이름이 모델까지 간다 — 오프셋만 실으면 계절이 바뀔 때 틀린다', () => {
204
- const { model } = withSpace({ timezone: 'America/Tijuana' })
205
-
206
- assert.equal((model as any).timezone, 'America/Tijuana', '이름이 모델에 없다 — 소비처가 순간마다 풀 수 없다')
207
- assert.equal(typeof (model as any).utcOffsetMinutes, 'number', '오프셋도 함께 실려야 한다 — 이름을 안 보는 소비처가 그 값으로 돈다')
208
- })
209
-
210
- test('시간대를 선언하지 않으면 두 칸 다 만들지 않는다 — 0 은 「UTC 라고 선언했다」는 주장이다', () => {
211
- const { model } = withSpace({})
212
-
213
- assert.equal((model as any).timezone, undefined)
214
- assert.equal((model as any).utcOffsetMinutes, undefined)
215
- })
216
-
217
- test('풀리지 않는 이름은 싣지 않고 경고로 말한다 — 실어 두면 소비처가 믿고 매번 실패한다', () => {
218
- const { model, warnings } = withSpace({ timezone: 'Mars/Olympus_Mons' })
219
-
220
- assert.equal((model as any).timezone, undefined)
221
- assert.equal((model as any).utcOffsetMinutes, undefined)
222
- assert.ok(
223
- (warnings ?? []).some((w: any) => JSON.stringify(w).includes('Mars/Olympus_Mons')),
224
- '모르는 시간대를 조용히 버리지 않는다'
225
- )
226
- })
@@ -1,89 +0,0 @@
1
- /*
2
- * ★ 자리 타입을 **누구에게 묻는가** — 원본이 선언했으면 그 선언이 정본이다.
3
- *
4
- * ── 무엇이 틀렸나 (2026-08-20) ──────────────────────────────────────────────
5
- * 호스트는 「이 자리 타입을 아는가」를 **내장 카탈로그**에게만 물었다(`DOMAIN_CATALOG[system]`).
6
- * 그런데 원본은 자기 `DomainDefinition.locationTypes` 를 함께 보낼 수 있고, 그러면 **그 선언이
7
- * 정본**이다 — 카탈로그는 우리가 아는 도메인들의 기본 어휘일 뿐이다.
8
- *
9
- * 상대가 틀렸으니 결과가 이랬다: 자기 어휘를 선언한 원본(예: F&B 라인 — 배합·가열·세척·금속검출·
10
- * 소분·포장)은 **정상적인 자리마다 경고를 하나씩** 받는다. 경고가 소음이 되면 사람은 그것을 읽지 않게
11
- * 되고, 그때 **진짜 경고도 함께 죽는다.**
12
- *
13
- * ── 지키는 것 ───────────────────────────────────────────────────────────────
14
- * ① 선언이 있으면 선언에 대조한다 ② 선언이 없으면 카탈로그로 떨어진다 ③ 선언을 **못 읽은 것**과
15
- * 「아무것도 선언하지 않은 것」을 가른다(못 읽었으면 카탈로그로 떨어진다 — 빈 목록으로 읽으면 모든
16
- * 자리가 경고를 받는다) ④ 아무 데도 없는 타입은 여전히 경고한다.
17
- */
18
- import { test } from 'node:test'
19
- import assert from 'node:assert/strict'
20
- import { createRequire } from 'node:module'
21
-
22
- const req = createRequire(import.meta.url)
23
- const { masterToTwin, declaredLocationTypes } = req('../dist-server/service/reference/reference-master.js')
24
-
25
- /** F&B 라인 — 내장 MES 카탈로그(트레일러 제조)에는 없는 어휘. */
26
- const FNB = ['mixing', 'cooking', 'washing', 'metal-detect', 'portioning', 'packing']
27
-
28
- const CATALOG = { mes: { locationTypes: ['raw-store', 'cut-station', 'fg-store'] } }
29
-
30
- const master = (types: string[], productionSpec?: unknown) => ({
31
- source: 'chef-1',
32
- system: 'mes',
33
- siteName: '식품 공장',
34
- /* `masterToTwin` 이 공간에서 spaceId 를 꺼낸다 — 최소 모양을 준다. */
35
- space: { spaceId: 'chef-site', width: 60, depth: 30, unit: 'm' },
36
- locations: types.map((t, i) => ({ id: `loc-${i}`, type: t, role: 'location' as const })),
37
- equipment: [],
38
- ...(productionSpec ? { productionSpec } : {})
39
- })
40
-
41
- const specWith = (keys: string[]) => ({ definition: { locationTypes: keys.map(k => ({ key: k, label: k })) } })
42
-
43
- const unknownWarnings = (r: any) => (r.warnings ?? []).filter((w: any) => w.code === 'unknown-location-type')
44
-
45
- test('원본이 선언했으면 그 선언에 대조한다 — 정상적인 자리에 경고를 주지 않는다', () => {
46
- const r = masterToTwin(master(FNB, specWith(FNB)), CATALOG)
47
-
48
- assert.deepEqual(unknownWarnings(r), [], 'F&B 여섯 자리 모두 선언돼 있다')
49
- })
50
-
51
- test('선언이 없으면 카탈로그로 떨어진다 — 예전 거동 그대로', () => {
52
- const r = masterToTwin(master(['raw-store', 'mixing']), CATALOG)
53
- const w = unknownWarnings(r)
54
-
55
- assert.equal(w.length, 1, '카탈로그에 없는 하나만')
56
- assert.equal(w[0].params.type, 'mixing')
57
- })
58
-
59
- test('선언에도 카탈로그에도 없으면 경고한다 — 진짜 경고는 죽이지 않는다', () => {
60
- const r = masterToTwin(master([...FNB, 'ghost-station'], specWith(FNB)), CATALOG)
61
- const w = unknownWarnings(r)
62
-
63
- assert.equal(w.length, 1)
64
- assert.equal(w[0].params.type, 'ghost-station')
65
- })
66
-
67
- test('선언을 못 읽으면 카탈로그로 떨어진다 — 빈 목록으로 읽지 않는다', () => {
68
- /*
69
- * 「없는 것」과 「못 읽은 것」은 다르다. 못 읽은 것을 빈 목록으로 읽으면 **모든 자리가 경고**를 받고,
70
- * 그것이 바로 이 시험이 막으려는 소음이다.
71
- */
72
- for (const broken of [{}, { definition: {} }, { definition: { locationTypes: [] } }, { definition: { locationTypes: 'nope' } }]) {
73
- assert.equal(declaredLocationTypes(broken), undefined, `못 읽은 모양: ${JSON.stringify(broken)}`)
74
- }
75
-
76
- const r = masterToTwin(master(['raw-store', 'mixing'], { definition: { locationTypes: [] } }), CATALOG)
77
- assert.equal(unknownWarnings(r).length, 1, '카탈로그 기준으로 하나만 경고한다')
78
- })
79
-
80
- test('선언 목록의 모양을 너그럽게 읽는다 — 문자열 목록도 받는다', () => {
81
- assert.deepEqual(declaredLocationTypes({ definition: { locationTypes: ['mixing', 'packing'] } }), ['mixing', 'packing'])
82
- assert.deepEqual(declaredLocationTypes({ definition: { locationTypes: [{ key: 'mixing' }, { nope: 1 }] } }), ['mixing'])
83
- })
84
-
85
- test('카탈로그도 선언도 없으면 아무 경고도 하지 않는다 — 모르는 것을 문제로 만들지 않는다', () => {
86
- const r = masterToTwin(master(FNB), undefined)
87
-
88
- assert.deepEqual(unknownWarnings(r), [], '견줄 상대가 없으면 판단하지 않는다')
89
- })
@@ -1,88 +0,0 @@
1
- /*
2
- * 자극은 **원본이 선언한다** — 그리고 재기동에도 살아 있다.
3
- *
4
- * ── 무엇이 났나 (2026-08-19) ────────────────────────────────────────────────
5
- * 데모의 시나리오는 시드 코드가 **메모리에만** 실었다(`runtime.scenario.load`). 그래서 트윈을 재기동하면
6
- * 자극이 사라지고 구조만 서 있는 트윈이 남았다 — 작업 0·오더 0. 「살아 있는 데모」가 첫 재기동까지만
7
- * 살았고, 오늘 서버를 여러 번 띄우는 동안 데모 트윈들이 실제로 그 상태였다.
8
- *
9
- * ── 집을 트윈이 아니라 원본으로 (ADR-0029 · plans/simulator-as-source.md §4) ─
10
- * 무엇이 들어오고 무슨 주문이 나는지는 **시뮬레이터(원본)가 정하는 사실**이고 트윈은 반영한다. 트윈에
11
- * 축을 만들면 ADR-0029 가 나중에 걷어내야 하고, 원본(`TwinReference.connectionConfig`)에 두면 그 계획의
12
- * 첫 조각(`openLiveFeed`)이 같은 선언을 그대로 읽는다.
13
- *
14
- * 이 시험이 지키는 것:
15
- * ① 선언이 없으면 알리지 않고 지난다(정적 구조만 반영하는 트윈이 정상이다).
16
- * ② **미러에는 싣지 않는다** — 외부 실물이 진실인 트윈에 도착을 지어 주면 그것은 현실이 아니다.
17
- * ③ 검사를 통과하지 못한 선언은 **태우지 않고** 이유를 남긴다(잘못된 선언 하나가 서버를 내린 이력이 있다).
18
- * ④ 검사기가 없으면 싣지 않는다 — 검사할 수 없는 선언을 태우는 것이 가장 비싼 선택이다.
19
- * ⑤ 선언을 얹을 때 **옆 설정을 지우지 않는다**(접속 정보가 같은 자리에 산다).
20
- */
21
- import { test } from 'node:test'
22
- import assert from 'node:assert/strict'
23
- import { readFileSync } from 'node:fs'
24
- import { fileURLToPath } from 'node:url'
25
-
26
- import { planStimulus, withStimulus } from '../server/engine/declared-stimulus.ts'
27
-
28
- const scenario = { seed: 1, generators: [{ kind: 'inbound-arrival', rate: { distribution: 'constant', meanPerHour: 60 }, content: {} }] }
29
- const ok = () => ({ ok: true as const })
30
- const bad = () => ({ ok: false as const, errorCode: 'scenario-sku-mix-required' })
31
- const sim = { hasScenarioEngine: true, mode: 'sim' as const }
32
-
33
- test('선언이 없으면 알리지 않고 지난다 — 구조만 반영하는 트윈이 정상이다', () => {
34
- assert.deepEqual(planStimulus(undefined, sim, ok), { action: 'skip', reason: 'none' })
35
- assert.deepEqual(planStimulus({ endpoint: 'x' }, sim, ok), { action: 'skip', reason: 'none' })
36
- /* 시나리오 자리에 객체가 아닌 것이 오면 선언이 아니다(문자열을 시나리오로 읽지 않는다). */
37
- assert.deepEqual(planStimulus({ scenario: 'daily' }, sim, ok), { action: 'skip', reason: 'none' })
38
- })
39
-
40
- test('관측으로 도는 트윈에는 싣지 않는다 — 현실을 지어내지 않는다', () => {
41
- const plan = planStimulus({ scenario }, { hasScenarioEngine: true, mode: 'live' }, ok)
42
- assert.deepEqual(plan, { action: 'skip', reason: 'observed' })
43
- })
44
-
45
- test('시나리오 엔진이 없으면 싣지 않는다 — 알리지 않고 아무 일도 없게 두지 않는다', () => {
46
- const plan = planStimulus({ scenario }, { hasScenarioEngine: false, mode: 'sim' }, ok)
47
- assert.deepEqual(plan, { action: 'skip', reason: 'no-engine' })
48
- })
49
-
50
- test('검사를 통과하지 못한 선언은 태우지 않는다 — 사유를 든다', () => {
51
- const plan = planStimulus({ scenario }, sim, bad)
52
- assert.deepEqual(plan, { action: 'skip', reason: 'invalid', detail: 'scenario-sku-mix-required' })
53
- })
54
-
55
- test('검사기가 없으면 싣지 않는다 — 검사할 수 없는 선언이 가장 위험하다', () => {
56
- const plan = planStimulus({ scenario }, sim, undefined)
57
- assert.equal(plan.action, 'skip')
58
- assert.equal((plan as any).reason, 'invalid')
59
- })
60
-
61
- test('통과한 선언은 그대로 싣는다 — 값을 손대지 않는다', () => {
62
- const plan = planStimulus({ scenario }, sim, ok)
63
- assert.deepEqual(plan, { action: 'load', scenario })
64
- })
65
-
66
- test('선언을 얹으면서 접속 정보를 지우지 않는다', () => {
67
- const merged = withStimulus({ endpoint: 'https://sim', token: 't' }, scenario)
68
- assert.deepEqual(merged, { endpoint: 'https://sim', token: 't', scenario })
69
- /* 설정이 없던 원본에도 얹힌다(빈 객체에서 시작). */
70
- assert.deepEqual(withStimulus(undefined, scenario), { scenario })
71
- })
72
-
73
- /*
74
- * ── 배선 (소스로 지킨다) ────────────────────────────────────────────────────
75
- * 판정은 순수 함수가 하지만, 그것을 **기동 때 부르지 않으면** 아무 일도 일어나지 않는다. 그리고 못 실은
76
- * 이유는 말해야 한다 — 「선언했는데 안 실렸다」를 말하지 않으면 사용자는 트윈이 고장 난 줄로 읽는다.
77
- */
78
- test('두 기동 경로에서 부른다 — 시뮬은 싣고, 미러는 그 사실을 말한다', () => {
79
- const src = readFileSync(fileURLToPath(new URL('../server/engine/twin-engine.ts', import.meta.url)), 'utf-8')
80
- const calls = src.match(/this\.installStimulus\(domainId, id, inst\)/g) ?? []
81
- assert.equal(calls.length, 2, `기동 경로 둘에서 불러야 한다(발견 ${calls.length})`)
82
- assert.match(src, /planStimulus\(config, \{ hasScenarioEngine/, '판정은 순수 함수에 맡긴다')
83
- assert.match(src, /validateScenario/, '커널 검사기를 그대로 쓴다(규칙을 두 벌로 만들지 않는다)')
84
- assert.match(src, /a stimulus is declared on its source but was not loaded/, '못 실은 이유를 말한다')
85
- /* 선언을 적는 문도 있어야 한다 — 읽기만 있으면 아무도 선언할 수 없다. */
86
- assert.match(src, /static async declareStimulus/)
87
- assert.match(src, /no source reference — a stimulus has nowhere to be declared/, '원본이 없으면 지어 만들지 않는다')
88
- })
@@ -1,112 +0,0 @@
1
- /*
2
- * 변환·담김의 정체가 **무엇이 무엇으로 되었나**로 갈리나.
3
- *
4
- * ── 왜 필요한가 (2026-09-07) ────────────────────────────────────────────────
5
- * 이 자리가 없어서 **사실 하나가 없어졌습니다.** 거절이 아니라 되풀이로 세어져서 경고도 없었습니다.
6
- *
7
- * ```
8
- * plant outbox seq 37 in LOT-CT-SIDE-001 24개 → out LOT-CT-MAIN-003 12개
9
- * plant outbox seq 42 in LOT-CT-SIDE-001 18개 → out LOT-CT-MAIN-004 9개
10
- * transformationID · bizStep · 초까지 전부 같다
11
- * 저널에 남은 것 LOT-CT-MAIN-003 하나
12
- * ```
13
- *
14
- * `LOT-CT-MAIN-004` 를 어느 패널로 만들었는지 트윈이 답하지 못했습니다. 인티그레이션 레인이
15
- * 원본과 저널의 건수를 맞춰 보다 찾았습니다 — 4건이 나갔고 3건이 앉았습니다.
16
- *
17
- * 아래 값은 그 두 봉투에서 온 것입니다. 지어낸 모양이 아닙니다.
18
- */
19
- import test from 'node:test'
20
- import assert from 'node:assert/strict'
21
-
22
- import { factIdentity } from '../server/engine/ingest-dedupe.js'
23
-
24
- const AT = '2026-09-05T05:00:00.000Z'
25
-
26
- const transformation = (inQty: number, outClass: string, outQty: number) => ({
27
- eventId: `evt-${outClass}-${outQty}`,
28
- eventType: 'epcis.TransformationEvent',
29
- eventTime: AT,
30
- data: {
31
- type: 'TransformationEvent',
32
- bizStep: 'urn:epcglobal:cbv:bizstep:commissioning',
33
- transformationID: 'WO-20260831-001',
34
- inputQuantityList: [{ epcClass: 'LOT-CT-SIDE-001', quantity: inQty }],
35
- outputQuantityList: [{ epcClass: outClass, quantity: outQty }]
36
- }
37
- })
38
-
39
- test('산출 로트가 다르면 다른 사실이다 — 이것이 실제로 없어진 자리다', () => {
40
- const a = factIdentity(transformation(24, 'LOT-CT-MAIN-003', 12))
41
- const b = factIdentity(transformation(18, 'LOT-CT-MAIN-004', 9))
42
-
43
- assert.ok(a, '정체를 만들지 못하면 dedupe 밖이다')
44
- assert.notEqual(a, b, '같은 오더·같은 공정·같은 초라도 산출이 다르면 다른 변환이다')
45
- })
46
-
47
- test('똑같은 봉투가 두 번 오면 한 사실이다 — 갈라 놓기만 하면 되풀이를 못 막는다', () => {
48
- assert.equal(
49
- factIdentity(transformation(24, 'LOT-CT-MAIN-003', 12)),
50
- factIdentity(transformation(24, 'LOT-CT-MAIN-003', 12))
51
- )
52
- })
53
-
54
- test('산출 이름이 같고 수량만 다르면 다른 사실이다 — 분할이 그 모양이다', () => {
55
- const a = factIdentity(transformation(24, 'LOT-CT-MAIN-003', 12))
56
- const b = factIdentity(transformation(24, 'LOT-CT-MAIN-003', 6))
57
-
58
- assert.notEqual(a, b)
59
- })
60
-
61
- test('입력 수량만 다르면 다른 사실이다 — 산출이 같아도 소비가 다르다', () => {
62
- const a = factIdentity(transformation(24, 'LOT-CT-MAIN-003', 12))
63
- const b = factIdentity(transformation(18, 'LOT-CT-MAIN-003', 12))
64
-
65
- assert.notEqual(a, b)
66
- })
67
-
68
- test('오더가 다르면 다른 사실이다 — 같은 공정을 두 오더로 같은 초에 돌릴 수 있다', () => {
69
- const withTx = (tx: string) => {
70
- const e = transformation(24, 'LOT-CT-MAIN-003', 12) as any
71
- e.data.bizTransactionList = [{ type: 'urn:epcglobal:cbv:btt:prodorder', bizTransaction: tx }]
72
- return factIdentity(e)
73
- }
74
-
75
- assert.notEqual(withTx('urn:x:bt:WO-A'), withTx('urn:x:bt:WO-B'))
76
- })
77
-
78
- test('담김의 자식이 다르면 다른 사실이다 — 한 종류만 고치면 나머지에 같은 결함이 남는다', () => {
79
- const aggregation = (child: string) => ({
80
- eventId: `agg-${child}`,
81
- eventType: 'epcis.AggregationEvent',
82
- eventTime: AT,
83
- data: {
84
- type: 'AggregationEvent',
85
- action: 'ADD',
86
- bizStep: 'urn:epcglobal:cbv:bizstep:packing',
87
- parentID: 'urn:epc:id:sscc:0614141.1234567890',
88
- childQuantityList: [{ epcClass: child, quantity: 10 }]
89
- }
90
- })
91
-
92
- assert.notEqual(factIdentity(aggregation('LOT-A')), factIdentity(aggregation('LOT-B')))
93
- })
94
-
95
- test('수량 목록 전체를 본다 — 첫 원소만 보면 뒤가 다른 둘이 뭉친다', () => {
96
- const twoLines = (second: string) => ({
97
- eventId: `evt-${second}`,
98
- eventType: 'epcis.TransformationEvent',
99
- eventTime: AT,
100
- data: {
101
- type: 'TransformationEvent',
102
- bizStep: 'urn:epcglobal:cbv:bizstep:commissioning',
103
- transformationID: 'WO-20260831-001',
104
- outputQuantityList: [
105
- { epcClass: 'LOT-SAME', quantity: 1 },
106
- { epcClass: second, quantity: 1 }
107
- ]
108
- }
109
- })
110
-
111
- assert.notEqual(factIdentity(twoLines('LOT-X')), factIdentity(twoLines('LOT-Y')))
112
- })
@@ -1,75 +0,0 @@
1
- /*
2
- * 사이트 발견 결과 — **"못 찾았다" 를 "없다" 로 말하지 않게.**
3
- *
4
- * 실 시스템을 연결해 트윈을 만드는 경로에서, 발견이 실패하면 화면이 "사이트를 찾지 못했습니다" 라고만
5
- * 말했다. 레퍼런스 미등록·어댑터 미상·조회 실패·정말 0건이 그 한 문장에 섞여 있었다 — 자격이
6
- * 틀렸는지 주소가 틀렸는지 알 수 없었다.
7
- */
8
- import { test } from 'node:test'
9
- import assert from 'node:assert/strict'
10
-
11
- import {
12
- discovered, failed, detailOf,
13
- referenceNotFound, adapterUnknown, discoveryFailed, discoveryTimedOut
14
- } from '../server/service/reference/discovery-result.ts'
15
-
16
- test('사이트가 없는 것은 실패가 아니다 — 사유 없는 빈 목록이 "없다" 를 뜻한다', () => {
17
- /* 권한이 좁거나 아직 등록되지 않아 공장이 하나도 없는 시스템은 있을 수 있다. 그것은 사실이므로
18
- 실패로 뭉개면 사용자가 있지도 않은 문제를 찾는다. */
19
- const r = discovered([])
20
- assert.deepEqual(r, { sites: [] })
21
- assert.equal(r.error, undefined, '사유가 없다 = 성공')
22
- })
23
-
24
- test('찾은 것을 그대로 돌려주되 입력을 붙들지 않는다', () => {
25
- const src = [{ siteId: 'PL1' }, { siteId: 'PL2' }]
26
- const r = discovered(src)
27
- assert.deepEqual(r.sites, src)
28
- src.push({ siteId: 'PL3' })
29
- assert.equal(r.sites.length, 2, '나중에 바뀐 원본이 결과를 바꾸지 않는다')
30
- })
31
-
32
- test('없는 목록·null 도 견딘다', () => {
33
- assert.deepEqual(discovered(null), { sites: [] })
34
- assert.deepEqual(discovered(undefined), { sites: [] })
35
- })
36
-
37
- test('실패는 사유와 함께, 사이트는 비워서 — 반쪽 목록을 성공처럼 보이지 않게', () => {
38
- const r = failed(referenceNotFound('sap-ewm-1710'))
39
- assert.deepEqual(r.sites, [])
40
- assert.equal(r.error?.code, 'reference-not-found')
41
- assert.equal(r.error?.params?.source, 'sap-ewm-1710')
42
- assert.match(r.error!.message, /not registered/, '영어 canonical 문장이 로그·폴백으로 남는다')
43
- })
44
-
45
- test('네 가지 사유가 서로 구별된다 — 이것이 이 작업의 요점이다', () => {
46
- const codes = [
47
- referenceNotFound('s').code,
48
- adapterUnknown('sap-ewm', 's').code,
49
- discoveryFailed('s', '401 Unauthorized').code,
50
- discoveryTimedOut('s', 15).code
51
- ]
52
- assert.deepEqual(codes, ['reference-not-found', 'adapter-unknown', 'discovery-failed', 'discovery-timeout'])
53
- assert.equal(new Set(codes).size, 4, '넷이 한 코드로 합쳐지지 않는다')
54
- })
55
-
56
- test('원 시스템이 준 사유를 감추지 않는다 — 사용자가 관리자에게 물어볼 수 있게', () => {
57
- const e = discoveryFailed('sap-ewm-1710', '401 Unauthorized')
58
- assert.equal(e.params?.detail, '401 Unauthorized')
59
- assert.match(e.message, /401 Unauthorized/)
60
- })
61
-
62
- test('타임아웃은 초 단위로 알린다 — 얼마를 기다렸는지 알 수 있게', () => {
63
- const e = discoveryTimedOut('s', 15)
64
- assert.equal(e.params?.seconds, 15)
65
- assert.match(e.message, /15s/)
66
- })
67
-
68
- test('어댑터가 낸 오류에서 사유를 뽑는다 — 형태를 가정하지 않는다', () => {
69
- assert.equal(detailOf(new Error('ECONNREFUSED')), 'ECONNREFUSED')
70
- assert.equal(detailOf('404 Not Found'), '404 Not Found')
71
- /* 무엇이 왔는지 모르면 그렇게 말한다 — 빈 문장으로 "이유 없음" 처럼 보이게 하지 않는다. */
72
- for (const weird of [undefined, null, {}, 0, new Error('')]) {
73
- assert.match(detailOf(weird), /without a message/, `이상한 입력: ${JSON.stringify(weird)}`)
74
- }
75
- })