@things-factory/headless-twin 10.0.18 โ†’ 10.1.0

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 (331) hide show
  1. package/dist-server/engine/canonical-ingest.d.ts +10 -1
  2. package/dist-server/engine/canonical-ingest.js +110 -33
  3. package/dist-server/engine/canonical-ingest.js.map +1 -1
  4. package/dist-server/engine/event-time.d.ts +25 -0
  5. package/dist-server/engine/event-time.js +98 -0
  6. package/dist-server/engine/event-time.js.map +1 -0
  7. package/dist-server/engine/index.d.ts +2 -0
  8. package/dist-server/engine/index.js +23 -0
  9. package/dist-server/engine/index.js.map +1 -1
  10. package/dist-server/engine/ingest-dedupe.d.ts +18 -6
  11. package/dist-server/engine/ingest-dedupe.js +201 -15
  12. package/dist-server/engine/ingest-dedupe.js.map +1 -1
  13. package/dist-server/engine/ingest-health.d.ts +60 -1
  14. package/dist-server/engine/ingest-health.js +43 -8
  15. package/dist-server/engine/ingest-health.js.map +1 -1
  16. package/dist-server/engine/kpi-fold.d.ts +19 -0
  17. package/dist-server/engine/kpi-fold.js +4 -1
  18. package/dist-server/engine/kpi-fold.js.map +1 -1
  19. package/dist-server/engine/kpi-query.js +23 -3
  20. package/dist-server/engine/kpi-query.js.map +1 -1
  21. package/dist-server/engine/oee-accumulator.d.ts +35 -2
  22. package/dist-server/engine/oee-accumulator.js +56 -4
  23. package/dist-server/engine/oee-accumulator.js.map +1 -1
  24. package/dist-server/engine/twin-engine.d.ts +72 -3
  25. package/dist-server/engine/twin-engine.js +118 -5
  26. package/dist-server/engine/twin-engine.js.map +1 -1
  27. package/dist-server/index.js +21 -0
  28. package/dist-server/index.js.map +1 -1
  29. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.d.ts +5 -0
  30. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js +66 -0
  31. package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js.map +1 -0
  32. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.d.ts +5 -0
  33. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js +79 -0
  34. package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js.map +1 -0
  35. package/dist-server/migrations/index.js +5 -1
  36. package/dist-server/migrations/index.js.map +1 -1
  37. package/dist-server/routes.js +19 -16
  38. package/dist-server/routes.js.map +1 -1
  39. package/dist-server/service/actuation/actuation-advisor.d.ts +60 -0
  40. package/dist-server/service/actuation/actuation-advisor.js +53 -0
  41. package/dist-server/service/actuation/actuation-advisor.js.map +1 -0
  42. package/dist-server/service/actuation/actuation-outcome.d.ts +52 -0
  43. package/dist-server/service/actuation/actuation-outcome.js +34 -0
  44. package/dist-server/service/actuation/actuation-outcome.js.map +1 -0
  45. package/dist-server/service/actuation/actuation-rule-resolver.d.ts +19 -0
  46. package/dist-server/service/actuation/actuation-rule-resolver.js +161 -0
  47. package/dist-server/service/actuation/actuation-rule-resolver.js.map +1 -0
  48. package/dist-server/service/actuation/actuation-rule.d.ts +55 -0
  49. package/dist-server/service/actuation/actuation-rule.js +130 -0
  50. package/dist-server/service/actuation/actuation-rule.js.map +1 -0
  51. package/dist-server/service/actuation/approval-gateway.d.ts +20 -0
  52. package/dist-server/service/actuation/approval-gateway.js +14 -0
  53. package/dist-server/service/actuation/approval-gateway.js.map +1 -0
  54. package/dist-server/service/actuation/catch-up-effects.d.ts +16 -0
  55. package/dist-server/service/actuation/catch-up-effects.js +120 -0
  56. package/dist-server/service/actuation/catch-up-effects.js.map +1 -0
  57. package/dist-server/service/actuation/command-dispatcher.d.ts +230 -0
  58. package/dist-server/service/actuation/command-dispatcher.js +269 -0
  59. package/dist-server/service/actuation/command-dispatcher.js.map +1 -0
  60. package/dist-server/service/actuation/command-store.d.ts +11 -0
  61. package/dist-server/service/actuation/command-store.js +219 -0
  62. package/dist-server/service/actuation/command-store.js.map +1 -0
  63. package/dist-server/service/actuation/dispatch-after-approval.d.ts +11 -0
  64. package/dist-server/service/actuation/dispatch-after-approval.js +73 -0
  65. package/dist-server/service/actuation/dispatch-after-approval.js.map +1 -0
  66. package/dist-server/service/actuation/effect-match.d.ts +53 -0
  67. package/dist-server/service/actuation/effect-match.js +65 -0
  68. package/dist-server/service/actuation/effect-match.js.map +1 -0
  69. package/dist-server/service/actuation/index.d.ts +25 -0
  70. package/dist-server/service/actuation/index.js +30 -0
  71. package/dist-server/service/actuation/index.js.map +1 -0
  72. package/dist-server/service/actuation/retry-plan.d.ts +63 -0
  73. package/dist-server/service/actuation/retry-plan.js +99 -0
  74. package/dist-server/service/actuation/retry-plan.js.map +1 -0
  75. package/dist-server/service/actuation/rule-evaluate.d.ts +127 -0
  76. package/dist-server/service/actuation/rule-evaluate.js +205 -0
  77. package/dist-server/service/actuation/rule-evaluate.js.map +1 -0
  78. package/dist-server/service/actuation/rule-loop.d.ts +5 -0
  79. package/dist-server/service/actuation/rule-loop.js +156 -0
  80. package/dist-server/service/actuation/rule-loop.js.map +1 -0
  81. package/dist-server/service/actuation/rule-runner.d.ts +52 -0
  82. package/dist-server/service/actuation/rule-runner.js +135 -0
  83. package/dist-server/service/actuation/rule-runner.js.map +1 -0
  84. package/dist-server/service/actuation/rule-wiring.d.ts +24 -0
  85. package/dist-server/service/actuation/rule-wiring.js +80 -0
  86. package/dist-server/service/actuation/rule-wiring.js.map +1 -0
  87. package/dist-server/service/actuation/settle-effects.d.ts +21 -0
  88. package/dist-server/service/actuation/settle-effects.js +101 -0
  89. package/dist-server/service/actuation/settle-effects.js.map +1 -0
  90. package/dist-server/service/actuation/sweep-dispatch.d.ts +37 -0
  91. package/dist-server/service/actuation/sweep-dispatch.js +125 -0
  92. package/dist-server/service/actuation/sweep-dispatch.js.map +1 -0
  93. package/dist-server/service/actuation/twin-command-resolver.d.ts +120 -0
  94. package/dist-server/service/actuation/twin-command-resolver.js +406 -0
  95. package/dist-server/service/actuation/twin-command-resolver.js.map +1 -0
  96. package/dist-server/service/actuation/twin-command.d.ts +111 -0
  97. package/dist-server/service/actuation/twin-command.js +170 -0
  98. package/dist-server/service/actuation/twin-command.js.map +1 -0
  99. package/dist-server/service/actuation/twin-now.d.ts +41 -0
  100. package/dist-server/service/actuation/twin-now.js +65 -0
  101. package/dist-server/service/actuation/twin-now.js.map +1 -0
  102. package/dist-server/service/index.d.ts +5 -2
  103. package/dist-server/service/index.js +28 -17
  104. package/dist-server/service/index.js.map +1 -1
  105. package/dist-server/service/reference/actuation-routing.d.ts +60 -0
  106. package/dist-server/service/reference/actuation-routing.js +126 -0
  107. package/dist-server/service/reference/actuation-routing.js.map +1 -0
  108. package/dist-server/service/reference/actuation-target.d.ts +65 -0
  109. package/dist-server/service/reference/actuation-target.js +94 -0
  110. package/dist-server/service/reference/actuation-target.js.map +1 -0
  111. package/dist-server/service/reference/connection-portability-resolver.d.ts +29 -0
  112. package/dist-server/service/reference/connection-portability-resolver.js +181 -0
  113. package/dist-server/service/reference/connection-portability-resolver.js.map +1 -0
  114. package/dist-server/service/reference/connection-portability.d.ts +138 -0
  115. package/dist-server/service/reference/connection-portability.js +230 -0
  116. package/dist-server/service/reference/connection-portability.js.map +1 -0
  117. package/dist-server/service/reference/fill-cadence.d.ts +17 -0
  118. package/dist-server/service/reference/fill-cadence.js +31 -0
  119. package/dist-server/service/reference/fill-cadence.js.map +1 -0
  120. package/dist-server/service/reference/fill-dedupe.d.ts +16 -0
  121. package/dist-server/service/reference/fill-dedupe.js +63 -0
  122. package/dist-server/service/reference/fill-dedupe.js.map +1 -0
  123. package/dist-server/service/reference/fill-loop.d.ts +35 -0
  124. package/dist-server/service/reference/fill-loop.js +187 -0
  125. package/dist-server/service/reference/fill-loop.js.map +1 -0
  126. package/dist-server/service/reference/fill-span.d.ts +10 -0
  127. package/dist-server/service/reference/fill-span.js +37 -0
  128. package/dist-server/service/reference/fill-span.js.map +1 -0
  129. package/dist-server/service/reference/hook-contract.d.ts +149 -22
  130. package/dist-server/service/reference/hook-contract.js +236 -23
  131. package/dist-server/service/reference/hook-contract.js.map +1 -1
  132. package/dist-server/service/reference/hook-rejected.d.ts +25 -0
  133. package/dist-server/service/reference/hook-rejected.js +48 -0
  134. package/dist-server/service/reference/hook-rejected.js.map +1 -0
  135. package/dist-server/service/reference/hook-store.d.ts +3 -0
  136. package/dist-server/service/reference/hook-store.js +28 -0
  137. package/dist-server/service/reference/hook-store.js.map +1 -0
  138. package/dist-server/service/reference/index.d.ts +4 -1
  139. package/dist-server/service/reference/index.js +5 -1
  140. package/dist-server/service/reference/index.js.map +1 -1
  141. package/dist-server/service/reference/live-cadence.d.ts +68 -0
  142. package/dist-server/service/reference/live-cadence.js +44 -0
  143. package/dist-server/service/reference/live-cadence.js.map +1 -0
  144. package/dist-server/service/reference/live-feed-lease.d.ts +15 -0
  145. package/dist-server/service/reference/live-feed-lease.js +56 -0
  146. package/dist-server/service/reference/live-feed-lease.js.map +1 -0
  147. package/dist-server/service/reference/live-ingest.d.ts +21 -0
  148. package/dist-server/service/reference/live-ingest.js +66 -0
  149. package/dist-server/service/reference/live-ingest.js.map +1 -0
  150. package/dist-server/service/reference/reference-adapter.d.ts +355 -2
  151. package/dist-server/service/reference/reference-adapter.js +19 -1
  152. package/dist-server/service/reference/reference-adapter.js.map +1 -1
  153. package/dist-server/service/reference/reference-fill-run.d.ts +50 -0
  154. package/dist-server/service/reference/reference-fill-run.js +142 -0
  155. package/dist-server/service/reference/reference-fill-run.js.map +1 -0
  156. package/dist-server/service/reference/reference-fill.d.ts +90 -0
  157. package/dist-server/service/reference/reference-fill.js +141 -0
  158. package/dist-server/service/reference/reference-fill.js.map +1 -0
  159. package/dist-server/service/reference/reference-hook.d.ts +64 -6
  160. package/dist-server/service/reference/reference-hook.js +265 -27
  161. package/dist-server/service/reference/reference-hook.js.map +1 -1
  162. package/dist-server/service/reference/reference-link-groups.d.ts +10 -0
  163. package/dist-server/service/reference/reference-link-groups.js +15 -0
  164. package/dist-server/service/reference/reference-link-groups.js.map +1 -0
  165. package/dist-server/service/reference/reference-links.d.ts +14 -0
  166. package/dist-server/service/reference/reference-links.js +73 -0
  167. package/dist-server/service/reference/reference-links.js.map +1 -0
  168. package/dist-server/service/reference/reference-live.d.ts +1 -0
  169. package/dist-server/service/reference/reference-live.js +32 -6
  170. package/dist-server/service/reference/reference-live.js.map +1 -1
  171. package/dist-server/service/reference/reference-master.d.ts +56 -2
  172. package/dist-server/service/reference/reference-master.js +33 -3
  173. package/dist-server/service/reference/reference-master.js.map +1 -1
  174. package/dist-server/service/reference/reference-resolver.d.ts +27 -0
  175. package/dist-server/service/reference/reference-resolver.js +79 -1
  176. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  177. package/dist-server/service/twin-event/twin-event-keys.d.ts +31 -3
  178. package/dist-server/service/twin-event/twin-event-keys.js +36 -4
  179. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  180. package/dist-server/service/twin-event/twin-event.d.ts +1 -0
  181. package/dist-server/service/twin-event/twin-event.js +11 -2
  182. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  183. package/dist-server/service/twin-model/choose-recipe.d.ts +15 -0
  184. package/dist-server/service/twin-model/choose-recipe.js +33 -0
  185. package/dist-server/service/twin-model/choose-recipe.js.map +1 -0
  186. package/dist-server/service/twin-model/external-resolver.d.ts +76 -0
  187. package/dist-server/service/twin-model/external-resolver.js +109 -0
  188. package/dist-server/service/twin-model/external-resolver.js.map +1 -0
  189. package/dist-server/service/twin-model/project-structure.js +16 -3
  190. package/dist-server/service/twin-model/project-structure.js.map +1 -1
  191. package/dist-server/service/twin-model/twin-equipment.d.ts +17 -0
  192. package/dist-server/service/twin-model/twin-equipment.js +10 -0
  193. package/dist-server/service/twin-model/twin-equipment.js.map +1 -1
  194. package/dist-server/service/twin-model/twin-lineage-query.js +75 -1
  195. package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
  196. package/dist-server/service/twin-model/twin-model-item-query.js +94 -5
  197. package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
  198. package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
  199. package/dist-server/service/twin-space/twin-space.d.ts +29 -0
  200. package/dist-server/service/twin-space/twin-space.js +13 -0
  201. package/dist-server/service/twin-space/twin-space.js.map +1 -1
  202. package/dist-server/service/twin-subject/event-subjects.d.ts +3 -1
  203. package/dist-server/service/twin-subject/event-subjects.js +8 -1
  204. package/dist-server/service/twin-subject/event-subjects.js.map +1 -1
  205. package/dist-shared/entity-delta.js +1 -1
  206. package/dist-shared/entity-delta.js.map +1 -1
  207. package/package.json +7 -7
  208. package/server/engine/canonical-ingest.ts +119 -33
  209. package/server/engine/event-time.ts +96 -0
  210. package/server/engine/index.ts +20 -0
  211. package/server/engine/ingest-dedupe.ts +203 -27
  212. package/server/engine/ingest-health.ts +91 -6
  213. package/server/engine/kpi-fold.ts +24 -1
  214. package/server/engine/kpi-query.ts +23 -4
  215. package/server/engine/oee-accumulator.ts +80 -8
  216. package/server/engine/twin-engine.ts +119 -5
  217. package/server/index.ts +23 -0
  218. package/server/migrations/1786600000000-RenameOperatoMesAdapterType.ts +66 -0
  219. package/server/migrations/1786700000000-AddDispatchRetryColumns.ts +82 -0
  220. package/server/migrations/index.ts +5 -1
  221. package/server/routes.ts +19 -20
  222. package/server/service/actuation/actuation-advisor.ts +124 -0
  223. package/server/service/actuation/actuation-outcome.ts +97 -0
  224. package/server/service/actuation/actuation-rule-resolver.ts +147 -0
  225. package/server/service/actuation/actuation-rule.ts +139 -0
  226. package/server/service/actuation/approval-gateway.ts +44 -0
  227. package/server/service/actuation/catch-up-effects.ts +152 -0
  228. package/server/service/actuation/command-dispatcher.ts +511 -0
  229. package/server/service/actuation/command-store.ts +236 -0
  230. package/server/service/actuation/dispatch-after-approval.ts +71 -0
  231. package/server/service/actuation/effect-match.ts +124 -0
  232. package/server/service/actuation/index.ts +27 -0
  233. package/server/service/actuation/retry-plan.ts +145 -0
  234. package/server/service/actuation/rule-evaluate.ts +352 -0
  235. package/server/service/actuation/rule-loop.ts +160 -0
  236. package/server/service/actuation/rule-runner.ts +216 -0
  237. package/server/service/actuation/rule-wiring.ts +84 -0
  238. package/server/service/actuation/settle-effects.ts +115 -0
  239. package/server/service/actuation/sweep-dispatch.ts +179 -0
  240. package/server/service/actuation/twin-command-resolver.ts +387 -0
  241. package/server/service/actuation/twin-command.ts +232 -0
  242. package/server/service/actuation/twin-now.ts +97 -0
  243. package/server/service/index.ts +11 -0
  244. package/server/service/reference/actuation-routing.ts +165 -0
  245. package/server/service/reference/actuation-target.ts +163 -0
  246. package/server/service/reference/connection-portability-resolver.ts +171 -0
  247. package/server/service/reference/connection-portability.ts +285 -0
  248. package/server/service/reference/fill-cadence.ts +29 -0
  249. package/server/service/reference/fill-dedupe.ts +66 -0
  250. package/server/service/reference/fill-loop.ts +153 -0
  251. package/server/service/reference/fill-span.ts +31 -0
  252. package/server/service/reference/hook-contract.ts +280 -22
  253. package/server/service/reference/hook-rejected.ts +53 -0
  254. package/server/service/reference/hook-store.ts +28 -0
  255. package/server/service/reference/index.ts +5 -1
  256. package/server/service/reference/live-cadence.ts +129 -0
  257. package/server/service/reference/live-feed-lease.ts +56 -0
  258. package/server/service/reference/live-ingest.ts +94 -0
  259. package/server/service/reference/reference-adapter.ts +392 -5
  260. package/server/service/reference/reference-fill-run.ts +165 -0
  261. package/server/service/reference/reference-fill.ts +223 -0
  262. package/server/service/reference/reference-hook.ts +355 -32
  263. package/server/service/reference/reference-link-groups.ts +21 -0
  264. package/server/service/reference/reference-links.ts +77 -0
  265. package/server/service/reference/reference-live.ts +30 -5
  266. package/server/service/reference/reference-master.ts +90 -5
  267. package/server/service/reference/reference-resolver.ts +77 -2
  268. package/server/service/twin-event/twin-event-keys.ts +37 -4
  269. package/server/service/twin-event/twin-event.ts +18 -1
  270. package/server/service/twin-model/choose-recipe.ts +31 -0
  271. package/server/service/twin-model/external-resolver.ts +161 -0
  272. package/server/service/twin-model/project-structure.ts +16 -3
  273. package/server/service/twin-model/twin-equipment.ts +22 -0
  274. package/server/service/twin-model/twin-lineage-query.ts +82 -1
  275. package/server/service/twin-model/twin-model-item-query.ts +95 -4
  276. package/server/service/twin-model/twin-model-tree-query.ts +1 -1
  277. package/server/service/twin-space/twin-space.ts +39 -0
  278. package/server/service/twin-subject/event-subjects.ts +8 -1
  279. package/shared/entity-delta.ts +1 -1
  280. package/test/ack-shape-alignment.test.ts +97 -0
  281. package/test/actuation-approval-door.test.ts +421 -0
  282. package/test/actuation-dispatch.test.ts +209 -0
  283. package/test/actuation-effect.test.ts +162 -0
  284. package/test/actuation-outcome.test.ts +152 -0
  285. package/test/actuation-rule-runner.test.ts +281 -0
  286. package/test/actuation-rule.test.ts +266 -0
  287. package/test/actuation-seam.test.ts +249 -0
  288. package/test/actuation-settle.test.ts +164 -0
  289. package/test/actuation-target.test.ts +145 -0
  290. package/test/canonical-ingest-vocabularies.test.ts +49 -2
  291. package/test/capability-mapping.test.ts +1 -1
  292. package/test/choose-recipe.test.ts +117 -0
  293. package/test/command-store-writes-columns.test.ts +126 -0
  294. package/test/connection-portability-doors.test.ts +87 -0
  295. package/test/connector-capability-declaration.test.ts +54 -4
  296. package/test/declaration-reaches-model.test.ts +43 -0
  297. package/test/dedupe-transformation.test.ts +112 -0
  298. package/test/entity-delta.test.ts +1 -1
  299. package/test/event-subjects.test.ts +2 -1
  300. package/test/external-resolver.test.ts +171 -0
  301. package/test/fill-dedupe.test.ts +59 -0
  302. package/test/fill-loop.test.ts +35 -0
  303. package/test/first-envelope.test.ts +153 -0
  304. package/test/fold-shift-dst.test.ts +110 -0
  305. package/test/home-in-area.test.ts +90 -0
  306. package/test/hook-rejected-shape.test.ts +86 -0
  307. package/test/hook-response-sum.test.ts +193 -0
  308. package/test/hook-sequence.test.ts +333 -0
  309. package/test/ingest-dedupe.test.ts +56 -0
  310. package/test/ingest-expected-quiet.test.ts +111 -0
  311. package/test/ingest-idempotent.test.ts +79 -0
  312. package/test/ingest-reconcile-four-ways.test.ts +97 -0
  313. package/test/ingest-rules-header.test.ts +100 -0
  314. package/test/ingest-window-rolls-unobserved.test.ts +72 -0
  315. package/test/intake-mapping-parity.test.ts +175 -0
  316. package/test/live-cadence.test.ts +170 -0
  317. package/test/live-feed-lease.test.ts +63 -0
  318. package/test/live-mirror-parity.test.ts +1 -1
  319. package/test/oee-accumulator.test.ts +3 -3
  320. package/test/oee-site-calendar.test.ts +146 -0
  321. package/test/order-and-transaction-split.test.ts +107 -0
  322. package/test/reference-fill.test.ts +235 -0
  323. package/test/reference-hook.test.ts +114 -23
  324. package/test/reference-links.test.ts +56 -0
  325. package/test/retry-plan.test.ts +139 -0
  326. package/test/sweep-dispatch.test.ts +191 -0
  327. package/test/twin-event-keys.test.ts +20 -6
  328. package/test/twin-model-item-db.test.ts +6 -6
  329. package/test/twin-model-tree-db.test.ts +6 -6
  330. package/tsconfig.shared.tsbuildinfo +1 -1
  331. package/tsconfig.tsbuildinfo +1 -1
