@things-factory/ops-master 10.1.248 → 10.1.249

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/dist-client/bootstrap.d.ts +19 -0
  2. package/dist-client/bootstrap.js +66 -0
  3. package/dist-client/bootstrap.js.map +1 -0
  4. package/dist-client/index.d.ts +17 -0
  5. package/dist-client/index.js +21 -0
  6. package/dist-client/index.js.map +1 -0
  7. package/dist-client/master-change-approval.d.ts +14 -0
  8. package/dist-client/master-change-approval.js +36 -0
  9. package/dist-client/master-change-approval.js.map +1 -0
  10. package/dist-client/master-change-policy-axes.d.ts +37 -0
  11. package/dist-client/master-change-policy-axes.js +29 -0
  12. package/dist-client/master-change-policy-axes.js.map +1 -0
  13. package/dist-client/master-change-policy-panel.d.ts +59 -0
  14. package/dist-client/master-change-policy-panel.js +454 -0
  15. package/dist-client/master-change-policy-panel.js.map +1 -0
  16. package/dist-client/master-change-providers.d.ts +4 -0
  17. package/dist-client/master-change-providers.js +91 -0
  18. package/dist-client/master-change-providers.js.map +1 -0
  19. package/dist-client/pages/master/applied-when-dialog.d.ts +48 -0
  20. package/dist-client/pages/master/applied-when-dialog.js +137 -0
  21. package/dist-client/pages/master/applied-when-dialog.js.map +1 -0
  22. package/dist-client/pages/master/assignment-fields.d.ts +27 -0
  23. package/dist-client/pages/master/assignment-fields.js +62 -0
  24. package/dist-client/pages/master/assignment-fields.js.map +1 -0
  25. package/dist-client/pages/master/equipment-class.d.ts +12 -0
  26. package/dist-client/pages/master/equipment-class.js +42 -0
  27. package/dist-client/pages/master/equipment-class.js.map +1 -0
  28. package/dist-client/pages/master/equipment.d.ts +12 -0
  29. package/dist-client/pages/master/equipment.js +58 -0
  30. package/dist-client/pages/master/equipment.js.map +1 -0
  31. package/dist-client/pages/master/grist-iso-duration.d.ts +20 -0
  32. package/dist-client/pages/master/grist-iso-duration.js +70 -0
  33. package/dist-client/pages/master/grist-iso-duration.js.map +1 -0
  34. package/dist-client/pages/master/grist-reference.d.ts +91 -0
  35. package/dist-client/pages/master/grist-reference.js +419 -0
  36. package/dist-client/pages/master/grist-reference.js.map +1 -0
  37. package/dist-client/pages/master/import-rows.d.ts +35 -0
  38. package/dist-client/pages/master/import-rows.js +66 -0
  39. package/dist-client/pages/master/import-rows.js.map +1 -0
  40. package/dist-client/pages/master/iso-duration.d.ts +34 -0
  41. package/dist-client/pages/master/iso-duration.js +76 -0
  42. package/dist-client/pages/master/iso-duration.js.map +1 -0
  43. package/dist-client/pages/master/master-options.d.ts +40 -0
  44. package/dist-client/pages/master/master-options.js +54 -0
  45. package/dist-client/pages/master/master-options.js.map +1 -0
  46. package/dist-client/pages/master/master-page-base.d.ts +369 -0
  47. package/dist-client/pages/master/master-page-base.js +657 -0
  48. package/dist-client/pages/master/master-page-base.js.map +1 -0
  49. package/dist-client/pages/master/material-class.d.ts +12 -0
  50. package/dist-client/pages/master/material-class.js +42 -0
  51. package/dist-client/pages/master/material-class.js.map +1 -0
  52. package/dist-client/pages/master/material-definition.d.ts +5 -0
  53. package/dist-client/pages/master/material-definition.js +14 -0
  54. package/dist-client/pages/master/material-definition.js.map +1 -0
  55. package/dist-client/pages/master/material-revision-fields.d.ts +2 -0
  56. package/dist-client/pages/master/material-revision-fields.js +43 -0
  57. package/dist-client/pages/master/material-revision-fields.js.map +1 -0
  58. package/dist-client/pages/master/operation-definition.d.ts +12 -0
  59. package/dist-client/pages/master/operation-definition.js +49 -0
  60. package/dist-client/pages/master/operation-definition.js.map +1 -0
  61. package/dist-client/pages/master/operational-location.d.ts +84 -0
  62. package/dist-client/pages/master/operational-location.js +432 -0
  63. package/dist-client/pages/master/operational-location.js.map +1 -0
  64. package/dist-client/pages/master/person.d.ts +12 -0
  65. package/dist-client/pages/master/person.js +41 -0
  66. package/dist-client/pages/master/person.js.map +1 -0
  67. package/dist-client/pages/master/personnel-class.d.ts +12 -0
  68. package/dist-client/pages/master/personnel-class.js +43 -0
  69. package/dist-client/pages/master/personnel-class.js.map +1 -0
  70. package/dist-client/pages/master/physical-asset-class.d.ts +12 -0
  71. package/dist-client/pages/master/physical-asset-class.js +40 -0
  72. package/dist-client/pages/master/physical-asset-class.js.map +1 -0
  73. package/dist-client/pages/master/physical-asset.d.ts +12 -0
  74. package/dist-client/pages/master/physical-asset.js +41 -0
  75. package/dist-client/pages/master/physical-asset.js.map +1 -0
  76. package/dist-client/pages/master/recipe-definition.d.ts +5 -0
  77. package/dist-client/pages/master/recipe-definition.js +14 -0
  78. package/dist-client/pages/master/recipe-definition.js.map +1 -0
  79. package/dist-client/pages/master/reference-targets.d.ts +42 -0
  80. package/dist-client/pages/master/reference-targets.js +82 -0
  81. package/dist-client/pages/master/reference-targets.js.map +1 -0
  82. package/dist-client/pages/master/revision-comparison.d.ts +49 -0
  83. package/dist-client/pages/master/revision-comparison.js +560 -0
  84. package/dist-client/pages/master/revision-comparison.js.map +1 -0
  85. package/dist-client/pages/master/revision-view.d.ts +34 -0
  86. package/dist-client/pages/master/revision-view.js +145 -0
  87. package/dist-client/pages/master/revision-view.js.map +1 -0
  88. package/dist-client/pages/master/revision-workspace.d.ts +50 -0
  89. package/dist-client/pages/master/revision-workspace.js +763 -0
  90. package/dist-client/pages/master/revision-workspace.js.map +1 -0
  91. package/dist-client/pages/master/route-definition.d.ts +19 -0
  92. package/dist-client/pages/master/route-definition.js +40 -0
  93. package/dist-client/pages/master/route-definition.js.map +1 -0
  94. package/dist-client/pages/master/stop-reason.d.ts +12 -0
  95. package/dist-client/pages/master/stop-reason.js +48 -0
  96. package/dist-client/pages/master/stop-reason.js.map +1 -0
  97. package/dist-client/pages/master/test-specification.d.ts +5 -0
  98. package/dist-client/pages/master/test-specification.js +14 -0
  99. package/dist-client/pages/master/test-specification.js.map +1 -0
  100. package/dist-client/pages/master-axes.d.ts +24 -0
  101. package/dist-client/pages/master-axes.js +39 -0
  102. package/dist-client/pages/master-axes.js.map +1 -0
  103. package/dist-client/route.d.ts +1 -0
  104. package/dist-client/route.js +81 -0
  105. package/dist-client/route.js.map +1 -0
  106. package/dist-client/tsconfig.tsbuildinfo +1 -0
  107. package/dist-server/index.d.ts +1 -0
  108. package/dist-server/index.js +19 -0
  109. package/dist-server/index.js.map +1 -0
  110. package/dist-server/service/ai-entry/master-entry-rules.d.ts +175 -0
  111. package/dist-server/service/ai-entry/master-entry-rules.js +302 -0
  112. package/dist-server/service/ai-entry/master-entry-rules.js.map +1 -0
  113. package/dist-server/service/ai-entry/master-entry-targets.d.ts +23 -0
  114. package/dist-server/service/ai-entry/master-entry-targets.js +293 -0
  115. package/dist-server/service/ai-entry/master-entry-targets.js.map +1 -0
  116. package/dist-server/service/approval-route.d.ts +37 -0
  117. package/dist-server/service/approval-route.js +34 -0
  118. package/dist-server/service/approval-route.js.map +1 -0
  119. package/dist-server/service/asset/asset-lifecycle.d.ts +106 -0
  120. package/dist-server/service/asset/asset-lifecycle.js +126 -0
  121. package/dist-server/service/asset/asset-lifecycle.js.map +1 -0
  122. package/dist-server/service/asset/asset-master-resolver.d.ts +53 -0
  123. package/dist-server/service/asset/asset-master-resolver.js +185 -0
  124. package/dist-server/service/asset/asset-master-resolver.js.map +1 -0
  125. package/dist-server/service/asset/asset-master.d.ts +21 -0
  126. package/dist-server/service/asset/asset-master.js +25 -0
  127. package/dist-server/service/asset/asset-master.js.map +1 -0
  128. package/dist-server/service/asset/asset-query.d.ts +16 -0
  129. package/dist-server/service/asset/asset-query.js +72 -0
  130. package/dist-server/service/asset/asset-query.js.map +1 -0
  131. package/dist-server/service/asset/index.d.ts +6 -0
  132. package/dist-server/service/asset/index.js +10 -0
  133. package/dist-server/service/asset/index.js.map +1 -0
  134. package/dist-server/service/asset/physical-asset-class.d.ts +34 -0
  135. package/dist-server/service/asset/physical-asset-class.js +104 -0
  136. package/dist-server/service/asset/physical-asset-class.js.map +1 -0
  137. package/dist-server/service/asset/physical-asset.d.ts +66 -0
  138. package/dist-server/service/asset/physical-asset.js +123 -0
  139. package/dist-server/service/asset/physical-asset.js.map +1 -0
  140. package/dist-server/service/assignment/applied-when.d.ts +24 -0
  141. package/dist-server/service/assignment/applied-when.js +16 -0
  142. package/dist-server/service/assignment/applied-when.js.map +1 -0
  143. package/dist-server/service/assignment/assignment-history.d.ts +92 -0
  144. package/dist-server/service/assignment/assignment-history.js +289 -0
  145. package/dist-server/service/assignment/assignment-history.js.map +1 -0
  146. package/dist-server/service/assignment/assignment-write.d.ts +42 -0
  147. package/dist-server/service/assignment/assignment-write.js +101 -0
  148. package/dist-server/service/assignment/assignment-write.js.map +1 -0
  149. package/dist-server/service/assignment/master-value-claim.d.ts +135 -0
  150. package/dist-server/service/assignment/master-value-claim.js +174 -0
  151. package/dist-server/service/assignment/master-value-claim.js.map +1 -0
  152. package/dist-server/service/equipment/equipment-class.d.ts +34 -0
  153. package/dist-server/service/equipment/equipment-class.js +104 -0
  154. package/dist-server/service/equipment/equipment-class.js.map +1 -0
  155. package/dist-server/service/equipment/equipment-master-resolver.d.ts +77 -0
  156. package/dist-server/service/equipment/equipment-master-resolver.js +266 -0
  157. package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -0
  158. package/dist-server/service/equipment/equipment-master.d.ts +30 -0
  159. package/dist-server/service/equipment/equipment-master.js +53 -0
  160. package/dist-server/service/equipment/equipment-master.js.map +1 -0
  161. package/dist-server/service/equipment/equipment-query.d.ts +16 -0
  162. package/dist-server/service/equipment/equipment-query.js +72 -0
  163. package/dist-server/service/equipment/equipment-query.js.map +1 -0
  164. package/dist-server/service/equipment/equipment.d.ts +71 -0
  165. package/dist-server/service/equipment/equipment.js +138 -0
  166. package/dist-server/service/equipment/equipment.js.map +1 -0
  167. package/dist-server/service/equipment/index.d.ts +8 -0
  168. package/dist-server/service/equipment/index.js +12 -0
  169. package/dist-server/service/equipment/index.js.map +1 -0
  170. package/dist-server/service/equipment/state-period-rules.d.ts +95 -0
  171. package/dist-server/service/equipment/state-period-rules.js +122 -0
  172. package/dist-server/service/equipment/state-period-rules.js.map +1 -0
  173. package/dist-server/service/equipment/stop-reason-query.d.ts +11 -0
  174. package/dist-server/service/equipment/stop-reason-query.js +39 -0
  175. package/dist-server/service/equipment/stop-reason-query.js.map +1 -0
  176. package/dist-server/service/equipment/stop-reason.d.ts +58 -0
  177. package/dist-server/service/equipment/stop-reason.js +114 -0
  178. package/dist-server/service/equipment/stop-reason.js.map +1 -0
  179. package/dist-server/service/index.d.ts +82 -0
  180. package/dist-server/service/index.js +145 -0
  181. package/dist-server/service/index.js.map +1 -0
  182. package/dist-server/service/location/index.d.ts +5 -0
  183. package/dist-server/service/location/index.js +9 -0
  184. package/dist-server/service/location/index.js.map +1 -0
  185. package/dist-server/service/location/location-master-resolver.d.ts +60 -0
  186. package/dist-server/service/location/location-master-resolver.js +313 -0
  187. package/dist-server/service/location/location-master-resolver.js.map +1 -0
  188. package/dist-server/service/location/location-master.d.ts +26 -0
  189. package/dist-server/service/location/location-master.js +28 -0
  190. package/dist-server/service/location/location-master.js.map +1 -0
  191. package/dist-server/service/location/location-query.d.ts +15 -0
  192. package/dist-server/service/location/location-query.js +56 -0
  193. package/dist-server/service/location/location-query.js.map +1 -0
  194. package/dist-server/service/location/operational-location.d.ts +116 -0
  195. package/dist-server/service/location/operational-location.js +157 -0
  196. package/dist-server/service/location/operational-location.js.map +1 -0
  197. package/dist-server/service/master-axis.d.ts +40 -0
  198. package/dist-server/service/master-axis.js +57 -0
  199. package/dist-server/service/master-axis.js.map +1 -0
  200. package/dist-server/service/master-change-approval/approval-input.d.ts +17 -0
  201. package/dist-server/service/master-change-approval/approval-input.js +35 -0
  202. package/dist-server/service/master-change-approval/approval-input.js.map +1 -0
  203. package/dist-server/service/master-change-approval/builtin-axes.d.ts +4 -0
  204. package/dist-server/service/master-change-approval/builtin-axes.js +96 -0
  205. package/dist-server/service/master-change-approval/builtin-axes.js.map +1 -0
  206. package/dist-server/service/master-change-approval/index.d.ts +14 -0
  207. package/dist-server/service/master-change-approval/index.js +37 -0
  208. package/dist-server/service/master-change-approval/index.js.map +1 -0
  209. package/dist-server/service/master-change-approval/master-change-axis.d.ts +54 -0
  210. package/dist-server/service/master-change-approval/master-change-axis.js +17 -0
  211. package/dist-server/service/master-change-approval/master-change-axis.js.map +1 -0
  212. package/dist-server/service/master-change-approval/master-change-flow.d.ts +65 -0
  213. package/dist-server/service/master-change-approval/master-change-flow.js +125 -0
  214. package/dist-server/service/master-change-approval/master-change-flow.js.map +1 -0
  215. package/dist-server/service/master-change-approval/master-change-resolver.d.ts +18 -0
  216. package/dist-server/service/master-change-approval/master-change-resolver.js +58 -0
  217. package/dist-server/service/master-change-approval/master-change-resolver.js.map +1 -0
  218. package/dist-server/service/master-change-policy.d.ts +122 -0
  219. package/dist-server/service/master-change-policy.js +304 -0
  220. package/dist-server/service/master-change-policy.js.map +1 -0
  221. package/dist-server/service/master-conformance-resolver.d.ts +34 -0
  222. package/dist-server/service/master-conformance-resolver.js +153 -0
  223. package/dist-server/service/master-conformance-resolver.js.map +1 -0
  224. package/dist-server/service/master-conformance.d.ts +80 -0
  225. package/dist-server/service/master-conformance.js +266 -0
  226. package/dist-server/service/master-conformance.js.map +1 -0
  227. package/dist-server/service/master-crud.d.ts +55 -0
  228. package/dist-server/service/master-crud.js +93 -0
  229. package/dist-server/service/master-crud.js.map +1 -0
  230. package/dist-server/service/master-list.d.ts +12 -0
  231. package/dist-server/service/master-list.js +30 -0
  232. package/dist-server/service/master-list.js.map +1 -0
  233. package/dist-server/service/master-page-query.d.ts +33 -0
  234. package/dist-server/service/master-page-query.js +55 -0
  235. package/dist-server/service/master-page-query.js.map +1 -0
  236. package/dist-server/service/master-page.d.ts +85 -0
  237. package/dist-server/service/master-page.js +104 -0
  238. package/dist-server/service/master-page.js.map +1 -0
  239. package/dist-server/service/material/index.d.ts +7 -0
  240. package/dist-server/service/material/index.js +12 -0
  241. package/dist-server/service/material/index.js.map +1 -0
  242. package/dist-server/service/material/material-axis-status.d.ts +8 -0
  243. package/dist-server/service/material/material-axis-status.js +19 -0
  244. package/dist-server/service/material/material-axis-status.js.map +1 -0
  245. package/dist-server/service/material/material-class.d.ts +34 -0
  246. package/dist-server/service/material/material-class.js +104 -0
  247. package/dist-server/service/material/material-class.js.map +1 -0
  248. package/dist-server/service/material/material-definition.d.ts +45 -0
  249. package/dist-server/service/material/material-definition.js +125 -0
  250. package/dist-server/service/material/material-definition.js.map +1 -0
  251. package/dist-server/service/material/material-effective-list.d.ts +39 -0
  252. package/dist-server/service/material/material-effective-list.js +54 -0
  253. package/dist-server/service/material/material-effective-list.js.map +1 -0
  254. package/dist-server/service/material/material-master-resolver.d.ts +106 -0
  255. package/dist-server/service/material/material-master-resolver.js +351 -0
  256. package/dist-server/service/material/material-master-resolver.js.map +1 -0
  257. package/dist-server/service/material/material-master.d.ts +9 -0
  258. package/dist-server/service/material/material-master.js +24 -0
  259. package/dist-server/service/material/material-master.js.map +1 -0
  260. package/dist-server/service/material/material-query.d.ts +16 -0
  261. package/dist-server/service/material/material-query.js +79 -0
  262. package/dist-server/service/material/material-query.js.map +1 -0
  263. package/dist-server/service/material/material-revision-content.d.ts +10 -0
  264. package/dist-server/service/material/material-revision-content.js +92 -0
  265. package/dist-server/service/material/material-revision-content.js.map +1 -0
  266. package/dist-server/service/material/material-revision-resolver.d.ts +60 -0
  267. package/dist-server/service/material/material-revision-resolver.js +96 -0
  268. package/dist-server/service/material/material-revision-resolver.js.map +1 -0
  269. package/dist-server/service/material/material-revision-service.d.ts +179 -0
  270. package/dist-server/service/material/material-revision-service.js +687 -0
  271. package/dist-server/service/material/material-revision-service.js.map +1 -0
  272. package/dist-server/service/material/material-revision.d.ts +86 -0
  273. package/dist-server/service/material/material-revision.js +339 -0
  274. package/dist-server/service/material/material-revision.js.map +1 -0
  275. package/dist-server/service/material/recipe-index.d.ts +23 -0
  276. package/dist-server/service/material/recipe-index.js +44 -0
  277. package/dist-server/service/material/recipe-index.js.map +1 -0
  278. package/dist-server/service/operation/index.d.ts +6 -0
  279. package/dist-server/service/operation/index.js +10 -0
  280. package/dist-server/service/operation/index.js.map +1 -0
  281. package/dist-server/service/operation/operation-definition.d.ts +52 -0
  282. package/dist-server/service/operation/operation-definition.js +143 -0
  283. package/dist-server/service/operation/operation-definition.js.map +1 -0
  284. package/dist-server/service/operation/operation-master-resolver.d.ts +52 -0
  285. package/dist-server/service/operation/operation-master-resolver.js +187 -0
  286. package/dist-server/service/operation/operation-master-resolver.js.map +1 -0
  287. package/dist-server/service/operation/operation-master.d.ts +21 -0
  288. package/dist-server/service/operation/operation-master.js +28 -0
  289. package/dist-server/service/operation/operation-master.js.map +1 -0
  290. package/dist-server/service/operation/operation-query.d.ts +15 -0
  291. package/dist-server/service/operation/operation-query.js +56 -0
  292. package/dist-server/service/operation/operation-query.js.map +1 -0
  293. package/dist-server/service/operation/operation-readiness-resolver.d.ts +39 -0
  294. package/dist-server/service/operation/operation-readiness-resolver.js +111 -0
  295. package/dist-server/service/operation/operation-readiness-resolver.js.map +1 -0
  296. package/dist-server/service/operation/operation-readiness.d.ts +34 -0
  297. package/dist-server/service/operation/operation-readiness.js +133 -0
  298. package/dist-server/service/operation/operation-readiness.js.map +1 -0
  299. package/dist-server/service/personnel/index.d.ts +6 -0
  300. package/dist-server/service/personnel/index.js +10 -0
  301. package/dist-server/service/personnel/index.js.map +1 -0
  302. package/dist-server/service/personnel/person.d.ts +51 -0
  303. package/dist-server/service/personnel/person.js +119 -0
  304. package/dist-server/service/personnel/person.js.map +1 -0
  305. package/dist-server/service/personnel/personnel-class-readiness.d.ts +22 -0
  306. package/dist-server/service/personnel/personnel-class-readiness.js +98 -0
  307. package/dist-server/service/personnel/personnel-class-readiness.js.map +1 -0
  308. package/dist-server/service/personnel/personnel-class.d.ts +54 -0
  309. package/dist-server/service/personnel/personnel-class.js +114 -0
  310. package/dist-server/service/personnel/personnel-class.js.map +1 -0
  311. package/dist-server/service/personnel/personnel-master-resolver.d.ts +53 -0
  312. package/dist-server/service/personnel/personnel-master-resolver.js +187 -0
  313. package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -0
  314. package/dist-server/service/personnel/personnel-master.d.ts +39 -0
  315. package/dist-server/service/personnel/personnel-master.js +34 -0
  316. package/dist-server/service/personnel/personnel-master.js.map +1 -0
  317. package/dist-server/service/personnel/personnel-query.d.ts +29 -0
  318. package/dist-server/service/personnel/personnel-query.js +79 -0
  319. package/dist-server/service/personnel/personnel-query.js.map +1 -0
  320. package/dist-server/service/personnel/qualification.d.ts +104 -0
  321. package/dist-server/service/personnel/qualification.js +147 -0
  322. package/dist-server/service/personnel/qualification.js.map +1 -0
  323. package/dist-server/service/quality/index.d.ts +4 -0
  324. package/dist-server/service/quality/index.js +8 -0
  325. package/dist-server/service/quality/index.js.map +1 -0
  326. package/dist-server/service/quality/nonconformance-cause-resolver.d.ts +12 -0
  327. package/dist-server/service/quality/nonconformance-cause-resolver.js +60 -0
  328. package/dist-server/service/quality/nonconformance-cause-resolver.js.map +1 -0
  329. package/dist-server/service/quality/nonconformance-cause.d.ts +20 -0
  330. package/dist-server/service/quality/nonconformance-cause.js +90 -0
  331. package/dist-server/service/quality/nonconformance-cause.js.map +1 -0
  332. package/dist-server/service/recipe/index.d.ts +10 -0
  333. package/dist-server/service/recipe/index.js +16 -0
  334. package/dist-server/service/recipe/index.js.map +1 -0
  335. package/dist-server/service/recipe/recipe-definition.d.ts +75 -0
  336. package/dist-server/service/recipe/recipe-definition.js +143 -0
  337. package/dist-server/service/recipe/recipe-definition.js.map +1 -0
  338. package/dist-server/service/recipe/recipe-effective-list.d.ts +49 -0
  339. package/dist-server/service/recipe/recipe-effective-list.js +96 -0
  340. package/dist-server/service/recipe/recipe-effective-list.js.map +1 -0
  341. package/dist-server/service/recipe/recipe-master-resolver.d.ts +28 -0
  342. package/dist-server/service/recipe/recipe-master-resolver.js +128 -0
  343. package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -0
  344. package/dist-server/service/recipe/recipe-master.d.ts +37 -0
  345. package/dist-server/service/recipe/recipe-master.js +47 -0
  346. package/dist-server/service/recipe/recipe-master.js.map +1 -0
  347. package/dist-server/service/recipe/recipe-query.d.ts +21 -0
  348. package/dist-server/service/recipe/recipe-query.js +82 -0
  349. package/dist-server/service/recipe/recipe-query.js.map +1 -0
  350. package/dist-server/service/recipe/recipe-revision-content.d.ts +32 -0
  351. package/dist-server/service/recipe/recipe-revision-content.js +70 -0
  352. package/dist-server/service/recipe/recipe-revision-content.js.map +1 -0
  353. package/dist-server/service/recipe/recipe-revision-line.d.ts +30 -0
  354. package/dist-server/service/recipe/recipe-revision-line.js +95 -0
  355. package/dist-server/service/recipe/recipe-revision-line.js.map +1 -0
  356. package/dist-server/service/recipe/recipe-revision-resolver.d.ts +65 -0
  357. package/dist-server/service/recipe/recipe-revision-resolver.js +96 -0
  358. package/dist-server/service/recipe/recipe-revision-resolver.js.map +1 -0
  359. package/dist-server/service/recipe/recipe-revision-service.d.ts +183 -0
  360. package/dist-server/service/recipe/recipe-revision-service.js +754 -0
  361. package/dist-server/service/recipe/recipe-revision-service.js.map +1 -0
  362. package/dist-server/service/recipe/recipe-revision.d.ts +102 -0
  363. package/dist-server/service/recipe/recipe-revision.js +373 -0
  364. package/dist-server/service/recipe/recipe-revision.js.map +1 -0
  365. package/dist-server/service/recipe/route-definition.d.ts +51 -0
  366. package/dist-server/service/recipe/route-definition.js +114 -0
  367. package/dist-server/service/recipe/route-definition.js.map +1 -0
  368. package/dist-server/service/resource/class-lineage.d.ts +46 -0
  369. package/dist-server/service/resource/class-lineage.js +80 -0
  370. package/dist-server/service/resource/class-lineage.js.map +1 -0
  371. package/dist-server/service/resource/class-members.d.ts +36 -0
  372. package/dist-server/service/resource/class-members.js +59 -0
  373. package/dist-server/service/resource/class-members.js.map +1 -0
  374. package/dist-server/service/resource/referrers.d.ts +54 -0
  375. package/dist-server/service/resource/referrers.js +99 -0
  376. package/dist-server/service/resource/referrers.js.map +1 -0
  377. package/dist-server/service/resource/resource-class.d.ts +25 -0
  378. package/dist-server/service/resource/resource-class.js +29 -0
  379. package/dist-server/service/resource/resource-class.js.map +1 -0
  380. package/dist-server/service/revision-baseline.d.ts +71 -0
  381. package/dist-server/service/revision-baseline.js +87 -0
  382. package/dist-server/service/revision-baseline.js.map +1 -0
  383. package/dist-server/service/row-lock.d.ts +22 -0
  384. package/dist-server/service/row-lock.js +31 -0
  385. package/dist-server/service/row-lock.js.map +1 -0
  386. package/dist-server/service/status/axis-stamp.d.ts +16 -0
  387. package/dist-server/service/status/axis-stamp.js +22 -0
  388. package/dist-server/service/status/axis-stamp.js.map +1 -0
  389. package/dist-server/service/status/index.d.ts +3 -0
  390. package/dist-server/service/status/index.js +7 -0
  391. package/dist-server/service/status/index.js.map +1 -0
  392. package/dist-server/service/status/master-status.d.ts +38 -0
  393. package/dist-server/service/status/master-status.js +129 -0
  394. package/dist-server/service/status/master-status.js.map +1 -0
  395. package/dist-server/service/test-spec/criteria-check.d.ts +53 -0
  396. package/dist-server/service/test-spec/criteria-check.js +142 -0
  397. package/dist-server/service/test-spec/criteria-check.js.map +1 -0
  398. package/dist-server/service/test-spec/criteria-rows.d.ts +89 -0
  399. package/dist-server/service/test-spec/criteria-rows.js +139 -0
  400. package/dist-server/service/test-spec/criteria-rows.js.map +1 -0
  401. package/dist-server/service/test-spec/index.d.ts +6 -0
  402. package/dist-server/service/test-spec/index.js +11 -0
  403. package/dist-server/service/test-spec/index.js.map +1 -0
  404. package/dist-server/service/test-spec/test-spec-effective-list.d.ts +34 -0
  405. package/dist-server/service/test-spec/test-spec-effective-list.js +42 -0
  406. package/dist-server/service/test-spec/test-spec-effective-list.js.map +1 -0
  407. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +44 -0
  408. package/dist-server/service/test-spec/test-spec-master-resolver.js +144 -0
  409. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -0
  410. package/dist-server/service/test-spec/test-spec-master.d.ts +6 -0
  411. package/dist-server/service/test-spec/test-spec-master.js +18 -0
  412. package/dist-server/service/test-spec/test-spec-master.js.map +1 -0
  413. package/dist-server/service/test-spec/test-spec-query.d.ts +15 -0
  414. package/dist-server/service/test-spec/test-spec-query.js +61 -0
  415. package/dist-server/service/test-spec/test-spec-query.js.map +1 -0
  416. package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +59 -0
  417. package/dist-server/service/test-spec/test-spec-revision-resolver.js +96 -0
  418. package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -0
  419. package/dist-server/service/test-spec/test-spec-revision-service.d.ts +178 -0
  420. package/dist-server/service/test-spec/test-spec-revision-service.js +685 -0
  421. package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -0
  422. package/dist-server/service/test-spec/test-spec-revision.d.ts +86 -0
  423. package/dist-server/service/test-spec/test-spec-revision.js +334 -0
  424. package/dist-server/service/test-spec/test-spec-revision.js.map +1 -0
  425. package/dist-server/service/test-spec/test-specification.d.ts +47 -0
  426. package/dist-server/service/test-spec/test-specification.js +119 -0
  427. package/dist-server/service/test-spec/test-specification.js.map +1 -0
  428. package/dist-server/tsconfig.tsbuildinfo +1 -0
  429. package/package.json +3 -3
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MasterChangePolicyResolver = exports.DEFAULT_APPROVAL_REQUIRED = exports.MasterChangePolicy = exports.POLICY_AXES = void 0;
4
+ exports.axisHasRevision = axisHasRevision;
5
+ exports.masterChangePolicy = masterChangePolicy;
6
+ exports.standingPolicy = standingPolicy;
7
+ exports.standingPolicies = standingPolicies;
8
+ exports.declareMasterChangePolicy = declareMasterChangePolicy;
9
+ exports.assertDirectMasterChange = assertDirectMasterChange;
10
+ const tslib_1 = require("tslib");
11
+ const typeorm_1 = require("typeorm");
12
+ const typeorm_2 = require("typeorm");
13
+ const type_graphql_1 = require("type-graphql");
14
+ const shell_1 = require("@things-factory/shell");
15
+ const auth_base_1 = require("@things-factory/auth-base");
16
+ const master_axis_1 = require("./master-axis");
17
+ const approval_route_1 = require("./approval-route");
18
+ // WorkShift owns a domain-wide arrangement, not a row in the generic master CRUD registry.
19
+ function policyAxis(axis) {
20
+ if (axis !== 'workShift')
21
+ (0, master_axis_1.masterAxisOf)(axis);
22
+ }
23
+ /**
24
+ * 정책을 정할 수 있는 축들 — 마스터 축 열다섯에 `workShift` 를 더한다.
25
+ *
26
+ * `workShift` 는 별도 모듈이라 `MASTER_AXES` 에 없는데 정책은 받는다(§`policyAxis`).
27
+ */
28
+ exports.POLICY_AXES = [...master_axis_1.MASTER_AXES.map(one => one.key), 'workShift'];
29
+ /**
30
+ * 이 축의 바뀜을 **개정본으로 결재에 보낼 수 있나** — 승인으로 켤 수 있는 축인가.
31
+ *
32
+ * 마스터 축은 자기 선언(`MasterAxis.revisable`)이 답한다. `workShift` 는 그 표 밖에서 자기 패키지가
33
+ * 개정 체계를 지었으므로 참이다(`work-shift-revision-service`). 앱이 답하지 않는다 — 문이 없으면
34
+ * 어느 앱에서도 보낼 곳이 없다.
35
+ */
36
+ function axisHasRevision(axis) {
37
+ if (axis === 'workShift')
38
+ return true;
39
+ return (0, master_axis_1.masterAxisOf)(axis).revisable;
40
+ }
41
+ /** 도메인 × 축의 기준정보 변경 정책 — 정하는 것도 바꾸는 것도 사업장 소유자의 몫이다. */
42
+ let MasterChangePolicy = class MasterChangePolicy {
43
+ };
44
+ exports.MasterChangePolicy = MasterChangePolicy;
45
+ tslib_1.__decorate([
46
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
47
+ tslib_1.__metadata("design:type", String)
48
+ ], MasterChangePolicy.prototype, "id", void 0);
49
+ tslib_1.__decorate([
50
+ (0, typeorm_1.ManyToOne)(() => shell_1.Domain, { nullable: false }),
51
+ tslib_1.__metadata("design:type", shell_1.Domain)
52
+ ], MasterChangePolicy.prototype, "domain", void 0);
53
+ tslib_1.__decorate([
54
+ (0, typeorm_1.RelationId)((row) => row.domain),
55
+ tslib_1.__metadata("design:type", String)
56
+ ], MasterChangePolicy.prototype, "domainId", void 0);
57
+ tslib_1.__decorate([
58
+ (0, typeorm_1.Column)(),
59
+ tslib_1.__metadata("design:type", String)
60
+ ], MasterChangePolicy.prototype, "axis", void 0);
61
+ tslib_1.__decorate([
62
+ (0, typeorm_1.Column)(),
63
+ tslib_1.__metadata("design:type", Boolean)
64
+ ], MasterChangePolicy.prototype, "approvalRequired", void 0);
65
+ tslib_1.__decorate([
66
+ (0, typeorm_1.Column)('text'),
67
+ tslib_1.__metadata("design:type", String)
68
+ ], MasterChangePolicy.prototype, "reason", void 0);
69
+ tslib_1.__decorate([
70
+ (0, typeorm_1.Column)({ nullable: true }),
71
+ tslib_1.__metadata("design:type", Date
72
+ /**
73
+ * 누가 정했나 — **비어 있으면 아무도 안 정한 것**이고, 그 줄은 기본값으로 선 줄이다.
74
+ *
75
+ * 사람이 안 정한 줄에 사람을 적으면 그 사람이 정한 것이 된다. 사업장을 만든 사람도 이 축을 보고
76
+ * 고른 적이 없다.
77
+ */
78
+ )
79
+ ], MasterChangePolicy.prototype, "supersededAt", void 0);
80
+ tslib_1.__decorate([
81
+ (0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable: true }),
82
+ tslib_1.__metadata("design:type", auth_base_1.User)
83
+ ], MasterChangePolicy.prototype, "creator", void 0);
84
+ tslib_1.__decorate([
85
+ (0, typeorm_1.RelationId)((row) => row.creator),
86
+ tslib_1.__metadata("design:type", String)
87
+ ], MasterChangePolicy.prototype, "creatorId", void 0);
88
+ tslib_1.__decorate([
89
+ (0, typeorm_1.CreateDateColumn)(),
90
+ tslib_1.__metadata("design:type", Date)
91
+ ], MasterChangePolicy.prototype, "createdAt", void 0);
92
+ exports.MasterChangePolicy = MasterChangePolicy = tslib_1.__decorate([
93
+ (0, typeorm_1.Entity)('ops_master_change_policy')
94
+ /*
95
+ * 도메인 × 축에 **줄이 여럿 선다.** 정책은 바뀌고, 바뀌면 새 줄이 서고, 지난 개정본은 자기가 만들어질
96
+ * 때의 줄을 그대로 가리킨다 — 그래야 「그때는 무슨 규칙이었나」가 안 흔들린다.
97
+ *
98
+ * 전에는 유니크였다. 그래서 바꾸려면 그 줄을 덮어야 했고, 덮으면 승인받고 만든 개정본이 소급해서
99
+ * 승인 없이 만든 것이 됐다. 그래서 코드가 바꾸기를 거절했고, **정책을 영영 못 바꿨다.**
100
+ *
101
+ * ⚠ **이 정책을 바꾸는 일 자체는 결재에 안 태운다**(2026-09-22). 사업장 소유자가 정하는 것이라
102
+ * 소유자 확인만 받고 바로 선다. 태울 필요가 생기면 그때 결재 활동을 붙인다 — 줄이 여럿 서는
103
+ * 구조라 붙이는 자리는 이미 있다.
104
+ */
105
+ ,
106
+ (0, typeorm_1.Index)('ix_master_change_policy_axis', ['domain', 'axis']),
107
+ (0, typeorm_1.Index)('ix_master_change_policy_identity', ['domain', 'id'], { unique: true })
108
+ ], MasterChangePolicy);
109
+ /** 아무도 안 정한 축이 도는 방식 — 바꾸려면 여기 하나만 고치면 된다. */
110
+ exports.DEFAULT_APPROVAL_REQUIRED = false;
111
+ /**
112
+ * 이 축이 지금 어떻게 도는가. **아무도 안 정했으면 기본값으로 한 줄을 세우고 그것을 답한다.**
113
+ *
114
+ * 전에는 거절했다(`MASTER_POLICY_REQUIRED`). 그래서 새 사업장은 축 열여섯이 전부 막힌 채로 시작했고,
115
+ * 기준정보를 만들려던 사람이 「정책을 먼저 정하라」는 말만 받았다 — 어디서 정하는지는 안 적혀 있었다.
116
+ *
117
+ * 값을 그때그때 지어내지 않고 **줄을 세우는** 까닭은, 개정본이 자기가 어느 정책 아래 만들어졌는지를
118
+ * 그 줄로 가리키기 때문이다(ADR-0090). 가리킬 줄이 없으면 그 물음에 나중에 답할 수 없다.
119
+ *
120
+ * 그 줄의 `creator` 는 비어 있다. 아무도 고른 적이 없다는 것이 사실이고, 사업장을 만든 사람을 적으면
121
+ * 그 사람이 정한 것이 된다.
122
+ */
123
+ async function masterChangePolicy(manager, domainId, axis) {
124
+ policyAxis(axis);
125
+ const policy = await standingPolicy(manager, domainId, axis);
126
+ if (policy) {
127
+ return policy;
128
+ }
129
+ if (!manager.queryRunner?.isTransactionActive)
130
+ throw new shell_1.Refusal('TRANSACTION_REQUIRED', {}, 'A transaction is required.');
131
+ return manager.save(MasterChangePolicy, manager.create(MasterChangePolicy, {
132
+ domain: { id: domainId },
133
+ axis,
134
+ approvalRequired: exports.DEFAULT_APPROVAL_REQUIRED,
135
+ reason: 'nobody set this axis; it runs on the default'
136
+ }));
137
+ }
138
+ /** 이 축에서 물러나지 않은 줄 전부 — 보통 하나다. */
139
+ function standingRows(manager, domainId, axis) {
140
+ return manager.findBy(MasterChangePolicy, { domain: { id: domainId }, axis, supersededAt: (0, typeorm_2.IsNull)() });
141
+ }
142
+ /**
143
+ * 지금 서 있는 줄.
144
+ *
145
+ * 둘 이상이 서 있으면 **가장 늦게 만들어진 것**을 답한다. 그 상태는 이 코드가 못 만들지만, 물러남
146
+ * 표를 두기 전에 쌓인 줄들이 그렇게 남아 있다. 다음 선언이 전부 물러나게 하고 하나로 정리한다.
147
+ */
148
+ async function standingPolicy(manager, domainId, axis) {
149
+ const rows = await standingRows(manager, domainId, axis);
150
+ return rows.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()).pop() ?? null;
151
+ }
152
+ /** 이 도메인에서 지금 서 있는 줄 전부 — 축을 열쇠로. */
153
+ async function standingPolicies(manager, domainId) {
154
+ const rows = await manager.findBy(MasterChangePolicy, { domain: { id: domainId }, supersededAt: (0, typeorm_2.IsNull)() });
155
+ /* 이른 것부터 담아서 같은 축은 늦은 것이 이긴다 — `standingPolicy` 와 같은 답이 되도록. */
156
+ rows.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
157
+ return new Map(rows.map(one => [one.axis, one]));
158
+ }
159
+ async function declareMasterChangePolicy(manager, domainId, actorId, axis, approvalRequired, reason) {
160
+ if (!manager.queryRunner?.isTransactionActive)
161
+ throw new shell_1.Refusal('TRANSACTION_REQUIRED', {}, 'A transaction is required.');
162
+ policyAxis(axis);
163
+ const domain = await manager.findOneByOrFail(shell_1.Domain, { id: domainId });
164
+ if (domain.owner !== actorId)
165
+ throw new shell_1.Refusal('MASTER_POLICY_OWNER_REQUIRED', {}, 'Only the domain owner may declare or change the master change policy.');
166
+ if (!reason?.trim())
167
+ throw new shell_1.Refusal('MASTER_POLICY_REASON_REQUIRED', {}, 'Explain the policy declaration.');
168
+ /*
169
+ * 규제를 **거는** 쪽만 본다. 푸는 쪽은 결재선이 비어 있어도 되고, 오히려 비어서 멈춘 축을 푸는 것이
170
+ * 이 화면으로 할 수 있는 일이어야 한다.
171
+ */
172
+ if (approvalRequired) {
173
+ /*
174
+ * 개정본 문이 없는 축은 **켜는 것부터 막는다**(2026-09-24). 켜면 직접 쓰기가 전부 거절되는데 결재로
175
+ * 보낼 곳이 없어서 그 축이 통째로 잠긴다. 결재선을 묻기 전에 본다 — 결재선이 있어도 보낼 문이 없다.
176
+ */
177
+ if (!axisHasRevision(axis))
178
+ throw new shell_1.Refusal('MASTER_AXIS_HAS_NO_REVISION', { axis }, 'This master cannot be sent for approval yet, so it cannot be set to change only after approval.');
179
+ await (0, approval_route_1.assertApprovalRouteReady)(manager, domainId, axis);
180
+ }
181
+ const standing = await standingRows(manager, domainId, axis);
182
+ /*
183
+ * 같은 값을 다시 정하는 것은 아무 일도 아니다 — **하나만 서 있을 때** 그렇다. 여럿이 서 있으면
184
+ * 어느 것이 지금 것인지가 안 정해진 상태이므로, 값이 같아 보여도 전부 물리고 하나로 다시 세운다.
185
+ */
186
+ if (standing.length === 1 && standing[0].approvalRequired === approvalRequired) {
187
+ return standing[0];
188
+ }
189
+ const supersededAt = new Date();
190
+ for (const row of standing) {
191
+ row.supersededAt = supersededAt;
192
+ await manager.save(MasterChangePolicy, row);
193
+ }
194
+ /*
195
+ * 바뀌면 **새 줄을 세운다. 있던 줄은 그대로 둔다.**
196
+ *
197
+ * 지난 개정본들이 그 줄을 가리키고 있다(`RecipeRevision.policy`, RESTRICT). 덮으면 그것들이
198
+ * 소급해서 다른 규칙 아래 만들어진 것이 된다 — 그래서 덮지 않고 새로 세운다. 오늘부터는 새 줄이
199
+ * 현재 정책이고, 지난 것은 자기 때의 줄을 계속 가리킨다.
200
+ */
201
+ return manager.save(MasterChangePolicy, manager.create(MasterChangePolicy, {
202
+ domain: { id: domainId },
203
+ axis,
204
+ approvalRequired,
205
+ reason,
206
+ creator: { id: actorId }
207
+ }));
208
+ }
209
+ async function assertDirectMasterChange(manager, domainId, axis) {
210
+ const policy = await standingPolicy(manager, domainId, axis);
211
+ if (policy?.approvalRequired)
212
+ throw new shell_1.Refusal('MASTER_APPROVAL_REQUIRED', { axis }, 'This master axis requires approval in this domain.');
213
+ }
214
+ let MasterChangePolicyResolver = class MasterChangePolicyResolver {
215
+ async masterChangePolicy(axis, context) {
216
+ /* 읽기만 하는 자리다. 안 정한 축에 줄을 세우지 않는다 — 그것은 고치러 들어간 쪽이 할 일이다. */
217
+ policyAxis(axis);
218
+ const policy = await standingPolicy((0, shell_1.getRepository)(MasterChangePolicy).manager, context.state.domain.id, axis);
219
+ // A fresh site's editor must see the same default the first write will use, without inventing a policy id.
220
+ return policy
221
+ ? { ...policy, declared: true }
222
+ : { axis, declared: false, approvalRequired: exports.DEFAULT_APPROVAL_REQUIRED };
223
+ }
224
+ /**
225
+ * 축 전부의 정책 상태 — **안 정한 것도 답한다.**
226
+ *
227
+ * 단일 조회처럼 안 정한 축은 기본값과 미선언 상태를 답한다. 목록에는 관리 권한과 결재 경로 상태도 담는다.
228
+ *
229
+ * `canDeclare` 는 **이 사람이 소유자인가**다. 화면이 스스로 판단하지 않게 서버가 말한다 —
230
+ * 눌러 보고 거절당하는 화면이 되지 않도록.
231
+ */
232
+ async masterChangePolicies(context) {
233
+ const { domain, user } = context.state;
234
+ const manager = (0, shell_1.getRepository)(MasterChangePolicy).manager;
235
+ /*
236
+ * **물러나지 않은 줄만** 읽는다. 축마다 줄이 여럿이라, 전부 담으면 저장소가 주는 차례대로 덮여서
237
+ * 바꾼 뒤에도 화면에 옛 값이 떴다(2026-09-22 화면에서 확인).
238
+ */
239
+ const byAxis = await standingPolicies(manager, domain.id);
240
+ return {
241
+ canDeclare: domain.owner === user?.id,
242
+ axes: await Promise.all(exports.POLICY_AXES.map(async (axis) => {
243
+ const policy = byAxis.get(axis);
244
+ /*
245
+ * 결재 길이 준비됐나 — **화면이 누르기 전에 알아야 한다.** 답이 없는 축은 이 앱이 아직 이
246
+ * 물음에 답할 길이 없다는 뜻이라 막지 않는다(`inspectApprovalRoute`).
247
+ */
248
+ const route = await (0, approval_route_1.inspectApprovalRoute)(manager, domain.id, axis);
249
+ return {
250
+ axis,
251
+ declared: !!policy,
252
+ /* 줄은 섰지만 사람이 고른 적은 없다 — 화면이 그것을 다르게 보인다. */
253
+ byDefault: !!policy && !policy.creatorId,
254
+ approvalRequired: policy?.approvalRequired ?? null,
255
+ reason: policy?.reason ?? null,
256
+ declaredAt: policy?.createdAt ?? null,
257
+ /* 승인으로 켤 수 있는 축인가 — 아니면 화면은 누르기 전에 그 까닭을 말한다. */
258
+ revisable: axisHasRevision(axis),
259
+ approvalReady: route ? route.ready : true,
260
+ approvalActivity: route?.activity ?? null
261
+ };
262
+ }))
263
+ };
264
+ }
265
+ async declareMasterChangePolicy(axis, approvalRequired, reason, context) {
266
+ const { tx, domain, user } = context.state;
267
+ return declareMasterChangePolicy(tx, domain.id, user.id, axis, approvalRequired, reason);
268
+ }
269
+ };
270
+ exports.MasterChangePolicyResolver = MasterChangePolicyResolver;
271
+ tslib_1.__decorate([
272
+ (0, type_graphql_1.Directive)('@privilege(category: "ops-master", privilege: "query", domainOwnerGranted: true)'),
273
+ (0, type_graphql_1.Query)(() => shell_1.ScalarObject),
274
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('axis')),
275
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
276
+ tslib_1.__metadata("design:type", Function),
277
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
278
+ tslib_1.__metadata("design:returntype", Promise)
279
+ ], MasterChangePolicyResolver.prototype, "masterChangePolicy", null);
280
+ tslib_1.__decorate([
281
+ (0, type_graphql_1.Directive)('@privilege(category: "ops-master", privilege: "query", domainOwnerGranted: true)'),
282
+ (0, type_graphql_1.Query)(() => shell_1.ScalarObject),
283
+ tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
284
+ tslib_1.__metadata("design:type", Function),
285
+ tslib_1.__metadata("design:paramtypes", [Object]),
286
+ tslib_1.__metadata("design:returntype", Promise)
287
+ ], MasterChangePolicyResolver.prototype, "masterChangePolicies", null);
288
+ tslib_1.__decorate([
289
+ (0, type_graphql_1.Directive)('@privilege(category: "ops-master", privilege: "mutation", domainOwnerGranted: true)'),
290
+ (0, type_graphql_1.Directive)('@transaction'),
291
+ (0, type_graphql_1.Mutation)(() => shell_1.ScalarObject),
292
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('axis')),
293
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('approvalRequired')),
294
+ tslib_1.__param(2, (0, type_graphql_1.Arg)('reason')),
295
+ tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
296
+ tslib_1.__metadata("design:type", Function),
297
+ tslib_1.__metadata("design:paramtypes", [String, Boolean, String, Object]),
298
+ tslib_1.__metadata("design:returntype", Promise)
299
+ ], MasterChangePolicyResolver.prototype, "declareMasterChangePolicy", null);
300
+ exports.MasterChangePolicyResolver = MasterChangePolicyResolver = tslib_1.__decorate([
301
+ (0, type_graphql_1.Resolver)(),
302
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
303
+ ], MasterChangePolicyResolver);
304
+ //# sourceMappingURL=master-change-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-change-policy.js","sourceRoot":"","sources":["../../server/service/master-change-policy.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n CreateDateColumn,\n Entity,\n EntityManager,\n Index,\n ManyToOne,\n PrimaryGeneratedColumn,\n RelationId\n} from 'typeorm'\nimport { IsNull } from 'typeorm'\nimport { Arg, Ctx, Directive, Mutation, Query, Resolver, UseMiddleware } from 'type-graphql'\nimport { Domain, getRepository, Refusal, ScalarObject, SpeakRefusals } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { MASTER_AXES, masterAxisOf } from './master-axis'\nimport { assertApprovalRouteReady, inspectApprovalRoute } from './approval-route'\n\n// WorkShift owns a domain-wide arrangement, not a row in the generic master CRUD registry.\nfunction policyAxis(axis: string) {\n if (axis !== 'workShift') masterAxisOf(axis)\n}\n\n/**\n * 정책을 정할 수 있는 축들 — 마스터 축 열다섯에 `workShift` 를 더한다.\n *\n * `workShift` 는 별도 모듈이라 `MASTER_AXES` 에 없는데 정책은 받는다(§`policyAxis`).\n */\nexport const POLICY_AXES = [...MASTER_AXES.map(one => one.key), 'workShift']\n\n/**\n * 이 축의 바뀜을 **개정본으로 결재에 보낼 수 있나** — 승인으로 켤 수 있는 축인가.\n *\n * 마스터 축은 자기 선언(`MasterAxis.revisable`)이 답한다. `workShift` 는 그 표 밖에서 자기 패키지가\n * 개정 체계를 지었으므로 참이다(`work-shift-revision-service`). 앱이 답하지 않는다 — 문이 없으면\n * 어느 앱에서도 보낼 곳이 없다.\n */\nexport function axisHasRevision(axis: string): boolean {\n if (axis === 'workShift') return true\n return masterAxisOf(axis).revisable\n}\n\n/** 도메인 × 축의 기준정보 변경 정책 — 정하는 것도 바꾸는 것도 사업장 소유자의 몫이다. */\n@Entity('ops_master_change_policy')\n/*\n * 도메인 × 축에 **줄이 여럿 선다.** 정책은 바뀌고, 바뀌면 새 줄이 서고, 지난 개정본은 자기가 만들어질\n * 때의 줄을 그대로 가리킨다 — 그래야 「그때는 무슨 규칙이었나」가 안 흔들린다.\n *\n * 전에는 유니크였다. 그래서 바꾸려면 그 줄을 덮어야 했고, 덮으면 승인받고 만든 개정본이 소급해서\n * 승인 없이 만든 것이 됐다. 그래서 코드가 바꾸기를 거절했고, **정책을 영영 못 바꿨다.**\n *\n * ⚠ **이 정책을 바꾸는 일 자체는 결재에 안 태운다**(2026-09-22). 사업장 소유자가 정하는 것이라\n * 소유자 확인만 받고 바로 선다. 태울 필요가 생기면 그때 결재 활동을 붙인다 — 줄이 여럿 서는\n * 구조라 붙이는 자리는 이미 있다.\n */\n@Index('ix_master_change_policy_axis', ['domain', 'axis'])\n@Index('ix_master_change_policy_identity', ['domain', 'id'], { unique: true })\nexport class MasterChangePolicy {\n @PrimaryGeneratedColumn('uuid') id: string\n @ManyToOne(() => Domain, { nullable: false }) domain: Domain\n @RelationId((row: MasterChangePolicy) => row.domain) domainId: string\n @Column() axis: string\n @Column() approvalRequired: boolean\n @Column('text') reason: string\n /**\n * 이 줄이 물러난 시각 — 비어 있는 줄이 **지금 정책**이다.\n *\n * 차례를 `createdAt` 으로 세우지 않는다. sqlite 의 `datetime('now')` 는 초까지라, 한 사람이 같은\n * 초에 두 번 바꾸면 어느 줄이 나중인지 저장소가 못 가린다. 물러난 줄에 표를 하면 그 물음이 사라진다.\n */\n @Column({ nullable: true }) supersededAt: Date\n /**\n * 누가 정했나 — **비어 있으면 아무도 안 정한 것**이고, 그 줄은 기본값으로 선 줄이다.\n *\n * 사람이 안 정한 줄에 사람을 적으면 그 사람이 정한 것이 된다. 사업장을 만든 사람도 이 축을 보고\n * 고른 적이 없다.\n */\n @ManyToOne(() => User, { nullable: true }) creator: User\n @RelationId((row: MasterChangePolicy) => row.creator) creatorId: string\n @CreateDateColumn() createdAt: Date\n}\n\n/** 아무도 안 정한 축이 도는 방식 — 바꾸려면 여기 하나만 고치면 된다. */\nexport const DEFAULT_APPROVAL_REQUIRED = false\n\n/**\n * 이 축이 지금 어떻게 도는가. **아무도 안 정했으면 기본값으로 한 줄을 세우고 그것을 답한다.**\n *\n * 전에는 거절했다(`MASTER_POLICY_REQUIRED`). 그래서 새 사업장은 축 열여섯이 전부 막힌 채로 시작했고,\n * 기준정보를 만들려던 사람이 「정책을 먼저 정하라」는 말만 받았다 — 어디서 정하는지는 안 적혀 있었다.\n *\n * 값을 그때그때 지어내지 않고 **줄을 세우는** 까닭은, 개정본이 자기가 어느 정책 아래 만들어졌는지를\n * 그 줄로 가리키기 때문이다(ADR-0090). 가리킬 줄이 없으면 그 물음에 나중에 답할 수 없다.\n *\n * 그 줄의 `creator` 는 비어 있다. 아무도 고른 적이 없다는 것이 사실이고, 사업장을 만든 사람을 적으면\n * 그 사람이 정한 것이 된다.\n */\nexport async function masterChangePolicy(manager: EntityManager, domainId: string, axis: string) {\n policyAxis(axis)\n const policy = await standingPolicy(manager, domainId, axis)\n if (policy) {\n return policy\n }\n\n if (!manager.queryRunner?.isTransactionActive)\n throw new Refusal('TRANSACTION_REQUIRED', {}, 'A transaction is required.')\n\n return manager.save(\n MasterChangePolicy,\n manager.create(MasterChangePolicy, {\n domain: { id: domainId },\n axis,\n approvalRequired: DEFAULT_APPROVAL_REQUIRED,\n reason: 'nobody set this axis; it runs on the default'\n })\n )\n}\n\n/** 이 축에서 물러나지 않은 줄 전부 — 보통 하나다. */\nfunction standingRows(manager: EntityManager, domainId: string, axis: string) {\n return manager.findBy(MasterChangePolicy, { domain: { id: domainId }, axis, supersededAt: IsNull() })\n}\n\n/**\n * 지금 서 있는 줄.\n *\n * 둘 이상이 서 있으면 **가장 늦게 만들어진 것**을 답한다. 그 상태는 이 코드가 못 만들지만, 물러남\n * 표를 두기 전에 쌓인 줄들이 그렇게 남아 있다. 다음 선언이 전부 물러나게 하고 하나로 정리한다.\n */\nexport async function standingPolicy(manager: EntityManager, domainId: string, axis: string) {\n const rows = await standingRows(manager, domainId, axis)\n\n return rows.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()).pop() ?? null\n}\n\n/** 이 도메인에서 지금 서 있는 줄 전부 — 축을 열쇠로. */\nexport async function standingPolicies(manager: EntityManager, domainId: string) {\n const rows = await manager.findBy(MasterChangePolicy, { domain: { id: domainId }, supersededAt: IsNull() })\n\n /* 이른 것부터 담아서 같은 축은 늦은 것이 이긴다 — `standingPolicy` 와 같은 답이 되도록. */\n rows.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())\n\n return new Map(rows.map(one => [one.axis, one]))\n}\n\nexport async function declareMasterChangePolicy(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n axis: string,\n approvalRequired: boolean,\n reason: string\n) {\n if (!manager.queryRunner?.isTransactionActive)\n throw new Refusal('TRANSACTION_REQUIRED', {}, 'A transaction is required.')\n policyAxis(axis)\n const domain = await manager.findOneByOrFail(Domain, { id: domainId })\n if (domain.owner !== actorId)\n throw new Refusal(\n 'MASTER_POLICY_OWNER_REQUIRED',\n {},\n 'Only the domain owner may declare or change the master change policy.'\n )\n if (!reason?.trim()) throw new Refusal('MASTER_POLICY_REASON_REQUIRED', {}, 'Explain the policy declaration.')\n\n /*\n * 규제를 **거는** 쪽만 본다. 푸는 쪽은 결재선이 비어 있어도 되고, 오히려 비어서 멈춘 축을 푸는 것이\n * 이 화면으로 할 수 있는 일이어야 한다.\n */\n if (approvalRequired) {\n /*\n * 개정본 문이 없는 축은 **켜는 것부터 막는다**(2026-09-24). 켜면 직접 쓰기가 전부 거절되는데 결재로\n * 보낼 곳이 없어서 그 축이 통째로 잠긴다. 결재선을 묻기 전에 본다 — 결재선이 있어도 보낼 문이 없다.\n */\n if (!axisHasRevision(axis))\n throw new Refusal(\n 'MASTER_AXIS_HAS_NO_REVISION',\n { axis },\n 'This master cannot be sent for approval yet, so it cannot be set to change only after approval.'\n )\n await assertApprovalRouteReady(manager, domainId, axis)\n }\n\n const standing = await standingRows(manager, domainId, axis)\n\n /*\n * 같은 값을 다시 정하는 것은 아무 일도 아니다 — **하나만 서 있을 때** 그렇다. 여럿이 서 있으면\n * 어느 것이 지금 것인지가 안 정해진 상태이므로, 값이 같아 보여도 전부 물리고 하나로 다시 세운다.\n */\n if (standing.length === 1 && standing[0].approvalRequired === approvalRequired) {\n return standing[0]\n }\n\n const supersededAt = new Date()\n for (const row of standing) {\n row.supersededAt = supersededAt\n await manager.save(MasterChangePolicy, row)\n }\n\n /*\n * 바뀌면 **새 줄을 세운다. 있던 줄은 그대로 둔다.**\n *\n * 지난 개정본들이 그 줄을 가리키고 있다(`RecipeRevision.policy`, RESTRICT). 덮으면 그것들이\n * 소급해서 다른 규칙 아래 만들어진 것이 된다 — 그래서 덮지 않고 새로 세운다. 오늘부터는 새 줄이\n * 현재 정책이고, 지난 것은 자기 때의 줄을 계속 가리킨다.\n */\n return manager.save(\n MasterChangePolicy,\n manager.create(MasterChangePolicy, {\n domain: { id: domainId },\n axis,\n approvalRequired,\n reason,\n creator: { id: actorId }\n })\n )\n}\n\nexport async function assertDirectMasterChange(manager: EntityManager, domainId: string, axis: string) {\n const policy = await standingPolicy(manager, domainId, axis)\n if (policy?.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', { axis }, 'This master axis requires approval in this domain.')\n}\n\n@Resolver()\n@UseMiddleware(SpeakRefusals)\nexport class MasterChangePolicyResolver {\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(() => ScalarObject)\n async masterChangePolicy(@Arg('axis') axis: string, @Ctx() context: ResolverContext) {\n /* 읽기만 하는 자리다. 안 정한 축에 줄을 세우지 않는다 — 그것은 고치러 들어간 쪽이 할 일이다. */\n policyAxis(axis)\n const policy = await standingPolicy(getRepository(MasterChangePolicy).manager, context.state.domain.id, axis)\n // A fresh site's editor must see the same default the first write will use, without inventing a policy id.\n return policy\n ? { ...policy, declared: true }\n : { axis, declared: false, approvalRequired: DEFAULT_APPROVAL_REQUIRED }\n }\n\n /**\n * 축 전부의 정책 상태 — **안 정한 것도 답한다.**\n *\n * 단일 조회처럼 안 정한 축은 기본값과 미선언 상태를 답한다. 목록에는 관리 권한과 결재 경로 상태도 담는다.\n *\n * `canDeclare` 는 **이 사람이 소유자인가**다. 화면이 스스로 판단하지 않게 서버가 말한다 —\n * 눌러 보고 거절당하는 화면이 되지 않도록.\n */\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(() => ScalarObject)\n async masterChangePolicies(@Ctx() context: ResolverContext) {\n const { domain, user } = context.state\n const manager = getRepository(MasterChangePolicy).manager\n /*\n * **물러나지 않은 줄만** 읽는다. 축마다 줄이 여럿이라, 전부 담으면 저장소가 주는 차례대로 덮여서\n * 바꾼 뒤에도 화면에 옛 값이 떴다(2026-09-22 화면에서 확인).\n */\n const byAxis = await standingPolicies(manager, domain.id)\n\n return {\n canDeclare: domain.owner === user?.id,\n axes: await Promise.all(\n POLICY_AXES.map(async axis => {\n const policy = byAxis.get(axis)\n /*\n * 결재 길이 준비됐나 — **화면이 누르기 전에 알아야 한다.** 답이 없는 축은 이 앱이 아직 이\n * 물음에 답할 길이 없다는 뜻이라 막지 않는다(`inspectApprovalRoute`).\n */\n const route = await inspectApprovalRoute(manager, domain.id, axis)\n\n return {\n axis,\n declared: !!policy,\n /* 줄은 섰지만 사람이 고른 적은 없다 — 화면이 그것을 다르게 보인다. */\n byDefault: !!policy && !policy.creatorId,\n approvalRequired: policy?.approvalRequired ?? null,\n reason: policy?.reason ?? null,\n declaredAt: policy?.createdAt ?? null,\n /* 승인으로 켤 수 있는 축인가 — 아니면 화면은 누르기 전에 그 까닭을 말한다. */\n revisable: axisHasRevision(axis),\n approvalReady: route ? route.ready : true,\n approvalActivity: route?.activity ?? null\n }\n })\n )\n }\n }\n\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(() => ScalarObject)\n async declareMasterChangePolicy(\n @Arg('axis') axis: string,\n @Arg('approvalRequired') approvalRequired: boolean,\n @Arg('reason') reason: string,\n @Ctx() context: ResolverContext\n ) {\n const { tx, domain, user } = context.state\n return declareMasterChangePolicy(tx, domain.id, user.id, axis, approvalRequired, reason)\n }\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 마스터 정합성 — **사람이 눌러서 도는 검사.**
3
+ *
4
+ * 목록 화면이 매번 부르는 것이 아니다. 표를 통째로 읽어야 답이 나오고, 상한을 두면 「어긋남 0건」이
5
+ * 거짓이 되기 때문이다. 정합성은 「전부 봤나」가 곧 답이다.
6
+ */
7
+ export declare class MasterFinding {
8
+ axis: string;
9
+ subject?: string;
10
+ kind: string;
11
+ field: string;
12
+ value?: string;
13
+ }
14
+ export declare class MasterFindingCount {
15
+ axis: string;
16
+ kind: string;
17
+ count: number;
18
+ }
19
+ export declare class MasterScanned {
20
+ axis: string;
21
+ rows: number;
22
+ }
23
+ export declare class MasterConformance {
24
+ /**
25
+ * 무엇을 몇 개 봤나. **어긋남 0건이 「멀쩡하다」인지 「안 돌았다」인지는 이것으로만 갈린다.**
26
+ */
27
+ scanned: MasterScanned[];
28
+ total: number;
29
+ counts: MasterFindingCount[];
30
+ findings: MasterFinding[];
31
+ }
32
+ export declare class MasterConformanceResolver {
33
+ masterConformance(context: ResolverContext): Promise<MasterConformance>;
34
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MasterConformanceResolver = exports.MasterConformance = exports.MasterScanned = exports.MasterFindingCount = exports.MasterFinding = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const physical_asset_1 = require("./asset/physical-asset");
8
+ const physical_asset_class_1 = require("./asset/physical-asset-class");
9
+ const equipment_1 = require("./equipment/equipment");
10
+ const equipment_class_1 = require("./equipment/equipment-class");
11
+ const stop_reason_1 = require("./equipment/stop-reason");
12
+ const operational_location_1 = require("./location/operational-location");
13
+ const material_class_1 = require("./material/material-class");
14
+ const material_definition_1 = require("./material/material-definition");
15
+ const operation_definition_1 = require("./operation/operation-definition");
16
+ const person_1 = require("./personnel/person");
17
+ const personnel_class_1 = require("./personnel/personnel-class");
18
+ const recipe_definition_1 = require("./recipe/recipe-definition");
19
+ const route_definition_1 = require("./recipe/route-definition");
20
+ const test_specification_1 = require("./test-spec/test-specification");
21
+ const master_conformance_1 = require("./master-conformance");
22
+ const recipe_effective_list_1 = require("./recipe/recipe-effective-list");
23
+ const material_effective_list_1 = require("./material/material-effective-list");
24
+ /**
25
+ * 마스터 정합성 — **사람이 눌러서 도는 검사.**
26
+ *
27
+ * 목록 화면이 매번 부르는 것이 아니다. 표를 통째로 읽어야 답이 나오고, 상한을 두면 「어긋남 0건」이
28
+ * 거짓이 되기 때문이다. 정합성은 「전부 봤나」가 곧 답이다.
29
+ */
30
+ let MasterFinding = class MasterFinding {
31
+ };
32
+ exports.MasterFinding = MasterFinding;
33
+ tslib_1.__decorate([
34
+ (0, type_graphql_1.Field)(),
35
+ tslib_1.__metadata("design:type", String)
36
+ ], MasterFinding.prototype, "axis", void 0);
37
+ tslib_1.__decorate([
38
+ (0, type_graphql_1.Field)({ nullable: true }),
39
+ tslib_1.__metadata("design:type", String)
40
+ ], MasterFinding.prototype, "subject", void 0);
41
+ tslib_1.__decorate([
42
+ (0, type_graphql_1.Field)(),
43
+ tslib_1.__metadata("design:type", String)
44
+ ], MasterFinding.prototype, "kind", void 0);
45
+ tslib_1.__decorate([
46
+ (0, type_graphql_1.Field)(),
47
+ tslib_1.__metadata("design:type", String)
48
+ ], MasterFinding.prototype, "field", void 0);
49
+ tslib_1.__decorate([
50
+ (0, type_graphql_1.Field)({ nullable: true }),
51
+ tslib_1.__metadata("design:type", String)
52
+ ], MasterFinding.prototype, "value", void 0);
53
+ exports.MasterFinding = MasterFinding = tslib_1.__decorate([
54
+ (0, type_graphql_1.ObjectType)({ description: 'One master data conformance finding' })
55
+ ], MasterFinding);
56
+ let MasterFindingCount = class MasterFindingCount {
57
+ };
58
+ exports.MasterFindingCount = MasterFindingCount;
59
+ tslib_1.__decorate([
60
+ (0, type_graphql_1.Field)(),
61
+ tslib_1.__metadata("design:type", String)
62
+ ], MasterFindingCount.prototype, "axis", void 0);
63
+ tslib_1.__decorate([
64
+ (0, type_graphql_1.Field)(),
65
+ tslib_1.__metadata("design:type", String)
66
+ ], MasterFindingCount.prototype, "kind", void 0);
67
+ tslib_1.__decorate([
68
+ (0, type_graphql_1.Field)(type => type_graphql_1.Int),
69
+ tslib_1.__metadata("design:type", Number)
70
+ ], MasterFindingCount.prototype, "count", void 0);
71
+ exports.MasterFindingCount = MasterFindingCount = tslib_1.__decorate([
72
+ (0, type_graphql_1.ObjectType)({ description: 'How many findings per axis and kind' })
73
+ ], MasterFindingCount);
74
+ let MasterScanned = class MasterScanned {
75
+ };
76
+ exports.MasterScanned = MasterScanned;
77
+ tslib_1.__decorate([
78
+ (0, type_graphql_1.Field)(),
79
+ tslib_1.__metadata("design:type", String)
80
+ ], MasterScanned.prototype, "axis", void 0);
81
+ tslib_1.__decorate([
82
+ (0, type_graphql_1.Field)(type => type_graphql_1.Int),
83
+ tslib_1.__metadata("design:type", Number)
84
+ ], MasterScanned.prototype, "rows", void 0);
85
+ exports.MasterScanned = MasterScanned = tslib_1.__decorate([
86
+ (0, type_graphql_1.ObjectType)({ description: 'How many rows were scanned per axis' })
87
+ ], MasterScanned);
88
+ let MasterConformance = class MasterConformance {
89
+ };
90
+ exports.MasterConformance = MasterConformance;
91
+ tslib_1.__decorate([
92
+ (0, type_graphql_1.Field)(type => [MasterScanned]),
93
+ tslib_1.__metadata("design:type", Array)
94
+ ], MasterConformance.prototype, "scanned", void 0);
95
+ tslib_1.__decorate([
96
+ (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many findings in total' }),
97
+ tslib_1.__metadata("design:type", Number)
98
+ ], MasterConformance.prototype, "total", void 0);
99
+ tslib_1.__decorate([
100
+ (0, type_graphql_1.Field)(type => [MasterFindingCount]),
101
+ tslib_1.__metadata("design:type", Array)
102
+ ], MasterConformance.prototype, "counts", void 0);
103
+ tslib_1.__decorate([
104
+ (0, type_graphql_1.Field)(type => [MasterFinding]),
105
+ tslib_1.__metadata("design:type", Array)
106
+ ], MasterConformance.prototype, "findings", void 0);
107
+ exports.MasterConformance = MasterConformance = tslib_1.__decorate([
108
+ (0, type_graphql_1.ObjectType)({ description: 'Master data conformance report' })
109
+ ], MasterConformance);
110
+ let MasterConformanceResolver = class MasterConformanceResolver {
111
+ async masterConformance(context) {
112
+ const { domain } = context.state;
113
+ const snapshot = await (0, master_conformance_1.readMasterSnapshot)(domain, (entity) => entity === recipe_definition_1.RecipeDefinition
114
+ ? { find: async () => (await (0, recipe_effective_list_1.listEffectiveRecipes)((0, shell_1.getRepository)(recipe_definition_1.RecipeDefinition).manager, domain, {
115
+ filters: [{ name: 'materialDefinitionName', operator: 'is_not_null', value: true }]
116
+ })).items }
117
+ : entity === material_definition_1.MaterialDefinition
118
+ ? { find: async () => (await (0, material_effective_list_1.listEffectiveMaterialDefinitions)((0, shell_1.getRepository)(material_definition_1.MaterialDefinition).manager, domain, {
119
+ filters: [{ name: 'revisionNumber', operator: 'is_not_null', value: true }]
120
+ })).items }
121
+ : (0, shell_1.getRepository)(entity), {
122
+ Person: person_1.Person,
123
+ PersonnelClass: personnel_class_1.PersonnelClass,
124
+ Equipment: equipment_1.Equipment,
125
+ EquipmentClass: equipment_class_1.EquipmentClass,
126
+ PhysicalAsset: physical_asset_1.PhysicalAsset,
127
+ PhysicalAssetClass: physical_asset_class_1.PhysicalAssetClass,
128
+ MaterialDefinition: material_definition_1.MaterialDefinition,
129
+ MaterialClass: material_class_1.MaterialClass,
130
+ OperationDefinition: operation_definition_1.OperationDefinition,
131
+ RouteDefinition: route_definition_1.RouteDefinition,
132
+ RecipeDefinition: recipe_definition_1.RecipeDefinition,
133
+ OperationalLocation: operational_location_1.OperationalLocation,
134
+ StopReason: stop_reason_1.StopReason,
135
+ TestSpecification: test_specification_1.TestSpecification
136
+ });
137
+ const findings = (0, master_conformance_1.checkMaster)(snapshot);
138
+ return { scanned: (0, master_conformance_1.scannedCounts)(snapshot), total: findings.length, counts: (0, master_conformance_1.summarize)(findings), findings };
139
+ }
140
+ };
141
+ exports.MasterConformanceResolver = MasterConformanceResolver;
142
+ tslib_1.__decorate([
143
+ (0, type_graphql_1.Directive)('@privilege(category: "ops-master", privilege: "query", domainOwnerGranted: true)'),
144
+ (0, type_graphql_1.Query)(returns => MasterConformance, { description: 'Check master data for missing fields and dangling references' }),
145
+ tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
146
+ tslib_1.__metadata("design:type", Function),
147
+ tslib_1.__metadata("design:paramtypes", [Object]),
148
+ tslib_1.__metadata("design:returntype", Promise)
149
+ ], MasterConformanceResolver.prototype, "masterConformance", null);
150
+ exports.MasterConformanceResolver = MasterConformanceResolver = tslib_1.__decorate([
151
+ (0, type_graphql_1.Resolver)()
152
+ ], MasterConformanceResolver);
153
+ //# sourceMappingURL=master-conformance-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-conformance-resolver.js","sourceRoot":"","sources":["../../server/service/master-conformance-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ctx, Directive, Field, Int, ObjectType, Query, Resolver } from 'type-graphql'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { PhysicalAsset } from './asset/physical-asset'\nimport { PhysicalAssetClass } from './asset/physical-asset-class'\nimport { Equipment } from './equipment/equipment'\nimport { EquipmentClass } from './equipment/equipment-class'\nimport { StopReason } from './equipment/stop-reason'\nimport { OperationalLocation } from './location/operational-location'\nimport { MaterialClass } from './material/material-class'\nimport { MaterialDefinition } from './material/material-definition'\nimport { OperationDefinition } from './operation/operation-definition'\nimport { Person } from './personnel/person'\nimport { PersonnelClass } from './personnel/personnel-class'\nimport { RecipeDefinition } from './recipe/recipe-definition'\nimport { RouteDefinition } from './recipe/route-definition'\nimport { TestSpecification } from './test-spec/test-specification'\nimport { checkMaster, readMasterSnapshot, scannedCounts, summarize } from './master-conformance'\nimport { listEffectiveRecipes } from './recipe/recipe-effective-list'\nimport { listEffectiveMaterialDefinitions } from './material/material-effective-list'\n\n/**\n * 마스터 정합성 — **사람이 눌러서 도는 검사.**\n *\n * 목록 화면이 매번 부르는 것이 아니다. 표를 통째로 읽어야 답이 나오고, 상한을 두면 「어긋남 0건」이\n * 거짓이 되기 때문이다. 정합성은 「전부 봤나」가 곧 답이다.\n */\n\n@ObjectType({ description: 'One master data conformance finding' })\nexport class MasterFinding {\n @Field()\n axis: string\n\n @Field({ nullable: true })\n subject?: string\n\n @Field()\n kind: string\n\n @Field()\n field: string\n\n @Field({ nullable: true })\n value?: string\n}\n\n@ObjectType({ description: 'How many findings per axis and kind' })\nexport class MasterFindingCount {\n @Field()\n axis: string\n\n @Field()\n kind: string\n\n @Field(type => Int)\n count: number\n}\n\n@ObjectType({ description: 'How many rows were scanned per axis' })\nexport class MasterScanned {\n @Field()\n axis: string\n\n @Field(type => Int)\n rows: number\n}\n\n@ObjectType({ description: 'Master data conformance report' })\nexport class MasterConformance {\n /**\n * 무엇을 몇 개 봤나. **어긋남 0건이 「멀쩡하다」인지 「안 돌았다」인지는 이것으로만 갈린다.**\n */\n @Field(type => [MasterScanned])\n scanned: MasterScanned[]\n\n @Field(type => Int, { description: 'How many findings in total' })\n total: number\n\n @Field(type => [MasterFindingCount])\n counts: MasterFindingCount[]\n\n @Field(type => [MasterFinding])\n findings: MasterFinding[]\n}\n\n@Resolver()\nexport class MasterConformanceResolver {\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => MasterConformance, { description: 'Check master data for missing fields and dangling references' })\n async masterConformance(@Ctx() context: ResolverContext): Promise<MasterConformance> {\n const { domain } = context.state\n\n const snapshot = await readMasterSnapshot(domain, (entity: any) => entity === RecipeDefinition\n ? { find: async () => (await listEffectiveRecipes(getRepository(RecipeDefinition).manager, domain, {\n filters: [{ name: 'materialDefinitionName', operator: 'is_not_null', value: true }]\n } as any)).items }\n : entity === MaterialDefinition\n ? { find: async () => (await listEffectiveMaterialDefinitions(getRepository(MaterialDefinition).manager, domain, {\n filters: [{ name: 'revisionNumber', operator: 'is_not_null', value: true }]\n } as any)).items }\n : getRepository(entity), {\n Person,\n PersonnelClass,\n Equipment,\n EquipmentClass,\n PhysicalAsset,\n PhysicalAssetClass,\n MaterialDefinition,\n MaterialClass,\n OperationDefinition,\n RouteDefinition,\n RecipeDefinition,\n OperationalLocation,\n StopReason,\n TestSpecification\n })\n\n const findings = checkMaster(snapshot)\n\n return { scanned: scannedCounts(snapshot), total: findings.length, counts: summarize(findings), findings }\n }\n}\n"]}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * 마스터가 **말이 되나** — 축을 가로질러 한 번에 본다.
3
+ *
4
+ * ── 왜 필요한가 ────────────────────────────────────────────────────────────
5
+ * 축마다 화면이 있고 축마다 값이 차 있는데, 그 사이가 이어지는지는 아무도 안 봤다. 설비 등급 다섯이
6
+ * 서 있고 설비 스물둘이 어느 등급에도 안 들어 있던 일이 그랬다 — 두 화면 다 멀쩡해 보였다.
7
+ * 카메라 자산 다섯이 ECU 등급에 들어 있던 것도, 정지 사유 고르기가 빈 목록으로 보이던 것도 같다.
8
+ *
9
+ * 사람이 열두 화면을 오가며 맞춰 보는 것으로는 안 된다. 맞춰 보지 않으면 아무도 모르고, 맞춰 봤는지
10
+ * 아닌지도 남지 않는다.
11
+ *
12
+ * ── 두 가지만 본다 ─────────────────────────────────────────────────────────
13
+ * **비어 있으면 안 되는 칸**과 **가리키는데 없는 것**이다. 둘 다 사실 판정이라 다툼이 없다.
14
+ * 「이 값이 옳은가」는 여기서 안 본다 — 그것은 현장이 정한다.
15
+ *
16
+ * ── 없는 것을 없다고 말한다 ────────────────────────────────────────────────
17
+ * 표가 통째로 비었으면 그것도 낸다. 「빠진 것 0건」과 「아직 아무것도 안 세웠다」는 다르고, 세지
18
+ * 않으면 둘이 같아 보인다.
19
+ */
20
+ /** 한 건의 어긋남. 사실만 담는다 — 무엇을, 어디서, 무엇이. */
21
+ export interface Finding {
22
+ /** 어느 축인가. `person` · `equipment` · `recipeDefinition` … */
23
+ axis: string;
24
+ /** 어느 줄인가. 표가 통째로 빈 경우에는 없다. */
25
+ subject?: string;
26
+ /** `missing` = 비어 있으면 안 되는 칸이 비었다 · `dangling` = 가리키는데 그런 것이 없다 · `empty` = 표가 비었다 · `unused` = 아무도 안 가리킨다 */
27
+ kind: 'missing' | 'dangling' | 'empty' | 'unused';
28
+ /** 어느 칸인가(`missing`·`dangling`), 또는 무엇이 비었나(`empty`·`unused`). */
29
+ field: string;
30
+ /** 가리키던 값. `dangling` 일 때만. */
31
+ value?: string;
32
+ }
33
+ /** 한 축이 내놓는 줄들. 이름과 칸 몇 개만 본다. */
34
+ export type Row = Record<string, any>;
35
+ export interface MasterSnapshot {
36
+ persons: Row[];
37
+ equipment: Row[];
38
+ physicalAssets: Row[];
39
+ materialDefinitions: Row[];
40
+ operationDefinitions: Row[];
41
+ routeDefinitions: Row[];
42
+ recipeDefinitions: Row[];
43
+ operationalLocations: Row[];
44
+ stopReasons: Row[];
45
+ testSpecifications: Row[];
46
+ personnelClasses: Row[];
47
+ equipmentClasses: Row[];
48
+ physicalAssetClasses: Row[];
49
+ materialClasses: Row[];
50
+ }
51
+ /**
52
+ * 마스터 전체를 잰다.
53
+ *
54
+ * **순서에 뜻이 없다.** 어느 축부터 보든 같은 답이 나와야 하고, 그래야 이 결과를 두 번 재서
55
+ * 견줄 수 있다.
56
+ */
57
+ export declare function checkMaster(snapshot: MasterSnapshot): Finding[];
58
+ /**
59
+ * **무엇을 몇 개 봤나.**
60
+ *
61
+ * 어긋남 0건이 「멀쩡하다」인지 「안 돌았다」인지는 이것으로만 갈린다. 본 수를 안 내면 두 답이
62
+ * 같은 글자로 나온다 — 검사기가 스스로를 못 믿게 만드는 가장 흔한 방식이다.
63
+ */
64
+ export declare function scannedCounts(snapshot: MasterSnapshot): {
65
+ axis: string;
66
+ rows: number;
67
+ }[];
68
+ /** 축·종류별로 몇 건인지. 사람이 먼저 볼 것을 고르는 데 쓴다. */
69
+ export declare function summarize(findings: Finding[]): {
70
+ axis: string;
71
+ kind: string;
72
+ count: number;
73
+ }[];
74
+ /**
75
+ * 한 도메인의 마스터를 통째로 읽어 잰다.
76
+ *
77
+ * **상한을 두지 않는다.** 정합성은 「전부 봤나」가 곧 답이라, 일부만 보고 「어긋남 0건」이라고 하면
78
+ * 그 답이 거짓이 된다. 그래서 이것은 목록 화면이 부르는 것이 아니라 **사람이 눌러서 도는 검사**다.
79
+ */
80
+ export declare function readMasterSnapshot(domain: any, getRepository: any, entities: Record<string, any>): Promise<MasterSnapshot>;