@things-factory/kpi 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 (409) hide show
  1. package/dist-client/bootstrap.d.ts +2 -0
  2. package/dist-client/bootstrap.js +7 -0
  3. package/dist-client/bootstrap.js.map +1 -0
  4. package/dist-client/charts/kpi-boxplot-chart.d.ts +24 -0
  5. package/dist-client/charts/kpi-boxplot-chart.js +324 -0
  6. package/dist-client/charts/kpi-boxplot-chart.js.map +1 -0
  7. package/dist-client/charts/kpi-mini-trend-chart.d.ts +14 -0
  8. package/dist-client/charts/kpi-mini-trend-chart.js +148 -0
  9. package/dist-client/charts/kpi-mini-trend-chart.js.map +1 -0
  10. package/dist-client/charts/kpi-radar-chart.d.ts +16 -0
  11. package/dist-client/charts/kpi-radar-chart.js +138 -0
  12. package/dist-client/charts/kpi-radar-chart.js.map +1 -0
  13. package/dist-client/charts/kpi-trend-chart.d.ts +25 -0
  14. package/dist-client/charts/kpi-trend-chart.js +186 -0
  15. package/dist-client/charts/kpi-trend-chart.js.map +1 -0
  16. package/dist-client/google-map/common-google-map.d.ts +34 -0
  17. package/dist-client/google-map/common-google-map.js +333 -0
  18. package/dist-client/google-map/common-google-map.js.map +1 -0
  19. package/dist-client/google-map/google-map-loader.d.ts +8 -0
  20. package/dist-client/google-map/google-map-loader.js +22 -0
  21. package/dist-client/google-map/google-map-loader.js.map +1 -0
  22. package/dist-client/index.d.ts +1 -0
  23. package/dist-client/index.js +2 -0
  24. package/dist-client/index.js.map +1 -0
  25. package/dist-client/pages/kpi/kpi-grade-editor.d.ts +35 -0
  26. package/dist-client/pages/kpi/kpi-grade-editor.js +165 -0
  27. package/dist-client/pages/kpi/kpi-grade-editor.js.map +1 -0
  28. package/dist-client/pages/kpi/kpi-importer.d.ts +23 -0
  29. package/dist-client/pages/kpi/kpi-importer.js +92 -0
  30. package/dist-client/pages/kpi/kpi-importer.js.map +1 -0
  31. package/dist-client/pages/kpi/kpi-list-page.d.ts +136 -0
  32. package/dist-client/pages/kpi/kpi-list-page.js +948 -0
  33. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -0
  34. package/dist-client/pages/kpi/kpi-overview-sample.d.ts +36 -0
  35. package/dist-client/pages/kpi/kpi-overview-sample.js +264 -0
  36. package/dist-client/pages/kpi/kpi-overview-sample.js.map +1 -0
  37. package/dist-client/pages/kpi/kpi-overview.d.ts +14 -0
  38. package/dist-client/pages/kpi/kpi-overview.js +361 -0
  39. package/dist-client/pages/kpi/kpi-overview.js.map +1 -0
  40. package/dist-client/pages/kpi/kpi-tree-page.d.ts +51 -0
  41. package/dist-client/pages/kpi/kpi-tree-page.js +355 -0
  42. package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -0
  43. package/dist-client/pages/kpi/kpi-view.d.ts +12 -0
  44. package/dist-client/pages/kpi/kpi-view.js +193 -0
  45. package/dist-client/pages/kpi/kpi-view.js.map +1 -0
  46. package/dist-client/pages/kpi/kpi-viz-editor.d.ts +19 -0
  47. package/dist-client/pages/kpi/kpi-viz-editor.js +562 -0
  48. package/dist-client/pages/kpi/kpi-viz-editor.js.map +1 -0
  49. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.d.ts +17 -0
  50. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js +279 -0
  51. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js.map +1 -0
  52. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.d.ts +19 -0
  53. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js +385 -0
  54. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js.map +1 -0
  55. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.d.ts +23 -0
  56. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js +465 -0
  57. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js.map +1 -0
  58. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.d.ts +8 -0
  59. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js +78 -0
  60. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js.map +1 -0
  61. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +24 -0
  62. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +440 -0
  63. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -0
  64. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +33 -0
  65. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +444 -0
  66. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -0
  67. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +23 -0
  68. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +369 -0
  69. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -0
  70. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.d.ts +18 -0
  71. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js +128 -0
  72. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js.map +1 -0
  73. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +31 -0
  74. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +493 -0
  75. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -0
  76. package/dist-client/pages/kpi-dashboard/kpi-dashboard.d.ts +50 -0
  77. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +884 -0
  78. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -0
  79. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.d.ts +12 -0
  80. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js +82 -0
  81. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js.map +1 -0
  82. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.d.ts +11 -0
  83. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js +65 -0
  84. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js.map +1 -0
  85. package/dist-client/pages/kpi-dashboard/kpi-list-summary.d.ts +13 -0
  86. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js +115 -0
  87. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js.map +1 -0
  88. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.d.ts +15 -0
  89. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js +146 -0
  90. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js.map +1 -0
  91. package/dist-client/pages/kpi-dashboard/kpi-value-entry.d.ts +7 -0
  92. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js +86 -0
  93. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js.map +1 -0
  94. package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +21 -0
  95. package/dist-client/pages/kpi-history/kpi-history-list-page.js +160 -0
  96. package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -0
  97. package/dist-client/pages/kpi-metric/kpi-metric-importer.d.ts +23 -0
  98. package/dist-client/pages/kpi-metric/kpi-metric-importer.js +92 -0
  99. package/dist-client/pages/kpi-metric/kpi-metric-importer.js.map +1 -0
  100. package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +65 -0
  101. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +415 -0
  102. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -0
  103. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +52 -0
  104. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +678 -0
  105. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -0
  106. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.d.ts +23 -0
  107. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js +75 -0
  108. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js.map +1 -0
  109. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +64 -0
  110. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +311 -0
  111. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -0
  112. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.d.ts +12 -0
  113. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +175 -0
  114. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -0
  115. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +35 -0
  116. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +161 -0
  117. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -0
  118. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.d.ts +47 -0
  119. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +655 -0
  120. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -0
  121. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.d.ts +23 -0
  122. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js +92 -0
  123. package/dist-client/pages/kpi-statistic/kpi-statistic-importer.js.map +1 -0
  124. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +65 -0
  125. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +416 -0
  126. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -0
  127. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +50 -0
  128. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +700 -0
  129. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -0
  130. package/dist-client/pages/kpi-value/kpi-value-importer.d.ts +23 -0
  131. package/dist-client/pages/kpi-value/kpi-value-importer.js +92 -0
  132. package/dist-client/pages/kpi-value/kpi-value-importer.js.map +1 -0
  133. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +73 -0
  134. package/dist-client/pages/kpi-value/kpi-value-list-page.js +403 -0
  135. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -0
  136. package/dist-client/route.d.ts +1 -0
  137. package/dist-client/route.js +47 -0
  138. package/dist-client/route.js.map +1 -0
  139. package/dist-client/tsconfig.tsbuildinfo +1 -0
  140. package/dist-client/viewparts/kpi-metric-input.d.ts +23 -0
  141. package/dist-client/viewparts/kpi-metric-input.js +140 -0
  142. package/dist-client/viewparts/kpi-metric-input.js.map +1 -0
  143. package/dist-client/viewparts/kpi-metric-meta-editor.d.ts +36 -0
  144. package/dist-client/viewparts/kpi-metric-meta-editor.js +321 -0
  145. package/dist-client/viewparts/kpi-metric-meta-editor.js.map +1 -0
  146. package/dist-client/viewparts/metric-input-hint.d.ts +26 -0
  147. package/dist-client/viewparts/metric-input-hint.js +19 -0
  148. package/dist-client/viewparts/metric-input-hint.js.map +1 -0
  149. package/dist-client/viewparts/metric-input.test.d.ts +1 -0
  150. package/dist-client/viewparts/metric-input.test.js +43 -0
  151. package/dist-client/viewparts/metric-input.test.js.map +1 -0
  152. package/dist-client/viewparts/metric-renderer-registry.d.ts +18 -0
  153. package/dist-client/viewparts/metric-renderer-registry.js +29 -0
  154. package/dist-client/viewparts/metric-renderer-registry.js.map +1 -0
  155. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.d.ts +19 -0
  156. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.js +76 -0
  157. package/dist-client/viewparts/ox-grist-editor-metric-input-hint.js.map +1 -0
  158. package/dist-server/calculator/calculator.test.d.ts +1 -0
  159. package/dist-server/calculator/calculator.test.js +126 -0
  160. package/dist-server/calculator/calculator.test.js.map +1 -0
  161. package/dist-server/calculator/evaluator.d.ts +8 -0
  162. package/dist-server/calculator/evaluator.js +42 -0
  163. package/dist-server/calculator/evaluator.js.map +1 -0
  164. package/dist-server/calculator/functions.d.ts +3 -0
  165. package/dist-server/calculator/functions.js +62 -0
  166. package/dist-server/calculator/functions.js.map +1 -0
  167. package/dist-server/calculator/index.d.ts +6 -0
  168. package/dist-server/calculator/index.js +10 -0
  169. package/dist-server/calculator/index.js.map +1 -0
  170. package/dist-server/calculator/parser.d.ts +34 -0
  171. package/dist-server/calculator/parser.js +185 -0
  172. package/dist-server/calculator/parser.js.map +1 -0
  173. package/dist-server/calculator/provider.d.ts +8 -0
  174. package/dist-server/calculator/provider.js +13 -0
  175. package/dist-server/calculator/provider.js.map +1 -0
  176. package/dist-server/calculator/score.d.ts +21 -0
  177. package/dist-server/calculator/score.js +36 -0
  178. package/dist-server/calculator/score.js.map +1 -0
  179. package/dist-server/calculator/score.test.d.ts +1 -0
  180. package/dist-server/calculator/score.test.js +47 -0
  181. package/dist-server/calculator/score.test.js.map +1 -0
  182. package/dist-server/calculator/validate.d.ts +15 -0
  183. package/dist-server/calculator/validate.js +30 -0
  184. package/dist-server/calculator/validate.js.map +1 -0
  185. package/dist-server/calculator/validate.test.d.ts +1 -0
  186. package/dist-server/calculator/validate.test.js +45 -0
  187. package/dist-server/calculator/validate.test.js.map +1 -0
  188. package/dist-server/controllers/index.d.ts +2 -0
  189. package/dist-server/controllers/index.js +6 -0
  190. package/dist-server/controllers/index.js.map +1 -0
  191. package/dist-server/controllers/kpi-metric-value-provider.d.ts +11 -0
  192. package/dist-server/controllers/kpi-metric-value-provider.js +97 -0
  193. package/dist-server/controllers/kpi-metric-value-provider.js.map +1 -0
  194. package/dist-server/controllers/kpi-value-provider.d.ts +11 -0
  195. package/dist-server/controllers/kpi-value-provider.js +50 -0
  196. package/dist-server/controllers/kpi-value-provider.js.map +1 -0
  197. package/dist-server/index.d.ts +5 -0
  198. package/dist-server/index.js +9 -0
  199. package/dist-server/index.js.map +1 -0
  200. package/dist-server/migrations/1752190849680-seed-kpi-metrics.d.ts +6 -0
  201. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js +102 -0
  202. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js.map +1 -0
  203. package/dist-server/migrations/1752190849681-seed-kpi.d.ts +5 -0
  204. package/dist-server/migrations/1752190849681-seed-kpi.js +315 -0
  205. package/dist-server/migrations/1752190849681-seed-kpi.js.map +1 -0
  206. package/dist-server/migrations/1752192090123-add-grades-to-kpi.d.ts +7 -0
  207. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js +51 -0
  208. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js.map +1 -0
  209. package/dist-server/migrations/1752192090124-add-kpi-statistics.d.ts +5 -0
  210. package/dist-server/migrations/1752192090124-add-kpi-statistics.js +710 -0
  211. package/dist-server/migrations/1752192090124-add-kpi-statistics.js.map +1 -0
  212. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.d.ts +6 -0
  213. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js +111 -0
  214. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js.map +1 -0
  215. package/dist-server/migrations/1752192090129-seed-kpi-values.d.ts +6 -0
  216. package/dist-server/migrations/1752192090129-seed-kpi-values.js +187 -0
  217. package/dist-server/migrations/1752192090129-seed-kpi-values.js.map +1 -0
  218. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.d.ts +10 -0
  219. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.js +26 -0
  220. package/dist-server/migrations/1752192090200-add-meta-to-kpi-metric.js.map +1 -0
  221. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.d.ts +11 -0
  222. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.js +54 -0
  223. package/dist-server/migrations/1752192090201-backfill-kpi-metric-meta.js.map +1 -0
  224. package/dist-server/migrations/grade-data/x11-performance-table.json +962 -0
  225. package/dist-server/migrations/grade-data/x12-performance-table.json +611 -0
  226. package/dist-server/migrations/grade-data/x14-performance-table.json +42 -0
  227. package/dist-server/migrations/grade-data/x21-performance-table.json +889 -0
  228. package/dist-server/migrations/grade-data/x22-performance-table.json +1064 -0
  229. package/dist-server/migrations/grade-data/x23-performance-table.json +42 -0
  230. package/dist-server/migrations/grade-data/x31-performance-table.json +644 -0
  231. package/dist-server/migrations/grade-data/x32-performance-table.json +993 -0
  232. package/dist-server/migrations/grade-data/x33-performance-table.json +195 -0
  233. package/dist-server/migrations/grade-data/x34-performance-table.json +12 -0
  234. package/dist-server/migrations/grade-data/x35-performance-table.json +42 -0
  235. package/dist-server/migrations/grade-data/x41-performance-table.json +825 -0
  236. package/dist-server/migrations/grade-data/x42-performance-table.json +786 -0
  237. package/dist-server/migrations/grade-data/x43-performance-table.json +12 -0
  238. package/dist-server/migrations/grade-data/x44-performance-table.json +42 -0
  239. package/dist-server/migrations/grade-data/x51-performance-table.json +924 -0
  240. package/dist-server/migrations/grade-data/x52-performance-table.json +42 -0
  241. package/dist-server/migrations/grade-data/x61-performance-table.json +261 -0
  242. package/dist-server/migrations/grade-data/x62-performance-table.json +42 -0
  243. package/dist-server/migrations/index.d.ts +1 -0
  244. package/dist-server/migrations/index.js +12 -0
  245. package/dist-server/migrations/index.js.map +1 -0
  246. package/dist-server/migrations/seed-data/kpi-metrics-seed.json +517 -0
  247. package/dist-server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
  248. package/dist-server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  249. package/dist-server/migrations/seed-data/kpi-values-seed.json +402 -0
  250. package/dist-server/migrations/seed-data/kpis-seed.json +488 -0
  251. package/dist-server/migrations/seed-data/scope-definitions-seed.json +90 -0
  252. package/dist-server/routes.d.ts +1 -0
  253. package/dist-server/routes.js +72 -0
  254. package/dist-server/routes.js.map +1 -0
  255. package/dist-server/service/index.d.ts +15 -0
  256. package/dist-server/service/index.js +49 -0
  257. package/dist-server/service/index.js.map +1 -0
  258. package/dist-server/service/kpi/aggregate-kpi.d.ts +8 -0
  259. package/dist-server/service/kpi/aggregate-kpi.js +123 -0
  260. package/dist-server/service/kpi/aggregate-kpi.js.map +1 -0
  261. package/dist-server/service/kpi/event-subscriber.d.ts +9 -0
  262. package/dist-server/service/kpi/event-subscriber.js +31 -0
  263. package/dist-server/service/kpi/event-subscriber.js.map +1 -0
  264. package/dist-server/service/kpi/index.d.ts +8 -0
  265. package/dist-server/service/kpi/index.js +12 -0
  266. package/dist-server/service/kpi/index.js.map +1 -0
  267. package/dist-server/service/kpi/kpi-formula.service.d.ts +49 -0
  268. package/dist-server/service/kpi/kpi-formula.service.js +165 -0
  269. package/dist-server/service/kpi/kpi-formula.service.js.map +1 -0
  270. package/dist-server/service/kpi/kpi-grade.types.d.ts +22 -0
  271. package/dist-server/service/kpi/kpi-grade.types.js +3 -0
  272. package/dist-server/service/kpi/kpi-grade.types.js.map +1 -0
  273. package/dist-server/service/kpi/kpi-history.d.ts +29 -0
  274. package/dist-server/service/kpi/kpi-history.js +148 -0
  275. package/dist-server/service/kpi/kpi-history.js.map +1 -0
  276. package/dist-server/service/kpi/kpi-mutation.d.ts +14 -0
  277. package/dist-server/service/kpi/kpi-mutation.js +553 -0
  278. package/dist-server/service/kpi/kpi-mutation.js.map +1 -0
  279. package/dist-server/service/kpi/kpi-query.d.ts +24 -0
  280. package/dist-server/service/kpi/kpi-query.js +309 -0
  281. package/dist-server/service/kpi/kpi-query.js.map +1 -0
  282. package/dist-server/service/kpi/kpi-type.d.ts +48 -0
  283. package/dist-server/service/kpi/kpi-type.js +221 -0
  284. package/dist-server/service/kpi/kpi-type.js.map +1 -0
  285. package/dist-server/service/kpi/kpi.d.ts +130 -0
  286. package/dist-server/service/kpi/kpi.js +356 -0
  287. package/dist-server/service/kpi/kpi.js.map +1 -0
  288. package/dist-server/service/kpi-alert/index.d.ts +2 -0
  289. package/dist-server/service/kpi-alert/index.js +6 -0
  290. package/dist-server/service/kpi-alert/index.js.map +1 -0
  291. package/dist-server/service/kpi-alert/kpi-alert-query.d.ts +4 -0
  292. package/dist-server/service/kpi-alert/kpi-alert-query.js +72 -0
  293. package/dist-server/service/kpi-alert/kpi-alert-query.js.map +1 -0
  294. package/dist-server/service/kpi-alert/kpi-alert-type.d.ts +8 -0
  295. package/dist-server/service/kpi-alert/kpi-alert-type.js +33 -0
  296. package/dist-server/service/kpi-alert/kpi-alert-type.js.map +1 -0
  297. package/dist-server/service/kpi-metric/aggregate-kpi-metric.d.ts +8 -0
  298. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +126 -0
  299. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -0
  300. package/dist-server/service/kpi-metric/index.d.ts +6 -0
  301. package/dist-server/service/kpi-metric/index.js +10 -0
  302. package/dist-server/service/kpi-metric/index.js.map +1 -0
  303. package/dist-server/service/kpi-metric/kpi-metric-meta.d.ts +46 -0
  304. package/dist-server/service/kpi-metric/kpi-metric-meta.js +27 -0
  305. package/dist-server/service/kpi-metric/kpi-metric-meta.js.map +1 -0
  306. package/dist-server/service/kpi-metric/kpi-metric-meta.test.d.ts +1 -0
  307. package/dist-server/service/kpi-metric/kpi-metric-meta.test.js +43 -0
  308. package/dist-server/service/kpi-metric/kpi-metric-meta.test.js.map +1 -0
  309. package/dist-server/service/kpi-metric/kpi-metric-mutation.d.ts +10 -0
  310. package/dist-server/service/kpi-metric/kpi-metric-mutation.js +296 -0
  311. package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -0
  312. package/dist-server/service/kpi-metric/kpi-metric-query.d.ts +14 -0
  313. package/dist-server/service/kpi-metric/kpi-metric-query.js +126 -0
  314. package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -0
  315. package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +45 -0
  316. package/dist-server/service/kpi-metric/kpi-metric-type.js +177 -0
  317. package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -0
  318. package/dist-server/service/kpi-metric/kpi-metric.d.ts +39 -0
  319. package/dist-server/service/kpi-metric/kpi-metric.js +174 -0
  320. package/dist-server/service/kpi-metric/kpi-metric.js.map +1 -0
  321. package/dist-server/service/kpi-metric-value/index.d.ts +6 -0
  322. package/dist-server/service/kpi-metric-value/index.js +10 -0
  323. package/dist-server/service/kpi-metric-value/index.js.map +1 -0
  324. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +11 -0
  325. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +283 -0
  326. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -0
  327. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.d.ts +13 -0
  328. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +106 -0
  329. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -0
  330. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.d.ts +26 -0
  331. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js +112 -0
  332. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js.map +1 -0
  333. package/dist-server/service/kpi-metric-value/kpi-metric-value.d.ts +23 -0
  334. package/dist-server/service/kpi-metric-value/kpi-metric-value.js +107 -0
  335. package/dist-server/service/kpi-metric-value/kpi-metric-value.js.map +1 -0
  336. package/dist-server/service/kpi-org-scope/index.d.ts +5 -0
  337. package/dist-server/service/kpi-org-scope/index.js +9 -0
  338. package/dist-server/service/kpi-org-scope/index.js.map +1 -0
  339. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.d.ts +8 -0
  340. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js +170 -0
  341. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js.map +1 -0
  342. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.d.ts +14 -0
  343. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js +152 -0
  344. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js.map +1 -0
  345. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.d.ts +26 -0
  346. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js +101 -0
  347. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js.map +1 -0
  348. package/dist-server/service/kpi-org-scope/kpi-org-scope.d.ts +26 -0
  349. package/dist-server/service/kpi-org-scope/kpi-org-scope.js +135 -0
  350. package/dist-server/service/kpi-org-scope/kpi-org-scope.js.map +1 -0
  351. package/dist-server/service/kpi-scope/index.d.ts +9 -0
  352. package/dist-server/service/kpi-scope/index.js +14 -0
  353. package/dist-server/service/kpi-scope/index.js.map +1 -0
  354. package/dist-server/service/kpi-scope/kpi-scope-mutation.d.ts +9 -0
  355. package/dist-server/service/kpi-scope/kpi-scope-mutation.js +140 -0
  356. package/dist-server/service/kpi-scope/kpi-scope-mutation.js.map +1 -0
  357. package/dist-server/service/kpi-scope/kpi-scope-query.d.ts +11 -0
  358. package/dist-server/service/kpi-scope/kpi-scope-query.js +89 -0
  359. package/dist-server/service/kpi-scope/kpi-scope-query.js.map +1 -0
  360. package/dist-server/service/kpi-scope/kpi-scope-type.d.ts +35 -0
  361. package/dist-server/service/kpi-scope/kpi-scope-type.js +138 -0
  362. package/dist-server/service/kpi-scope/kpi-scope-type.js.map +1 -0
  363. package/dist-server/service/kpi-scope/kpi-scope.d.ts +38 -0
  364. package/dist-server/service/kpi-scope/kpi-scope.js +144 -0
  365. package/dist-server/service/kpi-scope/kpi-scope.js.map +1 -0
  366. package/dist-server/service/kpi-statistic/index.d.ts +6 -0
  367. package/dist-server/service/kpi-statistic/index.js +10 -0
  368. package/dist-server/service/kpi-statistic/index.js.map +1 -0
  369. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.d.ts +43 -0
  370. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js +181 -0
  371. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js.map +1 -0
  372. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.d.ts +50 -0
  373. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js +324 -0
  374. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js.map +1 -0
  375. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +14 -0
  376. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +279 -0
  377. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -0
  378. package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +17 -0
  379. package/dist-server/service/kpi-statistic/kpi-statistic-query.js +183 -0
  380. package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -0
  381. package/dist-server/service/kpi-statistic/kpi-statistic-type.d.ts +59 -0
  382. package/dist-server/service/kpi-statistic/kpi-statistic-type.js +200 -0
  383. package/dist-server/service/kpi-statistic/kpi-statistic-type.js.map +1 -0
  384. package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +42 -0
  385. package/dist-server/service/kpi-statistic/kpi-statistic.js +210 -0
  386. package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -0
  387. package/dist-server/service/kpi-value/index.d.ts +6 -0
  388. package/dist-server/service/kpi-value/index.js +10 -0
  389. package/dist-server/service/kpi-value/index.js.map +1 -0
  390. package/dist-server/service/kpi-value/kpi-value-mutation.d.ts +13 -0
  391. package/dist-server/service/kpi-value/kpi-value-mutation.js +447 -0
  392. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -0
  393. package/dist-server/service/kpi-value/kpi-value-query.d.ts +22 -0
  394. package/dist-server/service/kpi-value/kpi-value-query.js +149 -0
  395. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -0
  396. package/dist-server/service/kpi-value/kpi-value-score.service.d.ts +24 -0
  397. package/dist-server/service/kpi-value/kpi-value-score.service.js +61 -0
  398. package/dist-server/service/kpi-value/kpi-value-score.service.js.map +1 -0
  399. package/dist-server/service/kpi-value/kpi-value-type.d.ts +33 -0
  400. package/dist-server/service/kpi-value/kpi-value-type.js +156 -0
  401. package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -0
  402. package/dist-server/service/kpi-value/kpi-value.d.ts +32 -0
  403. package/dist-server/service/kpi-value/kpi-value.js +175 -0
  404. package/dist-server/service/kpi-value/kpi-value.js.map +1 -0
  405. package/dist-server/service/utils/value-date-util.d.ts +4 -0
  406. package/dist-server/service/utils/value-date-util.js +117 -0
  407. package/dist-server/service/utils/value-date-util.js.map +1 -0
  408. package/dist-server/tsconfig.tsbuildinfo +1 -0
  409. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-alert-query.js","sourceRoot":"","sources":["../../../server/service/kpi-alert/kpi-alert-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8D;AAC9D,iDAAqD;AACrD,oCAAgC;AAChC,sDAAiD;AACjD,qDAA2C;AAGpC,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGlB,AAAN,KAAK,CAAC,SAAS,CAAQ,OAAO;QAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,eAAe;QACf,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAa,EAAC,SAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACpF,oBAAoB;QACpB,MAAM,MAAM,GAAe,EAAE,CAAA;QAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,oBAAQ,CAAC,CAAC,OAAO,CAAC;gBAClD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE;gBACzD,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;aAC7B,CAAC,CAAA;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC;oBACV,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,WAAW;oBACxB,GAAG;oBACH,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,UAAU;oBAC9B,KAAK,EAAE,MAAM;oBACb,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAA;gBACF,SAAQ;YACV,CAAC;YACD,yCAAyC;YACzC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,WAAW,CAAA;YACvC,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC;gBACjD,MAAM,CAAC,IAAI,CAAC;oBACV,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,cAAc;oBAC3B,GAAG;oBACH,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,SAAS,MAAM,MAAM;oBAC3D,KAAK,EAAE,SAAS;oBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAA;YACJ,CAAC;YACD,sBAAsB;YACtB,4BAA4B;YAC5B,+FAA+F;YAC/F,kEAAkE;YAClE,oBAAoB;YACpB,mCAAmC;YACnC,aAAa;YACb,mEAAmE;YACnE,2BAA2B;YAC3B,8BAA8B;YAC9B,SAAS;YACT,MAAM;YACN,IAAI;QACN,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;CACF,CAAA;AAnDY,sCAAa;AAGlB;IAFL,IAAA,wBAAS,EAAC,mGAAmG,CAAC;IAC9G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,yBAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAC/D,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;8CA+CrB;wBAlDU,aAAa;IADzB,IAAA,uBAAQ,GAAE;GACE,aAAa,CAmDzB","sourcesContent":["import { Directive, Resolver, Query, Ctx } from 'type-graphql'\nimport { getRepository } from '@things-factory/shell'\nimport { Kpi } from '../kpi/kpi'\nimport { KpiValue } from '../kpi-value/kpi-value'\nimport { KpiAlert } from './kpi-alert-type'\n\n@Resolver()\nexport class KpiAlertQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [KpiAlert], { description: 'KPI 실적/등급/목표 미달 등 경고/알림 리스트 반환' })\n async kpiAlerts(@Ctx() context): Promise<KpiAlert[]> {\n const { domain } = context.state\n // 1. KPI 전체 조회\n const kpis = await getRepository(Kpi).find({ where: { domain: { id: domain.id } } })\n // 2. KPI별 최신 실적값 조회\n const alerts: KpiAlert[] = []\n for (const kpi of kpis) {\n const value = await getRepository(KpiValue).findOne({\n where: { domain: { id: domain.id }, kpi: { id: kpi.id } },\n order: { valueDate: 'DESC' }\n })\n if (!value) {\n alerts.push({\n id: `${kpi.id}-no-value`,\n kpi,\n message: `${kpi.name} 실적값 미입력`,\n level: 'info',\n createdAt: new Date()\n })\n continue\n }\n // 목표값(예: kpi.vizMeta?.targetValue) 기준 경고\n const target = kpi.vizMeta?.targetValue\n if (target !== undefined && value.value < target) {\n alerts.push({\n id: `${kpi.id}-target-miss`,\n kpi,\n message: `${kpi.name} 실적(${value.value})이 목표(${target}) 미달`,\n level: 'warning',\n createdAt: new Date()\n })\n }\n // 등급 기준 경고(예: 최하위 등급)\n // if (kpi.grades?.length) {\n // const grade = kpi.grades.find(g => value.value >= g.minValue && value.value <= g.maxValue)\n // if (grade && grade.score !== undefined && grade.score <= 2) {\n // alerts.push({\n // id: `${kpi.id}-grade-low`,\n // kpi,\n // message: `${kpi.name} 등급(${grade.name})(${grade.score}점)`,\n // level: 'critical',\n // createdAt: new Date()\n // })\n // }\n // }\n }\n return alerts\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { Kpi } from '../kpi/kpi';
2
+ export declare class KpiAlert {
3
+ id: string;
4
+ kpi?: Kpi;
5
+ message: string;
6
+ level: string;
7
+ createdAt: Date;
8
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KpiAlert = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const kpi_1 = require("../kpi/kpi");
7
+ let KpiAlert = class KpiAlert {
8
+ };
9
+ exports.KpiAlert = KpiAlert;
10
+ tslib_1.__decorate([
11
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID),
12
+ tslib_1.__metadata("design:type", String)
13
+ ], KpiAlert.prototype, "id", void 0);
14
+ tslib_1.__decorate([
15
+ (0, type_graphql_1.Field)(type => kpi_1.Kpi, { nullable: true, description: '경고/알림이 발생한 KPI.' }),
16
+ tslib_1.__metadata("design:type", kpi_1.Kpi)
17
+ ], KpiAlert.prototype, "kpi", void 0);
18
+ tslib_1.__decorate([
19
+ (0, type_graphql_1.Field)({ description: '경고/알림 메시지.' }),
20
+ tslib_1.__metadata("design:type", String)
21
+ ], KpiAlert.prototype, "message", void 0);
22
+ tslib_1.__decorate([
23
+ (0, type_graphql_1.Field)({ description: '경고 레벨(예: warning, critical, info 등).' }),
24
+ tslib_1.__metadata("design:type", String)
25
+ ], KpiAlert.prototype, "level", void 0);
26
+ tslib_1.__decorate([
27
+ (0, type_graphql_1.Field)({ description: '경고/알림 발생 시각.' }),
28
+ tslib_1.__metadata("design:type", Date)
29
+ ], KpiAlert.prototype, "createdAt", void 0);
30
+ exports.KpiAlert = KpiAlert = tslib_1.__decorate([
31
+ (0, type_graphql_1.ObjectType)({ description: 'KPI 경고/알림 엔티티. KPI 실적, 등급, 목표 미달 등 경고/알림 정보를 제공.' })
32
+ ], KpiAlert);
33
+ //# sourceMappingURL=kpi-alert-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-alert-type.js","sourceRoot":"","sources":["../../../server/service/kpi-alert/kpi-alert-type.ts"],"names":[],"mappings":";;;;AAAA,+CAAoD;AACpD,oCAAgC;AAGzB,IAAM,QAAQ,GAAd,MAAM,QAAQ;CAepB,CAAA;AAfY,4BAAQ;AAEnB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,CAAC;;oCACR;AAGV;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,SAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;sCACjE,SAAG;qCAAA;AAGT;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;;yCACtB;AAGf;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;;uCAClD;AAGb;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;sCAC5B,IAAI;2CAAA;mBAdJ,QAAQ;IADpB,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC;GACnE,QAAQ,CAepB","sourcesContent":["import { ObjectType, Field, ID } from 'type-graphql'\nimport { Kpi } from '../kpi/kpi'\n\n@ObjectType({ description: 'KPI 경고/알림 엔티티. KPI 실적, 등급, 목표 미달 등 경고/알림 정보를 제공.' })\nexport class KpiAlert {\n @Field(type => ID)\n id: string\n\n @Field(type => Kpi, { nullable: true, description: '경고/알림이 발생한 KPI.' })\n kpi?: Kpi\n\n @Field({ description: '경고/알림 메시지.' })\n message: string\n\n @Field({ description: '경고 레벨(예: warning, critical, info 등).' })\n level: string\n\n @Field({ description: '경고/알림 발생 시각.' })\n createdAt: Date\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * KPI-Metric 집계/자동화 서비스 함수 (formula 지원, KPI Value 저장)
3
+ * @param metricId KPI-Metric ID
4
+ * @param domainId 도메인 ID
5
+ * @param context ResolverContext (state에 domain, user, tx 등 포함)
6
+ * @returns 저장된 KPI Value 배열
7
+ */
8
+ export declare function aggregateKpiMetricValue(metricId: string, domainId: string, context: ResolverContext): Promise<any[]>;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aggregateKpiMetricValue = aggregateKpiMetricValue;
4
+ const shell_1 = require("@things-factory/shell");
5
+ const dataset_1 = require("@things-factory/dataset");
6
+ const finalize_data_collection_1 = require("@things-factory/dataset/dist-server/controllers/finalize-data-collection");
7
+ const kpi_metric_1 = require("./kpi-metric");
8
+ const kpi_value_1 = require("../kpi-value/kpi-value");
9
+ const kpi_1 = require("../kpi/kpi");
10
+ const kpi_org_scope_1 = require("../kpi-org-scope/kpi-org-scope");
11
+ /**
12
+ * KPI-Metric 집계/자동화 서비스 함수 (formula 지원, KPI Value 저장)
13
+ * @param metricId KPI-Metric ID
14
+ * @param domainId 도메인 ID
15
+ * @param context ResolverContext (state에 domain, user, tx 등 포함)
16
+ * @returns 저장된 KPI Value 배열
17
+ */
18
+ async function aggregateKpiMetricValue(metricId, domainId, context) {
19
+ const tx = context.state?.tx || (0, shell_1.getRepository)(kpi_metric_1.KpiMetric).manager;
20
+ // 1. metric 정보 조회
21
+ const metric = await (0, shell_1.getRepository)(kpi_metric_1.KpiMetric).findOne({
22
+ where: { id: metricId, domain: { id: domainId } }
23
+ });
24
+ if (!metric)
25
+ throw new Error('Metric 정보 없음');
26
+ if (!metric.active)
27
+ throw new Error('비활성화된 Metric');
28
+ // formula 분기 제거: metric은 항상 dataset 집계만 수행
29
+ let values = [];
30
+ if (!metric.dataSetId || !metric.fieldName)
31
+ throw new Error('Metric 매핑 정보 누락');
32
+ await (0, finalize_data_collection_1.finalizeLatestDataCollection)(metric.dataSetId, context);
33
+ const summaries = await (0, shell_1.getRepository)(dataset_1.DataSummary).find({
34
+ where: { dataSet: { id: metric.dataSetId }, domain: { id: domainId } },
35
+ order: { date: 'DESC', period: 'DESC' }
36
+ });
37
+ values = summaries
38
+ .map(summary => {
39
+ if (summary.summary && metric.fieldName in summary.summary) {
40
+ return {
41
+ date: summary.date,
42
+ period: summary.period,
43
+ value: summary.summary[metric.fieldName],
44
+ org: {
45
+ key01: summary.key01,
46
+ key02: summary.key02,
47
+ key03: summary.key03,
48
+ key04: summary.key04,
49
+ key05: summary.key05
50
+ }
51
+ };
52
+ }
53
+ return null;
54
+ })
55
+ .filter(Boolean);
56
+ // 5. KPI Value로 저장 (metric 단위, KPI 단위 formula는 후속)
57
+ // metric이 속한 KPI 정보 조회 (여기서는 metric.name == kpi.name인 KPI를 임시로 매핑, 실제 연동 구조에 맞게 보완 필요)
58
+ const kpi = await (0, shell_1.getRepository)(kpi_1.Kpi).findOne({ where: { name: metric.name, domain: { id: domainId } } });
59
+ if (!kpi)
60
+ throw new Error('KPI 정보 없음 (metric.name과 동일한 KPI name 기준, 실제 연동 구조에 맞게 보완 필요)');
61
+ // KPI Value version, valueDate, org 등 매핑
62
+ const savedValues = [];
63
+ const kpiOrgScopeRepo = (0, shell_1.getRepository)(kpi_org_scope_1.KpiOrgScope, context.state?.tx);
64
+ const kpiValueRepo = (0, shell_1.getRepository)(kpi_value_1.KpiValue, context.state?.tx);
65
+ for (const v of values) {
66
+ const valueDate = v.date;
67
+ const orgData = v.org;
68
+ const version = kpi.version || 1;
69
+ const value = v.value;
70
+ if (value == null || isNaN(value))
71
+ continue;
72
+ // KpiOrgScope 찾기 또는 생성
73
+ let kpiOrgScope = null;
74
+ // key들로 조합된 org 식별자 생성
75
+ const orgIdentifier = [orgData.key01, orgData.key02, orgData.key03, orgData.key04, orgData.key05].filter(Boolean).join('-') ||
76
+ 'unknown-org';
77
+ // 기존 KpiOrgScope 조회 (entityName 기준)
78
+ kpiOrgScope = await kpiOrgScopeRepo.findOne({
79
+ where: { entityName: orgIdentifier, domain: { id: domainId } }
80
+ });
81
+ // 없으면 새로 생성
82
+ if (!kpiOrgScope) {
83
+ kpiOrgScope = await kpiOrgScopeRepo.save({
84
+ entityType: 'DataSummary', // DataSummary에서 온 데이터임을 표시
85
+ entityId: `datasummary-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
86
+ entityName: orgIdentifier,
87
+ org: orgIdentifier, // legacy field
88
+ scope01: orgData.key01,
89
+ scope02: orgData.key02,
90
+ scope03: orgData.key03,
91
+ scope04: orgData.key04,
92
+ scope05: orgData.key05,
93
+ domain: kpi.domain,
94
+ creator: context.state?.user,
95
+ updater: context.state?.user
96
+ });
97
+ }
98
+ // upsert KpiValue (동일 KPI, valueDate, kpiOrgScope, version 기준)
99
+ const existing = await kpiValueRepo.findOne({
100
+ where: {
101
+ kpi: { id: kpi.id },
102
+ valueDate,
103
+ kpiOrgScope: { id: kpiOrgScope.id },
104
+ version,
105
+ domain: { id: domainId }
106
+ }
107
+ });
108
+ let entity = existing || kpiValueRepo.create();
109
+ entity.kpi = kpi;
110
+ entity.kpiId = kpi.id;
111
+ entity.version = version;
112
+ entity.valueDate = valueDate;
113
+ entity.value = value;
114
+ entity.kpiOrgScope = kpiOrgScope;
115
+ entity.kpiOrgScopeId = kpiOrgScope.id;
116
+ entity.inputType = kpi_value_1.KpiValueInputType.AUTO;
117
+ entity.source = 'AUTO-AGGREGATE';
118
+ entity.domain = kpi.domain;
119
+ entity.creator = context.state?.user;
120
+ entity.updater = context.state?.user;
121
+ entity = await kpiValueRepo.save(entity);
122
+ savedValues.push(entity);
123
+ }
124
+ return savedValues;
125
+ }
126
+ //# sourceMappingURL=aggregate-kpi-metric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate-kpi-metric.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/aggregate-kpi-metric.ts"],"names":[],"mappings":";;AAiBA,0DAkHC;AAnID,iDAAqD;AAErD,qDAAqD;AACrD,uHAAuH;AACvH,6CAAwC;AACxC,sDAAoE;AACpE,oCAAgC;AAChC,kEAA4D;AAG5D;;;;;;GAMG;AACI,KAAK,UAAU,uBAAuB,CAAC,QAAgB,EAAE,QAAgB,EAAE,OAAwB;IACxG,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,IAAI,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAA;IAEhE,kBAAkB;IAClB,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC;QACpD,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;KAClD,CAAC,CAAA;IACF,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAA;IAEnD,2CAA2C;IAC3C,IAAI,MAAM,GAAU,EAAE,CAAA;IACtB,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC9E,MAAM,IAAA,uDAA4B,EAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC7D,MAAM,SAAS,GAAG,MAAM,IAAA,qBAAa,EAAC,qBAAW,CAAC,CAAC,IAAI,CAAC;QACtD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;QACtE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KACxC,CAAC,CAAA;IACF,MAAM,GAAG,SAAS;SACf,GAAG,CAAC,OAAO,CAAC,EAAE;QACb,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3D,OAAO;gBACL,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;gBACxC,GAAG,EAAE;oBACH,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB;aACF,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,mDAAmD;IACnD,uFAAuF;IACvF,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAa,EAAC,SAAG,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;IACxG,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IAEzF,yCAAyC;IACzC,MAAM,WAAW,GAAG,EAAE,CAAA;IACtB,MAAM,eAAe,GAAG,IAAA,qBAAa,EAAC,2BAAW,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACrE,MAAM,YAAY,GAAG,IAAA,qBAAa,EAAC,oBAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAE/D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAA;QACxB,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAA;QACrB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAA;QACrB,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC;YAAE,SAAQ;QAE3C,uBAAuB;QACvB,IAAI,WAAW,GAAuB,IAAI,CAAA;QAE1C,uBAAuB;QACvB,MAAM,aAAa,GACjB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACrG,aAAa,CAAA;QAEf,oCAAoC;QACpC,WAAW,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC;YAC1C,KAAK,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;SAC/D,CAAC,CAAA;QAEF,YAAY;QACZ,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC;gBACvC,UAAU,EAAE,aAAa,EAAE,2BAA2B;gBACtD,QAAQ,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;gBAChF,UAAU,EAAE,aAAa;gBACzB,GAAG,EAAE,aAAa,EAAE,eAAe;gBACnC,OAAO,EAAE,OAAO,CAAC,KAAK;gBACtB,OAAO,EAAE,OAAO,CAAC,KAAK;gBACtB,OAAO,EAAE,OAAO,CAAC,KAAK;gBACtB,OAAO,EAAE,OAAO,CAAC,KAAK;gBACtB,OAAO,EAAE,OAAO,CAAC,KAAK;gBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI;gBAC5B,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI;aAC7B,CAAC,CAAA;QACJ,CAAC;QAED,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC;YAC1C,KAAK,EAAE;gBACL,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE;gBACnB,SAAS;gBACT,WAAW,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE;gBACnC,OAAO;gBACP,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;aACzB;SACF,CAAC,CAAA;QAEF,IAAI,MAAM,GAAG,QAAQ,IAAI,YAAY,CAAC,MAAM,EAAE,CAAA;QAC9C,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA;QAChB,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAA;QACrB,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;QACxB,MAAM,CAAC,SAAS,GAAG,SAAS,CAAA;QAC5B,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;QACpB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAA;QAChC,MAAM,CAAC,aAAa,GAAG,WAAW,CAAC,EAAE,CAAA;QACrC,MAAM,CAAC,SAAS,GAAG,6BAAiB,CAAC,IAAI,CAAA;QACzC,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAA;QAChC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;QAC1B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAA;QACpC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAA;QACpC,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACxC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC1B,CAAC;IACD,OAAO,WAAW,CAAA;AACpB,CAAC","sourcesContent":["import { getRepository } from '@things-factory/shell'\nimport type ResolverContext from '@things-factory/auth-base'\nimport { DataSummary } from '@things-factory/dataset'\nimport { finalizeLatestDataCollection } from '@things-factory/dataset/dist-server/controllers/finalize-data-collection'\nimport { KpiMetric } from './kpi-metric'\nimport { KpiValue, KpiValueInputType } from '../kpi-value/kpi-value'\nimport { Kpi } from '../kpi/kpi'\nimport { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope'\nimport { KpiFormulaService } from '../kpi/kpi-formula.service'\n\n/**\n * KPI-Metric 집계/자동화 서비스 함수 (formula 지원, KPI Value 저장)\n * @param metricId KPI-Metric ID\n * @param domainId 도메인 ID\n * @param context ResolverContext (state에 domain, user, tx 등 포함)\n * @returns 저장된 KPI Value 배열\n */\nexport async function aggregateKpiMetricValue(metricId: string, domainId: string, context: ResolverContext) {\n const tx = context.state?.tx || getRepository(KpiMetric).manager\n\n // 1. metric 정보 조회\n const metric = await getRepository(KpiMetric).findOne({\n where: { id: metricId, domain: { id: domainId } }\n })\n if (!metric) throw new Error('Metric 정보 없음')\n if (!metric.active) throw new Error('비활성화된 Metric')\n\n // formula 분기 제거: metric은 항상 dataset 집계만 수행\n let values: any[] = []\n if (!metric.dataSetId || !metric.fieldName) throw new Error('Metric 매핑 정보 누락')\n await finalizeLatestDataCollection(metric.dataSetId, context)\n const summaries = await getRepository(DataSummary).find({\n where: { dataSet: { id: metric.dataSetId }, domain: { id: domainId } },\n order: { date: 'DESC', period: 'DESC' }\n })\n values = summaries\n .map(summary => {\n if (summary.summary && metric.fieldName in summary.summary) {\n return {\n date: summary.date,\n period: summary.period,\n value: summary.summary[metric.fieldName],\n org: {\n key01: summary.key01,\n key02: summary.key02,\n key03: summary.key03,\n key04: summary.key04,\n key05: summary.key05\n }\n }\n }\n return null\n })\n .filter(Boolean)\n\n // 5. KPI Value로 저장 (metric 단위, KPI 단위 formula는 후속)\n // metric이 속한 KPI 정보 조회 (여기서는 metric.name == kpi.name인 KPI를 임시로 매핑, 실제 연동 구조에 맞게 보완 필요)\n const kpi = await getRepository(Kpi).findOne({ where: { name: metric.name, domain: { id: domainId } } })\n if (!kpi) throw new Error('KPI 정보 없음 (metric.name과 동일한 KPI name 기준, 실제 연동 구조에 맞게 보완 필요)')\n\n // KPI Value version, valueDate, org 등 매핑\n const savedValues = []\n const kpiOrgScopeRepo = getRepository(KpiOrgScope, context.state?.tx)\n const kpiValueRepo = getRepository(KpiValue, context.state?.tx)\n\n for (const v of values) {\n const valueDate = v.date\n const orgData = v.org\n const version = kpi.version || 1\n const value = v.value\n if (value == null || isNaN(value)) continue\n\n // KpiOrgScope 찾기 또는 생성\n let kpiOrgScope: KpiOrgScope | null = null\n\n // key들로 조합된 org 식별자 생성\n const orgIdentifier =\n [orgData.key01, orgData.key02, orgData.key03, orgData.key04, orgData.key05].filter(Boolean).join('-') ||\n 'unknown-org'\n\n // 기존 KpiOrgScope 조회 (entityName 기준)\n kpiOrgScope = await kpiOrgScopeRepo.findOne({\n where: { entityName: orgIdentifier, domain: { id: domainId } }\n })\n\n // 없으면 새로 생성\n if (!kpiOrgScope) {\n kpiOrgScope = await kpiOrgScopeRepo.save({\n entityType: 'DataSummary', // DataSummary에서 온 데이터임을 표시\n entityId: `datasummary-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n entityName: orgIdentifier,\n org: orgIdentifier, // legacy field\n scope01: orgData.key01,\n scope02: orgData.key02,\n scope03: orgData.key03,\n scope04: orgData.key04,\n scope05: orgData.key05,\n domain: kpi.domain,\n creator: context.state?.user,\n updater: context.state?.user\n })\n }\n\n // upsert KpiValue (동일 KPI, valueDate, kpiOrgScope, version 기준)\n const existing = await kpiValueRepo.findOne({\n where: {\n kpi: { id: kpi.id },\n valueDate,\n kpiOrgScope: { id: kpiOrgScope.id },\n version,\n domain: { id: domainId }\n }\n })\n\n let entity = existing || kpiValueRepo.create()\n entity.kpi = kpi\n entity.kpiId = kpi.id\n entity.version = version\n entity.valueDate = valueDate\n entity.value = value\n entity.kpiOrgScope = kpiOrgScope\n entity.kpiOrgScopeId = kpiOrgScope.id\n entity.inputType = KpiValueInputType.AUTO\n entity.source = 'AUTO-AGGREGATE'\n entity.domain = kpi.domain\n entity.creator = context.state?.user\n entity.updater = context.state?.user\n entity = await kpiValueRepo.save(entity)\n savedValues.push(entity)\n }\n return savedValues\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { KpiMetric } from './kpi-metric';
2
+ import { KpiMetricQuery } from './kpi-metric-query';
3
+ import { KpiMetricMutation } from './kpi-metric-mutation';
4
+ export declare const entities: (typeof KpiMetric)[];
5
+ export declare const resolvers: (typeof KpiMetricQuery | typeof KpiMetricMutation)[];
6
+ export declare const subscribers: any[];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.subscribers = exports.resolvers = exports.entities = void 0;
4
+ const kpi_metric_1 = require("./kpi-metric");
5
+ const kpi_metric_query_1 = require("./kpi-metric-query");
6
+ const kpi_metric_mutation_1 = require("./kpi-metric-mutation");
7
+ exports.entities = [kpi_metric_1.KpiMetric];
8
+ exports.resolvers = [kpi_metric_query_1.KpiMetricQuery, kpi_metric_mutation_1.KpiMetricMutation];
9
+ exports.subscribers = [];
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/index.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AACxC,yDAAmD;AACnD,+DAAyD;AAE5C,QAAA,QAAQ,GAAG,CAAC,sBAAS,CAAC,CAAA;AACtB,QAAA,SAAS,GAAG,CAAC,iCAAc,EAAE,uCAAiB,CAAC,CAAA;AAC/C,QAAA,WAAW,GAAG,EAAE,CAAA","sourcesContent":["import { KpiMetric } from './kpi-metric'\nimport { KpiMetricQuery } from './kpi-metric-query'\nimport { KpiMetricMutation } from './kpi-metric-mutation'\n\nexport const entities = [KpiMetric]\nexport const resolvers = [KpiMetricQuery, KpiMetricMutation]\nexport const subscribers = []\n"]}
@@ -0,0 +1,46 @@
1
+ export type InputWidget = 'number' | 'rating' | 'select' | 'date' | 'text' | 'toggle';
2
+ /** 값 입력 위젯/검증 힌트. */
3
+ export interface InputHint {
4
+ widget: InputWidget;
5
+ min?: number;
6
+ max?: number;
7
+ step?: number;
8
+ options?: {
9
+ value: string | number;
10
+ label: string;
11
+ }[];
12
+ required?: boolean;
13
+ decimals?: number;
14
+ /** 파생/자동수집 값 등 사용자 입력 불가. 미지정이면 collectType=AUTO 에서 추론. */
15
+ readonly?: boolean;
16
+ /** '계획값 vs 실제값' 2열 여부. */
17
+ hasPlan?: boolean;
18
+ placeholder?: string;
19
+ default?: any;
20
+ }
21
+ /** metric ↔ 소스 바인딩 (값이 어디서 오는지). */
22
+ export interface SourceBinding {
23
+ type: 'entityField' | 'dataset' | 'external' | 'manual';
24
+ entity?: string;
25
+ field?: string;
26
+ datasetId?: string;
27
+ }
28
+ export interface KpiMetricMeta {
29
+ input?: InputHint;
30
+ /** 고정속성(attribute) vs 시계열 성과(performance). */
31
+ kind?: 'attribute' | 'performance';
32
+ source?: SourceBinding;
33
+ /** 향후 확장(display/validation/collection …) */
34
+ [key: string]: any;
35
+ }
36
+ /**
37
+ * metric 의 "효과적 입력 힌트" 를 결정한다.
38
+ * - meta.input 이 있으면 그것을 기본값과 함께 사용
39
+ * - 없으면 안전 폴백(number). **이름 추측 금지.**
40
+ * - readonly: 명시값 우선(false 도 존중), 미지정이면 AUTO 수집이면 true
41
+ * - rating: max 기본 5, step 기본 1
42
+ */
43
+ export declare function resolveInputHint(metric: {
44
+ meta?: KpiMetricMeta | null;
45
+ collectType?: string;
46
+ } | null | undefined): InputHint;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ // KpiMetric.meta 타입 + 순수 헬퍼 (shell/DB 무관 — 단위 테스트 용이)
3
+ //
4
+ // meta 는 metric 의 확장 네임스페이스. 용도별 최상위 키(input/kind/source…)로
5
+ // 스키마 재변경 없이 확장한다. (형제 엔티티 Kpi.vizMeta / KpiValue.meta 와 동일 패턴)
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.resolveInputHint = resolveInputHint;
8
+ /**
9
+ * metric 의 "효과적 입력 힌트" 를 결정한다.
10
+ * - meta.input 이 있으면 그것을 기본값과 함께 사용
11
+ * - 없으면 안전 폴백(number). **이름 추측 금지.**
12
+ * - readonly: 명시값 우선(false 도 존중), 미지정이면 AUTO 수집이면 true
13
+ * - rating: max 기본 5, step 기본 1
14
+ */
15
+ function resolveInputHint(metric) {
16
+ const isAuto = metric?.collectType === 'AUTO';
17
+ const hint = metric?.meta?.input;
18
+ if (hint?.widget) {
19
+ const readonly = hint.readonly ?? isAuto;
20
+ if (hint.widget === 'rating') {
21
+ return { ...hint, max: hint.max ?? 5, step: hint.step ?? 1, readonly };
22
+ }
23
+ return { ...hint, readonly };
24
+ }
25
+ return { widget: 'number', readonly: isAuto };
26
+ }
27
+ //# sourceMappingURL=kpi-metric-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-metric-meta.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric-meta.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,EAAE;AACF,4DAA4D;AAC5D,gEAAgE;;AA6ChE,4CAeC;AAtBD;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAC9B,MAAgF;IAEhF,MAAM,MAAM,GAAG,MAAM,EAAE,WAAW,KAAK,MAAM,CAAA;IAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,CAAA;IAEhC,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAA;QACxC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;QACxE,CAAC;QACD,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAA;IAC9B,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AAC/C,CAAC","sourcesContent":["// KpiMetric.meta 타입 + 순수 헬퍼 (shell/DB 무관 — 단위 테스트 용이)\n//\n// meta 는 metric 의 확장 네임스페이스. 용도별 최상위 키(input/kind/source…)로\n// 스키마 재변경 없이 확장한다. (형제 엔티티 Kpi.vizMeta / KpiValue.meta 와 동일 패턴)\n\nexport type InputWidget = 'number' | 'rating' | 'select' | 'date' | 'text' | 'toggle'\n\n/** 값 입력 위젯/검증 힌트. */\nexport interface InputHint {\n widget: InputWidget\n min?: number\n max?: number\n step?: number\n options?: { value: string | number; label: string }[]\n required?: boolean\n decimals?: number\n /** 파생/자동수집 값 등 사용자 입력 불가. 미지정이면 collectType=AUTO 에서 추론. */\n readonly?: boolean\n /** '계획값 vs 실제값' 2열 여부. */\n hasPlan?: boolean\n placeholder?: string\n default?: any\n}\n\n/** metric ↔ 소스 바인딩 (값이 어디서 오는지). */\nexport interface SourceBinding {\n type: 'entityField' | 'dataset' | 'external' | 'manual'\n entity?: string\n field?: string\n datasetId?: string\n}\n\nexport interface KpiMetricMeta {\n input?: InputHint\n /** 고정속성(attribute) vs 시계열 성과(performance). */\n kind?: 'attribute' | 'performance'\n source?: SourceBinding\n /** 향후 확장(display/validation/collection …) */\n [key: string]: any\n}\n\n/**\n * metric 의 \"효과적 입력 힌트\" 를 결정한다.\n * - meta.input 이 있으면 그것을 기본값과 함께 사용\n * - 없으면 안전 폴백(number). **이름 추측 금지.**\n * - readonly: 명시값 우선(false 도 존중), 미지정이면 AUTO 수집이면 true\n * - rating: max 기본 5, step 기본 1\n */\nexport function resolveInputHint(\n metric: { meta?: KpiMetricMeta | null; collectType?: string } | null | undefined\n): InputHint {\n const isAuto = metric?.collectType === 'AUTO'\n const hint = metric?.meta?.input\n\n if (hint?.widget) {\n const readonly = hint.readonly ?? isAuto\n if (hint.widget === 'rating') {\n return { ...hint, max: hint.max ?? 5, step: hint.step ?? 1, readonly }\n }\n return { ...hint, readonly }\n }\n\n return { widget: 'number', readonly: isAuto }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const kpi_metric_meta_1 = require("./kpi-metric-meta");
4
+ describe('resolveInputHint (순수)', () => {
5
+ it('meta 없음 → number 폴백 (이름추측 없음)', () => {
6
+ expect((0, kpi_metric_meta_1.resolveInputHint)(null)).toEqual({ widget: 'number', readonly: false });
7
+ expect((0, kpi_metric_meta_1.resolveInputHint)({})).toEqual({ widget: 'number', readonly: false });
8
+ });
9
+ it('meta 없고 collectType AUTO → number + readonly', () => {
10
+ expect((0, kpi_metric_meta_1.resolveInputHint)({ collectType: 'AUTO' })).toEqual({ widget: 'number', readonly: true });
11
+ });
12
+ it('rating: max/step 기본값(5/1) 채움', () => {
13
+ expect((0, kpi_metric_meta_1.resolveInputHint)({ meta: { input: { widget: 'rating' } } })).toEqual({
14
+ widget: 'rating',
15
+ max: 5,
16
+ step: 1,
17
+ readonly: false
18
+ });
19
+ });
20
+ it('rating: 명시 step(0.5)·max 는 존중', () => {
21
+ const r = (0, kpi_metric_meta_1.resolveInputHint)({ meta: { input: { widget: 'rating', max: 10, step: 0.5 } } });
22
+ expect(r.max).toBe(10);
23
+ expect(r.step).toBe(0.5);
24
+ });
25
+ it('number: min/max passthrough + AUTO 면 readonly', () => {
26
+ expect((0, kpi_metric_meta_1.resolveInputHint)({ collectType: 'AUTO', meta: { input: { widget: 'number', min: 0, max: 100 } } })).toEqual({
27
+ widget: 'number',
28
+ min: 0,
29
+ max: 100,
30
+ readonly: true
31
+ });
32
+ });
33
+ it('readonly 명시값(false) 은 AUTO 라도 존중 (false 가 우선)', () => {
34
+ const r = (0, kpi_metric_meta_1.resolveInputHint)({ collectType: 'AUTO', meta: { input: { widget: 'number', readonly: false } } });
35
+ expect(r.readonly).toBe(false);
36
+ });
37
+ it('select: options passthrough', () => {
38
+ const r = (0, kpi_metric_meta_1.resolveInputHint)({ meta: { input: { widget: 'select', options: [{ value: 'A', label: 'A' }] } } });
39
+ expect(r.widget).toBe('select');
40
+ expect(r.options).toEqual([{ value: 'A', label: 'A' }]);
41
+ });
42
+ });
43
+ //# sourceMappingURL=kpi-metric-meta.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-metric-meta.test.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric-meta.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveInputHint } from './kpi-metric-meta'\n\ndescribe('resolveInputHint (순수)', () => {\n it('meta 없음 → number 폴백 (이름추측 없음)', () => {\n expect(resolveInputHint(null)).toEqual({ widget: 'number', readonly: false })\n expect(resolveInputHint({})).toEqual({ widget: 'number', readonly: false })\n })\n\n it('meta 없고 collectType AUTO → number + readonly', () => {\n expect(resolveInputHint({ collectType: 'AUTO' })).toEqual({ widget: 'number', readonly: true })\n })\n\n it('rating: max/step 기본값(5/1) 채움', () => {\n expect(resolveInputHint({ meta: { input: { widget: 'rating' } } })).toEqual({\n widget: 'rating',\n max: 5,\n step: 1,\n readonly: false\n })\n })\n\n it('rating: 명시 step(0.5)·max 는 존중', () => {\n const r = resolveInputHint({ meta: { input: { widget: 'rating', max: 10, step: 0.5 } } })\n expect(r.max).toBe(10)\n expect(r.step).toBe(0.5)\n })\n\n it('number: min/max passthrough + AUTO 면 readonly', () => {\n expect(resolveInputHint({ collectType: 'AUTO', meta: { input: { widget: 'number', min: 0, max: 100 } } })).toEqual({\n widget: 'number',\n min: 0,\n max: 100,\n readonly: true\n })\n })\n\n it('readonly 명시값(false) 은 AUTO 라도 존중 (false 가 우선)', () => {\n const r = resolveInputHint({ collectType: 'AUTO', meta: { input: { widget: 'number', readonly: false } } })\n expect(r.readonly).toBe(false)\n })\n\n it('select: options passthrough', () => {\n const r = resolveInputHint({ meta: { input: { widget: 'select', options: [{ value: 'A', label: 'A' }] } } })\n expect(r.widget).toBe('select')\n expect(r.options).toEqual([{ value: 'A', label: 'A' }])\n })\n})\n"]}
@@ -0,0 +1,10 @@
1
+ import { KpiMetric } from './kpi-metric';
2
+ import { NewKpiMetric, KpiMetricPatch } from './kpi-metric-type';
3
+ export declare class KpiMetricMutation {
4
+ createKpiMetric(kpiMetric: NewKpiMetric, context: ResolverContext): Promise<KpiMetric>;
5
+ updateKpiMetric(id: string, patch: KpiMetricPatch, context: ResolverContext): Promise<KpiMetric>;
6
+ updateMultipleKpiMetric(patches: KpiMetricPatch[], context: ResolverContext): Promise<KpiMetric[]>;
7
+ deleteKpiMetric(id: string, context: ResolverContext): Promise<boolean>;
8
+ deleteKpiMetrics(ids: string[], context: ResolverContext): Promise<boolean>;
9
+ importKpiMetrics(kpiMetrics: KpiMetricPatch[], context: ResolverContext): Promise<boolean>;
10
+ }