@@ -12,6 +12,9 @@ require("./routes.js");
12
12
  const index_js_2 = require("./engine/index.js");
13
13
  const reference_live_js_1 = require("./service/reference/reference-live.js");
14
14
  const index_js_3 = require("./service/twin-ingest-window/index.js");
15
+ const reference_links_js_1 = require("./service/reference/reference-links.js");
16
+ const rule_loop_js_1 = require("./service/actuation/rule-loop.js");
17
+ const fill_loop_js_1 = require("./service/reference/fill-loop.js");
15
18
  /*
16
19
  * ๋ชจ๋“ˆ ๋ถ€ํŒ… โ€” **๋„๋Š” ํŠธ์œˆ์„ ๋˜์‚ด๋ฆฐ๋‹ค.**
17
20
  *
@@ -28,6 +31,11 @@ process.on('bootstrap-module-start', async ({ app, config, client }) => {
28
31
  * ๋‚จ๋Š”๋‹ค. ์ปค๋„ ์ธต์€ ์ €์žฅ ๊ณ„์ธต์„ ๋ชจ๋ฅด๋ฏ€๋กœ ์ด ๋“ฑ๋ก์ด ๊ทธ ๋‘˜์„ ์ž‡๋Š” ์œ ์ผํ•œ ์ž๋ฆฌ๋‹ค.
29
32
  */
30
33
  (0, index_js_3.installIngestWindowWriter)();
34
+ /*
35
+ * ์›๋ณธ์—๋งŒ ์žˆ๋Š” ๊ด€๊ณ„๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฌธ์„ ์—ฐ๋‹ค โ€” MES ์˜ ์ƒ์‚ฐ ์‹ค์ ยท์ •๋น„ ๊ณ„ํš์ฒ˜๋Ÿผ ํŠธ์œˆ์ด ๋‹ด์ง€ ์•Š๋Š”
36
+ * ๊ฒƒ๋“ค. ์กฐํšŒ์šฉ ์ฐธ์กฐ๋Š” ํŠธ์œˆ์œผ๋กœ ๋ณต์ œํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋•Œ ๋ฌผ์–ด๋ณธ๋‹ค.
37
+ */
38
+ (0, reference_links_js_1.installReferenceLinkResolver)();
31
39
  /*
32
40
  * **์ €๋„ ๋ณด์กด ๊ธฐ๊ฐ„์€ ์„ ์–ธ์—์„œ ์˜จ๋‹ค** โ€” ์ฝ”๋“œ์— ๋ฐ•์•„ ๋‘์ง€ ์•Š๋Š”๋‹ค(2026-08-22).
33
41
  *
@@ -55,6 +63,19 @@ process.on('bootstrap-module-start', async ({ app, config, client }) => {
55
63
  }
56
64
  await index_js_2.TwinEngine.bootstrap();
57
65
  await (0, reference_live_js_1.resumeReferenceLiveFeeds)();
66
+ /*
67
+ * ๋น ์ง„ ๊ตฌ๊ฐ„์„ ๋‹ค์‹œ ๋ฐ›๋Š” ์ฃผ๊ธฐ โ€” ๊ธฐ๋™์—์„œ ํ•œ ๋ฒˆ, ๊ทธ ๋’ค 10๋ถ„๋งˆ๋‹ค(ยง`fill-loop.ts`).
68
+ * ํ”ผ๋“œ๋ฅผ ๋ถ™์ธ **๋’ค์—** ์„ธ์šด๋‹ค: ์ปค๋„์ด ๋˜์‚ด์•„๋‚˜๊ธฐ ์ „์— ๋ถ€๋ฅด๋ฉด ๋„๋Š” ํŠธ์œˆ์ด 0๊ฐœ๋‹ค.
69
+ */
70
+ (0, fill_loop_js_1.startFillLoop)();
71
+ /*
72
+ * ์กฐ์น˜ ๊ทœ์น™ ์ฃผ๊ธฐ โ€” **ํŠธ์œˆ์ด ๋‹ค ์„  ๋’ค์—** ์„ธ์šด๋‹ค. ์•ž์— ์„ธ์šฐ๋ฉด ์ฒซ ๋ฐ”ํ€ด๊ฐ€ ์•„์ง ์•ˆ ์„  ํŠธ์œˆ๋“ค์„ ๋Œ๊ณ 
73
+ * ใ€Œ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์—†๋‹คใ€๋ฅผ ๊ทœ์น™ ํ–‰์— ์ ๋Š”๋‹ค. ๊ทธ๊ฒƒ์€ ์‚ฌ์‹ค์ด์ง€๋งŒ ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ์˜คํ•ด๋‹ค.
74
+ *
75
+ * ์ปค๋„ ํ‹ฑ๊ณผ ๋”ฐ๋กœ ๋ˆ๋‹ค โ€” ํ‹ฑ์€ ์˜ˆ์™ธ๊ฐ€ ๋‚˜๋ฉด ๊ทธ ํŠธ์œˆ์„ ๋ฉˆ์ถ”๊ณ , ๊ทœ์น™ ํ•˜๋‚˜๊ฐ€ ์ž˜๋ชป๋๋‹ค๊ณ  ๊ณต์žฅ์ด ๋ฉˆ์ถ”๋ฉด
76
+ * ์•ˆ ๋œ๋‹ค(ยง`rule-loop.ts`).
77
+ */
78
+ (0, rule_loop_js_1.startActuationRuleLoop)();
58
79
  (0, log_js_1.twinLog)('Headless Twin host has started.');
59
80
  }
60
81
  catch (ex) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;;AAAA,4DAAiC;AACjC,6DAAkC;AAClC,qEAAqE;AACrE,kDAAkD;AAAzC,sGAAA,UAAU,OAAA;AAEnB,4CAAoD;AACpD,uBAAoB;AAEpB,gDAA8C;AAC9C,6EAAgF;AAChF,oEAAiF;AAEjF;;;;;;;;GAQG;AACH,OAAO,CAAC,EAAE,CAAC,wBAA+B,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAO,EAAE,EAAE;IACjF,IAAI,CAAC;QACH;;;WAGG;QACH,IAAA,oCAAyB,GAAE,CAAA;QAC3B;;;;;;;;WAQG;QACH;;;;;;;;WAQG;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,CAAC,CAAA;QACpE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,oBAAoB,IAAI,CAAC,CAAC,CAAA;QAC3E,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAA;QACxD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,qBAAU,CAAC,sBAAsB,GAAG,aAAa,CAAA;YACjD,IAAA,gBAAO,EAAC,4BAA4B,aAAa,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAA;QACxF,CAAC;QAED,MAAM,qBAAU,CAAC,SAAS,EAAE,CAAA;QAC5B,MAAM,IAAA,4CAAwB,GAAE,CAAA;QAChC,IAAA,gBAAO,EAAC,iCAAiC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAA,kBAAS,EAAC,qCAAqC,EAAE,EAAE,CAAC,CAAA;IACtD,CAAC;AACH,CAAC,CAAC,CAAA","sourcesContent":["export * from './engine/index.js'\nexport * from './service/index.js'\n/* ์Šคํ‚ค๋งˆ ์ด๋ ฅ โ€” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ `migrations` export ๋ฅผ ๋ชจ์•„ ์‹คํ–‰ํ•œ๋‹ค(`run migration`). */\nexport { migrations } from './migrations/index.js'\n\nimport { twinLog, twinError } from './engine/log.js'\nimport './routes.js'\n\nimport { TwinEngine } from './engine/index.js'\nimport { resumeReferenceLiveFeeds } from './service/reference/reference-live.js'\nimport { installIngestWindowWriter } from './service/twin-ingest-window/index.js'\n\n/*\n * ๋ชจ๋“ˆ ๋ถ€ํŒ… โ€” **๋„๋Š” ํŠธ์œˆ์„ ๋˜์‚ด๋ฆฐ๋‹ค.**\n *\n * ๋‘ ์ธต์ด ์ˆœ์„œ๋Œ€๋กœ๋‹ค: โ‘  ์—”์ง„์ด ๋“ฑ๋ก๋ถ€์˜ `running` ํ–‰์„ ์„ ์–ธ๋œ `restartPolicy` ๊ทธ๋Œ€๋กœ ๋˜์‚ด๋ฆฌ๊ณ \n * (`bootstrap`), โ‘ก ๋ ˆํผ๋Ÿฐ์Šค ๊ณ„์ธต์ด ๋ฏธ๋Ÿฌ ํŠธ์œˆ์˜ ์ปค๋„ฅํ„ฐ ํ”ผ๋“œ๋ฅผ ๋‹ค์‹œ ๋ถ™์ธ๋‹ค. ์ˆœ์„œ๊ฐ€ ๋’ค์ง‘ํžˆ๋ฉด ํ”ผ๋“œ๊ฐ€\n * ์•„์ง ์—†๋Š” ์ปค๋„์— ๊ณ„์ธก์„ ๋ถ“๊ฒŒ ๋œ๋‹ค.\n *\n * ์˜ˆ์ „์—๋Š” โ‘ ๋„ โ‘ก๋„ ์—†์—ˆ๋‹ค โ€” ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์— ๋“ฑ๋ก๋ถ€๋งŒ ใ€Œ๋„๋Š” ์ค‘ใ€์ด๋ผ ๋งํ•˜๋Š” ํŠธ์œˆ์ด ๋‚จ์•˜๋‹ค.\n */\nprocess.on('bootstrap-module-start' as any, async ({ app, config, client }: any) => {\n try {\n /*\n * ๋‹ซํžŒ ์ธ์ œ์ŠคํŠธ ์ฐฝ์„ ํ‘œ๋กœ ์˜ฎ๊ธฐ๋Š” ๋ฌธ์„ ๋จผ์ € ์—ฐ๋‹ค โ€” ํŠธ์œˆ์„ ๋˜์‚ด๋ฆฌ๊ธฐ **์ „์—** ๋“ฑ๋กํ•ด์•ผ ์ฒซ ์ฐฝ๋ถ€ํ„ฐ\n * ๋‚จ๋Š”๋‹ค. ์ปค๋„ ์ธต์€ ์ €์žฅ ๊ณ„์ธต์„ ๋ชจ๋ฅด๋ฏ€๋กœ ์ด ๋“ฑ๋ก์ด ๊ทธ ๋‘˜์„ ์ž‡๋Š” ์œ ์ผํ•œ ์ž๋ฆฌ๋‹ค.\n */\n installIngestWindowWriter()\n /*\n * **์ €๋„ ๋ณด์กด ๊ธฐ๊ฐ„์€ ์„ ์–ธ์—์„œ ์˜จ๋‹ค** โ€” ์ฝ”๋“œ์— ๋ฐ•์•„ ๋‘์ง€ ์•Š๋Š”๋‹ค(2026-08-22).\n *\n * ์‹ค์ธก: ๊ฐœ๋ฐœ ์ €๋„์ด ์‹œ๊ฐ„๋‹น 581,794ํ–‰ ยท 0.85GB(ํ•˜๋ฃจ 20GB) ๋กœ ์ž๋ž๊ณ  ์ง€์šฐ๋Š” ๊ฒƒ์ด ์—†์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ\n * ใ€Œ๋ฉฐ์น ๊นŒ์ง€ ๋‚จ๊ธฐ๋‚˜ใ€๋Š” **๋ฐฐํฌ๋งˆ๋‹ค ๊ฐˆ๋ฆฌ๋Š” ์‚ฌ์‹ค**์ด๋‹ค โ€” ๊ฐœ๋ฐœ์€ ์งง์•„๋„ ๋˜๊ณ  ์‹ค์ฆ์€ ๊ธธ์–ด์•ผ ํ•œ๋‹ค.\n *\n * ์„ ์–ธ์ด ์—†์œผ๋ฉด **์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.** ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ง€์šฐ๋Š” ํŽธ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์Œ“๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚˜์˜๋‹ค.\n * ๊ฐ’์€ ์Šค๋ƒ…์ƒท TTL(7์ผ)๋ณด๋‹ค ์งง์„ ์ˆ˜ ์—†๋‹ค โ€” ์—”์ง„์ด ๊ทธ๊ฒƒ์„ ์˜ฌ๋ ค ์ฃผ๊ณ  ๊ทธ ์‚ฌ์‹ค์„ ๋งํ•œ๋‹ค.\n */\n /*\n * ์ฝ๋Š” ์ˆœ์„œ: **ํ™˜๊ฒฝ๋ณ€์ˆ˜ โ†’ ์„ค์ • โ†’ ์—†์Œ.**\n *\n * ์„ค์ •(`config.twin.journalRetentionDays`)์ด ๋ฐฐํฌ์˜ ์„ ์–ธ์ด๊ณ , ํ™˜๊ฒฝ๋ณ€์ˆ˜\n * (`TWIN_JOURNAL_RETENTION_DAYS`)๋Š” ๊ทธ๊ฒƒ์„ **๊ทธ ์ž๋ฆฌ์—์„œ** ๋ฎ๋Š”๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋กœ ๋„๋Š” ๋ฐฐํฌ์—์„œ๋Š”\n * ํŒŒ์ผ์„ ๊ณ ์น˜์ง€ ์•Š๊ณ  ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ณ , ๊ฐœ๋ฐœ์—์„œ๋„ ๊ทธ ํŽธ์ด ๋น ๋ฅด๋‹ค.\n *\n * ๋‘˜ ๋‹ค ์—†์œผ๋ฉด **์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.**\n */\n const fromEnv = Number(process.env.TWIN_JOURNAL_RETENTION_DAYS ?? 0)\n const fromConfig = Number(config?.get?.('twin')?.journalRetentionDays ?? 0)\n const retentionDays = fromEnv > 0 ? fromEnv : fromConfig\n if (retentionDays > 0) {\n TwinEngine.JOURNAL_RETENTION_DAYS = retentionDays\n twinLog(`[twin] journal retention ${retentionDays}์ผ (${fromEnv > 0 ? 'ํ™˜๊ฒฝ๋ณ€์ˆ˜' : '์„ค์ •'})`)\n }\n\n await TwinEngine.bootstrap()\n await resumeReferenceLiveFeeds()\n twinLog('Headless Twin host has started.')\n } catch (ex) {\n twinError('Headless Twin host failed to start.', ex)\n }\n})\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;;AAAA,4DAAiC;AACjC,6DAAkC;AAClC,qEAAqE;AACrE,kDAAkD;AAAzC,sGAAA,UAAU,OAAA;AAEnB,4CAAoD;AACpD,uBAAoB;AAEpB,gDAA8C;AAC9C,6EAAgF;AAChF,oEAAiF;AACjF,+EAAqF;AACrF,mEAAyE;AACzE,mEAAgE;AAEhE;;;;;;;;GAQG;AACH,OAAO,CAAC,EAAE,CAAC,wBAA+B,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAO,EAAE,EAAE;IACjF,IAAI,CAAC;QACH;;;WAGG;QACH,IAAA,oCAAyB,GAAE,CAAA;QAC3B;;;WAGG;QACH,IAAA,iDAA4B,GAAE,CAAA;QAC9B;;;;;;;;WAQG;QACH;;;;;;;;WAQG;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,CAAC,CAAA;QACpE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,oBAAoB,IAAI,CAAC,CAAC,CAAA;QAC3E,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAA;QACxD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,qBAAU,CAAC,sBAAsB,GAAG,aAAa,CAAA;YACjD,IAAA,gBAAO,EAAC,4BAA4B,aAAa,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAA;QACxF,CAAC;QAED,MAAM,qBAAU,CAAC,SAAS,EAAE,CAAA;QAC5B,MAAM,IAAA,4CAAwB,GAAE,CAAA;QAChC;;;WAGG;QACH,IAAA,4BAAa,GAAE,CAAA;QAEf;;;;;;WAMG;QACH,IAAA,qCAAsB,GAAE,CAAA;QAExB,IAAA,gBAAO,EAAC,iCAAiC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAA,kBAAS,EAAC,qCAAqC,EAAE,EAAE,CAAC,CAAA;IACtD,CAAC;AACH,CAAC,CAAC,CAAA","sourcesContent":["export * from './engine/index.js'\nexport * from './service/index.js'\n/* ์Šคํ‚ค๋งˆ ์ด๋ ฅ โ€” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ `migrations` export ๋ฅผ ๋ชจ์•„ ์‹คํ–‰ํ•œ๋‹ค(`run migration`). */\nexport { migrations } from './migrations/index.js'\n\nimport { twinLog, twinError } from './engine/log.js'\nimport './routes.js'\n\nimport { TwinEngine } from './engine/index.js'\nimport { resumeReferenceLiveFeeds } from './service/reference/reference-live.js'\nimport { installIngestWindowWriter } from './service/twin-ingest-window/index.js'\nimport { installReferenceLinkResolver } from './service/reference/reference-links.js'\nimport { startActuationRuleLoop } from './service/actuation/rule-loop.js'\nimport { startFillLoop } from './service/reference/fill-loop.js'\n\n/*\n * ๋ชจ๋“ˆ ๋ถ€ํŒ… โ€” **๋„๋Š” ํŠธ์œˆ์„ ๋˜์‚ด๋ฆฐ๋‹ค.**\n *\n * ๋‘ ์ธต์ด ์ˆœ์„œ๋Œ€๋กœ๋‹ค: โ‘  ์—”์ง„์ด ๋“ฑ๋ก๋ถ€์˜ `running` ํ–‰์„ ์„ ์–ธ๋œ `restartPolicy` ๊ทธ๋Œ€๋กœ ๋˜์‚ด๋ฆฌ๊ณ \n * (`bootstrap`), โ‘ก ๋ ˆํผ๋Ÿฐ์Šค ๊ณ„์ธต์ด ๋ฏธ๋Ÿฌ ํŠธ์œˆ์˜ ์ปค๋„ฅํ„ฐ ํ”ผ๋“œ๋ฅผ ๋‹ค์‹œ ๋ถ™์ธ๋‹ค. ์ˆœ์„œ๊ฐ€ ๋’ค์ง‘ํžˆ๋ฉด ํ”ผ๋“œ๊ฐ€\n * ์•„์ง ์—†๋Š” ์ปค๋„์— ๊ณ„์ธก์„ ๋ถ“๊ฒŒ ๋œ๋‹ค.\n *\n * ์˜ˆ์ „์—๋Š” โ‘ ๋„ โ‘ก๋„ ์—†์—ˆ๋‹ค โ€” ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์— ๋“ฑ๋ก๋ถ€๋งŒ ใ€Œ๋„๋Š” ์ค‘ใ€์ด๋ผ ๋งํ•˜๋Š” ํŠธ์œˆ์ด ๋‚จ์•˜๋‹ค.\n */\nprocess.on('bootstrap-module-start' as any, async ({ app, config, client }: any) => {\n try {\n /*\n * ๋‹ซํžŒ ์ธ์ œ์ŠคํŠธ ์ฐฝ์„ ํ‘œ๋กœ ์˜ฎ๊ธฐ๋Š” ๋ฌธ์„ ๋จผ์ € ์—ฐ๋‹ค โ€” ํŠธ์œˆ์„ ๋˜์‚ด๋ฆฌ๊ธฐ **์ „์—** ๋“ฑ๋กํ•ด์•ผ ์ฒซ ์ฐฝ๋ถ€ํ„ฐ\n * ๋‚จ๋Š”๋‹ค. ์ปค๋„ ์ธต์€ ์ €์žฅ ๊ณ„์ธต์„ ๋ชจ๋ฅด๋ฏ€๋กœ ์ด ๋“ฑ๋ก์ด ๊ทธ ๋‘˜์„ ์ž‡๋Š” ์œ ์ผํ•œ ์ž๋ฆฌ๋‹ค.\n */\n installIngestWindowWriter()\n /*\n * ์›๋ณธ์—๋งŒ ์žˆ๋Š” ๊ด€๊ณ„๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฌธ์„ ์—ฐ๋‹ค โ€” MES ์˜ ์ƒ์‚ฐ ์‹ค์ ยท์ •๋น„ ๊ณ„ํš์ฒ˜๋Ÿผ ํŠธ์œˆ์ด ๋‹ด์ง€ ์•Š๋Š”\n * ๊ฒƒ๋“ค. ์กฐํšŒ์šฉ ์ฐธ์กฐ๋Š” ํŠธ์œˆ์œผ๋กœ ๋ณต์ œํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋•Œ ๋ฌผ์–ด๋ณธ๋‹ค.\n */\n installReferenceLinkResolver()\n /*\n * **์ €๋„ ๋ณด์กด ๊ธฐ๊ฐ„์€ ์„ ์–ธ์—์„œ ์˜จ๋‹ค** โ€” ์ฝ”๋“œ์— ๋ฐ•์•„ ๋‘์ง€ ์•Š๋Š”๋‹ค(2026-08-22).\n *\n * ์‹ค์ธก: ๊ฐœ๋ฐœ ์ €๋„์ด ์‹œ๊ฐ„๋‹น 581,794ํ–‰ ยท 0.85GB(ํ•˜๋ฃจ 20GB) ๋กœ ์ž๋ž๊ณ  ์ง€์šฐ๋Š” ๊ฒƒ์ด ์—†์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ\n * ใ€Œ๋ฉฐ์น ๊นŒ์ง€ ๋‚จ๊ธฐ๋‚˜ใ€๋Š” **๋ฐฐํฌ๋งˆ๋‹ค ๊ฐˆ๋ฆฌ๋Š” ์‚ฌ์‹ค**์ด๋‹ค โ€” ๊ฐœ๋ฐœ์€ ์งง์•„๋„ ๋˜๊ณ  ์‹ค์ฆ์€ ๊ธธ์–ด์•ผ ํ•œ๋‹ค.\n *\n * ์„ ์–ธ์ด ์—†์œผ๋ฉด **์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.** ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์ง€์šฐ๋Š” ํŽธ์ด ์•Œ๋ฆฌ์ง€ ์•Š๊ณ  ์Œ“๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚˜์˜๋‹ค.\n * ๊ฐ’์€ ์Šค๋ƒ…์ƒท TTL(7์ผ)๋ณด๋‹ค ์งง์„ ์ˆ˜ ์—†๋‹ค โ€” ์—”์ง„์ด ๊ทธ๊ฒƒ์„ ์˜ฌ๋ ค ์ฃผ๊ณ  ๊ทธ ์‚ฌ์‹ค์„ ๋งํ•œ๋‹ค.\n */\n /*\n * ์ฝ๋Š” ์ˆœ์„œ: **ํ™˜๊ฒฝ๋ณ€์ˆ˜ โ†’ ์„ค์ • โ†’ ์—†์Œ.**\n *\n * ์„ค์ •(`config.twin.journalRetentionDays`)์ด ๋ฐฐํฌ์˜ ์„ ์–ธ์ด๊ณ , ํ™˜๊ฒฝ๋ณ€์ˆ˜\n * (`TWIN_JOURNAL_RETENTION_DAYS`)๋Š” ๊ทธ๊ฒƒ์„ **๊ทธ ์ž๋ฆฌ์—์„œ** ๋ฎ๋Š”๋‹ค. ์ปจํ…Œ์ด๋„ˆ๋กœ ๋„๋Š” ๋ฐฐํฌ์—์„œ๋Š”\n * ํŒŒ์ผ์„ ๊ณ ์น˜์ง€ ์•Š๊ณ  ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ณ , ๊ฐœ๋ฐœ์—์„œ๋„ ๊ทธ ํŽธ์ด ๋น ๋ฅด๋‹ค.\n *\n * ๋‘˜ ๋‹ค ์—†์œผ๋ฉด **์•„๋ฌด๊ฒƒ๋„ ์ง€์šฐ์ง€ ์•Š๋Š”๋‹ค.**\n */\n const fromEnv = Number(process.env.TWIN_JOURNAL_RETENTION_DAYS ?? 0)\n const fromConfig = Number(config?.get?.('twin')?.journalRetentionDays ?? 0)\n const retentionDays = fromEnv > 0 ? fromEnv : fromConfig\n if (retentionDays > 0) {\n TwinEngine.JOURNAL_RETENTION_DAYS = retentionDays\n twinLog(`[twin] journal retention ${retentionDays}์ผ (${fromEnv > 0 ? 'ํ™˜๊ฒฝ๋ณ€์ˆ˜' : '์„ค์ •'})`)\n }\n\n await TwinEngine.bootstrap()\n await resumeReferenceLiveFeeds()\n /*\n * ๋น ์ง„ ๊ตฌ๊ฐ„์„ ๋‹ค์‹œ ๋ฐ›๋Š” ์ฃผ๊ธฐ โ€” ๊ธฐ๋™์—์„œ ํ•œ ๋ฒˆ, ๊ทธ ๋’ค 10๋ถ„๋งˆ๋‹ค(ยง`fill-loop.ts`).\n * ํ”ผ๋“œ๋ฅผ ๋ถ™์ธ **๋’ค์—** ์„ธ์šด๋‹ค: ์ปค๋„์ด ๋˜์‚ด์•„๋‚˜๊ธฐ ์ „์— ๋ถ€๋ฅด๋ฉด ๋„๋Š” ํŠธ์œˆ์ด 0๊ฐœ๋‹ค.\n */\n startFillLoop()\n\n /*\n * ์กฐ์น˜ ๊ทœ์น™ ์ฃผ๊ธฐ โ€” **ํŠธ์œˆ์ด ๋‹ค ์„  ๋’ค์—** ์„ธ์šด๋‹ค. ์•ž์— ์„ธ์šฐ๋ฉด ์ฒซ ๋ฐ”ํ€ด๊ฐ€ ์•„์ง ์•ˆ ์„  ํŠธ์œˆ๋“ค์„ ๋Œ๊ณ \n * ใ€Œ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์—†๋‹คใ€๋ฅผ ๊ทœ์น™ ํ–‰์— ์ ๋Š”๋‹ค. ๊ทธ๊ฒƒ์€ ์‚ฌ์‹ค์ด์ง€๋งŒ ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ์˜คํ•ด๋‹ค.\n *\n * ์ปค๋„ ํ‹ฑ๊ณผ ๋”ฐ๋กœ ๋ˆ๋‹ค โ€” ํ‹ฑ์€ ์˜ˆ์™ธ๊ฐ€ ๋‚˜๋ฉด ๊ทธ ํŠธ์œˆ์„ ๋ฉˆ์ถ”๊ณ , ๊ทœ์น™ ํ•˜๋‚˜๊ฐ€ ์ž˜๋ชป๋๋‹ค๊ณ  ๊ณต์žฅ์ด ๋ฉˆ์ถ”๋ฉด\n * ์•ˆ ๋œ๋‹ค(ยง`rule-loop.ts`).\n */\n startActuationRuleLoop()\n\n twinLog('Headless Twin host has started.')\n } catch (ex) {\n twinError('Headless Twin host failed to start.', ex)\n }\n})\n"]}
