@things-factory/headless-twin 10.1.278 → 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,178 +0,0 @@
1
- /*
2
- * ★ 여러 종류를 시각순으로 — 거르는 축과 정렬 축이 어긋나면 색인이 버려진다.
3
- *
4
- * ── 실측 (2026-08-28 · 승화푸드 저널 3,374,894행) ───────────────────────────
5
- * 종류 8개 IN + 시각순 50건 SEARCH USING INDEX ix_twin_event_1 (domain, instance) 37.181초 · 0건
6
- * 같은 조건 · 정렬 없음 SEARCH USING INDEX ix_twin_event_7 (…, event_type=?) 0.003초
7
- * 종류 하나 + 시각순 SEARCH USING INDEX ix_twin_event_7 (…, event_type=?) 0.003초
8
- *
9
- * 정렬을 붙이는 순간 여러 종류의 순서를 합칠 방법이 없어 시각 색인으로 337만 행을 걸으며 행마다 종류를
10
- * 확인한다. 그 트윈에 에너지 사건은 **0건**이다 — 없는 것을 찾느라 37초를 쓴다.
11
- *
12
- * 360 이력이 64초였던 것과 같은 부류다. 고침도 같은 성질이다: **있는 색인을 쓰게 한다.**
13
- */
14
- import { test } from 'node:test'
15
- import assert from 'node:assert/strict'
16
- import { readFileSync } from 'node:fs'
17
- import { join } from 'node:path'
18
-
19
- import { splitShape } from '../server/service/twin-journal/event-type-split-shape.js'
20
-
21
- const dir = (...p: string[]) => join(import.meta.dirname, '..', 'server', ...p)
22
- const split = readFileSync(dir('service', 'twin-journal', 'event-type-split.ts'), 'utf8')
23
- const shape = readFileSync(dir('service', 'twin-journal', 'event-type-split-shape.ts'), 'utf8')
24
- const journal = readFileSync(dir('service', 'twin-journal', 'twin-journal-query.ts'), 'utf8')
25
-
26
- const DESC = [{ name: 'eventTime', desc: true }]
27
- const ENERGY = ['energy.measured', 'energy.equipment', 'energy.demand.window', 'energy.peak']
28
-
29
- test('★ 에너지 원장이 보내는 모양이 이 갈래로 간다', () => {
30
- const shape = splitShape({ filters: [{ name: 'eventType', operator: 'in', value: ENERGY }] }, DESC)
31
- assert.ok(shape)
32
- assert.deepEqual(shape!.eventTypes, ENERGY)
33
- })
34
-
35
- test('시간창이 함께 와도 간다 — 화면이 구간을 지정한다', () => {
36
- const shape = splitShape(
37
- {
38
- filters: [
39
- { name: 'eventType', operator: 'in', value: ENERGY },
40
- { name: 'eventTime', operator: 'between', value: ['2026-08-01T00:00:00.000Z', '2026-08-02T00:00:00.000Z'] }
41
- ]
42
- },
43
- DESC
44
- )
45
- assert.ok(shape)
46
- assert.equal(shape!.fromTime?.toISOString(), '2026-08-01T00:00:00.000Z')
47
- assert.equal(shape!.untilTime?.toISOString(), '2026-08-02T00:00:00.000Z')
48
- })
49
-
50
- test('★ 맞지 않는 물음은 일반 경로로 보낸다 — 억지로 답하면 목록이 알리지 않고 달라진다', () => {
51
- const cases: [string, any, any[]][] = [
52
- ['종류가 하나', { filters: [{ name: 'eventType', operator: 'in', value: ['a'] }] }, DESC],
53
- ['종류가 너무 많다', { filters: [{ name: 'eventType', operator: 'in', value: Array.from({ length: 13 }, (_, i) => `t${i}`) }] }, DESC],
54
- ['종류 필터가 없다', { filters: [] }, DESC],
55
- ['정확일치', { filters: [{ name: 'eventType', operator: 'eq', value: 'a' }] }, DESC],
56
- ['제외 목록', { filters: [{ name: 'eventType', operator: 'notin_with_null', value: ENERGY }] }, DESC],
57
- ['자유 검색어', { search: '전력', filters: [{ name: 'eventType', operator: 'in', value: ENERGY }] }, DESC],
58
- ['다른 필터가 섞였다', { filters: [{ name: 'eventType', operator: 'in', value: ENERGY }, { name: 'epc', operator: 'search', value: 'x' }] }, DESC],
59
- ['리비전 정렬', { filters: [{ name: 'eventType', operator: 'in', value: ENERGY }] }, [{ name: 'revision', desc: true }]],
60
- ['오름차순', { filters: [{ name: 'eventType', operator: 'in', value: ENERGY }] }, [{ name: 'eventTime', desc: false }]],
61
- ['못 읽는 시각', { filters: [{ name: 'eventType', operator: 'in', value: ENERGY }, { name: 'eventTime', operator: 'lte', value: '어제' }] }, DESC]
62
- ]
63
- for (const [why, params, sortings] of cases) {
64
- assert.equal(splitShape(params, sortings), null, `${why} 는 일반 경로로 가야 한다`)
65
- }
66
- })
67
-
68
- test('★ 종류를 정확일치로 묻는다 — 이 한 줄이 색인을 쓰게 한다', () => {
69
- assert.match(split, /andWhere\('e\.eventType = :eventType', \{ eventType \}\)/)
70
- assert.doesNotMatch(split, /eventType IN/, '나눈 뒤에 다시 여러 값으로 묻지 않는다')
71
- /* 정렬 축이 색인의 마지막 칸과 같아야 한다. */
72
- assert.match(split, /orderBy\('e\.eventTime', 'DESC'\)/)
73
- })
74
-
75
- test('★ 한 갈래라도 못 읽으면 반쪽을 전부인 것처럼 내지 않는다', () => {
76
- assert.match(split, /if \(!page\) return null/)
77
- })
78
-
79
- test('★ 이어 읽기 지점을 모든 갈래에 같이 건다', () => {
80
- /* 갈래마다 다르게 걸면 어떤 종류는 이미 지나간 구간을 다시 낸다. */
81
- assert.match(split, /e\.eventTime < :curAt OR \(e\.eventTime = :curAt AND e\.\$\{tiebreak\} < :curTie\)/)
82
- assert.match(split, /if \(!cursor\) return null/, '못 읽는 커서로는 답하지 않는다')
83
- })
84
-
85
- test('★ 나눌 수를 제한한다 — 나누는 것이 손해가 되는 지점이 있다', () => {
86
- assert.match(shape, /export const MAX_SPLIT = 24/)
87
- assert.match(split, /if \(!pairs \|\| pairs > MAX_SPLIT\) return null/)
88
- })
89
-
90
- test('★ 화면이 부르는 자리에 붙어 있다', () => {
91
- assert.match(journal, /const split = splitShape\(effective, effective\.sortings \?\? \[\]\)/)
92
- assert.match(journal, /await eventTypeSplitPage\(domain\.id, instanceIds, split, limit, tiebreak, effective\.pagination\?\.after\)/)
93
- /* 파생 테이블 갈래보다 뒤, 일반 저널 질의보다 앞이어야 한다. */
94
- assert.ok(journal.indexOf('readModelPage(domain.id') < journal.indexOf('splitShape(effective'))
95
- assert.ok(journal.indexOf('splitShape(effective') < journal.indexOf('const qb = getQueryBuilderFromListParams'))
96
- })
97
-
98
- test('★ 걷을 조건이 적혀 있다 — 부르는 데가 없어지면 지운다', () => {
99
- /*
100
- * 앱에서 종류를 여러 값으로 보내는 곳은 에너지 원장 한 곳뿐이다. 그 화면이 종류를 하나씩 고르는
101
- * 모양으로 바뀌면 이 갈래는 아무도 부르지 않는다 — 그때 지워야 한다. 그 조건을 코드에 적어 두지
102
- * 않으면 아무것도 하지 않는 갈래가 무언가를 받쳐 주는 것처럼 남는다.
103
- */
104
- assert.match(split, /이 갈래를 걷을 조건/)
105
- assert.match(split, /그때 \*\*지운다\.\*\*/)
106
- })
107
-
108
- /* ── 공정 단계 칩 (2026-08-29) ─────────────────────────────────────────────
109
- *
110
- * ★ 칩을 고른 순간 이 갈래가 꺼져서, **고르지 않은 쪽이 더 빨랐다.**
111
- *
112
- * 원장은 종류 넷을 담아 묻고 그 위에 단계 칩을 겹친다. 앞 버전은 `bizStep` 필터를 만나면 모양을
113
- * 알아보지 못해 예전 경로로 떨어졌다 — 좁혀 물으면 느려지는 화면이 된다.
114
- */
115
-
116
- test('공정 단계 하나로 좁혀도 갈래 경로가 답한다', () => {
117
- const shape = splitShape(
118
- {
119
- filters: [
120
- { name: 'eventType', operator: 'in', value: ['epcis.ObjectEvent', 'epcis.AggregationEvent'] },
121
- { name: 'bizStep', operator: 'eq', value: 'shipping' }
122
- ]
123
- } as any,
124
- [{ name: 'eventTime', desc: true }] as any
125
- )
126
- assert.ok(shape, '이 모양을 알아봐야 한다')
127
- assert.equal(shape?.bizStep, 'shipping')
128
- assert.deepEqual(shape?.eventTypes, ['epcis.ObjectEvent', 'epcis.AggregationEvent'])
129
- })
130
-
131
- test('단계를 여러 값으로 주면 답하지 않는다 — 갈래가 곱해진다', () => {
132
- const shape = splitShape(
133
- {
134
- filters: [
135
- { name: 'eventType', operator: 'in', value: ['epcis.ObjectEvent', 'epcis.AggregationEvent'] },
136
- { name: 'bizStep', operator: 'in', value: ['shipping', 'receiving'] }
137
- ]
138
- } as any,
139
- [{ name: 'eventTime', desc: true }] as any
140
- )
141
- assert.equal(shape, null)
142
- })
143
-
144
- test('빈 단계 값은 받지 않는다 — 모든 행을 뜻하는지 없는 단계를 뜻하는지 알 수 없다', () => {
145
- const shape = splitShape(
146
- {
147
- filters: [
148
- { name: 'eventType', operator: 'in', value: ['epcis.ObjectEvent', 'epcis.AggregationEvent'] },
149
- { name: 'bizStep', operator: 'eq', value: ' ' }
150
- ]
151
- } as any,
152
- [{ name: 'eventTime', desc: true }] as any
153
- )
154
- assert.equal(shape, null)
155
- })
156
-
157
-
158
- /*
159
- * ── 목록과 건수가 같은 축을 본다 (2026-09-19) ───────────────────────────────
160
- *
161
- * 빠른 갈래는 건수를 **다른 빌더**로 센다. 그 빌더가 검색 축을 빈 배열로 선언하고 있었다 — 목록은
162
- * 걸러지고 건수는 안 걸러지는 모양이다(UX 레인이 검색 길을 세다 짚었다).
163
- *
164
- * **지금 그 일은 일어날 수 없다**: 검색어가 있으면 빠른 갈래를 아예 안 탄다(위 「자유 검색어」가 그
165
- * 축을 붙든다). 그래서 이것은 산 결함이 아니라 **잠긴 함정**이고, 두 자리가 같은 상수를 보게 해서
166
- * 닫는다 — 저 규칙이 언젠가 느슨해지면 그때 조용히 갈릴 자리다.
167
- */
168
- test('★ 건수 probe 와 목록이 같은 검색 축을 쓴다 — 한쪽만 걸러지면 화면이 「한 건 / 전체 수」를 말한다', () => {
169
- const uses = [...journal.matchAll(/searchables:\s*([^,\n]+)/g)].map(m => m[1].trim())
170
-
171
- assert.ok(uses.length >= 2, '검색 축을 선언하는 자리가 둘이어야 한다(목록 · 건수 probe)')
172
- assert.deepEqual(
173
- [...new Set(uses)],
174
- ['[...JOURNAL_SEARCHABLES]'],
175
- '두 자리가 같은 상수를 봐야 한다 — 배열을 따로 적으면 한쪽만 늘어난다'
176
- )
177
- assert.doesNotMatch(journal, /searchables:\s*\[\]/, '빈 목록은 「검색어를 조용히 버린다」는 뜻이다')
178
- })
@@ -1,177 +0,0 @@
1
- /*
2
- * ★ **밖을 가리키는 관계를 푸는 자리** — 선언은 있고 코드가 0곳이던 이음새.
3
- *
4
- * ── 무엇이 있었나 (2026-09-05 실측) ────────────────────────────────────────
5
- * 계약이 `target: { kind: 'external', entity: … }` 를 선언하고 주석에 「해소는 호스트가 한다」고
6
- * 적어 두었다. 그런데 `headless-twin/server` 어디에도 그것을 다루는 코드가 없었다(0곳).
7
- *
8
- * `space.area` 가 도는 것처럼 보인 이유는 이음새가 있어서가 아니라 **호스트에서 그것이 평범한 FK
9
- * 라서**다 — 선언이 길을 낸 것이 아니다.
10
- *
11
- * ── 왜 지금 채웠나 ─────────────────────────────────────────────────────────
12
- * 아침에는 「아무도 안 막혔으니 급하지 않다」로 적었고 **그 판단이 규모를 작게 잡은 것**이었다.
13
- *
14
- * 360 의 소비처는 무한히 늘어난다(사용자 방향). 그러면 각 제품의 자기 저장소가 관계의 원천이 된다.
15
- * 그때 선언은 「밖을 가리킨다」고 말하는데 푸는 길이 없으면 **제품마다 자기 길을 낸다** — 그것이
16
- * 정확히 「무한히 갈린다」다.
17
- */
18
- import { test } from 'node:test'
19
- import assert from 'node:assert/strict'
20
-
21
- import {
22
- clearExternalResolvers,
23
- externalIncoming,
24
- externalResolverEntities,
25
- registerExternalResolver,
26
- resolveExternal
27
- } from '../server/service/twin-model/external-resolver.js'
28
-
29
- const AREA = 'space.area'
30
-
31
- /*
32
- * 어느 트윈의 관계인지 — `resolve` 는 이것을 함께 받는다(2026-09-18). 밖의 id 는 도메인에서 유일하지
33
- * 않아서(구역 id 는 공간 안에서만 유일), 문맥 없이 답하면 남의 공간 이름이 이 자리의 부모로 보인다.
34
- */
35
- const CTX = { instanceId: 'probe-twin' }
36
-
37
- /* ── 못 풀면 못 푼다고 말한다 ────────────────────────────────────────────── */
38
-
39
- test('★ 꽂힌 것이 없으면 「해소기가 없다」고 말한다 — 「없다」가 아니다', async () => {
40
- /*
41
- * 링크를 지우면 화면은 「그런 관계가 없다」로 읽는다. 실제로는 「아무도 답할 수 없다」다.
42
- * 사람이 할 일이 다르다 — 앞은 자료를 채울 일이고 뒤는 해소기를 꽂을 일이다.
43
- */
44
- clearExternalResolvers()
45
- const got = await resolveExternal(AREA, 'd1', ['LINE-CAM'], CTX)
46
-
47
- assert.equal(got.unresolved, 'no-resolver')
48
- assert.equal(got.refs, undefined)
49
- })
50
-
51
- test('★ 해소기가 터져도 360 을 죽이지 않는다 — 알리고 못 풀었다고 한다', async () => {
52
- clearExternalResolvers()
53
- const said: string[] = []
54
- registerExternalResolver({ entity: AREA, resolve: async () => { throw new Error('DB down') } })
55
-
56
- const got = await resolveExternal(AREA, 'd1', ['X'], CTX, m => said.push(m))
57
-
58
- assert.equal(got.unresolved, 'failed')
59
- assert.ok(said.some(m => m.includes('DB down')), '사유를 삼켰다')
60
- })
61
-
62
- /* ── 풀면 무엇인지 말한다 ────────────────────────────────────────────────── */
63
-
64
- test('★ 이름과 갈 곳을 낸다 — 막다른 링크를 만들지 않으려고', async () => {
65
- clearExternalResolvers()
66
- registerExternalResolver({
67
- entity: AREA,
68
- resolve: async (_d, ids) => ids.map(id => ({ id, name: `라인 ${id}`, href: `/areas/${id}` }))
69
- })
70
-
71
- const got = await resolveExternal(AREA, 'd1', ['LINE-CAM'], CTX)
72
- assert.equal(got.refs?.[0].name, '라인 LINE-CAM')
73
- assert.equal(got.refs?.[0].href, '/areas/LINE-CAM')
74
- })
75
-
76
- test('★ 없는 id 는 없다고 말한다 — 답에서 빼지 않는다', async () => {
77
- /* 빼면 화면은 그 참조가 원래 없었던 것으로 읽는다. 실제로는 가리키는데 대상이 없는 것이다. */
78
- clearExternalResolvers()
79
- registerExternalResolver({ entity: AREA, resolve: async (_d, ids) => ids.map(id => ({ id, missing: true })) })
80
-
81
- const got = await resolveExternal(AREA, 'd1', ['사라진구역'], CTX)
82
- assert.equal(got.refs?.length, 1)
83
- assert.equal(got.refs?.[0].missing, true)
84
- })
85
-
86
- /* ── 들어오는 쪽 ─────────────────────────────────────────────────────────── */
87
-
88
- test('★ 제품이 자기 저장소의 관계를 싣는다 — 커널은 그 표를 모른다', async () => {
89
- clearExternalResolvers()
90
- registerExternalResolver({
91
- entity: 'mes.records',
92
- incoming: async () => [
93
- { via: 'mes.rel.report', from: 'productionReports', tense: 'past', ids: ['PR-1', 'PR-2'], total: 2 },
94
- { via: 'mes.rel.maintenance', from: 'maintenancePlans', tense: 'future', ids: ['MP-1'], total: 1 }
95
- ]
96
- })
97
-
98
- const got = await externalIncoming('d1', 'mes-miratek', 'equipment', 'EQ-CT-MWELD-01')
99
-
100
- assert.equal(got.length, 2)
101
- assert.deepEqual(got.map(g => g.tense).sort(), ['future', 'past'], '시간축이 안 실렸다')
102
- })
103
-
104
- test('★ 시간축이 실린다 — 「걸린 것이 열」이 두 뜻이 되는 자리', async () => {
105
- /*
106
- * 지난 일 아홉 · 앞으로 올 일 하나와 그 반대는 「이 설비를 세워도 되나」의 답이 정반대다.
107
- * 묶음이 스스로 말해야 화면이 가를 수 있다.
108
- */
109
- clearExternalResolvers()
110
- registerExternalResolver({
111
- entity: 'mes.records',
112
- incoming: async () => [{ via: 'mes.rel.report', from: 'x', tense: 'past', ids: ['a'], total: 9 }]
113
- })
114
-
115
- const got = await externalIncoming('d1', 'i', 'equipment', 'E-1')
116
- assert.equal(got[0].tense, 'past')
117
- assert.equal(got[0].total, 9, '전체 수를 안 말한다 — 잘린 목록만으로는 규모를 모른다')
118
- })
119
-
120
- test('빈 묶음은 싣지 않는다 — 그 제품이 이 축을 안 보는 것이고 할 말이 없다', async () => {
121
- clearExternalResolvers()
122
- registerExternalResolver({
123
- entity: 'mes.records',
124
- incoming: async () => [{ via: 'x', from: 'y', ids: [], total: 0 }]
125
- })
126
- assert.deepEqual(await externalIncoming('d1', 'i', 'equipment', 'E-1'), [])
127
- })
128
-
129
- test('★ 한 제품이 터져도 나머지는 실린다', async () => {
130
- clearExternalResolvers()
131
- const said: string[] = []
132
- registerExternalResolver({ entity: 'broken', incoming: async () => { throw new Error('boom') } })
133
- registerExternalResolver({
134
- entity: 'ok',
135
- incoming: async () => [{ via: 'v', from: 'f', ids: ['a'], total: 1 }]
136
- })
137
-
138
- const got = await externalIncoming('d1', 'i', 'equipment', 'E-1', m => said.push(m))
139
- assert.equal(got.length, 1, '하나가 터져서 나머지도 안 실렸다')
140
- assert.ok(said.some(m => m.includes('boom')))
141
- })
142
-
143
- /* ── 꽂는 규율 ───────────────────────────────────────────────────────────── */
144
-
145
- test('★ 같은 대상을 두 제품이 답하려 하면 알린다 — 조용히 덮지 않는다', async () => {
146
- clearExternalResolvers()
147
- const said: string[] = []
148
- registerExternalResolver({ entity: AREA, resolve: async () => [] })
149
- registerExternalResolver({ entity: AREA, resolve: async () => [] }, m => said.push(m))
150
-
151
- assert.ok(said.some(m => m.includes(AREA)), '덮어쓴 것을 안 알렸다')
152
- })
153
-
154
- test('entity 없는 해소기는 안 꽂는다 — 아무 관계에도 안 붙는다', async () => {
155
- clearExternalResolvers()
156
- const said: string[] = []
157
- registerExternalResolver({ entity: ' ' } as any, m => said.push(m))
158
-
159
- assert.deepEqual(externalResolverEntities(), [])
160
- assert.ok(said.length, '조용히 넘겼다')
161
- })
162
-
163
- test('★ 무엇을 풀 수 있나를 밖에서 잴 수 있다 — 「모른다」와 「없다」를 가르려고', async () => {
164
- clearExternalResolvers()
165
- registerExternalResolver({ entity: 'b', resolve: async () => [] })
166
- registerExternalResolver({ entity: 'a', resolve: async () => [] })
167
-
168
- assert.deepEqual(externalResolverEntities(), ['a', 'b'])
169
- })
170
-
171
- test('★ 이 검사가 실제로 무언가를 잰다 — 견준 것이 0이면 빨강', async () => {
172
- clearExternalResolvers()
173
- assert.deepEqual(externalResolverEntities(), [], '지우기가 안 듣는다')
174
- registerExternalResolver({ entity: AREA, resolve: async (_d, ids) => ids.map(id => ({ id })) })
175
- const got = await resolveExternal(AREA, 'd', ['X'], CTX)
176
- assert.equal(got.refs?.length, 1, '꽂았는데 안 불린다')
177
- })
@@ -1,96 +0,0 @@
1
- /*
2
- * 마감된 구간 사실의 **범위 배선** — 유입을 부르는 곳은 모두 어느 트윈인지 말해야 한다.
3
- *
4
- * ── 왜 이 시험이 있나 (2026-08-30) ────────────────────────────────────────
5
- * 커널은 `new Kernel(domainId, …)` 으로 서므로 자기가 어느 트윈인지 모른다. 설비 번호·계량 지점 번호는
6
- * 트윈 안에서만 통하는 이름표라, 범위를 넘기지 않으면 **서로 다른 설비의 같은 날이 한 사실**이 된다.
7
- * 실측으로 그 일이 났다 — 두 발전소의 `002` 가 겹쳐, 저널에 6줄이 있는데 서로 다른 이름은 5개였다.
8
- * 여러 현장을 함께 계산하는 성과 화면은 이름으로 중복을 걷어내므로 한쪽 발전량이 사라진다.
9
- *
10
- * 배선은 조용히 빠진다. 인자를 안 넘겨도 컴파일되고, 시험도 초록이고, 실 서버에서 값이 하나 사라질
11
- * 뿐이다. 그래서 **부르는 자리를 세어서** 지킨다 — `ingest-wiring-guard` 와 같은 부류다.
12
- */
13
- import { test } from 'node:test'
14
- import assert from 'node:assert/strict'
15
- import { readFileSync, readdirSync, statSync } from 'node:fs'
16
- import { fileURLToPath } from 'node:url'
17
- import { dirname, join } from 'node:path'
18
-
19
- import { resolveSubject, ingestEnergyGenerationPeriodRecords } from '@operato/ops-contract'
20
-
21
- const here = dirname(fileURLToPath(import.meta.url))
22
- const serverDir = join(here, '..', 'server')
23
-
24
- function allTs(dir: string, out: string[] = []): string[] {
25
- for (const name of readdirSync(dir)) {
26
- const full = join(dir, name)
27
- if (statSync(full).isDirectory()) allTs(full, out)
28
- else if (name.endsWith('.ts')) out.push(full)
29
- }
30
- return out
31
- }
32
-
33
- /**
34
- * 주석을 걷어낸다 — **설명에 적힌 이름을 호출로 세지 않는다.**
35
- *
36
- * 처음 이 시험을 만들었을 때 `reference-live.ts` 의 흐름 설명 한 줄(`ingestCanonicalRecords(정규→봉투)`)을
37
- * 배선 빠진 호출로 잡았다. 주석을 고치게 만드는 시험은 아무것도 지키지 않는다.
38
- */
39
- function withoutComments(src: string): string {
40
- return src.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:])\/\/[^\n]*/g, '$1')
41
- }
42
-
43
- test('★ 유입을 부르는 곳은 모두 어느 트윈인지 말한다 — 안 말하면 두 현장의 같은 번호가 겹친다', () => {
44
- const bad: string[] = []
45
- for (const file of allTs(serverDir)) {
46
- if (file.endsWith('canonical-ingest.ts')) continue // 정의하는 자리
47
- const src = withoutComments(readFileSync(file, 'utf-8'))
48
- let i = src.indexOf('ingestCanonicalRecords(')
49
- while (i >= 0) {
50
- /* 호출 하나를 괄호 균형으로 잘라 낸다 — 줄바꿈이 있어도 본다. */
51
- let depth = 0
52
- let j = i + 'ingestCanonicalRecords'.length
53
- for (; j < src.length; j++) {
54
- if (src[j] === '(') depth++
55
- else if (src[j] === ')') {
56
- depth--
57
- if (depth === 0) break
58
- }
59
- }
60
- const call = src.slice(i, j + 1)
61
- if (!call.includes('factScope')) {
62
- bad.push(`${file.slice(serverDir.length + 1)}: ${call.replace(/\s+/g, ' ').slice(0, 90)}`)
63
- }
64
- i = src.indexOf('ingestCanonicalRecords(', j)
65
- }
66
- }
67
- assert.deepEqual(
68
- bad,
69
- [],
70
- `범위를 넘기지 않는 유입 호출:\n${bad.join('\n')}\n` +
71
- 'TwinEngine.factScope(domainId, instanceId) 를 넷째 인자로 넘겨라 — ' +
72
- '넘기지 않으면 다른 현장의 같은 설비 번호가 한 사실로 겹치고, 성과 화면에서 한쪽이 사라진다.'
73
- )
74
- })
75
-
76
- test('★ 범위를 넘기면 두 현장의 같은 번호가 다른 사실이다', () => {
77
- const rec = { equipmentId: '002', from: '2026-08-28T15:00:00.000Z', to: '2026-08-29T15:00:00.000Z', kWh: 400.6 }
78
- const a = ingestEnergyGenerationPeriodRecords(rec, { tenantId: 'd', scopeId: 'twin-a' }).accepted[0]
79
- const b = ingestEnergyGenerationPeriodRecords(rec, { tenantId: 'd', scopeId: 'twin-b' }).accepted[0]
80
- assert.notEqual(a.eventId, b.eventId)
81
- })
82
-
83
- test('선언된 정체성이 있으면 범위와 무관하게 한 사실이다 — 그릇이 정체성을 정하지 않는다', () => {
84
- const rec = { equipmentId: '002', from: '2026-08-28T15:00:00.000Z', to: '2026-08-29T15:00:00.000Z', kWh: 400.6 }
85
- const identityOf = () => 'https://example.com/obj/inv-002'
86
- const a = ingestEnergyGenerationPeriodRecords(rec, { tenantId: 'd', scopeId: 'twin-a', identityOf }).accepted[0]
87
- const b = ingestEnergyGenerationPeriodRecords(rec, { tenantId: 'd', scopeId: 'twin-b', identityOf }).accepted[0]
88
- assert.equal(a.eventId, b.eventId)
89
- assert.equal((a.data as any).subjectBasis, 'declared')
90
- })
91
-
92
- test('커널이 범위를 답할 자리가 있다 — 호스트가 그것을 넘긴다', () => {
93
- const r = resolveSubject('equipment', '002', { tenantId: 'd', scopeId: 'ppms-호현' })
94
- assert.equal(r.basis, 'twin-local')
95
- assert.equal(r.subject, 'ppms-호현/002')
96
- })
@@ -1,59 +0,0 @@
1
- /*
2
- * backfill 이 이미 있는 사실을 다시 앉히지 않게 하는 부분.
3
- *
4
- * ── 무엇이 있었나 (2026-09-06 측정) ─────────────────────────────────────────
5
- * 중복 판정 기억은 프로세스 안에만 있다. 재기동하면 비워지고, 그 뒤 backfill 을 돌리면 이미 저널에
6
- * 있는 사실도 「처음 본 것」이 된다.
7
- *
8
- * ```
9
- * mes-line-a 를 재기동 뒤 backfill
10
- * 저널 44 → 83건 · 서로 다른 것 39가지 · 중복 44가지
11
- * 같은 프로세스에서 다시 돌리면 applied 0 (기억이 살아 있어서)
12
- * ```
13
- *
14
- * 저널 조회는 DB 를 물어야 해서 여기서 다루지 않는다. 확인하는 것은 **어느 구간을 읽을지 정하는
15
- * 판정**이다 — 그것이 틀리면 조회가 엉뚱한 곳을 보고 기억이 안 찬다.
16
- */
17
- import { test } from 'node:test'
18
- import assert from 'node:assert/strict'
19
-
20
- import { spanOf } from '../server/service/reference/fill-span.js'
21
-
22
- const at = (s: string) => ({ subjectId: 'L', decision: 'scrap', at: s })
23
-
24
- test('★ 레코드가 덮는 구간을 정한다', () => {
25
- const span = spanOf([at('2026-09-01T00:00:00.000Z'), at('2026-09-03T12:00:00.000Z'), at('2026-09-02T00:00:00.000Z')])
26
- assert.ok(span)
27
- assert.equal(span!.from.toISOString(), '2026-08-31T23:59:59.000Z')
28
- assert.equal(span!.to.toISOString(), '2026-09-03T12:00:01.000Z')
29
- })
30
-
31
- test('★ 양쪽을 1초씩 넓힌다 — 좁게 읽으면 경계의 사실이 다시 앉는다', () => {
32
- /*
33
- * 저장된 시각은 밀리초까지 있고 경계에서 같은 값이 갈릴 수 있다. 넓게 읽는 것은 기억이 조금 더
34
- * 차는 것뿐이라 손해가 없다.
35
- */
36
- const one = '2026-09-01T00:00:00.000Z'
37
- const span = spanOf([at(one)])!
38
- assert.equal(span.to.getTime() - span.from.getTime(), 2000)
39
- })
40
-
41
- test('★ 하나도 시각을 안 말하면 구간이 없다 — 저널 전체를 읽지 않는다', () => {
42
- /*
43
- * 구간을 못 정하면 채우지 않는다. 저널 전체를 읽는 쪽으로 넓히면 2백만 줄을 훑게 되고, 그것이
44
- * 필요한 상황이면 조회가 아니라 정체 색인으로 풀어야 한다.
45
- */
46
- assert.equal(spanOf([{ subjectId: 'L', decision: 'scrap' }]), undefined)
47
- assert.equal(spanOf([]), undefined)
48
- })
49
-
50
- test('시각을 말하는 것과 안 말하는 것이 섞이면 말하는 것으로 정한다', () => {
51
- const span = spanOf([{ subjectId: 'A' }, at('2026-09-01T00:00:00.000Z'), { subjectId: 'B' }])
52
- assert.ok(span, '한 줄이라도 말하면 구간이 있다')
53
- })
54
-
55
- test('★ 이 테스트가 실제로 무언가를 잰다 — 견준 것이 0이면 빨강', () => {
56
- const narrow = spanOf([at('2026-09-01T00:00:00.000Z')])!
57
- const wide = spanOf([at('2026-09-01T00:00:00.000Z'), at('2026-09-10T00:00:00.000Z')])!
58
- assert.ok(wide.to.getTime() > narrow.to.getTime(), '구간이 레코드를 안 따라간다')
59
- })
@@ -1,35 +0,0 @@
1
- /*
2
- * 빠진 구간을 **언제** 다시 받나 — 세 자리의 규율.
3
- *
4
- * ```
5
- * 1 재기동 직후 한 번 우리가 내려가 있는 동안 그쪽이 보낸 것
6
- * 2 구멍을 본 그 자리 번호가 비었다는 것을 아는 가장 이른 순간
7
- * 3 10분 그물 위 둘이 다 놓치는 경우
8
- * ```
9
- *
10
- * 여기서 확인하는 것은 **두 번 부르지 않는 규율**이다. 밀어 받는 쪽이 구멍 뒤의 봉투를 계속 보내면
11
- * 그때마다 구멍 판정이 나고, 막지 않으면 봉투마다 backfill 이 돈다.
12
- *
13
- * 실제 조회는 DB 와 어댑터를 물어야 해서 여기서 다루지 않는다.
14
- */
15
- import { test } from 'node:test'
16
- import assert from 'node:assert/strict'
17
-
18
- import { FILL_DEBOUNCE_MS, FILL_PERIOD_MS } from '../server/service/reference/fill-cadence.js'
19
-
20
- test('★ 그물은 10분이다 — 30초가 아니다', () => {
21
- /*
22
- * 인티그레이션 레인이 측정으로 준 권고다. backfill 은 원본에 조회를 걸고 저널을 읽는다.
23
- * 30초마다 돌면 얻는 것 없이 두 쪽을 계속 친다 — 놓친 구간은 10분 뒤에 받아도 사실이 달라지지 않는다.
24
- *
25
- * 규칙 주기(30초)에 얹지 않은 이유이기도 하다. 얹으면 간격이 그쪽에 묶이고, 나중에 규칙 주기를
26
- * 바꾸면 이쪽이 소리 없이 따라간다.
27
- */
28
- assert.equal(FILL_PERIOD_MS, 10 * 60_000)
29
- assert.notEqual(FILL_PERIOD_MS, 30_000, '규칙 주기와 같아졌다 — 그러면 하나를 바꿀 때 둘이 움직인다')
30
- })
31
-
32
- test('★ 같은 단위를 1분 안에 두 번 안 받는다 — 봉투마다 돌면 안 된다', () => {
33
- assert.equal(FILL_DEBOUNCE_MS, 60_000)
34
- assert.ok(FILL_DEBOUNCE_MS < FILL_PERIOD_MS, '막는 간격이 그물보다 길면 그물이 헛돈다')
35
- })