@things-factory/ops-master 10.1.247 → 10.1.248

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 (429) hide show
  1. package/package.json +3 -3
  2. package/dist-client/bootstrap.d.ts +0 -19
  3. package/dist-client/bootstrap.js +0 -66
  4. package/dist-client/bootstrap.js.map +0 -1
  5. package/dist-client/index.d.ts +0 -17
  6. package/dist-client/index.js +0 -21
  7. package/dist-client/index.js.map +0 -1
  8. package/dist-client/master-change-approval.d.ts +0 -14
  9. package/dist-client/master-change-approval.js +0 -36
  10. package/dist-client/master-change-approval.js.map +0 -1
  11. package/dist-client/master-change-policy-axes.d.ts +0 -37
  12. package/dist-client/master-change-policy-axes.js +0 -29
  13. package/dist-client/master-change-policy-axes.js.map +0 -1
  14. package/dist-client/master-change-policy-panel.d.ts +0 -59
  15. package/dist-client/master-change-policy-panel.js +0 -454
  16. package/dist-client/master-change-policy-panel.js.map +0 -1
  17. package/dist-client/master-change-providers.d.ts +0 -4
  18. package/dist-client/master-change-providers.js +0 -91
  19. package/dist-client/master-change-providers.js.map +0 -1
  20. package/dist-client/pages/master/applied-when-dialog.d.ts +0 -48
  21. package/dist-client/pages/master/applied-when-dialog.js +0 -137
  22. package/dist-client/pages/master/applied-when-dialog.js.map +0 -1
  23. package/dist-client/pages/master/assignment-fields.d.ts +0 -27
  24. package/dist-client/pages/master/assignment-fields.js +0 -62
  25. package/dist-client/pages/master/assignment-fields.js.map +0 -1
  26. package/dist-client/pages/master/equipment-class.d.ts +0 -12
  27. package/dist-client/pages/master/equipment-class.js +0 -42
  28. package/dist-client/pages/master/equipment-class.js.map +0 -1
  29. package/dist-client/pages/master/equipment.d.ts +0 -12
  30. package/dist-client/pages/master/equipment.js +0 -58
  31. package/dist-client/pages/master/equipment.js.map +0 -1
  32. package/dist-client/pages/master/grist-iso-duration.d.ts +0 -20
  33. package/dist-client/pages/master/grist-iso-duration.js +0 -70
  34. package/dist-client/pages/master/grist-iso-duration.js.map +0 -1
  35. package/dist-client/pages/master/grist-reference.d.ts +0 -91
  36. package/dist-client/pages/master/grist-reference.js +0 -419
  37. package/dist-client/pages/master/grist-reference.js.map +0 -1
  38. package/dist-client/pages/master/import-rows.d.ts +0 -35
  39. package/dist-client/pages/master/import-rows.js +0 -66
  40. package/dist-client/pages/master/import-rows.js.map +0 -1
  41. package/dist-client/pages/master/iso-duration.d.ts +0 -34
  42. package/dist-client/pages/master/iso-duration.js +0 -76
  43. package/dist-client/pages/master/iso-duration.js.map +0 -1
  44. package/dist-client/pages/master/master-options.d.ts +0 -40
  45. package/dist-client/pages/master/master-options.js +0 -54
  46. package/dist-client/pages/master/master-options.js.map +0 -1
  47. package/dist-client/pages/master/master-page-base.d.ts +0 -369
  48. package/dist-client/pages/master/master-page-base.js +0 -657
  49. package/dist-client/pages/master/master-page-base.js.map +0 -1
  50. package/dist-client/pages/master/material-class.d.ts +0 -12
  51. package/dist-client/pages/master/material-class.js +0 -42
  52. package/dist-client/pages/master/material-class.js.map +0 -1
  53. package/dist-client/pages/master/material-definition.d.ts +0 -5
  54. package/dist-client/pages/master/material-definition.js +0 -14
  55. package/dist-client/pages/master/material-definition.js.map +0 -1
  56. package/dist-client/pages/master/material-revision-fields.d.ts +0 -2
  57. package/dist-client/pages/master/material-revision-fields.js +0 -43
  58. package/dist-client/pages/master/material-revision-fields.js.map +0 -1
  59. package/dist-client/pages/master/operation-definition.d.ts +0 -12
  60. package/dist-client/pages/master/operation-definition.js +0 -49
  61. package/dist-client/pages/master/operation-definition.js.map +0 -1
  62. package/dist-client/pages/master/operational-location.d.ts +0 -84
  63. package/dist-client/pages/master/operational-location.js +0 -432
  64. package/dist-client/pages/master/operational-location.js.map +0 -1
  65. package/dist-client/pages/master/person.d.ts +0 -12
  66. package/dist-client/pages/master/person.js +0 -41
  67. package/dist-client/pages/master/person.js.map +0 -1
  68. package/dist-client/pages/master/personnel-class.d.ts +0 -12
  69. package/dist-client/pages/master/personnel-class.js +0 -43
  70. package/dist-client/pages/master/personnel-class.js.map +0 -1
  71. package/dist-client/pages/master/physical-asset-class.d.ts +0 -12
  72. package/dist-client/pages/master/physical-asset-class.js +0 -40
  73. package/dist-client/pages/master/physical-asset-class.js.map +0 -1
  74. package/dist-client/pages/master/physical-asset.d.ts +0 -12
  75. package/dist-client/pages/master/physical-asset.js +0 -41
  76. package/dist-client/pages/master/physical-asset.js.map +0 -1
  77. package/dist-client/pages/master/recipe-definition.d.ts +0 -5
  78. package/dist-client/pages/master/recipe-definition.js +0 -14
  79. package/dist-client/pages/master/recipe-definition.js.map +0 -1
  80. package/dist-client/pages/master/reference-targets.d.ts +0 -42
  81. package/dist-client/pages/master/reference-targets.js +0 -82
  82. package/dist-client/pages/master/reference-targets.js.map +0 -1
  83. package/dist-client/pages/master/revision-comparison.d.ts +0 -49
  84. package/dist-client/pages/master/revision-comparison.js +0 -560
  85. package/dist-client/pages/master/revision-comparison.js.map +0 -1
  86. package/dist-client/pages/master/revision-view.d.ts +0 -34
  87. package/dist-client/pages/master/revision-view.js +0 -145
  88. package/dist-client/pages/master/revision-view.js.map +0 -1
  89. package/dist-client/pages/master/revision-workspace.d.ts +0 -50
  90. package/dist-client/pages/master/revision-workspace.js +0 -763
  91. package/dist-client/pages/master/revision-workspace.js.map +0 -1
  92. package/dist-client/pages/master/route-definition.d.ts +0 -19
  93. package/dist-client/pages/master/route-definition.js +0 -40
  94. package/dist-client/pages/master/route-definition.js.map +0 -1
  95. package/dist-client/pages/master/stop-reason.d.ts +0 -12
  96. package/dist-client/pages/master/stop-reason.js +0 -48
  97. package/dist-client/pages/master/stop-reason.js.map +0 -1
  98. package/dist-client/pages/master/test-specification.d.ts +0 -5
  99. package/dist-client/pages/master/test-specification.js +0 -14
  100. package/dist-client/pages/master/test-specification.js.map +0 -1
  101. package/dist-client/pages/master-axes.d.ts +0 -24
  102. package/dist-client/pages/master-axes.js +0 -39
  103. package/dist-client/pages/master-axes.js.map +0 -1
  104. package/dist-client/route.d.ts +0 -1
  105. package/dist-client/route.js +0 -81
  106. package/dist-client/route.js.map +0 -1
  107. package/dist-client/tsconfig.tsbuildinfo +0 -1
  108. package/dist-server/index.d.ts +0 -1
  109. package/dist-server/index.js +0 -19
  110. package/dist-server/index.js.map +0 -1
  111. package/dist-server/service/ai-entry/master-entry-rules.d.ts +0 -175
  112. package/dist-server/service/ai-entry/master-entry-rules.js +0 -302
  113. package/dist-server/service/ai-entry/master-entry-rules.js.map +0 -1
  114. package/dist-server/service/ai-entry/master-entry-targets.d.ts +0 -23
  115. package/dist-server/service/ai-entry/master-entry-targets.js +0 -293
  116. package/dist-server/service/ai-entry/master-entry-targets.js.map +0 -1
  117. package/dist-server/service/approval-route.d.ts +0 -37
  118. package/dist-server/service/approval-route.js +0 -34
  119. package/dist-server/service/approval-route.js.map +0 -1
  120. package/dist-server/service/asset/asset-lifecycle.d.ts +0 -106
  121. package/dist-server/service/asset/asset-lifecycle.js +0 -126
  122. package/dist-server/service/asset/asset-lifecycle.js.map +0 -1
  123. package/dist-server/service/asset/asset-master-resolver.d.ts +0 -53
  124. package/dist-server/service/asset/asset-master-resolver.js +0 -185
  125. package/dist-server/service/asset/asset-master-resolver.js.map +0 -1
  126. package/dist-server/service/asset/asset-master.d.ts +0 -21
  127. package/dist-server/service/asset/asset-master.js +0 -25
  128. package/dist-server/service/asset/asset-master.js.map +0 -1
  129. package/dist-server/service/asset/asset-query.d.ts +0 -16
  130. package/dist-server/service/asset/asset-query.js +0 -72
  131. package/dist-server/service/asset/asset-query.js.map +0 -1
  132. package/dist-server/service/asset/index.d.ts +0 -6
  133. package/dist-server/service/asset/index.js +0 -10
  134. package/dist-server/service/asset/index.js.map +0 -1
  135. package/dist-server/service/asset/physical-asset-class.d.ts +0 -34
  136. package/dist-server/service/asset/physical-asset-class.js +0 -104
  137. package/dist-server/service/asset/physical-asset-class.js.map +0 -1
  138. package/dist-server/service/asset/physical-asset.d.ts +0 -66
  139. package/dist-server/service/asset/physical-asset.js +0 -123
  140. package/dist-server/service/asset/physical-asset.js.map +0 -1
  141. package/dist-server/service/assignment/applied-when.d.ts +0 -24
  142. package/dist-server/service/assignment/applied-when.js +0 -16
  143. package/dist-server/service/assignment/applied-when.js.map +0 -1
  144. package/dist-server/service/assignment/assignment-history.d.ts +0 -92
  145. package/dist-server/service/assignment/assignment-history.js +0 -289
  146. package/dist-server/service/assignment/assignment-history.js.map +0 -1
  147. package/dist-server/service/assignment/assignment-write.d.ts +0 -42
  148. package/dist-server/service/assignment/assignment-write.js +0 -101
  149. package/dist-server/service/assignment/assignment-write.js.map +0 -1
  150. package/dist-server/service/assignment/master-value-claim.d.ts +0 -135
  151. package/dist-server/service/assignment/master-value-claim.js +0 -174
  152. package/dist-server/service/assignment/master-value-claim.js.map +0 -1
  153. package/dist-server/service/equipment/equipment-class.d.ts +0 -34
  154. package/dist-server/service/equipment/equipment-class.js +0 -104
  155. package/dist-server/service/equipment/equipment-class.js.map +0 -1
  156. package/dist-server/service/equipment/equipment-master-resolver.d.ts +0 -77
  157. package/dist-server/service/equipment/equipment-master-resolver.js +0 -266
  158. package/dist-server/service/equipment/equipment-master-resolver.js.map +0 -1
  159. package/dist-server/service/equipment/equipment-master.d.ts +0 -30
  160. package/dist-server/service/equipment/equipment-master.js +0 -53
  161. package/dist-server/service/equipment/equipment-master.js.map +0 -1
  162. package/dist-server/service/equipment/equipment-query.d.ts +0 -16
  163. package/dist-server/service/equipment/equipment-query.js +0 -72
  164. package/dist-server/service/equipment/equipment-query.js.map +0 -1
  165. package/dist-server/service/equipment/equipment.d.ts +0 -71
  166. package/dist-server/service/equipment/equipment.js +0 -138
  167. package/dist-server/service/equipment/equipment.js.map +0 -1
  168. package/dist-server/service/equipment/index.d.ts +0 -8
  169. package/dist-server/service/equipment/index.js +0 -12
  170. package/dist-server/service/equipment/index.js.map +0 -1
  171. package/dist-server/service/equipment/state-period-rules.d.ts +0 -95
  172. package/dist-server/service/equipment/state-period-rules.js +0 -122
  173. package/dist-server/service/equipment/state-period-rules.js.map +0 -1
  174. package/dist-server/service/equipment/stop-reason-query.d.ts +0 -11
  175. package/dist-server/service/equipment/stop-reason-query.js +0 -39
  176. package/dist-server/service/equipment/stop-reason-query.js.map +0 -1
  177. package/dist-server/service/equipment/stop-reason.d.ts +0 -58
  178. package/dist-server/service/equipment/stop-reason.js +0 -114
  179. package/dist-server/service/equipment/stop-reason.js.map +0 -1
  180. package/dist-server/service/index.d.ts +0 -82
  181. package/dist-server/service/index.js +0 -145
  182. package/dist-server/service/index.js.map +0 -1
  183. package/dist-server/service/location/index.d.ts +0 -5
  184. package/dist-server/service/location/index.js +0 -9
  185. package/dist-server/service/location/index.js.map +0 -1
  186. package/dist-server/service/location/location-master-resolver.d.ts +0 -60
  187. package/dist-server/service/location/location-master-resolver.js +0 -313
  188. package/dist-server/service/location/location-master-resolver.js.map +0 -1
  189. package/dist-server/service/location/location-master.d.ts +0 -26
  190. package/dist-server/service/location/location-master.js +0 -28
  191. package/dist-server/service/location/location-master.js.map +0 -1
  192. package/dist-server/service/location/location-query.d.ts +0 -15
  193. package/dist-server/service/location/location-query.js +0 -56
  194. package/dist-server/service/location/location-query.js.map +0 -1
  195. package/dist-server/service/location/operational-location.d.ts +0 -116
  196. package/dist-server/service/location/operational-location.js +0 -157
  197. package/dist-server/service/location/operational-location.js.map +0 -1
  198. package/dist-server/service/master-axis.d.ts +0 -40
  199. package/dist-server/service/master-axis.js +0 -57
  200. package/dist-server/service/master-axis.js.map +0 -1
  201. package/dist-server/service/master-change-approval/approval-input.d.ts +0 -17
  202. package/dist-server/service/master-change-approval/approval-input.js +0 -35
  203. package/dist-server/service/master-change-approval/approval-input.js.map +0 -1
  204. package/dist-server/service/master-change-approval/builtin-axes.d.ts +0 -4
  205. package/dist-server/service/master-change-approval/builtin-axes.js +0 -96
  206. package/dist-server/service/master-change-approval/builtin-axes.js.map +0 -1
  207. package/dist-server/service/master-change-approval/index.d.ts +0 -14
  208. package/dist-server/service/master-change-approval/index.js +0 -37
  209. package/dist-server/service/master-change-approval/index.js.map +0 -1
  210. package/dist-server/service/master-change-approval/master-change-axis.d.ts +0 -54
  211. package/dist-server/service/master-change-approval/master-change-axis.js +0 -17
  212. package/dist-server/service/master-change-approval/master-change-axis.js.map +0 -1
  213. package/dist-server/service/master-change-approval/master-change-flow.d.ts +0 -65
  214. package/dist-server/service/master-change-approval/master-change-flow.js +0 -125
  215. package/dist-server/service/master-change-approval/master-change-flow.js.map +0 -1
  216. package/dist-server/service/master-change-approval/master-change-resolver.d.ts +0 -18
  217. package/dist-server/service/master-change-approval/master-change-resolver.js +0 -58
  218. package/dist-server/service/master-change-approval/master-change-resolver.js.map +0 -1
  219. package/dist-server/service/master-change-policy.d.ts +0 -122
  220. package/dist-server/service/master-change-policy.js +0 -304
  221. package/dist-server/service/master-change-policy.js.map +0 -1
  222. package/dist-server/service/master-conformance-resolver.d.ts +0 -34
  223. package/dist-server/service/master-conformance-resolver.js +0 -153
  224. package/dist-server/service/master-conformance-resolver.js.map +0 -1
  225. package/dist-server/service/master-conformance.d.ts +0 -80
  226. package/dist-server/service/master-conformance.js +0 -266
  227. package/dist-server/service/master-conformance.js.map +0 -1
  228. package/dist-server/service/master-crud.d.ts +0 -55
  229. package/dist-server/service/master-crud.js +0 -93
  230. package/dist-server/service/master-crud.js.map +0 -1
  231. package/dist-server/service/master-list.d.ts +0 -12
  232. package/dist-server/service/master-list.js +0 -30
  233. package/dist-server/service/master-list.js.map +0 -1
  234. package/dist-server/service/master-page-query.d.ts +0 -33
  235. package/dist-server/service/master-page-query.js +0 -55
  236. package/dist-server/service/master-page-query.js.map +0 -1
  237. package/dist-server/service/master-page.d.ts +0 -85
  238. package/dist-server/service/master-page.js +0 -104
  239. package/dist-server/service/master-page.js.map +0 -1
  240. package/dist-server/service/material/index.d.ts +0 -7
  241. package/dist-server/service/material/index.js +0 -12
  242. package/dist-server/service/material/index.js.map +0 -1
  243. package/dist-server/service/material/material-axis-status.d.ts +0 -8
  244. package/dist-server/service/material/material-axis-status.js +0 -19
  245. package/dist-server/service/material/material-axis-status.js.map +0 -1
  246. package/dist-server/service/material/material-class.d.ts +0 -34
  247. package/dist-server/service/material/material-class.js +0 -104
  248. package/dist-server/service/material/material-class.js.map +0 -1
  249. package/dist-server/service/material/material-definition.d.ts +0 -45
  250. package/dist-server/service/material/material-definition.js +0 -125
  251. package/dist-server/service/material/material-definition.js.map +0 -1
  252. package/dist-server/service/material/material-effective-list.d.ts +0 -39
  253. package/dist-server/service/material/material-effective-list.js +0 -54
  254. package/dist-server/service/material/material-effective-list.js.map +0 -1
  255. package/dist-server/service/material/material-master-resolver.d.ts +0 -106
  256. package/dist-server/service/material/material-master-resolver.js +0 -351
  257. package/dist-server/service/material/material-master-resolver.js.map +0 -1
  258. package/dist-server/service/material/material-master.d.ts +0 -9
  259. package/dist-server/service/material/material-master.js +0 -24
  260. package/dist-server/service/material/material-master.js.map +0 -1
  261. package/dist-server/service/material/material-query.d.ts +0 -16
  262. package/dist-server/service/material/material-query.js +0 -79
  263. package/dist-server/service/material/material-query.js.map +0 -1
  264. package/dist-server/service/material/material-revision-content.d.ts +0 -10
  265. package/dist-server/service/material/material-revision-content.js +0 -92
  266. package/dist-server/service/material/material-revision-content.js.map +0 -1
  267. package/dist-server/service/material/material-revision-resolver.d.ts +0 -60
  268. package/dist-server/service/material/material-revision-resolver.js +0 -96
  269. package/dist-server/service/material/material-revision-resolver.js.map +0 -1
  270. package/dist-server/service/material/material-revision-service.d.ts +0 -179
  271. package/dist-server/service/material/material-revision-service.js +0 -687
  272. package/dist-server/service/material/material-revision-service.js.map +0 -1
  273. package/dist-server/service/material/material-revision.d.ts +0 -86
  274. package/dist-server/service/material/material-revision.js +0 -339
  275. package/dist-server/service/material/material-revision.js.map +0 -1
  276. package/dist-server/service/material/recipe-index.d.ts +0 -23
  277. package/dist-server/service/material/recipe-index.js +0 -44
  278. package/dist-server/service/material/recipe-index.js.map +0 -1
  279. package/dist-server/service/operation/index.d.ts +0 -6
  280. package/dist-server/service/operation/index.js +0 -10
  281. package/dist-server/service/operation/index.js.map +0 -1
  282. package/dist-server/service/operation/operation-definition.d.ts +0 -52
  283. package/dist-server/service/operation/operation-definition.js +0 -143
  284. package/dist-server/service/operation/operation-definition.js.map +0 -1
  285. package/dist-server/service/operation/operation-master-resolver.d.ts +0 -52
  286. package/dist-server/service/operation/operation-master-resolver.js +0 -187
  287. package/dist-server/service/operation/operation-master-resolver.js.map +0 -1
  288. package/dist-server/service/operation/operation-master.d.ts +0 -21
  289. package/dist-server/service/operation/operation-master.js +0 -28
  290. package/dist-server/service/operation/operation-master.js.map +0 -1
  291. package/dist-server/service/operation/operation-query.d.ts +0 -15
  292. package/dist-server/service/operation/operation-query.js +0 -56
  293. package/dist-server/service/operation/operation-query.js.map +0 -1
  294. package/dist-server/service/operation/operation-readiness-resolver.d.ts +0 -39
  295. package/dist-server/service/operation/operation-readiness-resolver.js +0 -111
  296. package/dist-server/service/operation/operation-readiness-resolver.js.map +0 -1
  297. package/dist-server/service/operation/operation-readiness.d.ts +0 -34
  298. package/dist-server/service/operation/operation-readiness.js +0 -133
  299. package/dist-server/service/operation/operation-readiness.js.map +0 -1
  300. package/dist-server/service/personnel/index.d.ts +0 -6
  301. package/dist-server/service/personnel/index.js +0 -10
  302. package/dist-server/service/personnel/index.js.map +0 -1
  303. package/dist-server/service/personnel/person.d.ts +0 -51
  304. package/dist-server/service/personnel/person.js +0 -119
  305. package/dist-server/service/personnel/person.js.map +0 -1
  306. package/dist-server/service/personnel/personnel-class-readiness.d.ts +0 -22
  307. package/dist-server/service/personnel/personnel-class-readiness.js +0 -98
  308. package/dist-server/service/personnel/personnel-class-readiness.js.map +0 -1
  309. package/dist-server/service/personnel/personnel-class.d.ts +0 -54
  310. package/dist-server/service/personnel/personnel-class.js +0 -114
  311. package/dist-server/service/personnel/personnel-class.js.map +0 -1
  312. package/dist-server/service/personnel/personnel-master-resolver.d.ts +0 -53
  313. package/dist-server/service/personnel/personnel-master-resolver.js +0 -187
  314. package/dist-server/service/personnel/personnel-master-resolver.js.map +0 -1
  315. package/dist-server/service/personnel/personnel-master.d.ts +0 -39
  316. package/dist-server/service/personnel/personnel-master.js +0 -34
  317. package/dist-server/service/personnel/personnel-master.js.map +0 -1
  318. package/dist-server/service/personnel/personnel-query.d.ts +0 -29
  319. package/dist-server/service/personnel/personnel-query.js +0 -79
  320. package/dist-server/service/personnel/personnel-query.js.map +0 -1
  321. package/dist-server/service/personnel/qualification.d.ts +0 -104
  322. package/dist-server/service/personnel/qualification.js +0 -147
  323. package/dist-server/service/personnel/qualification.js.map +0 -1
  324. package/dist-server/service/quality/index.d.ts +0 -4
  325. package/dist-server/service/quality/index.js +0 -8
  326. package/dist-server/service/quality/index.js.map +0 -1
  327. package/dist-server/service/quality/nonconformance-cause-resolver.d.ts +0 -12
  328. package/dist-server/service/quality/nonconformance-cause-resolver.js +0 -60
  329. package/dist-server/service/quality/nonconformance-cause-resolver.js.map +0 -1
  330. package/dist-server/service/quality/nonconformance-cause.d.ts +0 -20
  331. package/dist-server/service/quality/nonconformance-cause.js +0 -90
  332. package/dist-server/service/quality/nonconformance-cause.js.map +0 -1
  333. package/dist-server/service/recipe/index.d.ts +0 -10
  334. package/dist-server/service/recipe/index.js +0 -16
  335. package/dist-server/service/recipe/index.js.map +0 -1
  336. package/dist-server/service/recipe/recipe-definition.d.ts +0 -75
  337. package/dist-server/service/recipe/recipe-definition.js +0 -143
  338. package/dist-server/service/recipe/recipe-definition.js.map +0 -1
  339. package/dist-server/service/recipe/recipe-effective-list.d.ts +0 -49
  340. package/dist-server/service/recipe/recipe-effective-list.js +0 -96
  341. package/dist-server/service/recipe/recipe-effective-list.js.map +0 -1
  342. package/dist-server/service/recipe/recipe-master-resolver.d.ts +0 -28
  343. package/dist-server/service/recipe/recipe-master-resolver.js +0 -128
  344. package/dist-server/service/recipe/recipe-master-resolver.js.map +0 -1
  345. package/dist-server/service/recipe/recipe-master.d.ts +0 -37
  346. package/dist-server/service/recipe/recipe-master.js +0 -47
  347. package/dist-server/service/recipe/recipe-master.js.map +0 -1
  348. package/dist-server/service/recipe/recipe-query.d.ts +0 -21
  349. package/dist-server/service/recipe/recipe-query.js +0 -82
  350. package/dist-server/service/recipe/recipe-query.js.map +0 -1
  351. package/dist-server/service/recipe/recipe-revision-content.d.ts +0 -32
  352. package/dist-server/service/recipe/recipe-revision-content.js +0 -70
  353. package/dist-server/service/recipe/recipe-revision-content.js.map +0 -1
  354. package/dist-server/service/recipe/recipe-revision-line.d.ts +0 -30
  355. package/dist-server/service/recipe/recipe-revision-line.js +0 -95
  356. package/dist-server/service/recipe/recipe-revision-line.js.map +0 -1
  357. package/dist-server/service/recipe/recipe-revision-resolver.d.ts +0 -65
  358. package/dist-server/service/recipe/recipe-revision-resolver.js +0 -96
  359. package/dist-server/service/recipe/recipe-revision-resolver.js.map +0 -1
  360. package/dist-server/service/recipe/recipe-revision-service.d.ts +0 -183
  361. package/dist-server/service/recipe/recipe-revision-service.js +0 -754
  362. package/dist-server/service/recipe/recipe-revision-service.js.map +0 -1
  363. package/dist-server/service/recipe/recipe-revision.d.ts +0 -102
  364. package/dist-server/service/recipe/recipe-revision.js +0 -373
  365. package/dist-server/service/recipe/recipe-revision.js.map +0 -1
  366. package/dist-server/service/recipe/route-definition.d.ts +0 -51
  367. package/dist-server/service/recipe/route-definition.js +0 -114
  368. package/dist-server/service/recipe/route-definition.js.map +0 -1
  369. package/dist-server/service/resource/class-lineage.d.ts +0 -46
  370. package/dist-server/service/resource/class-lineage.js +0 -80
  371. package/dist-server/service/resource/class-lineage.js.map +0 -1
  372. package/dist-server/service/resource/class-members.d.ts +0 -36
  373. package/dist-server/service/resource/class-members.js +0 -59
  374. package/dist-server/service/resource/class-members.js.map +0 -1
  375. package/dist-server/service/resource/referrers.d.ts +0 -54
  376. package/dist-server/service/resource/referrers.js +0 -99
  377. package/dist-server/service/resource/referrers.js.map +0 -1
  378. package/dist-server/service/resource/resource-class.d.ts +0 -25
  379. package/dist-server/service/resource/resource-class.js +0 -29
  380. package/dist-server/service/resource/resource-class.js.map +0 -1
  381. package/dist-server/service/revision-baseline.d.ts +0 -71
  382. package/dist-server/service/revision-baseline.js +0 -87
  383. package/dist-server/service/revision-baseline.js.map +0 -1
  384. package/dist-server/service/row-lock.d.ts +0 -22
  385. package/dist-server/service/row-lock.js +0 -31
  386. package/dist-server/service/row-lock.js.map +0 -1
  387. package/dist-server/service/status/axis-stamp.d.ts +0 -16
  388. package/dist-server/service/status/axis-stamp.js +0 -22
  389. package/dist-server/service/status/axis-stamp.js.map +0 -1
  390. package/dist-server/service/status/index.d.ts +0 -3
  391. package/dist-server/service/status/index.js +0 -7
  392. package/dist-server/service/status/index.js.map +0 -1
  393. package/dist-server/service/status/master-status.d.ts +0 -38
  394. package/dist-server/service/status/master-status.js +0 -129
  395. package/dist-server/service/status/master-status.js.map +0 -1
  396. package/dist-server/service/test-spec/criteria-check.d.ts +0 -53
  397. package/dist-server/service/test-spec/criteria-check.js +0 -142
  398. package/dist-server/service/test-spec/criteria-check.js.map +0 -1
  399. package/dist-server/service/test-spec/criteria-rows.d.ts +0 -89
  400. package/dist-server/service/test-spec/criteria-rows.js +0 -139
  401. package/dist-server/service/test-spec/criteria-rows.js.map +0 -1
  402. package/dist-server/service/test-spec/index.d.ts +0 -6
  403. package/dist-server/service/test-spec/index.js +0 -11
  404. package/dist-server/service/test-spec/index.js.map +0 -1
  405. package/dist-server/service/test-spec/test-spec-effective-list.d.ts +0 -34
  406. package/dist-server/service/test-spec/test-spec-effective-list.js +0 -42
  407. package/dist-server/service/test-spec/test-spec-effective-list.js.map +0 -1
  408. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +0 -44
  409. package/dist-server/service/test-spec/test-spec-master-resolver.js +0 -144
  410. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +0 -1
  411. package/dist-server/service/test-spec/test-spec-master.d.ts +0 -6
  412. package/dist-server/service/test-spec/test-spec-master.js +0 -18
  413. package/dist-server/service/test-spec/test-spec-master.js.map +0 -1
  414. package/dist-server/service/test-spec/test-spec-query.d.ts +0 -15
  415. package/dist-server/service/test-spec/test-spec-query.js +0 -61
  416. package/dist-server/service/test-spec/test-spec-query.js.map +0 -1
  417. package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +0 -59
  418. package/dist-server/service/test-spec/test-spec-revision-resolver.js +0 -96
  419. package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +0 -1
  420. package/dist-server/service/test-spec/test-spec-revision-service.d.ts +0 -178
  421. package/dist-server/service/test-spec/test-spec-revision-service.js +0 -685
  422. package/dist-server/service/test-spec/test-spec-revision-service.js.map +0 -1
  423. package/dist-server/service/test-spec/test-spec-revision.d.ts +0 -86
  424. package/dist-server/service/test-spec/test-spec-revision.js +0 -334
  425. package/dist-server/service/test-spec/test-spec-revision.js.map +0 -1
  426. package/dist-server/service/test-spec/test-specification.d.ts +0 -47
  427. package/dist-server/service/test-spec/test-specification.js +0 -119
  428. package/dist-server/service/test-spec/test-specification.js.map +0 -1
  429. package/dist-server/tsconfig.tsbuildinfo +0 -1