@@ -0,0 +1,5 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class RenameOperatoMesAdapterType1786600000000 implements MigrationInterface {
3
+ up(queryRunner: QueryRunner): Promise<void>;
4
+ down(queryRunner: QueryRunner): Promise<void>;
5
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenameOperatoMesAdapterType1786600000000 = void 0;
4
+ /**
5
+ * `twin_references.adapter_type` โ€” `operato-mes` โ†’ `operato-plant`.
6
+ *
7
+ * โ”€โ”€ ์™œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
8
+ * ์ปค๋„ฅํ„ฐ์˜ `type` ์€ **์ €์žฅ๋˜๋Š” ์‹๋ณ„์ž**๋‹ค. ํŠธ์œˆ์„ ์›๋ณธ์— ๋ถ™์ผ ๋•Œ ๊ทธ ๋ฌธ์ž์—ด์ด ์ด ์ปฌ๋Ÿผ์— ์ ํžˆ๊ณ ,
9
+ * ๋„˜๊ธธ ๋•Œยท๋ผ์ด๋ธŒ๋ฅผ ์—ด ๋•Œ ๊ทธ ๊ฐ’์œผ๋กœ ์ปค๋„ฅํ„ฐ๋ฅผ ์ฐพ๋Š”๋‹ค(ยง`getAdapter`).
10
+ *
11
+ * ๊ทธ๋ž˜์„œ ์ œํ’ˆ ๊ฐœ๋ช…(`operato-mes` โ†’ `operato-plant`)์ด ์ฝ”๋“œ๋งŒ ๋ฐ”๋€Œ๋ฉด **์ด๋ฏธ ๋ถ™์–ด ์žˆ๋Š” ์›๋ณธ์ด ์ปค๋„ฅํ„ฐ๋ฅผ
12
+ * ๋ชป ์ฐพ๋Š”๋‹ค.** ๊ทธ๋•Œ ๋‚˜์˜ค๋Š” ๊ฒƒ์€ ์ด๋ ‡๋‹ค.
13
+ *
14
+ * ์กฐ์น˜ ๋„˜๊น€ `no-adapter` ๋กœ ๊ฑฐ์ ˆ
15
+ * ๋ผ์ด๋ธŒ ์ปค๋„ฅํ„ฐ๊ฐ€ ์—†์–ด ๊ด€์ธก์ด ๋Š๊ธด๋‹ค
16
+ * ํ™”๋ฉด ใ€Œ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์ปค๋„ฅํ„ฐ์ž…๋‹ˆ๋‹ค (operato-mes)ใ€ ํ•œ ์ค„
17
+ *
18
+ * **์˜ค๋ฅ˜๋Š” ์•ˆ ๋‚˜๊ณ , ์›์ธ์ด ๊ฐœ๋ช…์ด๋ผ๋Š” ๊ฒƒ์ด ๊ทธ ๋ฌธ์žฅ์— ์—†๋‹ค.** ํŠธ์œˆ์€ ๊ทธ๋Œ€๋กœ ์„œ ์žˆ๊ณ  ๊ฐ’๋งŒ ์•ˆ ์˜จ๋‹ค.
19
+ * ์ด ์ €์žฅ์†Œ์—์„œ ๊ฐœ๋ช…์ด ์ €์žฅ๋œ ์‹๋ณ„์ž์— ๋‹ฟ์•˜์„ ๋•Œ ๋Š˜ ์ด ๋ชจ์–‘์œผ๋กœ ๋‚ฌ๋‹ค(๋ณด๋“œ ํ‚คยท์”ฌ ์ปดํฌ๋„ŒํŠธ ํƒ€์ž…).
20
+ *
21
+ * โ”€โ”€ ์™œ ์ด ํŒจํ‚ค์ง€์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
22
+ * ํ‘œ๋ฅผ ๋“  ์ชฝ์ด ์ด ํŒจํ‚ค์ง€๋‹ค(`twin_references`). ์ปค๋„ฅํ„ฐ๋Š” `operato-twin` ์ด ๋“ฑ๋กํ•˜์ง€๋งŒ, ๊ทธ ๊ฐ’์ด ์‚ฌ๋Š”
23
+ * ์ž๋ฆฌ๋Š” ์—ฌ๊ธฐ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ํ‘œ๋ฅผ ๋“  ํŒจํ‚ค์ง€์— ๋‘”๋‹ค.
24
+ *
25
+ * โ”€โ”€ ๋˜๋Œ๋ฆฌ๊ธฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
26
+ * `down` ์ด ๊ฐ’์„ ๋˜๋Œ๋ฆฐ๋‹ค. ์˜› ์ฝ”๋“œ๋กœ ๋˜๋Œ์•„๊ฐ€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์‹ค์ œ๋กœ ์žˆ๊ณ (๋ฐฐํฌ ๋กค๋ฐฑ), ๊ทธ๋•Œ ๊ฐ’์ด ์ƒˆ ์ด๋ฆ„์œผ๋กœ
27
+ * ๋‚จ์•„ ์žˆ์œผ๋ฉด ๊ฐ™์€ ๊ฒฐํ•จ์ด ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ๋‚œ๋‹ค.
28
+ *
29
+ * ๋ฉฑ๋“ฑ: ํ•ด๋‹นํ•˜๋Š” ํ–‰์ด ์—†์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. TypeORM ์งˆ์˜ ๋นŒ๋”๋งŒ ์“ด๋‹ค โ€” ๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค ํŒŒ๋ผ๋ฏธํ„ฐ
30
+ * ํ‘œ๊ธฐ๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ raw SQL ์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
31
+ */
32
+ const REFS = 'twin_references';
33
+ const COLUMN = 'adapter_type';
34
+ /**
35
+ * ์งˆ์˜ ๋นŒ๋”์—๋Š” **์†์„ฑ ์ด๋ฆ„**์„ ์ค€๋‹ค.
36
+ *
37
+ * ์ฒ˜์Œ์— ์ปฌ๋Ÿผ ์ด๋ฆ„(`adapter_type`)์œผ๋กœ ์ผ๋”๋‹ˆ TypeORM ์ด ํ‘œ ์ด๋ฆ„์„ ์—”ํ‹ฐํ‹ฐ(`TwinReference`)๋กœ ํ’€๊ณ 
38
+ * ใ€Œ๊ทธ๋Ÿฐ ์†์„ฑ์ด ์—†๋‹คใ€๋กœ ๊ฑฐ์ ˆํ–ˆ๋‹ค โ€” ํ‘œ ์ด๋ฆ„์„ ์ฃผ๋”๋ผ๋„ ๋งคํ•‘์€ ์—”ํ‹ฐํ‹ฐ ๊ธฐ์ค€์ด๋‹ค. ์ปฌ๋Ÿผ ์ด๋ฆ„์€ ํ‘œ๊ฐ€
39
+ * ์žˆ๋Š”์ง€ ๋ณผ ๋•Œ๋งŒ ์“ด๋‹ค.
40
+ */
41
+ const PROPERTY = 'adapterType';
42
+ const OLD = 'operato-mes';
43
+ const NEW = 'operato-plant';
44
+ async function rename(queryRunner, from, to) {
45
+ /* ํ‘œ๊ฐ€ ์•„์ง ์—†๋Š” ๋ฐฐํฌ(์ฒซ ๊ธฐ๋™)์—์„œ๋Š” ํ•  ์ผ์ด ์—†๋‹ค. */
46
+ const table = await queryRunner.getTable(REFS);
47
+ if (!table?.columns.some(c => c.name === COLUMN))
48
+ return;
49
+ /* ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ค€๋‹ค โ€” ๋ฌธ์ž์—ด ์กฐ๊ฑด์€ ๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค ์‹๋ณ„์ž ์ธ์šฉ์ด ๋‹ฌ๋ผ ๊ทธ๋Œ€๋กœ ๋‚˜๊ฐ„๋‹ค. */
50
+ await queryRunner.manager
51
+ .createQueryBuilder()
52
+ .update(REFS)
53
+ .set({ [PROPERTY]: to })
54
+ .where({ [PROPERTY]: from })
55
+ .execute();
56
+ }
57
+ class RenameOperatoMesAdapterType1786600000000 {
58
+ async up(queryRunner) {
59
+ await rename(queryRunner, OLD, NEW);
60
+ }
61
+ async down(queryRunner) {
62
+ await rename(queryRunner, NEW, OLD);
63
+ }
64
+ }
65
+ exports.RenameOperatoMesAdapterType1786600000000 = RenameOperatoMesAdapterType1786600000000;
66
+ //# sourceMappingURL=1786600000000-RenameOperatoMesAdapterType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1786600000000-RenameOperatoMesAdapterType.js","sourceRoot":"","sources":["../../server/migrations/1786600000000-RenameOperatoMesAdapterType.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAC9B,MAAM,MAAM,GAAG,cAAc,CAAA;AAC7B;;;;;;GAMG;AACH,MAAM,QAAQ,GAAG,aAAa,CAAA;AAC9B,MAAM,GAAG,GAAG,aAAa,CAAA;AACzB,MAAM,GAAG,GAAG,eAAe,CAAA;AAE3B,KAAK,UAAU,MAAM,CAAC,WAAwB,EAAE,IAAY,EAAE,EAAU;IACtE,mCAAmC;IACnC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9C,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;QAAE,OAAM;IAExD,oDAAoD;IACpD,MAAM,WAAW,CAAC,OAAO;SACtB,kBAAkB,EAAE;SACpB,MAAM,CAAC,IAAI,CAAC;SACZ,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;SAC3B,OAAO,EAAE,CAAA;AACd,CAAC;AAED,MAAa,wCAAwC;IAC5C,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;CACF;AARD,4FAQC","sourcesContent":["import { MigrationInterface, QueryRunner } from 'typeorm'\n\n/**\n * `twin_references.adapter_type` โ€” `operato-mes` โ†’ `operato-plant`.\n *\n * โ”€โ”€ ์™œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ํ•„์š”ํ•œ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„ฅํ„ฐ์˜ `type` ์€ **์ €์žฅ๋˜๋Š” ์‹๋ณ„์ž**๋‹ค. ํŠธ์œˆ์„ ์›๋ณธ์— ๋ถ™์ผ ๋•Œ ๊ทธ ๋ฌธ์ž์—ด์ด ์ด ์ปฌ๋Ÿผ์— ์ ํžˆ๊ณ ,\n * ๋„˜๊ธธ ๋•Œยท๋ผ์ด๋ธŒ๋ฅผ ์—ด ๋•Œ ๊ทธ ๊ฐ’์œผ๋กœ ์ปค๋„ฅํ„ฐ๋ฅผ ์ฐพ๋Š”๋‹ค(ยง`getAdapter`).\n *\n * ๊ทธ๋ž˜์„œ ์ œํ’ˆ ๊ฐœ๋ช…(`operato-mes` โ†’ `operato-plant`)์ด ์ฝ”๋“œ๋งŒ ๋ฐ”๋€Œ๋ฉด **์ด๋ฏธ ๋ถ™์–ด ์žˆ๋Š” ์›๋ณธ์ด ์ปค๋„ฅํ„ฐ๋ฅผ\n * ๋ชป ์ฐพ๋Š”๋‹ค.** ๊ทธ๋•Œ ๋‚˜์˜ค๋Š” ๊ฒƒ์€ ์ด๋ ‡๋‹ค.\n *\n * ์กฐ์น˜ ๋„˜๊น€ `no-adapter` ๋กœ ๊ฑฐ์ ˆ\n * ๋ผ์ด๋ธŒ ์ปค๋„ฅํ„ฐ๊ฐ€ ์—†์–ด ๊ด€์ธก์ด ๋Š๊ธด๋‹ค\n * ํ™”๋ฉด ใ€Œ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์ปค๋„ฅํ„ฐ์ž…๋‹ˆ๋‹ค (operato-mes)ใ€ ํ•œ ์ค„\n *\n * **์˜ค๋ฅ˜๋Š” ์•ˆ ๋‚˜๊ณ , ์›์ธ์ด ๊ฐœ๋ช…์ด๋ผ๋Š” ๊ฒƒ์ด ๊ทธ ๋ฌธ์žฅ์— ์—†๋‹ค.** ํŠธ์œˆ์€ ๊ทธ๋Œ€๋กœ ์„œ ์žˆ๊ณ  ๊ฐ’๋งŒ ์•ˆ ์˜จ๋‹ค.\n * ์ด ์ €์žฅ์†Œ์—์„œ ๊ฐœ๋ช…์ด ์ €์žฅ๋œ ์‹๋ณ„์ž์— ๋‹ฟ์•˜์„ ๋•Œ ๋Š˜ ์ด ๋ชจ์–‘์œผ๋กœ ๋‚ฌ๋‹ค(๋ณด๋“œ ํ‚คยท์”ฌ ์ปดํฌ๋„ŒํŠธ ํƒ€์ž…).\n *\n * โ”€โ”€ ์™œ ์ด ํŒจํ‚ค์ง€์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ํ‘œ๋ฅผ ๋“  ์ชฝ์ด ์ด ํŒจํ‚ค์ง€๋‹ค(`twin_references`). ์ปค๋„ฅํ„ฐ๋Š” `operato-twin` ์ด ๋“ฑ๋กํ•˜์ง€๋งŒ, ๊ทธ ๊ฐ’์ด ์‚ฌ๋Š”\n * ์ž๋ฆฌ๋Š” ์—ฌ๊ธฐ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ํ‘œ๋ฅผ ๋“  ํŒจํ‚ค์ง€์— ๋‘”๋‹ค.\n *\n * โ”€โ”€ ๋˜๋Œ๋ฆฌ๊ธฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `down` ์ด ๊ฐ’์„ ๋˜๋Œ๋ฆฐ๋‹ค. ์˜› ์ฝ”๋“œ๋กœ ๋˜๋Œ์•„๊ฐ€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์‹ค์ œ๋กœ ์žˆ๊ณ (๋ฐฐํฌ ๋กค๋ฐฑ), ๊ทธ๋•Œ ๊ฐ’์ด ์ƒˆ ์ด๋ฆ„์œผ๋กœ\n * ๋‚จ์•„ ์žˆ์œผ๋ฉด ๊ฐ™์€ ๊ฒฐํ•จ์ด ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ๋‚œ๋‹ค.\n *\n * ๋ฉฑ๋“ฑ: ํ•ด๋‹นํ•˜๋Š” ํ–‰์ด ์—†์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. TypeORM ์งˆ์˜ ๋นŒ๋”๋งŒ ์“ด๋‹ค โ€” ๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค ํŒŒ๋ผ๋ฏธํ„ฐ\n * ํ‘œ๊ธฐ๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ raw SQL ์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.\n */\nconst REFS = 'twin_references'\nconst COLUMN = 'adapter_type'\n/**\n * ์งˆ์˜ ๋นŒ๋”์—๋Š” **์†์„ฑ ์ด๋ฆ„**์„ ์ค€๋‹ค.\n *\n * ์ฒ˜์Œ์— ์ปฌ๋Ÿผ ์ด๋ฆ„(`adapter_type`)์œผ๋กœ ์ผ๋”๋‹ˆ TypeORM ์ด ํ‘œ ์ด๋ฆ„์„ ์—”ํ‹ฐํ‹ฐ(`TwinReference`)๋กœ ํ’€๊ณ \n * ใ€Œ๊ทธ๋Ÿฐ ์†์„ฑ์ด ์—†๋‹คใ€๋กœ ๊ฑฐ์ ˆํ–ˆ๋‹ค โ€” ํ‘œ ์ด๋ฆ„์„ ์ฃผ๋”๋ผ๋„ ๋งคํ•‘์€ ์—”ํ‹ฐํ‹ฐ ๊ธฐ์ค€์ด๋‹ค. ์ปฌ๋Ÿผ ์ด๋ฆ„์€ ํ‘œ๊ฐ€\n * ์žˆ๋Š”์ง€ ๋ณผ ๋•Œ๋งŒ ์“ด๋‹ค.\n */\nconst PROPERTY = 'adapterType'\nconst OLD = 'operato-mes'\nconst NEW = 'operato-plant'\n\nasync function rename(queryRunner: QueryRunner, from: string, to: string): Promise<void> {\n /* ํ‘œ๊ฐ€ ์•„์ง ์—†๋Š” ๋ฐฐํฌ(์ฒซ ๊ธฐ๋™)์—์„œ๋Š” ํ•  ์ผ์ด ์—†๋‹ค. */\n const table = await queryRunner.getTable(REFS)\n if (!table?.columns.some(c => c.name === COLUMN)) return\n\n /* ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ค€๋‹ค โ€” ๋ฌธ์ž์—ด ์กฐ๊ฑด์€ ๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค ์‹๋ณ„์ž ์ธ์šฉ์ด ๋‹ฌ๋ผ ๊ทธ๋Œ€๋กœ ๋‚˜๊ฐ„๋‹ค. */\n await queryRunner.manager\n .createQueryBuilder()\n .update(REFS)\n .set({ [PROPERTY]: to })\n .where({ [PROPERTY]: from })\n .execute()\n}\n\nexport class RenameOperatoMesAdapterType1786600000000 implements MigrationInterface {\n public async up(queryRunner: QueryRunner): Promise<void> {\n await rename(queryRunner, OLD, NEW)\n }\n\n public async down(queryRunner: QueryRunner): Promise<void> {\n await rename(queryRunner, NEW, OLD)\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class AddDispatchRetryColumns1786700000000 implements MigrationInterface {
3
+ up(queryRunner: QueryRunner): Promise<void>;
4
+ down(queryRunner: QueryRunner): Promise<void>;
5
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddDispatchRetryColumns1786700000000 = void 0;
4
+ /*
5
+ * ์กฐ์น˜ ํ‘œ์— **์ผ๊พผ์ด ์“ธ ๋„ค ์นธ**์„ ๋”ํ•œ๋‹ค.
6
+ *
7
+ * โ”€โ”€ ์™œ ํ‘œ์— ๋‘๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
8
+ * ๋ฌผ๋Ÿฌ์„ฌ์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋‘๋ฉด ์žฌ๊ธฐ๋™์— ์‚ฌ๋ผ์ง€๊ณ , ๊ทธ๋Ÿฌ๋ฉด ๋ฌผ๋Ÿฌ์„œ๋˜ ๊ฒƒ์ด ์ „๋ถ€ ์ฆ‰์‹œ ์žฌ์‹œ๋„๊ฐ€ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ 
9
+ * ์ผ๊พผ์ด ์—ฌ๋Ÿฌ ๋Œ€๊ฐ€ ๋˜๋ฉด ๊ฐ™์€ ๋‹ต์„ ๋ด์•ผ ํ•œ๋‹ค.
10
+ *
11
+ * dispatch_note_next ์ €์ชฝ ๋ง ์ค‘ ใ€Œ๋‹ค์Œ์— ํ•  ์ผใ€ ํ•œ ์ค„ โ€” ์›์ธ์€ dispatch_note
12
+ * retry ๋‹ค์‹œ ํ•ด์„œ ๋  ์ผ์ธ๊ฐ€ (again ยท after-fix ยท never)
13
+ * attempts ๋ช‡ ๋ฒˆ ๋„˜๊ฒจ ๋ดค๋‚˜ โ€” ๋ชฉ๋ก์˜ ใ€Œ๋ช‡ ๋ฒˆ ํ•ด ๋ดค๋‚˜ใ€
14
+ * next_attempt_at ๋‹ค์Œ์— ๋„˜๊ฒจ ๋ณผ ์‹œ๊ฐ(ISO)
15
+ *
16
+ * โ”€โ”€ ํƒ€์ž…์„ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
17
+ * ์—”ํ‹ฐํ‹ฐ๊ฐ€ `@Column({ nullable: true })` ๋กœ ๋‘๋ฉด ๊ทธ๊ฒƒ์ด ์–ด๋А ์ปฌ๋Ÿผ ํƒ€์ž…์ด ๋˜๋Š”์ง€๋Š” **๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค
18
+ * ๋‹ค๋ฅด๋‹ค.** `'varchar'` ๋ผ๊ณ  ์ ์œผ๋ฉด sqliteยทpostgresยทmysql ์—์„œ๋Š” ๋งž๊ณ  MSSQLยทOracle ์—์„œ ์–ด๊ธ‹๋‚œ๋‹ค.
19
+ *
20
+ * ๊ทธ๋ž˜์„œ ๊ฐ™์€ ์„ฑ์งˆ๋กœ **์ด๋ฏธ ์„œ ์žˆ๋Š” ํ˜•์ œ ์นธ**์˜ ํƒ€์ž…์„ ์ฝ์–ด ๊ทธ๋Œ€๋กœ ์“ด๋‹ค โ€” ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์Šค์Šค๋กœ ๊ณ ๋ฅธ
21
+ * ๋‹ต์ด๋ผ ๋‹ค์„ฏ ๊ณณ์—์„œ ๋‹ค ๋งž๋Š”๋‹ค. ํ˜•์ œ๊ฐ€ ์—†์œผ๋ฉด ์ง์ž‘ํ•˜์ง€ ์•Š๊ณ  ๋ฉˆ์ถ˜๋‹ค.
22
+ *
23
+ * ๊ธ€์ž ์…‹ dispatch_note ์—์„œ
24
+ * ์ˆ˜ ํ•˜๋‚˜ effect_seen ์—์„œ
25
+ *
26
+ * plant ๋ ˆ์ธ์ด ์˜ค๋Š˜ `equipmentClassIds` ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—์„œ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ผ๋‹ค.
27
+ *
28
+ * โ”€โ”€ ๋ฉฑ๋“ฑ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
29
+ * ์นธ์ด ์ด๋ฏธ ์žˆ์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๊ฐœ๋ฐœ sqlite ๋Š” ์—”ํ‹ฐํ‹ฐ ์„ ์–ธ๋งŒ์œผ๋กœ ์ด๋ฏธ ๋งŒ๋“ค์–ด ๋‘”๋‹ค.
30
+ * ํ‘œ๊ฐ€ ์•„์ง ์—†๋Š” ์ฒซ ๊ธฐ๋™์—์„œ๋„ ํ•  ์ผ์ด ์—†๋‹ค.
31
+ */
32
+ const typeorm_1 = require("typeorm");
33
+ const TABLE = 'twin_command_records';
34
+ /** ๊ธ€์ž ์นธ์˜ ํ˜•์ œ โ€” ๊ฐ™์€ ์„ฑ์งˆ(์„ ํƒยท์ž์œ  ๋ฌธ์ž์—ด)๋กœ ์ด๋ฏธ ์„œ ์žˆ๋‹ค. */
35
+ const TEXT_SIBLING = 'dispatch_note';
36
+ /** ์ˆ˜ ์นธ์˜ ํ˜•์ œ โ€” ์„ ํƒยท์ •์ˆ˜. */
37
+ const INT_SIBLING = 'effect_seen';
38
+ const TEXT_COLUMNS = ['dispatch_note_next', 'retry', 'next_attempt_at'];
39
+ const INT_COLUMNS = ['attempts'];
40
+ class AddDispatchRetryColumns1786700000000 {
41
+ async up(queryRunner) {
42
+ const table = await queryRunner.getTable(TABLE);
43
+ if (!table)
44
+ return; /* ์ฒซ ๊ธฐ๋™ โ€” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋งŒ๋“ ๋‹ค */
45
+ const typeOf = (sibling) => table.columns.find(c => c.name === sibling)?.type;
46
+ const textType = typeOf(TEXT_SIBLING);
47
+ const intType = typeOf(INT_SIBLING);
48
+ /*
49
+ * ํ˜•์ œ๊ฐ€ ์—†์œผ๋ฉด **๋ฉˆ์ถ˜๋‹ค.** ์ง์ž‘ํ•œ ํƒ€์ž…์œผ๋กœ ์นธ์„ ์„ธ์šฐ๋ฉด ์–ด๋А ๋“œ๋ผ์ด๋ฒ„์—์„œ ์–ด๊ธ‹๋‚˜๋Š”์ง€ ๊ฐœ๋ฐœ์—์„œ
50
+ * ์•ˆ ์žกํžˆ๊ณ , ๊ทธ ๋ฐฐํฌ์—์„œ๋งŒ ๋‚œ๋‹ค.
51
+ */
52
+ if (!textType || !intType) {
53
+ throw new Error(`${TABLE} ์—์„œ ํ˜•์ œ ์นธ์„ ๋ชป ์ฐพ์•˜์Šต๋‹ˆ๋‹ค โ€” ${TEXT_SIBLING}(${textType ?? '์—†์Œ'}) ยท ` +
54
+ `${INT_SIBLING}(${intType ?? '์—†์Œ'}). ํƒ€์ž…์„ ์ง์ž‘ํ•˜์ง€ ์•Š๊ณ  ๋ฉˆ์ถฅ๋‹ˆ๋‹ค`);
55
+ }
56
+ for (const name of TEXT_COLUMNS) {
57
+ if (table.columns.some(c => c.name === name))
58
+ continue;
59
+ await queryRunner.addColumn(TABLE, new typeorm_1.TableColumn({ name, type: textType, isNullable: true }));
60
+ }
61
+ for (const name of INT_COLUMNS) {
62
+ if (table.columns.some(c => c.name === name))
63
+ continue;
64
+ await queryRunner.addColumn(TABLE, new typeorm_1.TableColumn({ name, type: intType, isNullable: true }));
65
+ }
66
+ }
67
+ async down(queryRunner) {
68
+ const table = await queryRunner.getTable(TABLE);
69
+ if (!table)
70
+ return;
71
+ for (const name of [...TEXT_COLUMNS, ...INT_COLUMNS]) {
72
+ if (!table.columns.some(c => c.name === name))
73
+ continue;
74
+ await queryRunner.dropColumn(TABLE, name);
75
+ }
76
+ }
77
+ }
78
+ exports.AddDispatchRetryColumns1786700000000 = AddDispatchRetryColumns1786700000000;
79
+ //# sourceMappingURL=1786700000000-AddDispatchRetryColumns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1786700000000-AddDispatchRetryColumns.js","sourceRoot":"","sources":["../../server/migrations/1786700000000-AddDispatchRetryColumns.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qCAAsE;AAEtE,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAEpC,4CAA4C;AAC5C,MAAM,YAAY,GAAG,eAAe,CAAA;AACpC,uBAAuB;AACvB,MAAM,WAAW,GAAG,aAAa,CAAA;AAEjC,MAAM,YAAY,GAAG,CAAC,oBAAoB,EAAE,OAAO,EAAE,iBAAiB,CAAU,CAAA;AAChF,MAAM,WAAW,GAAG,CAAC,UAAU,CAAU,CAAA;AAEzC,MAAa,oCAAoC;IACxC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAM,CAAC,qBAAqB;QAExC,MAAM,MAAM,GAAG,CAAC,OAAe,EAAsB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,IAAI,CAAA;QAEzG,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,CAAA;QAEnC;;;WAGG;QACH,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,uBAAuB,YAAY,IAAI,QAAQ,IAAI,IAAI,MAAM;gBACnE,GAAG,WAAW,IAAI,OAAO,IAAI,IAAI,qBAAqB,CACzD,CAAA;QACH,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAQ;YACtD,MAAM,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,qBAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACjG,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAQ;YACtD,MAAM,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,qBAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAChG,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,YAAY,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,SAAQ;YACvD,MAAM,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;CACF;AAzCD,oFAyCC","sourcesContent":["/*\n * ์กฐ์น˜ ํ‘œ์— **์ผ๊พผ์ด ์“ธ ๋„ค ์นธ**์„ ๋”ํ•œ๋‹ค.\n *\n * โ”€โ”€ ์™œ ํ‘œ์— ๋‘๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ฌผ๋Ÿฌ์„ฌ์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋‘๋ฉด ์žฌ๊ธฐ๋™์— ์‚ฌ๋ผ์ง€๊ณ , ๊ทธ๋Ÿฌ๋ฉด ๋ฌผ๋Ÿฌ์„œ๋˜ ๊ฒƒ์ด ์ „๋ถ€ ์ฆ‰์‹œ ์žฌ์‹œ๋„๊ฐ€ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ \n * ์ผ๊พผ์ด ์—ฌ๋Ÿฌ ๋Œ€๊ฐ€ ๋˜๋ฉด ๊ฐ™์€ ๋‹ต์„ ๋ด์•ผ ํ•œ๋‹ค.\n *\n * dispatch_note_next ์ €์ชฝ ๋ง ์ค‘ ใ€Œ๋‹ค์Œ์— ํ•  ์ผใ€ ํ•œ ์ค„ โ€” ์›์ธ์€ dispatch_note\n * retry ๋‹ค์‹œ ํ•ด์„œ ๋  ์ผ์ธ๊ฐ€ (again ยท after-fix ยท never)\n * attempts ๋ช‡ ๋ฒˆ ๋„˜๊ฒจ ๋ดค๋‚˜ โ€” ๋ชฉ๋ก์˜ ใ€Œ๋ช‡ ๋ฒˆ ํ•ด ๋ดค๋‚˜ใ€\n * next_attempt_at ๋‹ค์Œ์— ๋„˜๊ฒจ ๋ณผ ์‹œ๊ฐ(ISO)\n *\n * โ”€โ”€ ํƒ€์ž…์„ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์—”ํ‹ฐํ‹ฐ๊ฐ€ `@Column({ nullable: true })` ๋กœ ๋‘๋ฉด ๊ทธ๊ฒƒ์ด ์–ด๋А ์ปฌ๋Ÿผ ํƒ€์ž…์ด ๋˜๋Š”์ง€๋Š” **๋“œ๋ผ์ด๋ฒ„๋งˆ๋‹ค\n * ๋‹ค๋ฅด๋‹ค.** `'varchar'` ๋ผ๊ณ  ์ ์œผ๋ฉด sqliteยทpostgresยทmysql ์—์„œ๋Š” ๋งž๊ณ  MSSQLยทOracle ์—์„œ ์–ด๊ธ‹๋‚œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ๊ฐ™์€ ์„ฑ์งˆ๋กœ **์ด๋ฏธ ์„œ ์žˆ๋Š” ํ˜•์ œ ์นธ**์˜ ํƒ€์ž…์„ ์ฝ์–ด ๊ทธ๋Œ€๋กœ ์“ด๋‹ค โ€” ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์Šค์Šค๋กœ ๊ณ ๋ฅธ\n * ๋‹ต์ด๋ผ ๋‹ค์„ฏ ๊ณณ์—์„œ ๋‹ค ๋งž๋Š”๋‹ค. ํ˜•์ œ๊ฐ€ ์—†์œผ๋ฉด ์ง์ž‘ํ•˜์ง€ ์•Š๊ณ  ๋ฉˆ์ถ˜๋‹ค.\n *\n * ๊ธ€์ž ์…‹ dispatch_note ์—์„œ\n * ์ˆ˜ ํ•˜๋‚˜ effect_seen ์—์„œ\n *\n * plant ๋ ˆ์ธ์ด ์˜ค๋Š˜ `equipmentClassIds` ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—์„œ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ผ๋‹ค.\n *\n * โ”€โ”€ ๋ฉฑ๋“ฑ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์นธ์ด ์ด๋ฏธ ์žˆ์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๊ฐœ๋ฐœ sqlite ๋Š” ์—”ํ‹ฐํ‹ฐ ์„ ์–ธ๋งŒ์œผ๋กœ ์ด๋ฏธ ๋งŒ๋“ค์–ด ๋‘”๋‹ค.\n * ํ‘œ๊ฐ€ ์•„์ง ์—†๋Š” ์ฒซ ๊ธฐ๋™์—์„œ๋„ ํ•  ์ผ์ด ์—†๋‹ค.\n */\nimport { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'\n\nconst TABLE = 'twin_command_records'\n\n/** ๊ธ€์ž ์นธ์˜ ํ˜•์ œ โ€” ๊ฐ™์€ ์„ฑ์งˆ(์„ ํƒยท์ž์œ  ๋ฌธ์ž์—ด)๋กœ ์ด๋ฏธ ์„œ ์žˆ๋‹ค. */\nconst TEXT_SIBLING = 'dispatch_note'\n/** ์ˆ˜ ์นธ์˜ ํ˜•์ œ โ€” ์„ ํƒยท์ •์ˆ˜. */\nconst INT_SIBLING = 'effect_seen'\n\nconst TEXT_COLUMNS = ['dispatch_note_next', 'retry', 'next_attempt_at'] as const\nconst INT_COLUMNS = ['attempts'] as const\n\nexport class AddDispatchRetryColumns1786700000000 implements MigrationInterface {\n public async up(queryRunner: QueryRunner): Promise<void> {\n const table = await queryRunner.getTable(TABLE)\n if (!table) return /* ์ฒซ ๊ธฐ๋™ โ€” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋งŒ๋“ ๋‹ค */\n\n const typeOf = (sibling: string): string | undefined => table.columns.find(c => c.name === sibling)?.type\n\n const textType = typeOf(TEXT_SIBLING)\n const intType = typeOf(INT_SIBLING)\n\n /*\n * ํ˜•์ œ๊ฐ€ ์—†์œผ๋ฉด **๋ฉˆ์ถ˜๋‹ค.** ์ง์ž‘ํ•œ ํƒ€์ž…์œผ๋กœ ์นธ์„ ์„ธ์šฐ๋ฉด ์–ด๋А ๋“œ๋ผ์ด๋ฒ„์—์„œ ์–ด๊ธ‹๋‚˜๋Š”์ง€ ๊ฐœ๋ฐœ์—์„œ\n * ์•ˆ ์žกํžˆ๊ณ , ๊ทธ ๋ฐฐํฌ์—์„œ๋งŒ ๋‚œ๋‹ค.\n */\n if (!textType || !intType) {\n throw new Error(\n `${TABLE} ์—์„œ ํ˜•์ œ ์นธ์„ ๋ชป ์ฐพ์•˜์Šต๋‹ˆ๋‹ค โ€” ${TEXT_SIBLING}(${textType ?? '์—†์Œ'}) ยท ` +\n `${INT_SIBLING}(${intType ?? '์—†์Œ'}). ํƒ€์ž…์„ ์ง์ž‘ํ•˜์ง€ ์•Š๊ณ  ๋ฉˆ์ถฅ๋‹ˆ๋‹ค`\n )\n }\n\n for (const name of TEXT_COLUMNS) {\n if (table.columns.some(c => c.name === name)) continue\n await queryRunner.addColumn(TABLE, new TableColumn({ name, type: textType, isNullable: true }))\n }\n\n for (const name of INT_COLUMNS) {\n if (table.columns.some(c => c.name === name)) continue\n await queryRunner.addColumn(TABLE, new TableColumn({ name, type: intType, isNullable: true }))\n }\n }\n\n public async down(queryRunner: QueryRunner): Promise<void> {\n const table = await queryRunner.getTable(TABLE)\n if (!table) return\n\n for (const name of [...TEXT_COLUMNS, ...INT_COLUMNS]) {\n if (!table.columns.some(c => c.name === name)) continue\n await queryRunner.dropColumn(TABLE, name)\n }\n }\n}\n"]}
@@ -11,12 +11,16 @@ const _1786200000000_CarryLiveFeedCursor_js_1 = require("./1786200000000-CarryLi
11
11
  const _1786300000000_IndexEventTypeByTime_js_1 = require("./1786300000000-IndexEventTypeByTime.js");
12
12
  const _1786400000000_IndexEventCreatedAt_js_1 = require("./1786400000000-IndexEventCreatedAt.js");
13
13
  const _1786500000000_CreateTwinSubjectEvents_js_1 = require("./1786500000000-CreateTwinSubjectEvents.js");
14
+ const _1786700000000_AddDispatchRetryColumns_js_1 = require("./1786700000000-AddDispatchRetryColumns.js");
15
+ const _1786600000000_RenameOperatoMesAdapterType_js_1 = require("./1786600000000-RenameOperatoMesAdapterType.js");
14
16
  exports.migrations = [
15
17
  _1786000000000_RenameTwinInstanceBoardToModel_js_1.RenameTwinInstanceBoardToModel1786000000000,
16
18
  _1786100000000_PromoteEventActionAndSyncWarnings_js_1.PromoteEventActionAndSyncWarnings1786100000000,
17
19
  _1786200000000_CarryLiveFeedCursor_js_1.CarryLiveFeedCursor1786200000000,
18
20
  _1786300000000_IndexEventTypeByTime_js_1.IndexEventTypeByTime1786300000000,
19
21
  _1786400000000_IndexEventCreatedAt_js_1.IndexEventCreatedAt1786400000000,
20
- _1786500000000_CreateTwinSubjectEvents_js_1.CreateTwinSubjectEvents1786500000000
22
+ _1786500000000_CreateTwinSubjectEvents_js_1.CreateTwinSubjectEvents1786500000000,
23
+ _1786600000000_RenameOperatoMesAdapterType_js_1.RenameOperatoMesAdapterType1786600000000,
24
+ _1786700000000_AddDispatchRetryColumns_js_1.AddDispatchRetryColumns1786700000000
21
25
  ];
22
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/migrations/index.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,wHAA+G;AAC/G,8HAAqH;AACrH,kGAAyF;AACzF,oGAA2F;AAC3F,kGAAyF;AACzF,0GAAiG;AAEpF,QAAA,UAAU,GAAG;IACxB,8FAA2C;IAC3C,oGAA8C;IAC9C,wEAAgC;IAChC,0EAAiC;IACjC,wEAAgC;IAChC,gFAAoC;CACrC,CAAA","sourcesContent":["/*\n * ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋ฌถ์Œ โ€” ํ”„๋ ˆ์ž„์›Œํฌ ๊ทœ์•ฝ(`@things-factory/shell` ยท `auth-base` ์™€ ๊ฐ™์€ ๋ฐฉ์‹).\n * ํŒŒ์ผ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ export ํ•˜๊ณ  ์—ฌ๊ธฐ์„œ ๋ชจ์•„ `server/index.ts` ๊ฐ€ ๋‚ด๋ณด๋‚ธ๋‹ค.\n */\nimport { RenameTwinInstanceBoardToModel1786000000000 } from './1786000000000-RenameTwinInstanceBoardToModel.js'\nimport { PromoteEventActionAndSyncWarnings1786100000000 } from './1786100000000-PromoteEventActionAndSyncWarnings.js'\nimport { CarryLiveFeedCursor1786200000000 } from './1786200000000-CarryLiveFeedCursor.js'\nimport { IndexEventTypeByTime1786300000000 } from './1786300000000-IndexEventTypeByTime.js'\nimport { IndexEventCreatedAt1786400000000 } from './1786400000000-IndexEventCreatedAt.js'\nimport { CreateTwinSubjectEvents1786500000000 } from './1786500000000-CreateTwinSubjectEvents.js'\n\nexport const migrations = [\n RenameTwinInstanceBoardToModel1786000000000,\n PromoteEventActionAndSyncWarnings1786100000000,\n CarryLiveFeedCursor1786200000000,\n IndexEventTypeByTime1786300000000,\n IndexEventCreatedAt1786400000000,\n CreateTwinSubjectEvents1786500000000\n]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/migrations/index.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,wHAA+G;AAC/G,8HAAqH;AACrH,kGAAyF;AACzF,oGAA2F;AAC3F,kGAAyF;AACzF,0GAAiG;AACjG,0GAAiG;AACjG,kHAAyG;AAE5F,QAAA,UAAU,GAAG;IACxB,8FAA2C;IAC3C,oGAA8C;IAC9C,wEAAgC;IAChC,0EAAiC;IACjC,wEAAgC;IAChC,gFAAoC;IACpC,wFAAwC;IACxC,gFAAoC;CACrC,CAAA","sourcesContent":["/*\n * ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋ฌถ์Œ โ€” ํ”„๋ ˆ์ž„์›Œํฌ ๊ทœ์•ฝ(`@things-factory/shell` ยท `auth-base` ์™€ ๊ฐ™์€ ๋ฐฉ์‹).\n * ํŒŒ์ผ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ export ํ•˜๊ณ  ์—ฌ๊ธฐ์„œ ๋ชจ์•„ `server/index.ts` ๊ฐ€ ๋‚ด๋ณด๋‚ธ๋‹ค.\n */\nimport { RenameTwinInstanceBoardToModel1786000000000 } from './1786000000000-RenameTwinInstanceBoardToModel.js'\nimport { PromoteEventActionAndSyncWarnings1786100000000 } from './1786100000000-PromoteEventActionAndSyncWarnings.js'\nimport { CarryLiveFeedCursor1786200000000 } from './1786200000000-CarryLiveFeedCursor.js'\nimport { IndexEventTypeByTime1786300000000 } from './1786300000000-IndexEventTypeByTime.js'\nimport { IndexEventCreatedAt1786400000000 } from './1786400000000-IndexEventCreatedAt.js'\nimport { CreateTwinSubjectEvents1786500000000 } from './1786500000000-CreateTwinSubjectEvents.js'\nimport { AddDispatchRetryColumns1786700000000 } from './1786700000000-AddDispatchRetryColumns.js'\nimport { RenameOperatoMesAdapterType1786600000000 } from './1786600000000-RenameOperatoMesAdapterType.js'\n\nexport const migrations = [\n RenameTwinInstanceBoardToModel1786000000000,\n PromoteEventActionAndSyncWarnings1786100000000,\n CarryLiveFeedCursor1786200000000,\n IndexEventTypeByTime1786300000000,\n IndexEventCreatedAt1786400000000,\n CreateTwinSubjectEvents1786500000000,\n RenameOperatoMesAdapterType1786600000000,\n AddDispatchRetryColumns1786700000000\n]\n"]}
@@ -17,9 +17,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  * ๋Œ€์‹  **์—ฐ๊ฒฐ๋งˆ๋‹ค ๋น„๋ฐ€๊ฐ’**์„ ๋‘๊ณ  ๊ทธ๊ฒƒ์œผ๋กœ ํ™•์ธํ•œ๋‹ค. ๋น„๋ฐ€๊ฐ’์„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ์—ฐ๊ฒฐ์€ ํ›…์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค โ€”
18
18
  * ์ธ์ฆ ์—†๋Š” ์ž…๊ตฌ๋ฅผ ์—ด์–ด ๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ํ›…์„ ๋ชป ์“ฐ๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค.
19
19
  */
20
- const canonical_ingest_js_1 = require("./engine/canonical-ingest.js");
21
- const twin_engine_js_1 = require("./engine/twin-engine.js");
20
+ const live_ingest_js_1 = require("./service/reference/live-ingest.js");
21
+ const fill_loop_js_1 = require("./service/reference/fill-loop.js");
22
22
  const reference_hook_js_1 = require("./service/reference/reference-hook.js");
23
+ const hook_store_js_1 = require("./service/reference/hook-store.js");
23
24
  process.on('bootstrap-module-domain-public-route', (_app, router) => {
24
25
  /*
25
26
  * ์ฃผ์†Œ์— ํŠธ์œˆ๊นŒ์ง€ ์ ๋Š”๋‹ค โ€” ์–ด๋А ํŠธ์œˆ์— ๋„ฃ์„์ง€ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
@@ -40,24 +41,26 @@ process.on('bootstrap-module-domain-public-route', (_app, router) => {
40
41
  instanceId: String(ctx.params.instanceId ?? ''),
41
42
  headers: (ctx.request?.headers ?? {}),
42
43
  body: ctx.request?.body,
44
+ /*
45
+ * ๋ฐ›์€ ๋ฐ”์ดํŠธ ๊ทธ๋Œ€๋กœ โ€” ์„œ๋ช…์„ ํ™•์ธํ•˜๋ ค๋ฉด ์ด๊ฒƒ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. `koa-bodyparser` ๊ฐ€ ํŒŒ์‹ฑํ•œ ๋ณธ๋ฌธ๊ณผ
46
+ * ํ•จ๊ป˜ ๋‚จ๊ฒจ ์ค€๋‹ค. ํŒŒ์‹ฑ๋ณธ์„ ๋‹ค์‹œ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค๋ฉด ํ‚ค ์ˆœ์„œ์™€ ๊ณต๋ฐฑ์ด ๋‹ฌ๋ผ์ ธ ์„œ๋ช…์ด ๋งž์ง€ ์•Š๋Š”๋‹ค.
47
+ */
48
+ rawBody: typeof ctx.request?.rawBody === 'string' ? ctx.request.rawBody : undefined,
49
+ store: (0, hook_store_js_1.databaseStore)(),
43
50
  /*
44
51
  * ํด๋ง์ด ์“ฐ๋Š” ๊ธธ์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค โ€” ๊ฒ€์ฆ๋„ ์œ ์ž…๋„ ๊ฐ™์€ ์ž๋ฆฌ๋‹ค. ๊ทธ๋ž˜์„œ ํŠธ์œˆ ์ชฝ์—์„œ๋Š” ๋ฌผ์–ด์„œ ๋ฐ›์€
45
52
  * ๊ฒƒ๊ณผ ๋ฐ€์–ด ๋ฐ›์€ ๊ฒƒ์ด ๊ตฌ๋ณ„๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ตฌ๋ณ„๋˜๋Š” ๊ฒƒ์€ ์œ ์ž… ์žฅ๋ถ€์˜ `sources` ํ•œ ์ค„๋ฟ์ด๋‹ค.
46
53
  */
47
- ingest: (instanceId, records) => {
48
- const { accepted, rejected, masterData } = (0, canonical_ingest_js_1.ingestCanonicalRecords)(records, domain.id, new Date().toISOString(), twin_engine_js_1.TwinEngine.factScope(domain.id, instanceId));
49
- /* ์‚ฌ๊ฑด์ด ์•„๋‹Œ ๊ฒƒ์€ ์ƒํƒœ๋งŒ ์„ธ์šด๋‹ค โ€” ๋ฐ€์–ด ๋ฐ›๋Š” ๊ธธ๋„ ๊ฐ™์€ ๊ทœ์œจ์ด๋‹ค(ยง`applyMasterData`). */
50
- if (masterData.length)
51
- twin_engine_js_1.TwinEngine.applyMasterData(domain.id, instanceId, masterData);
52
- const { applied, duplicates } = twin_engine_js_1.TwinEngine.ingestLiveResult(domain.id, instanceId, accepted, 'hook');
53
- /*
54
- * ์ปค๋„์ด ๋ฐ›์ง€ ๋ชปํ•œ ์ˆ˜๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋‚จ๊ธด๋‹ค โ€” ํŠธ์œˆ์ด ๋ฉˆ์ถ˜ ์‚ฌ์ด ๋ฒ„๋ ค์ง„ ๋ ˆ์ฝ”๋“œ๋ฅผ ใ€Œํ†ต๊ณผใ€๋กœ ์„ธ๋ฉด
55
- * ํ™”๋ฉด์ด 100% ๋ผ๊ณ  ๋งํ•œ๋‹ค. ์ค‘๋ณต์œผ๋กœ ๊ฑธ๋Ÿฌ์ง„ ๊ฒƒ์€ ๋ฒ„๋ ค์ง„ ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœ ๋นผ๊ณ  ์„ผ๋‹ค.
56
- */
57
- const undelivered = Math.max(0, accepted.length - applied - duplicates);
58
- twin_engine_js_1.TwinEngine.recordIngestResult(domain.id, instanceId, records.length, rejected, Date.now(), undelivered);
59
- return { applied, duplicates, rejected: rejected.length };
60
- }
54
+ /*
55
+ * ์œ ์ž… ๋ชธํ†ต์€ `live-ingest.ts` ํ•œ ๊ณณ์— ์žˆ๋‹ค โ€” backfill ์ด ๊ฐ™์€ ๊ฒƒ์„ ์“ด๋‹ค. ์—ฌ๊ธฐ์— ๋‘๋ฉด ๋‘ ๊ธธ์ด
56
+ * ์„œ๋กœ ๋‹ค๋ฅธ ๊ทœ์น™์œผ๋กœ ๋ฐ›๊ฒŒ ๋˜๊ณ , ํ•œ์ชฝ๋งŒ ์ˆ˜์ •๋˜๋Š” ๋‚ ์ด ์˜จ๋‹ค.
57
+ */
58
+ ingest: (instanceId, records) => (0, live_ingest_js_1.liveIngest)(domain.id, instanceId, records, 'hook'),
59
+ /*
60
+ * ๊ตฌ๋ฉ์„ ๋ณธ ๊ทธ ์ž๋ฆฌ์—์„œ ๋ฐ”๋กœ ๋ฐ›๋Š”๋‹ค โ€” ๋ฒˆํ˜ธ๊ฐ€ ๋น„์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•„๋Š” ๊ฐ€์žฅ ์ด๋ฅธ ์ˆœ๊ฐ„์ด๋‹ค.
61
+ * ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๋‹ค(ยง`requestFill`): ํ›…์˜ ์‘๋‹ต์ด ๋Šฆ์œผ๋ฉด ๋ณด๋‚ด๋Š” ์ชฝ์ด ๋˜ํ’€์ดํ•œ๋‹ค.
62
+ */
63
+ onGap: scope => (0, fill_loop_js_1.requestFill)(domain.id, String(ctx.params.instanceId ?? ''), scope)
61
64
  });
62
65
  ctx.status = outcome.status;
63
66
  ctx.body = outcome.body;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../server/routes.ts"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,sEAAqE;AACrE,4DAAoD;AACpD,6EAAkE;AAElE,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,IAAS,EAAE,MAAW,EAAE,EAAE;IACnF;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,CAAA;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,GAAG,GAAG,CAAA;YAChB,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAU,EAAC;YAC/B,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YACvC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAA4B;YAChE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI;YACvB;;;eAGG;YACH,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;gBAC9B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAA,4CAAsB,EAC/D,OAAc,EACd,MAAM,CAAC,EAAE,EACT,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EACxB,2BAAU,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAC5C,CAAA;gBACD,+DAA+D;gBAC/D,IAAI,UAAU,CAAC,MAAM;oBAAE,2BAAU,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC,CAAA;gBACpF,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,2BAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;gBACpG;;;mBAGG;gBACH,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC,CAAA;gBACvE,2BAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAA;gBACvG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;YAC3D,CAAC;SACF,CAAC,CAAA;QACF,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC3B,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,2DAA2D;AAC3D,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA;AAC1F,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA;AAC3F,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA","sourcesContent":["/*\n * ์ด ํŒจํ‚ค์ง€๊ฐ€ ์—ฌ๋Š” HTTP ์ž๋ฆฌ โ€” ์ง€๊ธˆ์€ ์›นํ›… ํ•˜๋‚˜๋‹ค.\n *\n * โ”€โ”€ ์™œ ์—ฌ๊ธฐ์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„ฅํ„ฐ๋Š” ์ฃผ์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค. ์–ด๋Œ‘ํ„ฐ ๊ณ„์•ฝ์— ์ฃผ์†Œ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ์ž๋ฆฌ๊ฐ€ ์—†๊ณ , ์žˆ์–ด์„œ๋„ ์•ˆ ๋œ๋‹ค โ€” ์ฃผ์†Œ๋Š”\n * ์•ฑ์˜ ๊ฒƒ์ด๊ณ  ์ปค๋„ฅํ„ฐ๋งˆ๋‹ค ์ œ๊ฐ๊ธฐ ์—ด๋ฉด ์ธ์ฆ๋„ ์ œ๊ฐ๊ธฐ๊ฐ€ ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ž…๊ตฌ๋Š” **ํ•˜๋‚˜**๋‹ค. ์–ด๋А ์—ฐ๊ฒฐ์˜ ๊ฒƒ์ธ์ง€๋Š” ์ฃผ์†Œ์˜ ์ด๋ฆ„์œผ๋กœ ๊ฐ€๋ ค๋‚ด๊ณ , ๋ณธ๋ฌธ์„ ์šฐ๋ฆฌ ์–ดํœ˜๋กœ ์˜ฎ๊ธฐ๋Š”\n * ๊ฒƒ์€ ๊ทธ ์—ฐ๊ฒฐ์˜ ์ปค๋„ฅํ„ฐ๊ฐ€ ํ•œ๋‹ค(ยง`reference-hook`).\n *\n * โ”€โ”€ ์™œ ๋„๋ฉ”์ธ ๊ณต๊ฐœ ๋ผ์šฐํ„ฐ์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ฐ€์–ด ์ฃผ๋Š” ์ชฝ์€ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋‹ค. ์‚ฌ๋žŒ ์ธ์ฆ(JWT)์„ ์š”๊ตฌํ•˜๋ฉด ์—ฐ๊ฒฐ๋œ ์‹œ์Šคํ…œ์ด ์šฐ๋ฆฌ ํ† ํฐ์„ ๋ฐœ๊ธ‰๋ฐ›์•„\n * ๊ฐฑ์‹ ํ•˜๋ฉฐ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ํ˜„์žฅ์—์„œ ๊ทธ๊ฒƒ ๋•Œ๋ฌธ์— ์—ฐ๋™์ด ์„œ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ๋Œ€์‹  **์—ฐ๊ฒฐ๋งˆ๋‹ค ๋น„๋ฐ€๊ฐ’**์„ ๋‘๊ณ  ๊ทธ๊ฒƒ์œผ๋กœ ํ™•์ธํ•œ๋‹ค. ๋น„๋ฐ€๊ฐ’์„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ์—ฐ๊ฒฐ์€ ํ›…์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค โ€”\n * ์ธ์ฆ ์—†๋Š” ์ž…๊ตฌ๋ฅผ ์—ด์–ด ๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ํ›…์„ ๋ชป ์“ฐ๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค.\n */\nimport { ingestCanonicalRecords } from './engine/canonical-ingest.js'\nimport { TwinEngine } from './engine/twin-engine.js'\nimport { handleHook } from './service/reference/reference-hook.js'\n\nprocess.on('bootstrap-module-domain-public-route' as any, (_app: any, router: any) => {\n /*\n * ์ฃผ์†Œ์— ํŠธ์œˆ๊นŒ์ง€ ์ ๋Š”๋‹ค โ€” ์–ด๋А ํŠธ์œˆ์— ๋„ฃ์„์ง€ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.\n *\n * ํ•œ ์—ฐ๊ฒฐ์ด ์—ฌ๋Ÿฌ ์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ํŠธ์œˆ๋„ ์—ฌ๋Ÿฟ์ด๋‹ค. ๋ณธ๋ฌธ์„ ๋ณด๊ณ  ๊ณ ๋ฅด๊ฒŒ ํ•˜๋ฉด ๊ทธ ํŒ๋‹จ์ด ์ปค๋„ฅํ„ฐ๋งˆ๋‹ค\n * ๋‹ฌ๋ผ์ง€๊ณ , ํ‹€๋ฆฌ๋ฉด ๋‹ค๋ฅธ ๊ณต์žฅ์˜ ์‚ฌ์‹ค์ด ์ด ๊ณต์žฅ์— ๋“ค์–ด๊ฐ„๋‹ค. ์ฃผ์†Œ๊ฐ€ ๋งํ•˜๊ฒŒ ํ•˜๋ฉด ๊ทธ ์ผ์ด ์—†๋‹ค.\n */\n router.post('/twin/hook/:source/:instanceId', async (ctx: any) => {\n const domain = ctx.state?.domain\n if (!domain) {\n ctx.status = 400\n ctx.body = { ok: false, error: 'no domain context' }\n return\n }\n const outcome = await handleHook({\n domainId: domain.id,\n source: String(ctx.params.source ?? ''),\n instanceId: String(ctx.params.instanceId ?? ''),\n headers: (ctx.request?.headers ?? {}) as Record<string, unknown>,\n body: ctx.request?.body,\n /*\n * ํด๋ง์ด ์“ฐ๋Š” ๊ธธ์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค โ€” ๊ฒ€์ฆ๋„ ์œ ์ž…๋„ ๊ฐ™์€ ์ž๋ฆฌ๋‹ค. ๊ทธ๋ž˜์„œ ํŠธ์œˆ ์ชฝ์—์„œ๋Š” ๋ฌผ์–ด์„œ ๋ฐ›์€\n * ๊ฒƒ๊ณผ ๋ฐ€์–ด ๋ฐ›์€ ๊ฒƒ์ด ๊ตฌ๋ณ„๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ตฌ๋ณ„๋˜๋Š” ๊ฒƒ์€ ์œ ์ž… ์žฅ๋ถ€์˜ `sources` ํ•œ ์ค„๋ฟ์ด๋‹ค.\n */\n ingest: (instanceId, records) => {\n const { accepted, rejected, masterData } = ingestCanonicalRecords(\n records as any,\n domain.id,\n new Date().toISOString(),\n TwinEngine.factScope(domain.id, instanceId)\n )\n /* ์‚ฌ๊ฑด์ด ์•„๋‹Œ ๊ฒƒ์€ ์ƒํƒœ๋งŒ ์„ธ์šด๋‹ค โ€” ๋ฐ€์–ด ๋ฐ›๋Š” ๊ธธ๋„ ๊ฐ™์€ ๊ทœ์œจ์ด๋‹ค(ยง`applyMasterData`). */\n if (masterData.length) TwinEngine.applyMasterData(domain.id, instanceId, masterData)\n const { applied, duplicates } = TwinEngine.ingestLiveResult(domain.id, instanceId, accepted, 'hook')\n /*\n * ์ปค๋„์ด ๋ฐ›์ง€ ๋ชปํ•œ ์ˆ˜๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋‚จ๊ธด๋‹ค โ€” ํŠธ์œˆ์ด ๋ฉˆ์ถ˜ ์‚ฌ์ด ๋ฒ„๋ ค์ง„ ๋ ˆ์ฝ”๋“œ๋ฅผ ใ€Œํ†ต๊ณผใ€๋กœ ์„ธ๋ฉด\n * ํ™”๋ฉด์ด 100% ๋ผ๊ณ  ๋งํ•œ๋‹ค. ์ค‘๋ณต์œผ๋กœ ๊ฑธ๋Ÿฌ์ง„ ๊ฒƒ์€ ๋ฒ„๋ ค์ง„ ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœ ๋นผ๊ณ  ์„ผ๋‹ค.\n */\n const undelivered = Math.max(0, accepted.length - applied - duplicates)\n TwinEngine.recordIngestResult(domain.id, instanceId, records.length, rejected, Date.now(), undelivered)\n return { applied, duplicates, rejected: rejected.length }\n }\n })\n ctx.status = outcome.status\n ctx.body = outcome.body\n })\n})\n\n/* ๋‚˜๋จธ์ง€ ์…‹์€ ์ด ํŒจํ‚ค์ง€๊ฐ€ ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์ž๋ฆฌ๋Š” ๋‚จ๊ฒจ ๋‘”๋‹ค(๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด ๊ฐ™์€ ์‹ ํ˜ธ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค). */\nprocess.on('bootstrap-module-global-public-route' as any, (_app: any, _router: any) => {})\nprocess.on('bootstrap-module-global-private-route' as any, (_app: any, _router: any) => {})\nprocess.on('bootstrap-module-domain-private-route' as any, (_app: any, _router: any) => {})\n"]}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../server/routes.ts"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,uEAA+D;AAC/D,mEAA8D;AAC9D,6EAAkE;AAClE,qEAAiE;AAEjE,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,IAAS,EAAE,MAAW,EAAE,EAAE;IACnF;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,CAAA;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,GAAG,GAAG,CAAA;YAChB,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAU,EAAC;YAC/B,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YACvC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAA4B;YAChE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI;YACvB;;;eAGG;YACH,OAAO,EAAE,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACnF,KAAK,EAAE,IAAA,6BAAa,GAAE;YACtB;;;eAGG;YACH;;;eAGG;YACH,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC,IAAA,2BAAU,EAAC,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;YACnF;;;eAGG;YACH,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,IAAA,0BAAW,EAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC;SACnF,CAAC,CAAA;QACF,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC3B,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,2DAA2D;AAC3D,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA;AAC1F,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA;AAC3F,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,IAAS,EAAE,OAAY,EAAE,EAAE,GAAE,CAAC,CAAC,CAAA","sourcesContent":["/*\n * ์ด ํŒจํ‚ค์ง€๊ฐ€ ์—ฌ๋Š” HTTP ์ž๋ฆฌ โ€” ์ง€๊ธˆ์€ ์›นํ›… ํ•˜๋‚˜๋‹ค.\n *\n * โ”€โ”€ ์™œ ์—ฌ๊ธฐ์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ปค๋„ฅํ„ฐ๋Š” ์ฃผ์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค. ์–ด๋Œ‘ํ„ฐ ๊ณ„์•ฝ์— ์ฃผ์†Œ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ์ž๋ฆฌ๊ฐ€ ์—†๊ณ , ์žˆ์–ด์„œ๋„ ์•ˆ ๋œ๋‹ค โ€” ์ฃผ์†Œ๋Š”\n * ์•ฑ์˜ ๊ฒƒ์ด๊ณ  ์ปค๋„ฅํ„ฐ๋งˆ๋‹ค ์ œ๊ฐ๊ธฐ ์—ด๋ฉด ์ธ์ฆ๋„ ์ œ๊ฐ๊ธฐ๊ฐ€ ๋œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ž…๊ตฌ๋Š” **ํ•˜๋‚˜**๋‹ค. ์–ด๋А ์—ฐ๊ฒฐ์˜ ๊ฒƒ์ธ์ง€๋Š” ์ฃผ์†Œ์˜ ์ด๋ฆ„์œผ๋กœ ๊ฐ€๋ ค๋‚ด๊ณ , ๋ณธ๋ฌธ์„ ์šฐ๋ฆฌ ์–ดํœ˜๋กœ ์˜ฎ๊ธฐ๋Š”\n * ๊ฒƒ์€ ๊ทธ ์—ฐ๊ฒฐ์˜ ์ปค๋„ฅํ„ฐ๊ฐ€ ํ•œ๋‹ค(ยง`reference-hook`).\n *\n * โ”€โ”€ ์™œ ๋„๋ฉ”์ธ ๊ณต๊ฐœ ๋ผ์šฐํ„ฐ์ธ๊ฐ€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ฐ€์–ด ์ฃผ๋Š” ์ชฝ์€ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋‹ค. ์‚ฌ๋žŒ ์ธ์ฆ(JWT)์„ ์š”๊ตฌํ•˜๋ฉด ์—ฐ๊ฒฐ๋œ ์‹œ์Šคํ…œ์ด ์šฐ๋ฆฌ ํ† ํฐ์„ ๋ฐœ๊ธ‰๋ฐ›์•„\n * ๊ฐฑ์‹ ํ•˜๋ฉฐ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ํ˜„์žฅ์—์„œ ๊ทธ๊ฒƒ ๋•Œ๋ฌธ์— ์—ฐ๋™์ด ์„œ์ง€ ์•Š๋Š”๋‹ค.\n *\n * ๋Œ€์‹  **์—ฐ๊ฒฐ๋งˆ๋‹ค ๋น„๋ฐ€๊ฐ’**์„ ๋‘๊ณ  ๊ทธ๊ฒƒ์œผ๋กœ ํ™•์ธํ•œ๋‹ค. ๋น„๋ฐ€๊ฐ’์„ ์„ ์–ธํ•˜์ง€ ์•Š์€ ์—ฐ๊ฒฐ์€ ํ›…์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค โ€”\n * ์ธ์ฆ ์—†๋Š” ์ž…๊ตฌ๋ฅผ ์—ด์–ด ๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ํ›…์„ ๋ชป ์“ฐ๋Š” ๊ฒƒ์ด ๋‚ซ๋‹ค.\n */\nimport { liveIngest } from './service/reference/live-ingest.js'\nimport { requestFill } from './service/reference/fill-loop.js'\nimport { handleHook } from './service/reference/reference-hook.js'\nimport { databaseStore } from './service/reference/hook-store.js'\n\nprocess.on('bootstrap-module-domain-public-route' as any, (_app: any, router: any) => {\n /*\n * ์ฃผ์†Œ์— ํŠธ์œˆ๊นŒ์ง€ ์ ๋Š”๋‹ค โ€” ์–ด๋А ํŠธ์œˆ์— ๋„ฃ์„์ง€ ์ง์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.\n *\n * ํ•œ ์—ฐ๊ฒฐ์ด ์—ฌ๋Ÿฌ ์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ํŠธ์œˆ๋„ ์—ฌ๋Ÿฟ์ด๋‹ค. ๋ณธ๋ฌธ์„ ๋ณด๊ณ  ๊ณ ๋ฅด๊ฒŒ ํ•˜๋ฉด ๊ทธ ํŒ๋‹จ์ด ์ปค๋„ฅํ„ฐ๋งˆ๋‹ค\n * ๋‹ฌ๋ผ์ง€๊ณ , ํ‹€๋ฆฌ๋ฉด ๋‹ค๋ฅธ ๊ณต์žฅ์˜ ์‚ฌ์‹ค์ด ์ด ๊ณต์žฅ์— ๋“ค์–ด๊ฐ„๋‹ค. ์ฃผ์†Œ๊ฐ€ ๋งํ•˜๊ฒŒ ํ•˜๋ฉด ๊ทธ ์ผ์ด ์—†๋‹ค.\n */\n router.post('/twin/hook/:source/:instanceId', async (ctx: any) => {\n const domain = ctx.state?.domain\n if (!domain) {\n ctx.status = 400\n ctx.body = { ok: false, error: 'no domain context' }\n return\n }\n const outcome = await handleHook({\n domainId: domain.id,\n source: String(ctx.params.source ?? ''),\n instanceId: String(ctx.params.instanceId ?? ''),\n headers: (ctx.request?.headers ?? {}) as Record<string, unknown>,\n body: ctx.request?.body,\n /*\n * ๋ฐ›์€ ๋ฐ”์ดํŠธ ๊ทธ๋Œ€๋กœ โ€” ์„œ๋ช…์„ ํ™•์ธํ•˜๋ ค๋ฉด ์ด๊ฒƒ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. `koa-bodyparser` ๊ฐ€ ํŒŒ์‹ฑํ•œ ๋ณธ๋ฌธ๊ณผ\n * ํ•จ๊ป˜ ๋‚จ๊ฒจ ์ค€๋‹ค. ํŒŒ์‹ฑ๋ณธ์„ ๋‹ค์‹œ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค๋ฉด ํ‚ค ์ˆœ์„œ์™€ ๊ณต๋ฐฑ์ด ๋‹ฌ๋ผ์ ธ ์„œ๋ช…์ด ๋งž์ง€ ์•Š๋Š”๋‹ค.\n */\n rawBody: typeof ctx.request?.rawBody === 'string' ? ctx.request.rawBody : undefined,\n store: databaseStore(),\n /*\n * ํด๋ง์ด ์“ฐ๋Š” ๊ธธ์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค โ€” ๊ฒ€์ฆ๋„ ์œ ์ž…๋„ ๊ฐ™์€ ์ž๋ฆฌ๋‹ค. ๊ทธ๋ž˜์„œ ํŠธ์œˆ ์ชฝ์—์„œ๋Š” ๋ฌผ์–ด์„œ ๋ฐ›์€\n * ๊ฒƒ๊ณผ ๋ฐ€์–ด ๋ฐ›์€ ๊ฒƒ์ด ๊ตฌ๋ณ„๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ตฌ๋ณ„๋˜๋Š” ๊ฒƒ์€ ์œ ์ž… ์žฅ๋ถ€์˜ `sources` ํ•œ ์ค„๋ฟ์ด๋‹ค.\n */\n /*\n * ์œ ์ž… ๋ชธํ†ต์€ `live-ingest.ts` ํ•œ ๊ณณ์— ์žˆ๋‹ค โ€” backfill ์ด ๊ฐ™์€ ๊ฒƒ์„ ์“ด๋‹ค. ์—ฌ๊ธฐ์— ๋‘๋ฉด ๋‘ ๊ธธ์ด\n * ์„œ๋กœ ๋‹ค๋ฅธ ๊ทœ์น™์œผ๋กœ ๋ฐ›๊ฒŒ ๋˜๊ณ , ํ•œ์ชฝ๋งŒ ์ˆ˜์ •๋˜๋Š” ๋‚ ์ด ์˜จ๋‹ค.\n */\n ingest: (instanceId, records) => liveIngest(domain.id, instanceId, records, 'hook'),\n /*\n * ๊ตฌ๋ฉ์„ ๋ณธ ๊ทธ ์ž๋ฆฌ์—์„œ ๋ฐ”๋กœ ๋ฐ›๋Š”๋‹ค โ€” ๋ฒˆํ˜ธ๊ฐ€ ๋น„์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•„๋Š” ๊ฐ€์žฅ ์ด๋ฅธ ์ˆœ๊ฐ„์ด๋‹ค.\n * ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๋‹ค(ยง`requestFill`): ํ›…์˜ ์‘๋‹ต์ด ๋Šฆ์œผ๋ฉด ๋ณด๋‚ด๋Š” ์ชฝ์ด ๋˜ํ’€์ดํ•œ๋‹ค.\n */\n onGap: scope => requestFill(domain.id, String(ctx.params.instanceId ?? ''), scope)\n })\n ctx.status = outcome.status\n ctx.body = outcome.body\n })\n})\n\n/* ๋‚˜๋จธ์ง€ ์…‹์€ ์ด ํŒจํ‚ค์ง€๊ฐ€ ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์ž๋ฆฌ๋Š” ๋‚จ๊ฒจ ๋‘”๋‹ค(๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด ๊ฐ™์€ ์‹ ํ˜ธ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค). */\nprocess.on('bootstrap-module-global-public-route' as any, (_app: any, _router: any) => {})\nprocess.on('bootstrap-module-global-private-route' as any, (_app: any, _router: any) => {})\nprocess.on('bootstrap-module-domain-private-route' as any, (_app: any, _router: any) => {})\n"]}
@@ -0,0 +1,60 @@
1
+ import type { StoredCommand } from './command-dispatcher.js';
2
+ import type { TwinNow } from './twin-now.js';
3
+ /**
4
+ * AI ๊ฐ€ ์–ด๋–ค ํƒœ๋„๋ฅผ ๋ƒˆ๋‚˜ โ€” **์„ธ ๊ฐˆ๋ž˜์—ฌ์•ผ ํ•œ๋‹ค.**
5
+ *
6
+ * ใ€Œ๋ชจ๋ฅด๊ฒ ๋‹คใ€๊ฐ€ ์—†์œผ๋ฉด ๋ชจ๋ฅผ ๋•Œ ๋™์˜๋กœ ๋‹ตํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์Šน์ธ์ž๊ฐ€ ๊ทธ๊ฒƒ์„ ใ€ŒAI ๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ํ–ˆ๋‹คใ€๋กœ ์ฝ๋Š”๋‹ค.
7
+ * ์ž๋™ ์Šน์ธ ํŽธํ–ฅ์ด ๊ฑฐ๊ธฐ์„œ ์‹œ์ž‘ํ•œ๋‹ค.
8
+ */
9
+ export type AdvisorStance = 'object' | 'concur' | 'unsure';
10
+ export interface AdvisorOpinion {
11
+ stance: AdvisorStance;
12
+ /** ์‚ฌ๋žŒ์ด ์ฝ๋Š” ๋ฌธ์žฅ. AI ๊ฐ€ ์“ด ๊ทธ๋Œ€๋กœ โ€” ์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋“ฌ์ง€ ์•Š๋Š”๋‹ค(๋‹ค๋“ฌ์œผ๋ฉด ๋ˆ„๊ฐ€ ๋งํ•œ ๊ฒƒ์ธ์ง€ ํ๋ ค์ง„๋‹ค). */
13
+ text: string;
14
+ /** ๋ฌด์—‡์„ ๋ณด๊ณ  ๋งํ–ˆ๋‚˜ โ€” ์ฃผ์˜ ์‹๋ณ„์žยท๊ฐ’. ์Šน์ธ์ž๊ฐ€ ๊ทผ๊ฑฐ๋ฅผ ๋˜์งš์„ ์ˆ˜ ์žˆ๊ฒŒ. */
15
+ basis?: string[];
16
+ }
17
+ /** ์˜๊ฒฌ์„ ๋‚ด๋Š” ์ž๋ฆฌ โ€” ์•ฑ์ด ์ฑ„์šด๋‹ค(headless-twin ์€ `twin-ai` ๋ฅผ ๋ถ€๋ฅด์ง€ ์•Š๋Š”๋‹ค). */
18
+ export interface ActuationAdvisor {
19
+ /** ํ™”๋ฉด์ด ์ถœ์ฒ˜๋ฅผ ๋งํ•ด์•ผ ํ•œ๋‹ค โ€” ใ€ŒAI ์˜๊ฒฌใ€. ์‚ฌ๋žŒ์˜ ์˜๊ฒฌ๊ณผ ์„ž์ด๋ฉด ์•ˆ ๋œ๋‹ค. */
20
+ label: string;
21
+ /**
22
+ * ์ด ์กฐ์น˜์— ๋Œ€ํ•ด ํ•œ๋งˆ๋””.
23
+ *
24
+ * ์‹คํŒจยท์‹œ๊ฐ„์ดˆ๊ณผ๋ฉด `undefined` ๋ฅผ ๋Œ๋ ค์ค€๋‹ค. ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.
25
+ */
26
+ advise(input: {
27
+ command: StoredCommand;
28
+ twinNow: TwinNow;
29
+ locale?: string;
30
+ }): Promise<AdvisorOpinion | undefined>;
31
+ }
32
+ /** ์•ฑ์ด ๋ถ€ํŒ…์—์„œ ํ•œ ๋ฒˆ ๋ถ€๋ฅธ๋‹ค. */
33
+ export declare function setActuationAdvisor(next: ActuationAdvisor): void;
34
+ export declare function actuationAdvisor(): ActuationAdvisor | undefined;
35
+ /** ์˜๊ฒฌ์„ ๋ฌผ์€ ๊ฒฐ๊ณผ โ€” **์—†์Œ๋„ ์‚ฌ์‹ค์ด๋‹ค.** */
36
+ export interface AdvisorResult {
37
+ /** ๋ˆ„๊ฐ€ ๋งํ–ˆ๋‚˜. ์—†์œผ๋ฉด ์•„๋ฌด๋„ ๋งํ•˜์ง€ ์•Š์•˜๋‹ค. */
38
+ by?: string;
39
+ opinion?: AdvisorOpinion;
40
+ /**
41
+ * ์˜๊ฒฌ์ด ์—†์œผ๋ฉด ์™œ ์—†๋‚˜.
42
+ *
43
+ * ๋นˆ์นธ์„ ใ€ŒAI ๊ฐ€ ๋ฐ˜๋Œ€ํ•˜์ง€ ์•Š์•˜๋‹คใ€๋กœ ์ฝ์œผ๋ฉด ์•ˆ ๋œ๋‹ค. ํ™”๋ฉด์ด ์ด ๋ฌธ์žฅ์„ ๊ทธ๋Œ€๋กœ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.
44
+ */
45
+ absent?: string;
46
+ }
47
+ /** ๋ช‡ ์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋‚˜ โ€” ์Šน์ธ ํ™”๋ฉด์ด ์ด๊ฒƒ ๋•Œ๋ฌธ์— ์•ˆ ์—ด๋ฆฌ๋ฉด ์•ˆ ๋œ๋‹ค. */
48
+ export declare const ADVISOR_BUDGET_MS = 8000;
49
+ /**
50
+ * ์˜๊ฒฌ์„ ๋ฌป๋Š”๋‹ค โ€” **์—†์œผ๋ฉด ์—†๋‹ค๊ณ  ๋‹ตํ•œ๋‹ค.**
51
+ *
52
+ * ์‹คํŒจ๋ฅผ ์‚ผํ‚ค์ง€ ์•Š๋Š”๋‹ค. AI ๊ฐ€ ์ฃฝ์–ด ์žˆ์–ด์„œ ์˜๊ฒฌ์ด ์—†๋Š” ๊ฒƒ๊ณผ AI ๊ฐ€ ๋ฐ˜๋Œ€ํ•  ๊ฒƒ์ด ์—†์–ด์„œ ์กฐ์šฉํ•œ ๊ฒƒ์€ ๋‹ค๋ฅธ
53
+ * ์‚ฌ์‹ค์ด๊ณ , ์Šน์ธํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ๊ทธ ์ฐจ์ด๊ฐ€ ํฌ๋‹ค.
54
+ */
55
+ export declare function askAdvisor(args: {
56
+ command: StoredCommand;
57
+ twinNow: TwinNow;
58
+ locale?: string;
59
+ budgetMs?: number;
60
+ }): Promise<AdvisorResult>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ADVISOR_BUDGET_MS = void 0;
4
+ exports.setActuationAdvisor = setActuationAdvisor;
5
+ exports.actuationAdvisor = actuationAdvisor;
6
+ exports.askAdvisor = askAdvisor;
7
+ let advisor;
8
+ /** ์•ฑ์ด ๋ถ€ํŒ…์—์„œ ํ•œ ๋ฒˆ ๋ถ€๋ฅธ๋‹ค. */
9
+ function setActuationAdvisor(next) {
10
+ advisor = next;
11
+ }
12
+ function actuationAdvisor() {
13
+ return advisor;
14
+ }
15
+ /** ๋ช‡ ์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋‚˜ โ€” ์Šน์ธ ํ™”๋ฉด์ด ์ด๊ฒƒ ๋•Œ๋ฌธ์— ์•ˆ ์—ด๋ฆฌ๋ฉด ์•ˆ ๋œ๋‹ค. */
16
+ exports.ADVISOR_BUDGET_MS = 8_000;
17
+ /**
18
+ * ์˜๊ฒฌ์„ ๋ฌป๋Š”๋‹ค โ€” **์—†์œผ๋ฉด ์—†๋‹ค๊ณ  ๋‹ตํ•œ๋‹ค.**
19
+ *
20
+ * ์‹คํŒจ๋ฅผ ์‚ผํ‚ค์ง€ ์•Š๋Š”๋‹ค. AI ๊ฐ€ ์ฃฝ์–ด ์žˆ์–ด์„œ ์˜๊ฒฌ์ด ์—†๋Š” ๊ฒƒ๊ณผ AI ๊ฐ€ ๋ฐ˜๋Œ€ํ•  ๊ฒƒ์ด ์—†์–ด์„œ ์กฐ์šฉํ•œ ๊ฒƒ์€ ๋‹ค๋ฅธ
21
+ * ์‚ฌ์‹ค์ด๊ณ , ์Šน์ธํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ๊ทธ ์ฐจ์ด๊ฐ€ ํฌ๋‹ค.
22
+ */
23
+ async function askAdvisor(args) {
24
+ const a = advisor;
25
+ if (!a)
26
+ return { absent: 'AI ์˜๊ฒฌ์„ ๋‚ด๋Š” ์ž๋ฆฌ๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค' };
27
+ const budget = args.budgetMs ?? exports.ADVISOR_BUDGET_MS;
28
+ let timer;
29
+ try {
30
+ const opinion = await Promise.race([
31
+ a.advise({ command: args.command, twinNow: args.twinNow, ...(args.locale ? { locale: args.locale } : {}) }),
32
+ new Promise(resolve => {
33
+ timer = setTimeout(() => resolve(TIMED_OUT), budget);
34
+ })
35
+ ]);
36
+ if (opinion === TIMED_OUT) {
37
+ return { by: a.label, absent: `${Math.round(budget / 1000)}์ดˆ ์•ˆ์— ๋‹ต์ด ์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค` };
38
+ }
39
+ if (!opinion?.text?.trim())
40
+ return { by: a.label, absent: 'AI ๊ฐ€ ํ•  ๋ง์ด ์—†๋‹ค๊ณ  ๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค' };
41
+ return { by: a.label, opinion };
42
+ }
43
+ catch (e) {
44
+ return { by: a.label, absent: `์˜๊ฒฌ์„ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค โ€” ${String(e?.message ?? e)}` };
45
+ }
46
+ finally {
47
+ if (timer)
48
+ clearTimeout(timer);
49
+ }
50
+ }
51
+ /** ์‹œ๊ฐ„์ดˆ๊ณผ๋ฅผ ๊ฐ’์œผ๋กœ ๊ตฌ๋ณ„ํ•œ๋‹ค โ€” `undefined` ๋กœ ๋‘๋ฉด ใ€Œํ•  ๋ง ์—†์Œใ€๊ณผ ์„ž์ธ๋‹ค. */
52
+ const TIMED_OUT = Symbol('advisor-timeout');
53
+ //# sourceMappingURL=actuation-advisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actuation-advisor.js","sourceRoot":"","sources":["../../../server/service/actuation/actuation-advisor.ts"],"names":[],"mappings":";;;AA4DA,kDAEC;AAED,4CAEC;AAwBD,gCA8BC;AA/DD,IAAI,OAAqC,CAAA;AAEzC,uBAAuB;AACvB,SAAgB,mBAAmB,CAAC,IAAsB;IACxD,OAAO,GAAG,IAAI,CAAA;AAChB,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,OAAO,CAAA;AAChB,CAAC;AAeD,6CAA6C;AAChC,QAAA,iBAAiB,GAAG,KAAK,CAAA;AAEtC;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAAC,IAKhC;IACC,MAAM,CAAC,GAAG,OAAO,CAAA;IACjB,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAA;IAErD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,IAAI,yBAAiB,CAAA;IACjD,IAAI,KAAU,CAAA;IACd,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACjC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3G,IAAI,OAAO,CAAY,OAAO,CAAC,EAAE;gBAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAgB,CAAC,EAAE,MAAM,CAAC,CAAA;YAC7D,CAAC,CAAC;SACH,CAAC,CAAA;QAEF,IAAK,OAAe,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAChF,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAA;QAEjF,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAA;IACjC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,EAAE,EAAE,CAAA;IAC7E,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAA","sourcesContent":["/*\n * **AI ๊ฐ€ ์˜๊ฒฌ์„ ๋‚ด๋Š” ์ž๋ฆฌ** โ€” ํŒ์ •์ด ์•„๋‹ˆ๋ผ ๋ฐœ์–ธ.\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (2026-09-01, ์‚ฌ์šฉ์ž ์ง€์ ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌผ์—ˆ๋‹ค โ€” ใ€ŒAI ์ž์‹ ์€ ๊ฒฐ์žฌ/์Šน์ธ์˜ ๋‹ด๋‹น์ด ๋  ์ˆ˜ ์—†๋‚˜. ์ตœ์†Œํ•œ ์˜๊ฒฌ์ œ์‹œ์ž๋ผ๋„ ๋  ์ˆ˜ ์žˆ์ง€ ์•Š๋‚˜.ใ€\n *\n * ์Šน์ธ์ž๋Š” ์•ˆ ๋œ๋‹ค. ์Šน์ธ ๊ธฐ๋ก์˜ ๊ฐ’์–ด์น˜๋Š” ์‚ฌ๊ณ  ๋’ค์— **์ฑ…์ž„์„ ๋ฌผ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ**์ด๊ณ , ใ€ŒAI ๊ฐ€ ์Šน์ธํ–ˆ๋‹คใ€๋กœ๋Š”\n * ์•„๋ฌด์—๊ฒŒ๋„ ๋ฌป์ง€ ๋ชปํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ธ ์ชฝ์ด ์Šน์ธํ•˜๋ฉด ๋‘ ์‚ฌ๋žŒ์ด ์•„๋‹ˆ๋‹ค โ€” ์ž๊ธฐ ์Šน์ธ์„ ๋ง‰๋Š” ๊ทœ์น™๊ณผ ๊ฐ™์€ ์ด์œ ๋‹ค.\n *\n * ์˜๊ฒฌ์€ ๋‚ด์•ผ ํ•œ๋‹ค. `twinNow` ๋กœ ใ€Œ๋„๊ธˆ ๋Œ€๊ธฐ๊ฐ€ ์—ฌ์„ฏ ๋ฐฐ๋‹คใ€๋Š” ์‚ฌ์‹ค์„ ์Šน์ธ ํ™”๋ฉด์— ์‹ค์—ˆ์ง€๋งŒ, ๊ทธ๊ฑด ๊ณ„์‚ฐ๊ฐ’์ด๋‹ค.\n * ใ€Œ๊ทธ๋Ÿฌ๋‹ˆ ๋” ๋งŒ๋“ค๋ฉด ๋Œ€๊ธฐ๊ฐ€ ๋Š˜์–ด๋‚œ๋‹คใ€๊ฐ€ ์˜๊ฒฌ์ด๊ณ  ๊ทธ ์ž๋ฆฌ๊ฐ€ ์—†์—ˆ๋‹ค.\n *\n * โ”€โ”€ ์–ธ์ œ ๋ฌป๋‚˜ โ€” ์Šน์ธ ํ™”๋ฉด์„ ์—ด ๋•Œ๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๊ฒฐ์žฌ์„ ์— ์˜ฌ๋ฆด ๋•Œ ๋ฌป์ง€ ์•Š๋Š”๋‹ค. ๊ทธ ์ž๋ฆฌ๋Š” ํŠธ๋žœ์žญ์…˜ ์•ˆ์ด๊ณ (`raiseTwinCommand` ์˜ `@transaction`),\n * ๊ฑฐ๊ธฐ์„œ LLM ์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉด **DB ์—ฐ๊ฒฐ ํ•˜๋‚˜๋ฅผ ๋ช‡ ์ดˆ ๋ถ™์žก๋Š”๋‹ค**(sqlite ๋Š” ์—ฐ๊ฒฐ์ด ํ•˜๋‚˜๋‹ค).\n *\n * ๊ทธ๋ฆฌ๊ณ  ํ™”๋ฉด์„ ์—ด ๋•Œ ๋ฌป๋Š” ๊ฒƒ์ด ๋” ์˜ณ๋‹ค. ์Šน์ธํ•˜๋Š” ์‚ฌ๋žŒ์€ **์ง€๊ธˆ** ํŒ๋‹จํ•˜๊ณ , ์˜ฌ๋ฆฐ ์‹œ๊ฐ์˜ ์˜๊ฒฌ์€ ๋‚ก์•˜๋‹ค.\n *\n * โ”€โ”€ ํŒ์ •์— ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ด ๊ฐ’์„ ์ฝ์–ด ๋ฌด์—‡์„ ๋ง‰๋Š” ์ฝ”๋“œ๊ฐ€ ์—†๋‹ค. ์Šน์ธยท๊ฑฐ์ ˆ์€ ์‚ฌ๋žŒ์ด ํ•œ๋‹ค. AI ๊ฐ€ ๋ฐ˜๋Œ€ํ•ด๋„ ์Šน์ธ๋˜๊ณ , ๋™์˜ํ•ด๋„\n * ๊ฑฐ์ ˆ๋œ๋‹ค. ๊ทธ ์‚ฌ์‹ค์ด ์ฝ”๋“œ์— ๋“œ๋Ÿฌ๋‚˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค โ€” ํŒ์ •์— ์“ฐ๋ฉด AI ๊ฐ€ ์‚ฌ์‹ค์ƒ ์Šน์ธ์ž๊ฐ€ ๋œ๋‹ค.\n */\nimport type { StoredCommand } from './command-dispatcher.js'\nimport type { TwinNow } from './twin-now.js'\n\n/**\n * AI ๊ฐ€ ์–ด๋–ค ํƒœ๋„๋ฅผ ๋ƒˆ๋‚˜ โ€” **์„ธ ๊ฐˆ๋ž˜์—ฌ์•ผ ํ•œ๋‹ค.**\n *\n * ใ€Œ๋ชจ๋ฅด๊ฒ ๋‹คใ€๊ฐ€ ์—†์œผ๋ฉด ๋ชจ๋ฅผ ๋•Œ ๋™์˜๋กœ ๋‹ตํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์Šน์ธ์ž๊ฐ€ ๊ทธ๊ฒƒ์„ ใ€ŒAI ๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ํ–ˆ๋‹คใ€๋กœ ์ฝ๋Š”๋‹ค.\n * ์ž๋™ ์Šน์ธ ํŽธํ–ฅ์ด ๊ฑฐ๊ธฐ์„œ ์‹œ์ž‘ํ•œ๋‹ค.\n */\nexport type AdvisorStance = 'object' | 'concur' | 'unsure'\n\nexport interface AdvisorOpinion {\n stance: AdvisorStance\n /** ์‚ฌ๋žŒ์ด ์ฝ๋Š” ๋ฌธ์žฅ. AI ๊ฐ€ ์“ด ๊ทธ๋Œ€๋กœ โ€” ์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋“ฌ์ง€ ์•Š๋Š”๋‹ค(๋‹ค๋“ฌ์œผ๋ฉด ๋ˆ„๊ฐ€ ๋งํ•œ ๊ฒƒ์ธ์ง€ ํ๋ ค์ง„๋‹ค). */\n text: string\n /** ๋ฌด์—‡์„ ๋ณด๊ณ  ๋งํ–ˆ๋‚˜ โ€” ์ฃผ์˜ ์‹๋ณ„์žยท๊ฐ’. ์Šน์ธ์ž๊ฐ€ ๊ทผ๊ฑฐ๋ฅผ ๋˜์งš์„ ์ˆ˜ ์žˆ๊ฒŒ. */\n basis?: string[]\n}\n\n/** ์˜๊ฒฌ์„ ๋‚ด๋Š” ์ž๋ฆฌ โ€” ์•ฑ์ด ์ฑ„์šด๋‹ค(headless-twin ์€ `twin-ai` ๋ฅผ ๋ถ€๋ฅด์ง€ ์•Š๋Š”๋‹ค). */\nexport interface ActuationAdvisor {\n /** ํ™”๋ฉด์ด ์ถœ์ฒ˜๋ฅผ ๋งํ•ด์•ผ ํ•œ๋‹ค โ€” ใ€ŒAI ์˜๊ฒฌใ€. ์‚ฌ๋žŒ์˜ ์˜๊ฒฌ๊ณผ ์„ž์ด๋ฉด ์•ˆ ๋œ๋‹ค. */\n label: string\n /**\n * ์ด ์กฐ์น˜์— ๋Œ€ํ•ด ํ•œ๋งˆ๋””.\n *\n * ์‹คํŒจยท์‹œ๊ฐ„์ดˆ๊ณผ๋ฉด `undefined` ๋ฅผ ๋Œ๋ ค์ค€๋‹ค. ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค.\n */\n advise(input: {\n command: StoredCommand\n twinNow: TwinNow\n locale?: string\n }): Promise<AdvisorOpinion | undefined>\n}\n\nlet advisor: ActuationAdvisor | undefined\n\n/** ์•ฑ์ด ๋ถ€ํŒ…์—์„œ ํ•œ ๋ฒˆ ๋ถ€๋ฅธ๋‹ค. */\nexport function setActuationAdvisor(next: ActuationAdvisor): void {\n advisor = next\n}\n\nexport function actuationAdvisor(): ActuationAdvisor | undefined {\n return advisor\n}\n\n/** ์˜๊ฒฌ์„ ๋ฌผ์€ ๊ฒฐ๊ณผ โ€” **์—†์Œ๋„ ์‚ฌ์‹ค์ด๋‹ค.** */\nexport interface AdvisorResult {\n /** ๋ˆ„๊ฐ€ ๋งํ–ˆ๋‚˜. ์—†์œผ๋ฉด ์•„๋ฌด๋„ ๋งํ•˜์ง€ ์•Š์•˜๋‹ค. */\n by?: string\n opinion?: AdvisorOpinion\n /**\n * ์˜๊ฒฌ์ด ์—†์œผ๋ฉด ์™œ ์—†๋‚˜.\n *\n * ๋นˆ์นธ์„ ใ€ŒAI ๊ฐ€ ๋ฐ˜๋Œ€ํ•˜์ง€ ์•Š์•˜๋‹คใ€๋กœ ์ฝ์œผ๋ฉด ์•ˆ ๋œ๋‹ค. ํ™”๋ฉด์ด ์ด ๋ฌธ์žฅ์„ ๊ทธ๋Œ€๋กœ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.\n */\n absent?: string\n}\n\n/** ๋ช‡ ์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋‚˜ โ€” ์Šน์ธ ํ™”๋ฉด์ด ์ด๊ฒƒ ๋•Œ๋ฌธ์— ์•ˆ ์—ด๋ฆฌ๋ฉด ์•ˆ ๋œ๋‹ค. */\nexport const ADVISOR_BUDGET_MS = 8_000\n\n/**\n * ์˜๊ฒฌ์„ ๋ฌป๋Š”๋‹ค โ€” **์—†์œผ๋ฉด ์—†๋‹ค๊ณ  ๋‹ตํ•œ๋‹ค.**\n *\n * ์‹คํŒจ๋ฅผ ์‚ผํ‚ค์ง€ ์•Š๋Š”๋‹ค. AI ๊ฐ€ ์ฃฝ์–ด ์žˆ์–ด์„œ ์˜๊ฒฌ์ด ์—†๋Š” ๊ฒƒ๊ณผ AI ๊ฐ€ ๋ฐ˜๋Œ€ํ•  ๊ฒƒ์ด ์—†์–ด์„œ ์กฐ์šฉํ•œ ๊ฒƒ์€ ๋‹ค๋ฅธ\n * ์‚ฌ์‹ค์ด๊ณ , ์Šน์ธํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ๊ทธ ์ฐจ์ด๊ฐ€ ํฌ๋‹ค.\n */\nexport async function askAdvisor(args: {\n command: StoredCommand\n twinNow: TwinNow\n locale?: string\n budgetMs?: number\n}): Promise<AdvisorResult> {\n const a = advisor\n if (!a) return { absent: 'AI ์˜๊ฒฌ์„ ๋‚ด๋Š” ์ž๋ฆฌ๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค' }\n\n const budget = args.budgetMs ?? ADVISOR_BUDGET_MS\n let timer: any\n try {\n const opinion = await Promise.race([\n a.advise({ command: args.command, twinNow: args.twinNow, ...(args.locale ? { locale: args.locale } : {}) }),\n new Promise<undefined>(resolve => {\n timer = setTimeout(() => resolve(TIMED_OUT as any), budget)\n })\n ])\n\n if ((opinion as any) === TIMED_OUT) {\n return { by: a.label, absent: `${Math.round(budget / 1000)}์ดˆ ์•ˆ์— ๋‹ต์ด ์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค` }\n }\n if (!opinion?.text?.trim()) return { by: a.label, absent: 'AI ๊ฐ€ ํ•  ๋ง์ด ์—†๋‹ค๊ณ  ๋‹ตํ–ˆ์Šต๋‹ˆ๋‹ค' }\n\n return { by: a.label, opinion }\n } catch (e: any) {\n return { by: a.label, absent: `์˜๊ฒฌ์„ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค โ€” ${String(e?.message ?? e)}` }\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\n/** ์‹œ๊ฐ„์ดˆ๊ณผ๋ฅผ ๊ฐ’์œผ๋กœ ๊ตฌ๋ณ„ํ•œ๋‹ค โ€” `undefined` ๋กœ ๋‘๋ฉด ใ€Œํ•  ๋ง ์—†์Œใ€๊ณผ ์„ž์ธ๋‹ค. */\nconst TIMED_OUT = Symbol('advisor-timeout')\n"]}
@@ -0,0 +1,52 @@
1
+ import type { StoredCommand } from './command-dispatcher.js';
2
+ /** ์Šน์ธํ•œ ์‚ฌ๋žŒ์—๊ฒŒ ๋Œ๋ ค์ค„ ๊ฒƒ โ€” ํ™”๋ฉด์ด ๊ฒน์ณ ๋ณผ ๊ฒƒ์ด ์—†๊ฒŒ ํŒ์ •๊นŒ์ง€ ๋‚ธ๋‹ค. */
3
+ export interface ActuationOutcome {
4
+ id: string;
5
+ /** proposed ยท approved ยท dispatching ยท acked ยท failed ยท rejected. */
6
+ state: string;
7
+ /** ์ €์ชฝ์ด ์ค€ ์ด๋ฆ„ โ€” ๋‚˜๊ฐ”์„ ๋•Œ๋งŒ. ์—†์œผ๋ฉด ๋ฌด์—‡์„ ๋˜๋Œ๋ฆด์ง€ ์ง€๋ชฉํ•  ์ˆ˜ ์—†๋‹ค. */
8
+ dispatchRef?: string;
9
+ /** ๋ชป ๋‚˜๊ฐ„ ์‚ฌ์œ  โ€” ์ €์ชฝ ๋ฌธ์žฅ ๊ทธ๋Œ€๋กœ. */
10
+ error?: string;
11
+ /** ์ €์ชฝ์ด ๋ฐ›์œผ๋ฉด์„œ ๋ง๋ถ™์ธ ๋ง โ€” **์‹คํŒจ๊ฐ€ ์•„๋‹ˆ๋‹ค.** ์›์ธ ์ชฝ ๋ฌธ์žฅ. */
12
+ note?: string;
13
+ /**
14
+ * ๊ทธ ๋ง ์ค‘ **๋‹ค์Œ์— ํ•  ์ผ** ํ•œ ์ค„.
15
+ *
16
+ * ์™œ ๋‘˜๋กœ ์˜ค๋‚˜: ์ฝ๋Š” ์‚ฌ๋žŒ์€ ใ€Œ๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ๋ญ˜ ํ•ด์•ผ ํ•˜๋‚˜ใ€๋ฅผ ๋จผ์ € ์ฐพ๋Š”๋‹ค(UX ๋ ˆ์ธ). ํ•œ ๋ฌธ์žฅ์œผ๋กœ
17
+ * ์ฃผ๋ฉด ํ™”๋ฉด์ด ์ž๋ฅด๊ฒŒ ๋˜๊ณ , **์ž๋ฅด๋Š” ๊ทœ์น™์ด ํ™”๋ฉด๋งˆ๋‹ค ์ƒ๊ธด๋‹ค.** ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์ด๋ฏธ ๋‘˜๋กœ ์•Œ๊ณ  ์žˆ์œผ๋‹ˆ
18
+ * ๋ถ™์ด์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ๋‚˜๋ฅธ๋‹ค.
19
+ *
20
+ * ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์•„์ง ๊ฐˆ๋ผ ์ฃผ์ง€ ์•Š์œผ๋ฉด **๋น„์–ด ์žˆ๋‹ค.** ๊ทธ๋•Œ `note` ๋Š” ๋‘ ๋ฌธ์žฅ์ด ๋ถ™์€ ํ•œ ๋ฉ์ด์ด๊ณ ,
21
+ * ํ™”๋ฉด์€ ๊ทธ๊ฒƒ์„ ํ†ต์งธ๋กœ ๊ทธ๋ ค์•ผ ํ•œ๋‹ค โ€” ํŒŒ์‹ฑํ•ด์„œ ๋‚˜๋ˆ„๋ฉด ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๊ฐˆ๋ผ ์ฃผ๋Š” ๋‚  ์กฐ์šฉํžˆ ๊นจ์ง„๋‹ค.
22
+ */
23
+ noteNext?: string;
24
+ /** ์›์ฒœ์ด ๋ณด๊ณ ํ•œ ์ƒํƒœ โ€” ๋‚ฑ๋ง ๊ทธ๋Œ€๋กœ. */
25
+ effectStatus?: string;
26
+ /** ๊ทธ ๋ณด๊ณ ๋ฅผ ๋ณธ ์‹œ๊ฐ. */
27
+ effectAt?: string;
28
+ /**
29
+ * ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋‚˜ โ€” ํ™”๋ฉด์€ **์ฐธ์ผ ๋•Œ๋งŒ** ํ•œ ์ค„ ๋‚ธ๋‹ค.
30
+ *
31
+ * ์ง€๊ธˆ ๊ทœ์น™์—์„œ ๊ฒฐ์žฌํ•จ์— ์˜ฌ๋ผ์˜จ ์กฐ์น˜๋Š” ๊ฑฐ์˜ ๋‹ค ๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋‹ค(๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋Š” ๊ฒƒ๋งŒ ์Šน์ธ์„
32
+ * ์š”๊ตฌํ•œ๋‹ค). ๊ทธ๋ž˜์„œ ใ€Œ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹คใ€๋ฅผ ๋งค๋ฒˆ ์ ์œผ๋ฉด ๋Š˜ ์ฐธ์ธ ๊ฒฝ๊ณ ๊ฐ€ ๋˜๊ณ , ๋Š˜ ์ฐธ์ธ ๊ฒฝ๊ณ ๋Š”
33
+ * ์‚ฌํ˜์ด๋ฉด ์•ˆ ์ฝํžŒ๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด ๊ทธ ์ž๋ฆฌ์— ๋‹ค๋ฅธ ๋ง์ด ํ•„์š”ํ•œ ๋‚  ์ž๋ฆฌ๊ฐ€ ์ด๋ฏธ ์ฃฝ์–ด ์žˆ๋‹ค(UX ๋ ˆ์ธ ํŒ๋‹จ).
34
+ */
35
+ reversible?: boolean;
36
+ /**
37
+ * **์ €์ชฝ์—์„œ ์‚ฌ๋žŒ์ด ํ•  ์ผ์ด ๋‚จ์•˜๋‚˜** โ€” ์ด ํŒ์ •์ด ์ด ํƒ€์ž…์˜ ์กด์žฌ ์ด์œ ๋‹ค(๋จธ๋ฆฌ๋ง).
38
+ *
39
+ * ใ€Œ๋ชจ๋ฅธ๋‹คใ€๊ฐ€ ์žˆ๋‹ค: ์•„์ง ๋„˜๊ธฐ์ง€ ์•Š์•˜์œผ๋ฉด ๋ฌผ์–ด๋ณผ ๊ฒƒ์ด ์—†๋‹ค. `false` ๋กœ ์ ‘์œผ๋ฉด ํ™”๋ฉด์ด ใ€Œํ•  ์ผ
40
+ * ์—†์Œใ€์œผ๋กœ ๊ทธ๋ฆฌ๊ณ , ๊ทธ๊ฒƒ์€ ๋„˜๊ธด ๋’ค์™€ ๊ตฌ๋ณ„๋˜์ง€ ์•Š๋Š”๋‹ค.
41
+ */
42
+ pendingAtSource?: boolean;
43
+ /** ๋„˜๊ธธ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ธ๊ฐ€ โ€” `acked` ๋Š” ์ข…์ฐฉ์ด๋ผ ์ €์ชฝ์ด ์ค€๋น„๋ผ ์žˆ์–ด๋„ ๋‹ค์‹œ ๋„˜๊ธฐ์ง€ ์•Š๋Š”๋‹ค. */
44
+ dispatchable: boolean;
45
+ }
46
+ /**
47
+ * ์ €์žฅ๋œ ์กฐ์น˜ ํ•˜๋‚˜๋ฅผ ์‚ฌ๋žŒ์ด ์ฝ์„ ์‚ฌ์‹ค๋กœ ์˜ฎ๊ธด๋‹ค โ€” **์ˆœ์ˆ˜ํ•˜๋‹ค.**
48
+ *
49
+ * DB ๋„ ์–ด๋Œ‘ํ„ฐ๋„ ๋ณด์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํŒ์ •์€ ์‹œํ—˜์ด ๊ฐ’๋งŒ ๋ฐ”๊ฟ” ๊ฐ€๋ฉฐ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ํ™”๋ฉด์ด
50
+ * ๊ฐ™์€ ๊ทœ์น™์„ ๋‹ค์‹œ ์“ฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
51
+ */
52
+ export declare function actuationOutcomeOf(command: StoredCommand, dispatchable: boolean): ActuationOutcome;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.actuationOutcomeOf = actuationOutcomeOf;
4
+ /** ๋„˜๊น€์„ ์‹œ๋„ํ•ด ๋ณธ ์ƒํƒœ์ธ๊ฐ€ โ€” ์ด ๋’ค์—์•ผ ใ€Œ์ €์ชฝ์— ํ•  ์ผ์ด ๋‚จ์•˜๋‚˜ใ€๋ฅผ ๋ฌผ์„ ์ˆ˜ ์žˆ๋‹ค. */
5
+ const TRIED = new Set(['dispatching', 'acked', 'failed']);
6
+ /**
7
+ * ์ €์žฅ๋œ ์กฐ์น˜ ํ•˜๋‚˜๋ฅผ ์‚ฌ๋žŒ์ด ์ฝ์„ ์‚ฌ์‹ค๋กœ ์˜ฎ๊ธด๋‹ค โ€” **์ˆœ์ˆ˜ํ•˜๋‹ค.**
8
+ *
9
+ * DB ๋„ ์–ด๋Œ‘ํ„ฐ๋„ ๋ณด์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํŒ์ •์€ ์‹œํ—˜์ด ๊ฐ’๋งŒ ๋ฐ”๊ฟ” ๊ฐ€๋ฉฐ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ํ™”๋ฉด์ด
10
+ * ๊ฐ™์€ ๊ทœ์น™์„ ๋‹ค์‹œ ์“ฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
11
+ */
12
+ function actuationOutcomeOf(command, dispatchable) {
13
+ const note = command.dispatchNote;
14
+ const effect = command.effect;
15
+ /*
16
+ * ๋„˜๊ฒจ ๋ณด์ง€ ์•Š์•˜์œผ๋ฉด ํŒ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋„˜๊ธด ๋’ค๋ผ๋ฉด ใ€Œ๋ง์ด ์žˆ๋Š”๋ฐ ํšจ๊ณผ๊ฐ€ ์•„์ง ์—†๋‹คใ€๊ฐ€ ๊ณง
17
+ * ใ€Œ์ €์ชฝ์—์„œ ์‚ฌ๋žŒ์ด ํ•  ์ผ์ด ๋‚จ์•˜๋‹คใ€๋‹ค.
18
+ */
19
+ const pendingAtSource = TRIED.has(command.state) ? Boolean(note) && !effect?.status : undefined;
20
+ return {
21
+ id: command.id,
22
+ state: command.state,
23
+ ...(command.dispatchRef ? { dispatchRef: command.dispatchRef } : {}),
24
+ ...(command.error ? { error: command.error } : {}),
25
+ ...(note ? { note } : {}),
26
+ ...(command.dispatchNoteNext ? { noteNext: command.dispatchNoteNext } : {}),
27
+ ...(effect?.status ? { effectStatus: effect.status } : {}),
28
+ ...(effect?.at ? { effectAt: effect.at } : {}),
29
+ ...(command.reversible === undefined ? {} : { reversible: command.reversible }),
30
+ ...(pendingAtSource === undefined ? {} : { pendingAtSource }),
31
+ dispatchable
32
+ };
33
+ }
34
+ //# sourceMappingURL=actuation-outcome.js.map