@@ -1,266 +0,0 @@
1
- "use strict";
2
- /**
3
- * 마스터가 **말이 되나** — 축을 가로질러 한 번에 본다.
4
- *
5
- * ── 왜 필요한가 ────────────────────────────────────────────────────────────
6
- * 축마다 화면이 있고 축마다 값이 차 있는데, 그 사이가 이어지는지는 아무도 안 봤다. 설비 등급 다섯이
7
- * 서 있고 설비 스물둘이 어느 등급에도 안 들어 있던 일이 그랬다 — 두 화면 다 멀쩡해 보였다.
8
- * 카메라 자산 다섯이 ECU 등급에 들어 있던 것도, 정지 사유 고르기가 빈 목록으로 보이던 것도 같다.
9
- *
10
- * 사람이 열두 화면을 오가며 맞춰 보는 것으로는 안 된다. 맞춰 보지 않으면 아무도 모르고, 맞춰 봤는지
11
- * 아닌지도 남지 않는다.
12
- *
13
- * ── 두 가지만 본다 ─────────────────────────────────────────────────────────
14
- * **비어 있으면 안 되는 칸**과 **가리키는데 없는 것**이다. 둘 다 사실 판정이라 다툼이 없다.
15
- * 「이 값이 옳은가」는 여기서 안 본다 — 그것은 현장이 정한다.
16
- *
17
- * ── 없는 것을 없다고 말한다 ────────────────────────────────────────────────
18
- * 표가 통째로 비었으면 그것도 낸다. 「빠진 것 0건」과 「아직 아무것도 안 세웠다」는 다르고, 세지
19
- * 않으면 둘이 같아 보인다.
20
- */
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.checkMaster = checkMaster;
23
- exports.scannedCounts = scannedCounts;
24
- exports.summarize = summarize;
25
- exports.readMasterSnapshot = readMasterSnapshot;
26
- const nameSet = (rows) => new Set(rows.map(one => one.name).filter(Boolean));
27
- /** 값이 비었나 — 빈 문자열과 빈 배열도 빈 것으로 본다. */
28
- function blank(value) {
29
- if (value === null || value === undefined) {
30
- return true;
31
- }
32
- if (Array.isArray(value)) {
33
- return value.length === 0;
34
- }
35
- return String(value).trim() === '';
36
- }
37
- /** 이름 목록으로 만든다 — 한 개짜리 문자열도, 배열도 같게 다룬다. */
38
- function asList(value) {
39
- if (blank(value)) {
40
- return [];
41
- }
42
- return (Array.isArray(value) ? value : [value]).map(one => String(one).trim()).filter(Boolean);
43
- }
44
- /**
45
- * 축 하나를 잰다.
46
- *
47
- * `required` 는 비어 있으면 안 되는 칸, `refs` 는 「이 칸의 값이 저 이름들 안에 있어야 한다」이다.
48
- */
49
- function checkAxis(axis, rows, required, refs) {
50
- const found = [];
51
- if (rows.length === 0) {
52
- /* 표가 통째로 비었다. 「빠진 것 0건」과 다르다. */
53
- return [{ axis, kind: 'empty', field: axis }];
54
- }
55
- for (const row of rows) {
56
- for (const field of required) {
57
- if (blank(row[field])) {
58
- found.push({ axis, subject: row.name, kind: 'missing', field });
59
- }
60
- }
61
- for (const { field, within } of refs) {
62
- for (const value of asList(row[field])) {
63
- if (!within.has(value)) {
64
- found.push({ axis, subject: row.name, kind: 'dangling', field, value });
65
- }
66
- }
67
- }
68
- }
69
- return found;
70
- }
71
- /** 아무도 안 가리키는 것들 — 세워 놓고 쓰지 않는 선언. */
72
- function checkUnused(axis, rows, pointedAt, field) {
73
- return rows
74
- .filter(one => one.name && !pointedAt.has(one.name))
75
- .map(one => ({ axis, subject: one.name, kind: 'unused', field }));
76
- }
77
- /**
78
- * 마스터 전체를 잰다.
79
- *
80
- * **순서에 뜻이 없다.** 어느 축부터 보든 같은 답이 나와야 하고, 그래야 이 결과를 두 번 재서
81
- * 견줄 수 있다.
82
- */
83
- function checkMaster(snapshot) {
84
- const locations = nameSet(snapshot.operationalLocations);
85
- const operations = nameSet(snapshot.operationDefinitions);
86
- const routes = nameSet(snapshot.routeDefinitions);
87
- const materials = nameSet(snapshot.materialDefinitions);
88
- const specs = nameSet(snapshot.testSpecifications);
89
- const personnelClasses = nameSet(snapshot.personnelClasses);
90
- const equipmentClasses = nameSet(snapshot.equipmentClasses);
91
- const assetClasses = nameSet(snapshot.physicalAssetClasses);
92
- const materialClasses = nameSet(snapshot.materialClasses);
93
- const stopReasons = nameSet(snapshot.stopReasons);
94
- const found = [
95
- ...checkAxis('person', snapshot.persons, ['personnelClassIds', 'homeLocation'], [
96
- { field: 'personnelClassIds', within: personnelClasses },
97
- { field: 'homeLocation', within: locations },
98
- { field: 'testSpecificationIds', within: specs }
99
- ]),
100
- ...checkAxis('equipment', snapshot.equipment, ['kind', 'homeLocation', 'equipmentClassIds'], [
101
- { field: 'equipmentClassIds', within: equipmentClasses },
102
- { field: 'homeLocation', within: locations },
103
- { field: 'testSpecificationIds', within: specs }
104
- ]),
105
- ...checkAxis('physicalAsset', snapshot.physicalAssets, ['assetClassIds'], [
106
- { field: 'assetClassIds', within: assetClasses },
107
- { field: 'homeLocation', within: locations },
108
- { field: 'testSpecificationIds', within: specs }
109
- ]),
110
- ...checkAxis('materialDefinition', snapshot.materialDefinitions, ['materialClassIds'], [
111
- { field: 'materialClassIds', within: materialClasses },
112
- { field: 'testSpecificationIds', within: specs }
113
- ]),
114
- /*
115
- * 공정의 `resourceType` 은 설비 **종류**를 가리키는 값이라 이름 집합이 없다. 여기서는
116
- * 비었는지만 본다 — 없는 것을 있는 척 검사하지 않는다.
117
- */
118
- ...checkAxis('operationDefinition', snapshot.operationDefinitions, ['intent', 'locationType', 'duration'], []),
119
- ...checkAxis('routeDefinition', snapshot.routeDefinitions, ['steps'], [
120
- { field: 'steps', within: operations }
121
- ]),
122
- ...checkAxis('recipeDefinition', snapshot.recipeDefinitions, ['materialDefinitionName', 'route', 'inputs'], [
123
- { field: 'materialDefinitionName', within: materials },
124
- { field: 'route', within: routes }
125
- ]),
126
- ...checkAxis('operationalLocation', snapshot.operationalLocations, ['type', 'level'], [
127
- { field: 'parentId', within: locations }
128
- ]),
129
- ...checkAxis('stopReason', snapshot.stopReasons, ['status'], [{ field: 'parentName', within: stopReasons }]),
130
- ...checkAxis('testSpecification', snapshot.testSpecifications, ['criteria'], [])
131
- ];
132
- /*
133
- * 제조법의 투입은 한 줄이 여럿을 가리킨다. 위의 검사는 칸 하나를 보므로 여기서 따로 본다.
134
- */
135
- for (const recipe of snapshot.recipeDefinitions) {
136
- for (const part of recipe.inputs ?? []) {
137
- if (part?.material && !materials.has(part.material)) {
138
- found.push({ axis: 'recipeDefinition', subject: recipe.name, kind: 'dangling', field: 'inputs.material', value: part.material });
139
- }
140
- if (part?.operation && !operations.has(part.operation)) {
141
- found.push({ axis: 'recipeDefinition', subject: recipe.name, kind: 'dangling', field: 'inputs.operation', value: part.operation });
142
- }
143
- }
144
- }
145
- /*
146
- * ── 세워 놓고 아무도 안 든 등급 ─────────────────────────────────────────
147
- *
148
- * **상속을 타고 센다.** 등급은 등급을 상속하고(`baseIds`), 자격 판정도 그 사슬을 닫아서 본다
149
- * (커널의 `classClosure`). 그러니 「아무도 안 든다」도 닫힌 소속으로 물어야 한다.
150
- *
151
- * 직접 소속만 세면 뿌리 등급이 늘 걸린다. 품목의 유형 등급(완제품 · 반제품 · 원재료)이 그렇다 —
152
- * 품목은 성격 등급에 들고 그 등급이 유형을 상속하므로, 직접 소속은 언제나 0이다. 그것을 결함으로
153
- * 읽으면 멀쩡한 등급을 지우러 간다.
154
- *
155
- * 처음에는 품목만 따로 다뤘고 나머지 셋은 직접 소속으로 셌다. 아키텍트 레인이 설비 등급에도
156
- * 같은 축이 있다고 알려 주어 넷을 한 규칙으로 모았다 — 축마다 다르게 세면 한쪽만 고쳐지는 날이
157
- * 온다. [재봤음] 2026-09-04
158
- */
159
- const classAxes = [
160
- ['personnelClass', snapshot.personnelClasses, snapshot.persons, 'personnelClassIds'],
161
- ['equipmentClass', snapshot.equipmentClasses, snapshot.equipment, 'equipmentClassIds'],
162
- ['physicalAssetClass', snapshot.physicalAssetClasses, snapshot.physicalAssets, 'assetClassIds'],
163
- ['materialClass', snapshot.materialClasses, snapshot.materialDefinitions, 'materialClassIds']
164
- ];
165
- for (const [axis, classes, members, field] of classAxes) {
166
- found.push(...checkUnused(axis, classes, closedMembership(classes, members, field), 'members'));
167
- }
168
- /* 아무도 안 가리키는 라우팅·공정. 만들어 놓고 안 쓰는 것은 지워도 되는 것인지 사람이 판단한다. */
169
- const routesUsed = new Set(snapshot.recipeDefinitions.map(one => one.route).filter(Boolean));
170
- const operationsUsed = new Set([
171
- ...snapshot.routeDefinitions.flatMap(one => asList(one.steps)),
172
- ...snapshot.recipeDefinitions.flatMap(one => (one.inputs ?? []).map((part) => part?.operation).filter(Boolean))
173
- ]);
174
- found.push(...checkUnused('routeDefinition', snapshot.routeDefinitions, routesUsed, 'usedByRecipes'), ...checkUnused('operationDefinition', snapshot.operationDefinitions, operationsUsed, 'usedInRoutes'));
175
- return found;
176
- }
177
- /**
178
- * **닫힌 소속** — 소속이 상속을 타고 닿는 등급까지 모은다.
179
- *
180
- * 사람이 `welding-robot-6axis` 에 들고 그것이 `welding-equipment` 를 상속하면, 두 등급 다 「누가
181
- * 들었다」로 센다. 자격 판정이 그 사슬을 닫아서 보므로(커널의 `classClosure`) 여기서도 같게 본다.
182
- *
183
- * **고리를 밟으면 멈춘다.** `baseIds` 는 화면에서 손으로 넣을 수 있어 A→B→A 가 생길 수 있다.
184
- */
185
- function closedMembership(classes, members, field) {
186
- const baseOf = new Map(classes.map(one => [one.name, asList(one.baseIds)]));
187
- const reached = new Set();
188
- const walk = (name) => {
189
- if (!name || reached.has(name)) {
190
- return;
191
- }
192
- reached.add(name);
193
- for (const base of baseOf.get(name) ?? []) {
194
- walk(base);
195
- }
196
- };
197
- for (const row of members) {
198
- for (const name of asList(row[field])) {
199
- walk(name);
200
- }
201
- }
202
- return reached;
203
- }
204
- /** 여러 줄이 가리키는 이름들을 모은다. */
205
- function collect(rows, field) {
206
- return new Set(rows.flatMap(one => asList(one[field])));
207
- }
208
- /**
209
- * **무엇을 몇 개 봤나.**
210
- *
211
- * 어긋남 0건이 「멀쩡하다」인지 「안 돌았다」인지는 이것으로만 갈린다. 본 수를 안 내면 두 답이
212
- * 같은 글자로 나온다 — 검사기가 스스로를 못 믿게 만드는 가장 흔한 방식이다.
213
- */
214
- function scannedCounts(snapshot) {
215
- return Object.entries(snapshot)
216
- .map(([axis, rows]) => ({ axis, rows: rows.length }))
217
- .sort((a, b) => a.axis.localeCompare(b.axis));
218
- }
219
- /** 축·종류별로 몇 건인지. 사람이 먼저 볼 것을 고르는 데 쓴다. */
220
- function summarize(findings) {
221
- const tally = new Map();
222
- for (const one of findings) {
223
- const key = `${one.axis}${one.kind}`;
224
- tally.set(key, (tally.get(key) ?? 0) + 1);
225
- }
226
- return [...tally.entries()]
227
- .map(([key, count]) => {
228
- const [axis, kind] = key.split('');
229
- return { axis, kind, count };
230
- })
231
- .sort((a, b) => b.count - a.count || a.axis.localeCompare(b.axis));
232
- }
233
- /**
234
- * 한 도메인의 마스터를 통째로 읽어 잰다.
235
- *
236
- * **상한을 두지 않는다.** 정합성은 「전부 봤나」가 곧 답이라, 일부만 보고 「어긋남 0건」이라고 하면
237
- * 그 답이 거짓이 된다. 그래서 이것은 목록 화면이 부르는 것이 아니라 **사람이 눌러서 도는 검사**다.
238
- */
239
- async function readMasterSnapshot(domain, getRepository, entities) {
240
- const all = async (Entity, select) => (await getRepository(Entity).find({
241
- where: { domain: { id: domain.id } },
242
- select: ['id', 'name', ...select]
243
- }));
244
- const [persons, equipment, physicalAssets, materialDefinitions, operationDefinitions, routeDefinitions, recipeDefinitions, operationalLocations, stopReasons, testSpecifications, personnelClasses, equipmentClasses, physicalAssetClasses, materialClasses] = await Promise.all([
245
- all(entities.Person, ['personnelClassIds', 'homeLocation', 'testSpecificationIds']),
246
- all(entities.Equipment, ['kind', 'homeLocation', 'equipmentClassIds', 'testSpecificationIds']),
247
- all(entities.PhysicalAsset, ['assetClassIds', 'homeLocation', 'testSpecificationIds']),
248
- all(entities.MaterialDefinition, ['materialClassIds', 'testSpecificationIds']),
249
- all(entities.OperationDefinition, ['intent', 'locationType', 'resourceType', 'duration']),
250
- all(entities.RouteDefinition, ['steps']),
251
- all(entities.RecipeDefinition, ['materialDefinitionName', 'route', 'inputs']),
252
- all(entities.OperationalLocation, ['type', 'level', 'parentId']),
253
- all(entities.StopReason, ['status', 'parentName']),
254
- all(entities.TestSpecification, ['criteria']),
255
- all(entities.PersonnelClass, ['baseIds']),
256
- all(entities.EquipmentClass, ['baseIds']),
257
- all(entities.PhysicalAssetClass, ['baseIds']),
258
- all(entities.MaterialClass, ['baseIds'])
259
- ]);
260
- return {
261
- persons, equipment, physicalAssets, materialDefinitions, operationDefinitions,
262
- routeDefinitions, recipeDefinitions, operationalLocations, stopReasons, testSpecifications,
263
- personnelClasses, equipmentClasses, physicalAssetClasses, materialClasses
264
- };
265
- }
266
- //# sourceMappingURL=master-conformance.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"master-conformance.js","sourceRoot":"","sources":["../../server/service/master-conformance.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 마스터가 **말이 되나** — 축을 가로질러 한 번에 본다.\n *\n * ── 왜 필요한가 ────────────────────────────────────────────────────────────\n * 축마다 화면이 있고 축마다 값이 차 있는데, 그 사이가 이어지는지는 아무도 안 봤다. 설비 등급 다섯이\n * 서 있고 설비 스물둘이 어느 등급에도 안 들어 있던 일이 그랬다 — 두 화면 다 멀쩡해 보였다.\n * 카메라 자산 다섯이 ECU 등급에 들어 있던 것도, 정지 사유 고르기가 빈 목록으로 보이던 것도 같다.\n *\n * 사람이 열두 화면을 오가며 맞춰 보는 것으로는 안 된다. 맞춰 보지 않으면 아무도 모르고, 맞춰 봤는지\n * 아닌지도 남지 않는다.\n *\n * ── 두 가지만 본다 ─────────────────────────────────────────────────────────\n * **비어 있으면 안 되는 칸**과 **가리키는데 없는 것**이다. 둘 다 사실 판정이라 다툼이 없다.\n * 「이 값이 옳은가」는 여기서 안 본다 — 그것은 현장이 정한다.\n *\n * ── 없는 것을 없다고 말한다 ────────────────────────────────────────────────\n * 표가 통째로 비었으면 그것도 낸다. 「빠진 것 0건」과 「아직 아무것도 안 세웠다」는 다르고, 세지\n * 않으면 둘이 같아 보인다.\n */\n\n/** 한 건의 어긋남. 사실만 담는다 — 무엇을, 어디서, 무엇이. */\nexport interface Finding {\n /** 어느 축인가. `person` · `equipment` · `recipeDefinition` … */\n axis: string\n /** 어느 줄인가. 표가 통째로 빈 경우에는 없다. */\n subject?: string\n /** `missing` = 비어 있으면 안 되는 칸이 비었다 · `dangling` = 가리키는데 그런 것이 없다 · `empty` = 표가 비었다 · `unused` = 아무도 안 가리킨다 */\n kind: 'missing' | 'dangling' | 'empty' | 'unused'\n /** 어느 칸인가(`missing`·`dangling`), 또는 무엇이 비었나(`empty`·`unused`). */\n field: string\n /** 가리키던 값. `dangling` 일 때만. */\n value?: string\n}\n\n/** 한 축이 내놓는 줄들. 이름과 칸 몇 개만 본다. */\nexport type Row = Record<string, any>\n\nexport interface MasterSnapshot {\n persons: Row[]\n equipment: Row[]\n physicalAssets: Row[]\n materialDefinitions: Row[]\n operationDefinitions: Row[]\n routeDefinitions: Row[]\n recipeDefinitions: Row[]\n operationalLocations: Row[]\n stopReasons: Row[]\n testSpecifications: Row[]\n personnelClasses: Row[]\n equipmentClasses: Row[]\n physicalAssetClasses: Row[]\n materialClasses: Row[]\n}\n\nconst nameSet = (rows: Row[]) => new Set(rows.map(one => one.name).filter(Boolean))\n\n/** 값이 비었나 — 빈 문자열과 빈 배열도 빈 것으로 본다. */\nfunction blank(value: any): boolean {\n if (value === null || value === undefined) {\n return true\n }\n if (Array.isArray(value)) {\n return value.length === 0\n }\n\n return String(value).trim() === ''\n}\n\n/** 이름 목록으로 만든다 — 한 개짜리 문자열도, 배열도 같게 다룬다. */\nfunction asList(value: any): string[] {\n if (blank(value)) {\n return []\n }\n\n return (Array.isArray(value) ? value : [value]).map(one => String(one).trim()).filter(Boolean)\n}\n\n/**\n * 축 하나를 잰다.\n *\n * `required` 는 비어 있으면 안 되는 칸, `refs` 는 「이 칸의 값이 저 이름들 안에 있어야 한다」이다.\n */\nfunction checkAxis(\n axis: string,\n rows: Row[],\n required: string[],\n refs: { field: string; within: Set<string> }[]\n): Finding[] {\n const found: Finding[] = []\n\n if (rows.length === 0) {\n /* 표가 통째로 비었다. 「빠진 것 0건」과 다르다. */\n return [{ axis, kind: 'empty', field: axis }]\n }\n\n for (const row of rows) {\n for (const field of required) {\n if (blank(row[field])) {\n found.push({ axis, subject: row.name, kind: 'missing', field })\n }\n }\n\n for (const { field, within } of refs) {\n for (const value of asList(row[field])) {\n if (!within.has(value)) {\n found.push({ axis, subject: row.name, kind: 'dangling', field, value })\n }\n }\n }\n }\n\n return found\n}\n\n/** 아무도 안 가리키는 것들 — 세워 놓고 쓰지 않는 선언. */\nfunction checkUnused(axis: string, rows: Row[], pointedAt: Set<string>, field: string): Finding[] {\n return rows\n .filter(one => one.name && !pointedAt.has(one.name))\n .map(one => ({ axis, subject: one.name, kind: 'unused' as const, field }))\n}\n\n/**\n * 마스터 전체를 잰다.\n *\n * **순서에 뜻이 없다.** 어느 축부터 보든 같은 답이 나와야 하고, 그래야 이 결과를 두 번 재서\n * 견줄 수 있다.\n */\nexport function checkMaster(snapshot: MasterSnapshot): Finding[] {\n const locations = nameSet(snapshot.operationalLocations)\n const operations = nameSet(snapshot.operationDefinitions)\n const routes = nameSet(snapshot.routeDefinitions)\n const materials = nameSet(snapshot.materialDefinitions)\n const specs = nameSet(snapshot.testSpecifications)\n const personnelClasses = nameSet(snapshot.personnelClasses)\n const equipmentClasses = nameSet(snapshot.equipmentClasses)\n const assetClasses = nameSet(snapshot.physicalAssetClasses)\n const materialClasses = nameSet(snapshot.materialClasses)\n const stopReasons = nameSet(snapshot.stopReasons)\n\n const found: Finding[] = [\n ...checkAxis('person', snapshot.persons, ['personnelClassIds', 'homeLocation'], [\n { field: 'personnelClassIds', within: personnelClasses },\n { field: 'homeLocation', within: locations },\n { field: 'testSpecificationIds', within: specs }\n ]),\n\n ...checkAxis('equipment', snapshot.equipment, ['kind', 'homeLocation', 'equipmentClassIds'], [\n { field: 'equipmentClassIds', within: equipmentClasses },\n { field: 'homeLocation', within: locations },\n { field: 'testSpecificationIds', within: specs }\n ]),\n\n ...checkAxis('physicalAsset', snapshot.physicalAssets, ['assetClassIds'], [\n { field: 'assetClassIds', within: assetClasses },\n { field: 'homeLocation', within: locations },\n { field: 'testSpecificationIds', within: specs }\n ]),\n\n ...checkAxis('materialDefinition', snapshot.materialDefinitions, ['materialClassIds'], [\n { field: 'materialClassIds', within: materialClasses },\n { field: 'testSpecificationIds', within: specs }\n ]),\n\n /*\n * 공정의 `resourceType` 은 설비 **종류**를 가리키는 값이라 이름 집합이 없다. 여기서는\n * 비었는지만 본다 — 없는 것을 있는 척 검사하지 않는다.\n */\n ...checkAxis('operationDefinition', snapshot.operationDefinitions, ['intent', 'locationType', 'duration'], []),\n\n ...checkAxis('routeDefinition', snapshot.routeDefinitions, ['steps'], [\n { field: 'steps', within: operations }\n ]),\n\n ...checkAxis('recipeDefinition', snapshot.recipeDefinitions, ['materialDefinitionName', 'route', 'inputs'], [\n { field: 'materialDefinitionName', within: materials },\n { field: 'route', within: routes }\n ]),\n\n ...checkAxis('operationalLocation', snapshot.operationalLocations, ['type', 'level'], [\n { field: 'parentId', within: locations }\n ]),\n\n ...checkAxis('stopReason', snapshot.stopReasons, ['status'], [{ field: 'parentName', within: stopReasons }]),\n\n ...checkAxis('testSpecification', snapshot.testSpecifications, ['criteria'], [])\n ]\n\n /*\n * 제조법의 투입은 한 줄이 여럿을 가리킨다. 위의 검사는 칸 하나를 보므로 여기서 따로 본다.\n */\n for (const recipe of snapshot.recipeDefinitions) {\n for (const part of recipe.inputs ?? []) {\n if (part?.material && !materials.has(part.material)) {\n found.push({ axis: 'recipeDefinition', subject: recipe.name, kind: 'dangling', field: 'inputs.material', value: part.material })\n }\n if (part?.operation && !operations.has(part.operation)) {\n found.push({ axis: 'recipeDefinition', subject: recipe.name, kind: 'dangling', field: 'inputs.operation', value: part.operation })\n }\n }\n }\n\n /*\n * ── 세워 놓고 아무도 안 든 등급 ─────────────────────────────────────────\n *\n * **상속을 타고 센다.** 등급은 등급을 상속하고(`baseIds`), 자격 판정도 그 사슬을 닫아서 본다\n * (커널의 `classClosure`). 그러니 「아무도 안 든다」도 닫힌 소속으로 물어야 한다.\n *\n * 직접 소속만 세면 뿌리 등급이 늘 걸린다. 품목의 유형 등급(완제품 · 반제품 · 원재료)이 그렇다 —\n * 품목은 성격 등급에 들고 그 등급이 유형을 상속하므로, 직접 소속은 언제나 0이다. 그것을 결함으로\n * 읽으면 멀쩡한 등급을 지우러 간다.\n *\n * 처음에는 품목만 따로 다뤘고 나머지 셋은 직접 소속으로 셌다. 아키텍트 레인이 설비 등급에도\n * 같은 축이 있다고 알려 주어 넷을 한 규칙으로 모았다 — 축마다 다르게 세면 한쪽만 고쳐지는 날이\n * 온다. [재봤음] 2026-09-04\n */\n const classAxes: [string, Row[], Row[], string][] = [\n ['personnelClass', snapshot.personnelClasses, snapshot.persons, 'personnelClassIds'],\n ['equipmentClass', snapshot.equipmentClasses, snapshot.equipment, 'equipmentClassIds'],\n ['physicalAssetClass', snapshot.physicalAssetClasses, snapshot.physicalAssets, 'assetClassIds'],\n ['materialClass', snapshot.materialClasses, snapshot.materialDefinitions, 'materialClassIds']\n ]\n\n for (const [axis, classes, members, field] of classAxes) {\n found.push(...checkUnused(axis, classes, closedMembership(classes, members, field), 'members'))\n }\n\n /* 아무도 안 가리키는 라우팅·공정. 만들어 놓고 안 쓰는 것은 지워도 되는 것인지 사람이 판단한다. */\n const routesUsed = new Set(snapshot.recipeDefinitions.map(one => one.route).filter(Boolean))\n const operationsUsed = new Set([\n ...snapshot.routeDefinitions.flatMap(one => asList(one.steps)),\n ...snapshot.recipeDefinitions.flatMap(one => (one.inputs ?? []).map((part: any) => part?.operation).filter(Boolean))\n ])\n\n found.push(\n ...checkUnused('routeDefinition', snapshot.routeDefinitions, routesUsed, 'usedByRecipes'),\n ...checkUnused('operationDefinition', snapshot.operationDefinitions, operationsUsed, 'usedInRoutes')\n )\n\n return found\n}\n\n/**\n * **닫힌 소속** — 소속이 상속을 타고 닿는 등급까지 모은다.\n *\n * 사람이 `welding-robot-6axis` 에 들고 그것이 `welding-equipment` 를 상속하면, 두 등급 다 「누가\n * 들었다」로 센다. 자격 판정이 그 사슬을 닫아서 보므로(커널의 `classClosure`) 여기서도 같게 본다.\n *\n * **고리를 밟으면 멈춘다.** `baseIds` 는 화면에서 손으로 넣을 수 있어 A→B→A 가 생길 수 있다.\n */\nfunction closedMembership(classes: Row[], members: Row[], field: string): Set<string> {\n const baseOf = new Map(classes.map(one => [one.name, asList(one.baseIds)]))\n const reached = new Set<string>()\n\n const walk = (name: string) => {\n if (!name || reached.has(name)) {\n return\n }\n reached.add(name)\n\n for (const base of baseOf.get(name) ?? []) {\n walk(base)\n }\n }\n\n for (const row of members) {\n for (const name of asList(row[field])) {\n walk(name)\n }\n }\n\n return reached\n}\n\n/** 여러 줄이 가리키는 이름들을 모은다. */\nfunction collect(rows: Row[], field: string): Set<string> {\n return new Set(rows.flatMap(one => asList(one[field])))\n}\n\n/**\n * **무엇을 몇 개 봤나.**\n *\n * 어긋남 0건이 「멀쩡하다」인지 「안 돌았다」인지는 이것으로만 갈린다. 본 수를 안 내면 두 답이\n * 같은 글자로 나온다 — 검사기가 스스로를 못 믿게 만드는 가장 흔한 방식이다.\n */\nexport function scannedCounts(snapshot: MasterSnapshot): { axis: string; rows: number }[] {\n return Object.entries(snapshot)\n .map(([axis, rows]) => ({ axis, rows: (rows as Row[]).length }))\n .sort((a, b) => a.axis.localeCompare(b.axis))\n}\n\n/** 축·종류별로 몇 건인지. 사람이 먼저 볼 것을 고르는 데 쓴다. */\nexport function summarize(findings: Finding[]): { axis: string; kind: string; count: number }[] {\n const tally = new Map<string, number>()\n\n for (const one of findings) {\n const key = `${one.axis}\u0000${one.kind}`\n tally.set(key, (tally.get(key) ?? 0) + 1)\n }\n\n return [...tally.entries()]\n .map(([key, count]) => {\n const [axis, kind] = key.split('\u0000')\n\n return { axis, kind, count }\n })\n .sort((a, b) => b.count - a.count || a.axis.localeCompare(b.axis))\n}\n\n/**\n * 한 도메인의 마스터를 통째로 읽어 잰다.\n *\n * **상한을 두지 않는다.** 정합성은 「전부 봤나」가 곧 답이라, 일부만 보고 「어긋남 0건」이라고 하면\n * 그 답이 거짓이 된다. 그래서 이것은 목록 화면이 부르는 것이 아니라 **사람이 눌러서 도는 검사**다.\n */\nexport async function readMasterSnapshot(domain: any, getRepository: any, entities: Record<string, any>): Promise<MasterSnapshot> {\n const all = async (Entity: any, select: string[]) =>\n (await getRepository(Entity).find({\n where: { domain: { id: domain.id } } as any,\n select: ['id', 'name', ...select] as any\n })) as Row[]\n\n const [\n persons, equipment, physicalAssets, materialDefinitions, operationDefinitions,\n routeDefinitions, recipeDefinitions, operationalLocations, stopReasons, testSpecifications,\n personnelClasses, equipmentClasses, physicalAssetClasses, materialClasses\n ] = await Promise.all([\n all(entities.Person, ['personnelClassIds', 'homeLocation', 'testSpecificationIds']),\n all(entities.Equipment, ['kind', 'homeLocation', 'equipmentClassIds', 'testSpecificationIds']),\n all(entities.PhysicalAsset, ['assetClassIds', 'homeLocation', 'testSpecificationIds']),\n all(entities.MaterialDefinition, ['materialClassIds', 'testSpecificationIds']),\n all(entities.OperationDefinition, ['intent', 'locationType', 'resourceType', 'duration']),\n all(entities.RouteDefinition, ['steps']),\n all(entities.RecipeDefinition, ['materialDefinitionName', 'route', 'inputs']),\n all(entities.OperationalLocation, ['type', 'level', 'parentId']),\n all(entities.StopReason, ['status', 'parentName']),\n all(entities.TestSpecification, ['criteria']),\n all(entities.PersonnelClass, ['baseIds']),\n all(entities.EquipmentClass, ['baseIds']),\n all(entities.PhysicalAssetClass, ['baseIds']),\n all(entities.MaterialClass, ['baseIds'])\n ])\n\n return {\n persons, equipment, physicalAssets, materialDefinitions, operationDefinitions,\n routeDefinitions, recipeDefinitions, operationalLocations, stopReasons, testSpecifications,\n personnelClasses, equipmentClasses, physicalAssetClasses, materialClasses\n }\n}\n"]}
@@ -1,55 +0,0 @@
1
- import { EntityManager, ObjectLiteral } from 'typeorm';
2
- import { Domain } from '@things-factory/shell';
3
- /**
4
- * 마스터를 채우고 고치는 **한 벌의 규칙** — 열두 축이 같은 함수를 쓴다.
5
- *
6
- * ── 왜 마스터는 그리드에서 고칠 수 있나 ────────────────────────────────────
7
- * 업무 화면(실적 · 검사 · 처분)은 조회 전용이다. 그것은 **일어난 일의 기록**이라, 고칠 수 있으면
8
- * 「그때 무엇이 있었나」가 「지금 무엇으로 적혀 있나」로 바뀐다.
9
- *
10
- * 마스터는 다르다. 「이 사람이 용접 자격을 갖는다」는 일어난 일이 아니라 **선언**이다. 선언은 바뀌고,
11
- * 바뀐 것이 지금의 선언이다. 그래서 그리드에서 고친다.
12
- *
13
- * ── 지우는 것만 다르게 다룬다 ──────────────────────────────────────────────
14
- * 유효 기간을 가진 축은 **행을 지우지 않는다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다
15
- * (어제 실적이 가리키던 설비가 사라지면 그 실적은 어느 설비의 것도 아니게 된다). 대신
16
- * `effectiveEnd` 를 채워 오늘부터 유효하지 않게 한다.
17
- *
18
- * 유효 기간이 없는 축만 실제로 지운다.
19
- */
20
- /** 그리드가 보내는 표식. `+` 새로 만든 행 · `M` 고친 행 · `-` 지운 행. */
21
- export type CuFlag = '+' | 'M' | '-';
22
- export interface MasterPatch {
23
- id?: string;
24
- cuFlag?: string;
25
- [key: string]: unknown;
26
- }
27
- type EntityClass = {
28
- new (): ObjectLiteral;
29
- };
30
- export interface SaveMasterOptions {
31
- /**
32
- * **언제부터 그러한가** — 배정과 선언을 고칠 때.
33
- *
34
- * 안 주면 지금부터다. 미래면 주장만 남고 본행은 그 시각이 올 때까지 그대로다
35
- * (§`claimAssignmentChanges`).
36
- */
37
- appliedAt?: Date;
38
- /** 과거 시각일 때, **지연 기록인가 이미 적은 것의 정정인가.** 안 주면 지연 기록으로 본다. */
39
- appliedKind?: 'change' | 'correction';
40
- /** 정정이면 어느 구간까지인가. */
41
- appliedUntil?: Date;
42
- /**
43
- * 유효 기간을 갖는 축인가.
44
- *
45
- * 참이면 지우기가 **`effectiveEnd` 를 채우는 것**이 된다. 거짓이면 행을 지운다.
46
- */
47
- hasEffectivePeriod?: boolean;
48
- }
49
- /**
50
- * 그리드가 보낸 변경을 한 번에 적용한다.
51
- *
52
- * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.
53
- */
54
- export declare function saveMasterPatches(manager: EntityManager, domain: Domain, entity: EntityClass, patches: readonly MasterPatch[], user: unknown, options?: SaveMasterOptions): Promise<ObjectLiteral[]>;
55
- export {};
@@ -1,93 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.saveMasterPatches = saveMasterPatches;
4
- const typeorm_1 = require("typeorm");
5
- const shell_1 = require("@things-factory/shell");
6
- const master_axis_1 = require("./master-axis");
7
- const master_change_policy_1 = require("./master-change-policy");
8
- const assignment_write_1 = require("./assignment/assignment-write");
9
- /**
10
- * 그리드가 보낸 변경을 한 번에 적용한다.
11
- *
12
- * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.
13
- */
14
- async function saveMasterPatches(manager, domain, entity, patches, user, options = {}) {
15
- const axis = master_axis_1.MASTER_AXES.find(axis => axis.entity === entity);
16
- if (!axis)
17
- throw new Error('saveMasterPatches: the entity must be a declared master axis');
18
- await (0, master_change_policy_1.assertDirectMasterChange)(manager, domain.id, axis.key);
19
- if (['recipeDefinition', 'materialDefinition'].includes(axis.key))
20
- throw new shell_1.Refusal('REVISION_REQUIRED', { axis: axis.key }, 'Change this master through a revision draft, including non-regulated publication.');
21
- const repository = manager.getRepository(entity);
22
- const results = [];
23
- const created = patches.filter(patch => flagOf(patch) === '+');
24
- const updated = patches.filter(patch => flagOf(patch) === 'M');
25
- const removed = patches.filter(patch => flagOf(patch) === '-');
26
- for (const patch of created) {
27
- /* 새 행의 `id` 는 그리드가 임시로 붙인 것이다 — 그대로 저장하면 그것이 진짜 키가 된다. */
28
- const { cuFlag, id, ...values } = patch;
29
- results.push(await repository.save({ ...values, domain, creator: user, updater: user }));
30
- }
31
- for (const patch of updated) {
32
- const { cuFlag, id, ...values } = patch;
33
- if (!id) {
34
- throw new Error('saveMasterPatches: a changed row must carry its id');
35
- }
36
- const found = await repository.findOne({ where: { domain: { id: domain.id }, id } });
37
- /*
38
- * 없는 행을 고치라고 하면 만들지 않는다. 다른 사람이 지웠거나 다른 도메인의 행이고, 둘 다
39
- * 조용히 새 행을 만들 일이 아니다.
40
- */
41
- if (!found) {
42
- throw new Error(`saveMasterPatches: no such row to change — ${String(id)}`);
43
- }
44
- /*
45
- * ── 배정과 선언은 **주장으로 남기고, 미래는 본행에 안 쓴다** ──────────────
46
- *
47
- * 세 칸(`equipment.homeLocation` · `operationalLocation.workShiftNames` · `parentId`)은 가동률
48
- * 분모를 정한다. 그래서 「언제부터 그러한가」를 함께 받아 이력에 남긴다.
49
- *
50
- * **적용 시각이 미래면 본행을 안 건드린다.** 다음 달 이동을 지금 적었다고 다른 제품이 오늘부터
51
- * 새 자리를 읽으면 안 된다 — 도래하면 `projectDueClaims` 가 옮긴다.
52
- */
53
- const scheduled = await (0, assignment_write_1.claimAssignmentChanges)(manager, domain, axis.key, found, values, user, options);
54
- results.push(await repository.save({ ...found, ...values, ...scheduled.keepOnRow, updater: user }));
55
- }
56
- if (removed.length) {
57
- await retire(repository, domain, removed, user, options);
58
- }
59
- return results;
60
- }
61
- /**
62
- * 없앤다 — 유효 기간이 있으면 **끝을 채우고**, 없으면 지운다.
63
- */
64
- async function retire(repository, domain, removed, user, options) {
65
- const ids = removed.map(patch => patch.id).filter(Boolean);
66
- if (!ids.length) {
67
- return;
68
- }
69
- if (!options.hasEffectivePeriod) {
70
- await repository.delete({ domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) });
71
- return;
72
- }
73
- const rows = await repository.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) } });
74
- const now = new Date();
75
- for (const row of rows) {
76
- /*
77
- * 이미 끝이 적혀 있으면 그대로 둔다. 다시 오늘로 바꾸면 「언제부터 안 썼나」가 바뀐다.
78
- */
79
- if (row.effectiveEnd) {
80
- continue;
81
- }
82
- await repository.save({ ...row, effectiveEnd: now, updater: user });
83
- }
84
- }
85
- function flagOf(patch) {
86
- const flag = String(patch.cuFlag ?? '').toUpperCase();
87
- if (flag === '+' || flag === 'M' || flag === '-') {
88
- return flag;
89
- }
90
- /* 표식이 없으면 고침으로 본다 — 그리드가 표식을 안 붙이는 경우가 있고, 만드는 쪽으로 두면 행이 늘어난다. */
91
- return 'M';
92
- }
93
- //# sourceMappingURL=master-crud.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"master-crud.js","sourceRoot":"","sources":["../../server/service/master-crud.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In, ObjectLiteral, Repository } from 'typeorm'\n\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { MASTER_AXES } from './master-axis'\nimport { assertDirectMasterChange } from './master-change-policy'\nimport { claimAssignmentChanges } from './assignment/assignment-write'\n\n/**\n * 마스터를 채우고 고치는 **한 벌의 규칙** — 열두 축이 같은 함수를 쓴다.\n *\n * ── 왜 마스터는 그리드에서 고칠 수 있나 ────────────────────────────────────\n * 업무 화면(실적 · 검사 · 처분)은 조회 전용이다. 그것은 **일어난 일의 기록**이라, 고칠 수 있으면\n * 「그때 무엇이 있었나」가 「지금 무엇으로 적혀 있나」로 바뀐다.\n *\n * 마스터는 다르다. 「이 사람이 용접 자격을 갖는다」는 일어난 일이 아니라 **선언**이다. 선언은 바뀌고,\n * 바뀐 것이 지금의 선언이다. 그래서 그리드에서 고친다.\n *\n * ── 지우는 것만 다르게 다룬다 ──────────────────────────────────────────────\n * 유효 기간을 가진 축은 **행을 지우지 않는다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다\n * (어제 실적이 가리키던 설비가 사라지면 그 실적은 어느 설비의 것도 아니게 된다). 대신\n * `effectiveEnd` 를 채워 오늘부터 유효하지 않게 한다.\n *\n * 유효 기간이 없는 축만 실제로 지운다.\n */\n\n/** 그리드가 보내는 표식. `+` 새로 만든 행 · `M` 고친 행 · `-` 지운 행. */\nexport type CuFlag = '+' | 'M' | '-'\n\nexport interface MasterPatch {\n id?: string\n cuFlag?: string\n [key: string]: unknown\n}\n\ntype EntityClass = { new (): ObjectLiteral }\n\nexport interface SaveMasterOptions {\n /**\n * **언제부터 그러한가** — 배정과 선언을 고칠 때.\n *\n * 안 주면 지금부터다. 미래면 주장만 남고 본행은 그 시각이 올 때까지 그대로다\n * (§`claimAssignmentChanges`).\n */\n appliedAt?: Date\n /** 과거 시각일 때, **지연 기록인가 이미 적은 것의 정정인가.** 안 주면 지연 기록으로 본다. */\n appliedKind?: 'change' | 'correction'\n /** 정정이면 어느 구간까지인가. */\n appliedUntil?: Date\n /**\n * 유효 기간을 갖는 축인가.\n *\n * 참이면 지우기가 **`effectiveEnd` 를 채우는 것**이 된다. 거짓이면 행을 지운다.\n */\n hasEffectivePeriod?: boolean\n}\n\n/**\n * 그리드가 보낸 변경을 한 번에 적용한다.\n *\n * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.\n */\nexport async function saveMasterPatches(\n manager: EntityManager,\n domain: Domain,\n entity: EntityClass,\n patches: readonly MasterPatch[],\n user: unknown,\n options: SaveMasterOptions = {}\n): Promise<ObjectLiteral[]> {\n const axis = MASTER_AXES.find(axis => axis.entity === entity)\n if (!axis) throw new Error('saveMasterPatches: the entity must be a declared master axis')\n await assertDirectMasterChange(manager, domain.id, axis.key)\n if (['recipeDefinition', 'materialDefinition'].includes(axis.key))\n throw new Refusal('REVISION_REQUIRED', { axis: axis.key }, 'Change this master through a revision draft, including non-regulated publication.')\n const repository = manager.getRepository(entity)\n const results: ObjectLiteral[] = []\n\n const created = patches.filter(patch => flagOf(patch) === '+')\n const updated = patches.filter(patch => flagOf(patch) === 'M')\n const removed = patches.filter(patch => flagOf(patch) === '-')\n\n for (const patch of created) {\n /* 새 행의 `id` 는 그리드가 임시로 붙인 것이다 — 그대로 저장하면 그것이 진짜 키가 된다. */\n const { cuFlag, id, ...values } = patch\n\n results.push(await repository.save({ ...values, domain, creator: user, updater: user }))\n }\n\n for (const patch of updated) {\n const { cuFlag, id, ...values } = patch\n\n if (!id) {\n throw new Error('saveMasterPatches: a changed row must carry its id')\n }\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, id } })\n\n /*\n * 없는 행을 고치라고 하면 만들지 않는다. 다른 사람이 지웠거나 다른 도메인의 행이고, 둘 다\n * 조용히 새 행을 만들 일이 아니다.\n */\n if (!found) {\n throw new Error(`saveMasterPatches: no such row to change — ${String(id)}`)\n }\n\n /*\n * ── 배정과 선언은 **주장으로 남기고, 미래는 본행에 안 쓴다** ──────────────\n *\n * 세 칸(`equipment.homeLocation` · `operationalLocation.workShiftNames` · `parentId`)은 가동률\n * 분모를 정한다. 그래서 「언제부터 그러한가」를 함께 받아 이력에 남긴다.\n *\n * **적용 시각이 미래면 본행을 안 건드린다.** 다음 달 이동을 지금 적었다고 다른 제품이 오늘부터\n * 새 자리를 읽으면 안 된다 — 도래하면 `projectDueClaims` 가 옮긴다.\n */\n const scheduled = await claimAssignmentChanges(manager, domain, axis.key, found, values, user, options)\n\n results.push(await repository.save({ ...found, ...values, ...scheduled.keepOnRow, updater: user }))\n }\n\n if (removed.length) {\n await retire(repository, domain, removed, user, options)\n }\n\n return results\n}\n\n/**\n * 없앤다 — 유효 기간이 있으면 **끝을 채우고**, 없으면 지운다.\n */\nasync function retire(\n repository: Repository<ObjectLiteral>,\n domain: Domain,\n removed: readonly MasterPatch[],\n user: unknown,\n options: SaveMasterOptions\n): Promise<void> {\n const ids = removed.map(patch => patch.id).filter(Boolean) as string[]\n\n if (!ids.length) {\n return\n }\n\n if (!options.hasEffectivePeriod) {\n await repository.delete({ domain: { id: domain.id }, id: In(ids) })\n return\n }\n\n const rows = await repository.find({ where: { domain: { id: domain.id }, id: In(ids) } })\n const now = new Date()\n\n for (const row of rows) {\n /*\n * 이미 끝이 적혀 있으면 그대로 둔다. 다시 오늘로 바꾸면 「언제부터 안 썼나」가 바뀐다.\n */\n if (row.effectiveEnd) {\n continue\n }\n\n await repository.save({ ...row, effectiveEnd: now, updater: user })\n }\n}\n\nfunction flagOf(patch: MasterPatch): CuFlag {\n const flag = String(patch.cuFlag ?? '').toUpperCase()\n\n if (flag === '+' || flag === 'M' || flag === '-') {\n return flag\n }\n\n /* 표식이 없으면 고침으로 본다 — 그리드가 표식을 안 붙이는 경우가 있고, 만드는 쪽으로 두면 행이 늘어난다. */\n return 'M'\n}\n"]}
@@ -1,12 +0,0 @@
1
- import { ObjectLiteral } from 'typeorm';
2
- import { Domain, ListParam } from '@things-factory/shell';
3
- /**
4
- * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**
5
- *
6
- * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면
7
- * 잘린 목록과 「이게 전부」를 구별할 수 없다.
8
- */
9
- export declare function listMaster(axisKey: string, params: ListParam, domain: Domain): Promise<{
10
- items: ObjectLiteral[];
11
- total: number;
12
- }>;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.listMaster = listMaster;
4
- const shell_1 = require("@things-factory/shell");
5
- const master_axis_1 = require("./master-axis");
6
- const recipe_effective_list_1 = require("./recipe/recipe-effective-list");
7
- const material_effective_list_1 = require("./material/material-effective-list");
8
- /**
9
- * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**
10
- *
11
- * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면
12
- * 잘린 목록과 「이게 전부」를 구별할 수 없다.
13
- */
14
- async function listMaster(axisKey, params, domain) {
15
- const axis = (0, master_axis_1.masterAxisOf)(axisKey);
16
- if (axisKey === 'recipeDefinition')
17
- return (0, recipe_effective_list_1.listEffectiveRecipes)((0, shell_1.getRepository)(axis.entity).manager, domain, params);
18
- if (axisKey === 'materialDefinition')
19
- return (0, material_effective_list_1.listEffectiveMaterialDefinitions)((0, shell_1.getRepository)(axis.entity).manager, domain, params);
20
- const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
21
- repository: (0, shell_1.getRepository)(axis.entity),
22
- params,
23
- domain,
24
- searchables: axis.searchables,
25
- alias: 'm'
26
- });
27
- const [items, total] = await queryBuilder.getManyAndCount();
28
- return { items, total };
29
- }
30
- //# sourceMappingURL=master-list.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"master-list.js","sourceRoot":"","sources":["../../server/service/master-list.ts"],"names":[],"mappings":";;AAcA,gCAoBC;AAhCD,iDAAuG;AAEvG,+CAA4C;AAC5C,0EAAqE;AACrE,gFAAqF;AAErF;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,MAAiB,EACjB,MAAc;IAEd,MAAM,IAAI,GAAG,IAAA,0BAAY,EAAC,OAAO,CAAC,CAAA;IAClC,IAAI,OAAO,KAAK,kBAAkB;QAAE,OAAO,IAAA,4CAAoB,EAAC,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnH,IAAI,OAAO,KAAK,oBAAoB;QAAE,OAAO,IAAA,0DAAgC,EAAC,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAEjI,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;QACjD,UAAU,EAAE,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,CAAC;QACtC,MAAM;QACN,MAAM;QACN,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,GAAG;KACX,CAAC,CAAA;IAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;IAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AACzB,CAAC","sourcesContent":["import { ObjectLiteral } from 'typeorm'\n\nimport { Domain, ListParam, getQueryBuilderFromListParams, getRepository } from '@things-factory/shell'\n\nimport { masterAxisOf } from './master-axis'\nimport { listEffectiveRecipes } from './recipe/recipe-effective-list'\nimport { listEffectiveMaterialDefinitions } from './material/material-effective-list'\n\n/**\n * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**\n *\n * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면\n * 잘린 목록과 「이게 전부」를 구별할 수 없다.\n */\nexport async function listMaster(\n axisKey: string,\n params: ListParam,\n domain: Domain\n): Promise<{ items: ObjectLiteral[]; total: number }> {\n const axis = masterAxisOf(axisKey)\n if (axisKey === 'recipeDefinition') return listEffectiveRecipes(getRepository(axis.entity).manager, domain, params)\n if (axisKey === 'materialDefinition') return listEffectiveMaterialDefinitions(getRepository(axis.entity).manager, domain, params)\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(axis.entity),\n params,\n domain,\n searchables: axis.searchables,\n alias: 'm'\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n}\n"]}
@@ -1,33 +0,0 @@
1
- import { Domain } from '@things-factory/shell';
2
- import type { Page, PageRequest } from './master-page';
3
- /**
4
- * 마스터 한 축을 **나눠 읽는다** — 저장소 쪽. 판단은 `master-page` 가 한다.
5
- *
6
- * ═══════════════════════════════════════════════════════════════════════════
7
- * ── 등급은 매 쪽에 통째로 싣는다 ───────────────────────────────────────────
8
- * 이 축들은 구성원이 자기 **등급을 이름으로 가리킨다.** 등급과 구성원을 따로 나눠 보내면 구성원이
9
- * 먼저 도착하고 등급이 나중에 오는 순간이 생기고, 그 순간 받는 쪽은 **없는 등급을 가리키는 구성원**을
10
- * 갖는다. 원래 이 조회들이 「자르지 않는다」고 적어 둔 이유가 그것이다.
11
- *
12
- * 그래서 **구성원만 나누고 등급은 매 쪽에 전부 싣는다.** 등급은 수십 단위라 실어도 크지 않고, 그러면
13
- * 어느 쪽을 먼저 받아도 가리키는 곳이 항상 있다.
14
- *
15
- * ── 이름 다음부터 읽는다 ───────────────────────────────────────────────────
16
- * `skip` 은 규모에서 못 쓴다 — 건너뛴 만큼을 매번 다시 읽는다. 이 축들은 이미 이름으로 정렬해 내므로
17
- * **마지막 이름 다음부터** 읽으면 건너뛸 것이 없다.
18
- * ═══════════════════════════════════════════════════════════════════════════
19
- */
20
- /**
21
- * 한 축을 한 쪽만큼 읽는다.
22
- *
23
- * 이름 칸을 받는 이유: 축마다 다르다(`name` · `operationKey` …). 여기서 알아보려 하면 축이 늘 때마다
24
- * 이 함수를 고쳐야 한다.
25
- */
26
- export declare function pullPage<T>(entity: any, domain: Domain, request: PageRequest, nameColumn?: keyof T & string): Promise<Page<T>>;
27
- /**
28
- * **통째로 달라고 했는데 너무 크면 던진다.**
29
- *
30
- * 자르고 넘어가지 않는다 — 받는 쪽은 그것이 전부인 줄 알고 트윈을 세우고, 없는 품목이 화면에서 그냥
31
- * 존재하지 않게 된다. 오류가 안 난다. 그래서 **틀린 답 대신 오류**를 준다.
32
- */
33
- export declare function refuseIfTooLarge(axis: string, request: PageRequest, page: Page<unknown>): void;