@things-factory/kpi 9.0.31 → 9.0.33

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 (365) hide show
  1. package/README.md +1 -2
  2. package/client/charts/kpi-boxplot-chart.ts +182 -42
  3. package/client/charts/kpi-radar-chart.ts +9 -9
  4. package/client/pages/kpi/kpi-list-page.ts +196 -32
  5. package/client/pages/kpi/kpi-overview.ts +9 -11
  6. package/client/pages/kpi/kpi-tree-page.ts +409 -0
  7. package/client/pages/kpi/kpi-view.ts +187 -0
  8. package/client/pages/kpi-dashboard/cards/kpi-level1-card.ts +1 -1
  9. package/client/pages/kpi-dashboard/cards/kpi-level2-comparison.ts +1 -1
  10. package/client/pages/kpi-dashboard/cards/kpi-level3-comparison.ts +1 -1
  11. package/client/pages/kpi-dashboard/components/kpi-left-panel.ts +198 -160
  12. package/client/pages/kpi-dashboard/components/kpi-map-panel.ts +133 -0
  13. package/client/pages/kpi-dashboard/components/kpi-region-popup.ts +3 -2
  14. package/client/pages/kpi-dashboard/kpi-dashboard-map.ts +291 -48
  15. package/client/pages/kpi-dashboard/kpi-dashboard.ts +28 -30
  16. package/client/pages/kpi-history/kpi-history-list-page.ts +11 -11
  17. package/client/pages/kpi-metric/kpi-metric-list-page.ts +10 -2
  18. package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +7 -7
  19. package/client/pages/kpi-metric-value/kpi-metric-value-importer.ts +2 -2
  20. package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +16 -8
  21. package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.ts +5 -5
  22. package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +1 -2
  23. package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +10 -2
  24. package/client/pages/kpi-value/kpi-value-editor-page.ts +11 -7
  25. package/client/pages/kpi-value/kpi-value-list-page.ts +31 -7
  26. package/client/route.ts +2 -9
  27. package/design-entities.md +8 -12
  28. package/dist-client/charts/kpi-boxplot-chart.d.ts +2 -0
  29. package/dist-client/charts/kpi-boxplot-chart.js +168 -42
  30. package/dist-client/charts/kpi-boxplot-chart.js.map +1 -1
  31. package/dist-client/charts/kpi-radar-chart.js +9 -9
  32. package/dist-client/charts/kpi-radar-chart.js.map +1 -1
  33. package/dist-client/pages/kpi/kpi-list-page.d.ts +19 -3
  34. package/dist-client/pages/kpi/kpi-list-page.js +188 -32
  35. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
  36. package/dist-client/pages/kpi/kpi-overview.js +9 -11
  37. package/dist-client/pages/kpi/kpi-overview.js.map +1 -1
  38. package/dist-client/pages/kpi/kpi-tree-page.d.ts +59 -0
  39. package/dist-client/pages/kpi/kpi-tree-page.js +403 -0
  40. package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -0
  41. package/dist-client/pages/kpi/kpi-view.d.ts +12 -0
  42. package/dist-client/pages/kpi/kpi-view.js +191 -0
  43. package/dist-client/pages/kpi/kpi-view.js.map +1 -0
  44. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js +1 -1
  45. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js.map +1 -1
  46. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js +1 -1
  47. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js.map +1 -1
  48. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js +1 -1
  49. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js.map +1 -1
  50. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +3 -1
  51. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +197 -161
  52. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -1
  53. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +5 -0
  54. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +146 -0
  55. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
  56. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +3 -2
  57. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -1
  58. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +3 -1
  59. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +268 -46
  60. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
  61. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +28 -30
  62. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -1
  63. package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +6 -1
  64. package/dist-client/pages/kpi-history/kpi-history-list-page.js +11 -11
  65. package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -1
  66. package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +5 -0
  67. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +10 -2
  68. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
  69. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -1
  70. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +8 -8
  71. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
  72. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js +2 -2
  73. package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js.map +1 -1
  74. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +5 -0
  75. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +16 -8
  76. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  77. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.d.ts +1 -1
  78. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +6 -6
  79. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -1
  80. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +1 -2
  81. package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -1
  82. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +5 -0
  83. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +10 -2
  84. package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -1
  85. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +2 -1
  86. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +16 -8
  87. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -1
  88. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +5 -0
  89. package/dist-client/pages/kpi-value/kpi-value-list-page.js +31 -7
  90. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  91. package/dist-client/route.d.ts +1 -1
  92. package/dist-client/route.js +2 -8
  93. package/dist-client/route.js.map +1 -1
  94. package/dist-client/tsconfig.tsbuildinfo +1 -1
  95. package/dist-server/controllers/kpi-metric-value-provider.d.ts +1 -1
  96. package/dist-server/controllers/kpi-metric-value-provider.js +4 -4
  97. package/dist-server/controllers/kpi-metric-value-provider.js.map +1 -1
  98. package/dist-server/controllers/kpi-value-provider.d.ts +1 -1
  99. package/dist-server/controllers/kpi-value-provider.js +3 -3
  100. package/dist-server/controllers/kpi-value-provider.js.map +1 -1
  101. package/dist-server/migrations/1752190849680-seed-kpi-metrics.d.ts +6 -0
  102. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js +101 -0
  103. package/dist-server/migrations/1752190849680-seed-kpi-metrics.js.map +1 -0
  104. package/dist-server/migrations/1752190849681-seed-kpi.d.ts +5 -0
  105. package/dist-server/migrations/1752190849681-seed-kpi.js +315 -0
  106. package/dist-server/migrations/1752190849681-seed-kpi.js.map +1 -0
  107. package/dist-server/migrations/1752192090123-add-grades-to-kpi.d.ts +7 -0
  108. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js +51 -0
  109. package/dist-server/migrations/1752192090123-add-grades-to-kpi.js.map +1 -0
  110. package/dist-server/migrations/1752192090124-add-kpi-statistics.d.ts +5 -0
  111. package/dist-server/migrations/1752192090124-add-kpi-statistics.js +710 -0
  112. package/dist-server/migrations/1752192090124-add-kpi-statistics.js.map +1 -0
  113. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.d.ts +6 -0
  114. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js +111 -0
  115. package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js.map +1 -0
  116. package/dist-server/migrations/1752192090129-seed-kpi-values.d.ts +6 -0
  117. package/dist-server/migrations/1752192090129-seed-kpi-values.js +187 -0
  118. package/dist-server/migrations/1752192090129-seed-kpi-values.js.map +1 -0
  119. package/dist-server/migrations/grade-data/x11-performance-table.json +962 -0
  120. package/dist-server/migrations/grade-data/x12-performance-table.json +611 -0
  121. package/dist-server/migrations/grade-data/x14-performance-table.json +42 -0
  122. package/dist-server/migrations/grade-data/x21-performance-table.json +889 -0
  123. package/dist-server/migrations/grade-data/x22-performance-table.json +1064 -0
  124. package/dist-server/migrations/grade-data/x23-performance-table.json +42 -0
  125. package/dist-server/migrations/grade-data/x31-performance-table.json +644 -0
  126. package/dist-server/migrations/grade-data/x32-performance-table.json +993 -0
  127. package/dist-server/migrations/grade-data/x33-performance-table.json +195 -0
  128. package/dist-server/migrations/grade-data/x34-performance-table.json +12 -0
  129. package/dist-server/migrations/grade-data/x35-performance-table.json +42 -0
  130. package/dist-server/migrations/grade-data/x41-performance-table.json +825 -0
  131. package/dist-server/migrations/grade-data/x42-performance-table.json +786 -0
  132. package/dist-server/migrations/grade-data/x43-performance-table.json +12 -0
  133. package/dist-server/migrations/grade-data/x44-performance-table.json +42 -0
  134. package/dist-server/migrations/grade-data/x51-performance-table.json +924 -0
  135. package/dist-server/migrations/grade-data/x52-performance-table.json +42 -0
  136. package/dist-server/migrations/grade-data/x61-performance-table.json +261 -0
  137. package/dist-server/migrations/grade-data/x62-performance-table.json +42 -0
  138. package/dist-server/migrations/seed-data/kpi-metrics-seed.json +454 -0
  139. package/dist-server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
  140. package/dist-server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  141. package/dist-server/migrations/seed-data/kpi-values-seed.json +402 -0
  142. package/dist-server/migrations/seed-data/kpis-seed.json +488 -0
  143. package/dist-server/migrations/seed-data/scope-definitions-seed.json +90 -0
  144. package/dist-server/service/index.d.ts +4 -7
  145. package/dist-server/service/index.js +10 -13
  146. package/dist-server/service/index.js.map +1 -1
  147. package/dist-server/service/kpi/aggregate-kpi.js +30 -13
  148. package/dist-server/service/kpi/aggregate-kpi.js.map +1 -1
  149. package/dist-server/service/kpi/kpi-formula.service.d.ts +15 -0
  150. package/dist-server/service/kpi/kpi-formula.service.js +90 -0
  151. package/dist-server/service/kpi/kpi-formula.service.js.map +1 -1
  152. package/dist-server/service/kpi/kpi-history.d.ts +0 -3
  153. package/dist-server/service/kpi/kpi-history.js +0 -10
  154. package/dist-server/service/kpi/kpi-history.js.map +1 -1
  155. package/dist-server/service/kpi/kpi-mutation.d.ts +1 -1
  156. package/dist-server/service/kpi/kpi-mutation.js +57 -20
  157. package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
  158. package/dist-server/service/kpi/kpi-query.d.ts +7 -3
  159. package/dist-server/service/kpi/kpi-query.js +126 -10
  160. package/dist-server/service/kpi/kpi-query.js.map +1 -1
  161. package/dist-server/service/kpi/kpi-type.d.ts +4 -2
  162. package/dist-server/service/kpi/kpi-type.js +12 -4
  163. package/dist-server/service/kpi/kpi-type.js.map +1 -1
  164. package/dist-server/service/kpi/kpi.d.ts +4 -3
  165. package/dist-server/service/kpi/kpi.js +20 -8
  166. package/dist-server/service/kpi/kpi.js.map +1 -1
  167. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +46 -11
  168. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -1
  169. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +1 -1
  170. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +6 -6
  171. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  172. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.d.ts +2 -2
  173. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js +4 -4
  174. package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js.map +1 -1
  175. package/dist-server/service/kpi-metric-value/kpi-metric-value.d.ts +1 -1
  176. package/dist-server/service/kpi-metric-value/kpi-metric-value.js +3 -3
  177. package/dist-server/service/kpi-metric-value/kpi-metric-value.js.map +1 -1
  178. package/dist-server/service/kpi-org-scope/index.d.ts +5 -0
  179. package/dist-server/service/kpi-org-scope/index.js +9 -0
  180. package/dist-server/service/kpi-org-scope/index.js.map +1 -0
  181. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.d.ts +8 -0
  182. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js +170 -0
  183. package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js.map +1 -0
  184. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.d.ts +14 -0
  185. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js +152 -0
  186. package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js.map +1 -0
  187. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.d.ts +26 -0
  188. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js +101 -0
  189. package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js.map +1 -0
  190. package/dist-server/service/kpi-org-scope/kpi-org-scope.d.ts +26 -0
  191. package/dist-server/service/kpi-org-scope/kpi-org-scope.js +135 -0
  192. package/dist-server/service/kpi-org-scope/kpi-org-scope.js.map +1 -0
  193. package/dist-server/service/kpi-scope/index.d.ts +9 -0
  194. package/dist-server/service/kpi-scope/index.js +14 -0
  195. package/dist-server/service/kpi-scope/index.js.map +1 -0
  196. package/dist-server/service/kpi-scope/kpi-scope-mutation.d.ts +9 -0
  197. package/dist-server/service/kpi-scope/kpi-scope-mutation.js +135 -0
  198. package/dist-server/service/kpi-scope/kpi-scope-mutation.js.map +1 -0
  199. package/dist-server/service/kpi-scope/kpi-scope-query.d.ts +11 -0
  200. package/dist-server/service/kpi-scope/kpi-scope-query.js +89 -0
  201. package/dist-server/service/kpi-scope/kpi-scope-query.js.map +1 -0
  202. package/dist-server/service/kpi-scope/kpi-scope-type.d.ts +35 -0
  203. package/dist-server/service/kpi-scope/kpi-scope-type.js +138 -0
  204. package/dist-server/service/kpi-scope/kpi-scope-type.js.map +1 -0
  205. package/dist-server/service/kpi-scope/kpi-scope.d.ts +38 -0
  206. package/dist-server/service/kpi-scope/kpi-scope.js +144 -0
  207. package/dist-server/service/kpi-scope/kpi-scope.js.map +1 -0
  208. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.d.ts +43 -0
  209. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js +181 -0
  210. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js.map +1 -0
  211. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.d.ts +50 -0
  212. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js +324 -0
  213. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js.map +1 -0
  214. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +4 -0
  215. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +76 -0
  216. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -1
  217. package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +5 -1
  218. package/dist-server/service/kpi-statistic/kpi-statistic-query.js +92 -1
  219. package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -1
  220. package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +4 -0
  221. package/dist-server/service/kpi-statistic/kpi-statistic.js +33 -0
  222. package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -1
  223. package/dist-server/service/kpi-value/kpi-value-mutation.js +71 -7
  224. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
  225. package/dist-server/service/kpi-value/kpi-value-type.d.ts +4 -2
  226. package/dist-server/service/kpi-value/kpi-value-type.js +12 -4
  227. package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -1
  228. package/dist-server/service/kpi-value/kpi-value.d.ts +3 -1
  229. package/dist-server/service/kpi-value/kpi-value.js +11 -5
  230. package/dist-server/service/kpi-value/kpi-value.js.map +1 -1
  231. package/dist-server/service/utils/value-date-util.d.ts +1 -0
  232. package/dist-server/service/utils/value-date-util.js +41 -0
  233. package/dist-server/service/utils/value-date-util.js.map +1 -1
  234. package/dist-server/tsconfig.json +10 -0
  235. package/dist-server/tsconfig.tsbuildinfo +1 -1
  236. package/package.json +7 -6
  237. package/server/@types/index.d.ts +11 -0
  238. package/server/controllers/kpi-metric-value-provider.ts +5 -5
  239. package/server/controllers/kpi-value-provider.ts +4 -4
  240. package/server/migrations/1752190849680-seed-kpi-metrics.ts +124 -0
  241. package/server/migrations/1752190849681-seed-kpi.ts +356 -0
  242. package/server/migrations/1752192090123-add-grades-to-kpi.ts +67 -0
  243. package/server/migrations/1752192090124-add-kpi-statistics.ts +719 -0
  244. package/server/migrations/1752192090128-seed-kpi-org-scope.ts +132 -0
  245. package/server/migrations/1752192090129-seed-kpi-values.ts +207 -0
  246. package/server/migrations/grade-data/x11-performance-table.json +962 -0
  247. package/server/migrations/grade-data/x12-performance-table.json +611 -0
  248. package/server/migrations/grade-data/x14-performance-table.json +42 -0
  249. package/server/migrations/grade-data/x21-performance-table.json +889 -0
  250. package/server/migrations/grade-data/x22-performance-table.json +1064 -0
  251. package/server/migrations/grade-data/x23-performance-table.json +42 -0
  252. package/server/migrations/grade-data/x31-performance-table.json +644 -0
  253. package/server/migrations/grade-data/x32-performance-table.json +993 -0
  254. package/server/migrations/grade-data/x33-performance-table.json +195 -0
  255. package/server/migrations/grade-data/x34-performance-table.json +12 -0
  256. package/server/migrations/grade-data/x35-performance-table.json +42 -0
  257. package/server/migrations/grade-data/x41-performance-table.json +825 -0
  258. package/server/migrations/grade-data/x42-performance-table.json +786 -0
  259. package/server/migrations/grade-data/x43-performance-table.json +12 -0
  260. package/server/migrations/grade-data/x44-performance-table.json +42 -0
  261. package/server/migrations/grade-data/x51-performance-table.json +924 -0
  262. package/server/migrations/grade-data/x52-performance-table.json +42 -0
  263. package/server/migrations/grade-data/x61-performance-table.json +261 -0
  264. package/server/migrations/grade-data/x62-performance-table.json +42 -0
  265. package/server/migrations/seed-data/kpi-metrics-seed.json +454 -0
  266. package/server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
  267. package/server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  268. package/server/migrations/seed-data/kpi-values-seed.json +402 -0
  269. package/server/migrations/seed-data/kpis-seed.json +488 -0
  270. package/server/migrations/seed-data/scope-definitions-seed.json +90 -0
  271. package/server/service/index.ts +10 -13
  272. package/server/service/kpi/aggregate-kpi.ts +31 -13
  273. package/server/service/kpi/kpi-formula.service.ts +101 -0
  274. package/server/service/kpi/kpi-history.ts +0 -8
  275. package/server/service/kpi/kpi-mutation.ts +59 -19
  276. package/server/service/kpi/kpi-query.ts +119 -8
  277. package/server/service/kpi/kpi-type.ts +10 -4
  278. package/server/service/kpi/kpi.ts +17 -7
  279. package/server/service/kpi-metric/aggregate-kpi-metric.ts +55 -11
  280. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +6 -6
  281. package/server/service/kpi-metric-value/kpi-metric-value-type.ts +4 -4
  282. package/server/service/kpi-metric-value/kpi-metric-value.ts +3 -3
  283. package/server/service/kpi-org-scope/index.ts +6 -0
  284. package/server/service/kpi-org-scope/kpi-org-scope-mutation.ts +173 -0
  285. package/server/service/kpi-org-scope/kpi-org-scope-query.ts +127 -0
  286. package/server/service/kpi-org-scope/kpi-org-scope-type.ts +68 -0
  287. package/server/service/kpi-org-scope/kpi-org-scope.ts +123 -0
  288. package/server/service/kpi-scope/index.ts +11 -0
  289. package/server/service/kpi-scope/kpi-scope-mutation.ts +129 -0
  290. package/server/service/kpi-scope/kpi-scope-query.ts +63 -0
  291. package/server/service/kpi-scope/kpi-scope-type.ts +96 -0
  292. package/server/service/kpi-scope/kpi-scope.ts +143 -0
  293. package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +231 -0
  294. package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +410 -0
  295. package/server/service/kpi-statistic/kpi-statistic-mutation.ts +97 -0
  296. package/server/service/kpi-statistic/kpi-statistic-query.ts +89 -2
  297. package/server/service/kpi-statistic/kpi-statistic.ts +32 -0
  298. package/server/service/kpi-value/kpi-value-mutation.ts +73 -7
  299. package/server/service/kpi-value/kpi-value-type.ts +10 -4
  300. package/server/service/kpi-value/kpi-value.ts +10 -5
  301. package/server/service/utils/value-date-util.ts +47 -0
  302. package/server/types/global.d.ts +8 -0
  303. package/things-factory.config.js +1 -0
  304. package/translations/en.json +15 -3
  305. package/translations/ja.json +13 -3
  306. package/translations/ko.json +15 -3
  307. package/translations/ms.json +13 -3
  308. package/translations/zh.json +13 -3
  309. package/client/pages/kpi-category/kpi-category-importer.ts +0 -90
  310. package/client/pages/kpi-category/kpi-category-list-page.ts +0 -537
  311. package/client/pages/kpi-category/kpi-category-value-calculator.ts +0 -233
  312. package/client/pages/kpi-category-value/kpi-category-value-list-page.ts +0 -404
  313. package/dist-client/pages/kpi-category/kpi-category-importer.d.ts +0 -23
  314. package/dist-client/pages/kpi-category/kpi-category-importer.js +0 -92
  315. package/dist-client/pages/kpi-category/kpi-category-importer.js.map +0 -1
  316. package/dist-client/pages/kpi-category/kpi-category-list-page.d.ts +0 -74
  317. package/dist-client/pages/kpi-category/kpi-category-list-page.js +0 -517
  318. package/dist-client/pages/kpi-category/kpi-category-list-page.js.map +0 -1
  319. package/dist-client/pages/kpi-category/kpi-category-value-calculator.d.ts +0 -13
  320. package/dist-client/pages/kpi-category/kpi-category-value-calculator.js +0 -256
  321. package/dist-client/pages/kpi-category/kpi-category-value-calculator.js.map +0 -1
  322. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.d.ts +0 -63
  323. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js +0 -393
  324. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js.map +0 -1
  325. package/dist-server/service/kpi-category/index.d.ts +0 -6
  326. package/dist-server/service/kpi-category/index.js +0 -10
  327. package/dist-server/service/kpi-category/index.js.map +0 -1
  328. package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +0 -9
  329. package/dist-server/service/kpi-category/kpi-category-mutation.js +0 -221
  330. package/dist-server/service/kpi-category/kpi-category-mutation.js.map +0 -1
  331. package/dist-server/service/kpi-category/kpi-category-query.d.ts +0 -18
  332. package/dist-server/service/kpi-category/kpi-category-query.js +0 -115
  333. package/dist-server/service/kpi-category/kpi-category-query.js.map +0 -1
  334. package/dist-server/service/kpi-category/kpi-category-type.d.ts +0 -24
  335. package/dist-server/service/kpi-category/kpi-category-type.js +0 -100
  336. package/dist-server/service/kpi-category/kpi-category-type.js.map +0 -1
  337. package/dist-server/service/kpi-category/kpi-category.d.ts +0 -22
  338. package/dist-server/service/kpi-category/kpi-category.js +0 -106
  339. package/dist-server/service/kpi-category/kpi-category.js.map +0 -1
  340. package/dist-server/service/kpi-category-value/index.d.ts +0 -6
  341. package/dist-server/service/kpi-category-value/index.js +0 -10
  342. package/dist-server/service/kpi-category-value/index.js.map +0 -1
  343. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.d.ts +0 -8
  344. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js +0 -102
  345. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js.map +0 -1
  346. package/dist-server/service/kpi-category-value/kpi-category-value-query.d.ts +0 -13
  347. package/dist-server/service/kpi-category-value/kpi-category-value-query.js +0 -91
  348. package/dist-server/service/kpi-category-value/kpi-category-value-query.js.map +0 -1
  349. package/dist-server/service/kpi-category-value/kpi-category-value-type.d.ts +0 -19
  350. package/dist-server/service/kpi-category-value/kpi-category-value-type.js +0 -73
  351. package/dist-server/service/kpi-category-value/kpi-category-value-type.js.map +0 -1
  352. package/dist-server/service/kpi-category-value/kpi-category-value.d.ts +0 -19
  353. package/dist-server/service/kpi-category-value/kpi-category-value.js +0 -91
  354. package/dist-server/service/kpi-category-value/kpi-category-value.js.map +0 -1
  355. package/helps/kpi/kpi-category.md +0 -160
  356. package/server/service/kpi-category/index.ts +0 -7
  357. package/server/service/kpi-category/kpi-category-mutation.ts +0 -217
  358. package/server/service/kpi-category/kpi-category-query.ts +0 -87
  359. package/server/service/kpi-category/kpi-category-type.ts +0 -73
  360. package/server/service/kpi-category/kpi-category.ts +0 -95
  361. package/server/service/kpi-category-value/index.ts +0 -7
  362. package/server/service/kpi-category-value/kpi-category-value-mutation.ts +0 -88
  363. package/server/service/kpi-category-value/kpi-category-value-query.ts +0 -62
  364. package/server/service/kpi-category-value/kpi-category-value-type.ts +0 -48
  365. package/server/service/kpi-category-value/kpi-category-value.ts +0 -79
@@ -0,0 +1,123 @@
1
+ import {
2
+ CreateDateColumn,
3
+ UpdateDateColumn,
4
+ DeleteDateColumn,
5
+ Entity,
6
+ Index,
7
+ Column,
8
+ RelationId,
9
+ ManyToOne,
10
+ PrimaryGeneratedColumn,
11
+ EntityManager
12
+ } from 'typeorm'
13
+ import { ObjectType, Field, ID } from 'type-graphql'
14
+
15
+ import { Domain } from '@things-factory/shell'
16
+ import { User } from '@things-factory/auth-base'
17
+
18
+ @Entity()
19
+ @Index('ix_kpi_org_scope_0', (orgScope: KpiOrgScope) => [orgScope.domain, orgScope.entityType, orgScope.entityId], {
20
+ unique: true
21
+ })
22
+ @ObjectType({
23
+ description:
24
+ 'KPI organization scope mapping entity. Maps business entities to various scope dimensions for KPI analysis using generic reference pattern.'
25
+ })
26
+ export class KpiOrgScope {
27
+ @PrimaryGeneratedColumn('uuid')
28
+ @Field(type => ID, { description: 'Unique identifier for this org-scope mapping.' })
29
+ readonly id: string
30
+
31
+ @ManyToOne(type => Domain)
32
+ @Field({ nullable: true, description: 'Domain (tenant) to which this org-scope mapping belongs.' })
33
+ domain?: Domain
34
+
35
+ @RelationId((orgScope: KpiOrgScope) => orgScope.domain)
36
+ @Field({ nullable: true, description: 'ID of the domain (tenant) for this org-scope mapping.' })
37
+ domainId?: string
38
+
39
+ @Column()
40
+ @Field({ description: 'Type of the referenced business entity (e.g., Project, Department, Company, Employee)' })
41
+ entityType: string
42
+
43
+ @Column()
44
+ @Field({ description: 'ID of the referenced business entity' })
45
+ entityId: string
46
+
47
+ @Column()
48
+ @Field({ description: 'Name of the referenced business entity (denormalized for performance and convenience)' })
49
+ entityName: string
50
+
51
+ @Column({ nullable: true })
52
+ @Field({ nullable: true, description: 'Legacy org field for backward compatibility' })
53
+ org?: string
54
+
55
+ @Column({ nullable: true })
56
+ @Field({ nullable: true, description: 'First scope dimension (e.g., geographical region, business unit)' })
57
+ scope01?: string
58
+
59
+ @Column({ nullable: true })
60
+ @Field({ nullable: true, description: 'Second scope dimension (e.g., product line, customer segment)' })
61
+ scope02?: string
62
+
63
+ @Column({ nullable: true })
64
+ @Field({ nullable: true, description: 'Third scope dimension (e.g., process type, technology stack)' })
65
+ scope03?: string
66
+
67
+ @Column({ nullable: true })
68
+ @Field({ nullable: true, description: 'Fourth scope dimension (e.g., cost center, profit center)' })
69
+ scope04?: string
70
+
71
+ @Column({ nullable: true })
72
+ @Field({ nullable: true, description: 'Fifth scope dimension (e.g., risk level, priority tier)' })
73
+ scope05?: string
74
+
75
+ @CreateDateColumn()
76
+ @Field({ nullable: true, description: 'Timestamp when this org-scope mapping was created.' })
77
+ createdAt?: Date
78
+
79
+ @UpdateDateColumn()
80
+ @Field({ nullable: true, description: 'Timestamp when this org-scope mapping was last updated.' })
81
+ updatedAt?: Date
82
+
83
+ @ManyToOne(type => User, { nullable: true })
84
+ @Field(type => User, { nullable: true, description: 'User who created this org-scope mapping.' })
85
+ creator?: User
86
+
87
+ @RelationId((orgScope: KpiOrgScope) => orgScope.creator)
88
+ @Field({ nullable: true, description: 'ID of the user who created this org-scope mapping.' })
89
+ creatorId?: string
90
+
91
+ @ManyToOne(type => User, { nullable: true })
92
+ @Field(type => User, { nullable: true, description: 'User who last updated this org-scope mapping.' })
93
+ updater?: User
94
+
95
+ @RelationId((orgScope: KpiOrgScope) => orgScope.updater)
96
+ @Field({ nullable: true, description: 'ID of the user who last updated this org-scope mapping.' })
97
+ updaterId?: string
98
+
99
+ // Helper methods for Generic Reference Pattern
100
+ async getReferencedEntity(entityManager: EntityManager): Promise<any> {
101
+ try {
102
+ const repository = entityManager.getRepository(this.entityType)
103
+ return await repository.findOne({ where: { id: this.entityId } })
104
+ } catch (error) {
105
+ console.warn(`Failed to get referenced entity ${this.entityType}:${this.entityId}`, error)
106
+ return null
107
+ }
108
+ }
109
+
110
+ async validateEntityReference(entityManager: EntityManager): Promise<boolean> {
111
+ try {
112
+ const entity = await this.getReferencedEntity(entityManager)
113
+ return !!entity
114
+ } catch {
115
+ return false
116
+ }
117
+ }
118
+
119
+ // Convenience getter for display purposes
120
+ get displayName(): string {
121
+ return this.entityName || `${this.entityType}:${this.entityId}` || this.org || 'Unknown'
122
+ }
123
+ }
@@ -0,0 +1,11 @@
1
+ import { KpiScope } from './kpi-scope'
2
+ import { KpiScopeQuery } from './kpi-scope-query'
3
+ import { KpiScopeMutation } from './kpi-scope-mutation'
4
+
5
+ export const entities = [KpiScope]
6
+ export const resolvers = [KpiScopeQuery, KpiScopeMutation]
7
+
8
+ export * from './kpi-scope'
9
+ export * from './kpi-scope-query'
10
+ export * from './kpi-scope-mutation'
11
+ export * from './kpi-scope-type'
@@ -0,0 +1,129 @@
1
+ import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+ import { getRepository } from '@things-factory/shell'
4
+ import type ResolverContext from '@things-factory/auth-base'
5
+
6
+ import { KpiScope } from './kpi-scope'
7
+ import { NewKpiScope, KpiScopePatch } from './kpi-scope-type'
8
+
9
+ @Resolver(KpiScope)
10
+ export class KpiScopeMutation {
11
+ @Directive('@transaction')
12
+ @Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
13
+ @Mutation(returns => KpiScope, { description: 'Create a new scope dimension definition' })
14
+ async createKpiScope(
15
+ @Arg('kpiScope') kpiScope: NewKpiScope,
16
+ @Ctx() context: ResolverContext
17
+ ): Promise<KpiScope> {
18
+ const { domain, user, tx } = context.state
19
+
20
+ const result = await getRepository(KpiScope, tx).save({
21
+ ...kpiScope,
22
+ domain,
23
+ creator: user,
24
+ updater: user
25
+ })
26
+
27
+ return result
28
+ }
29
+
30
+ @Directive('@transaction')
31
+ @Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
32
+ @Mutation(returns => KpiScope, { description: 'Update a scope dimension definition' })
33
+ async updateKpiScope(
34
+ @Arg('id') id: string,
35
+ @Arg('patch') patch: KpiScopePatch,
36
+ @Ctx() context: ResolverContext
37
+ ): Promise<KpiScope> {
38
+ const { domain, user, tx } = context.state
39
+
40
+ const repository = getRepository(KpiScope, tx)
41
+ const kpiScope = await repository.findOne({
42
+ where: { domain: { id: domain.id }, id }
43
+ })
44
+
45
+ const result = await repository.save({
46
+ ...kpiScope,
47
+ ...patch,
48
+ updater: user
49
+ })
50
+
51
+ return result
52
+ }
53
+
54
+ @Directive('@transaction')
55
+ @Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
56
+ @Mutation(returns => [KpiScope], { description: "Update multiple scope dimension definitions" })
57
+ async updateMultipleKpiScope(
58
+ @Arg('patches', type => [KpiScopePatch]) patches: KpiScopePatch[],
59
+ @Ctx() context: ResolverContext
60
+ ): Promise<KpiScope[]> {
61
+ const { domain, user, tx } = context.state
62
+
63
+ let results = []
64
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
65
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
66
+ const kpiScopeRepo = getRepository(KpiScope, tx)
67
+
68
+ if (_createRecords.length > 0) {
69
+ for (let i = 0; i < _createRecords.length; i++) {
70
+ const newRecord = _createRecords[i]
71
+
72
+ const result = await kpiScopeRepo.save({
73
+ ...newRecord,
74
+ domain,
75
+ creator: user,
76
+ updater: user
77
+ })
78
+
79
+ results.push({ ...result, cuFlag: '+' })
80
+ }
81
+ }
82
+
83
+ if (_updateRecords.length > 0) {
84
+ for (let i = 0; i < _updateRecords.length; i++) {
85
+ const updateRecord = _updateRecords[i]
86
+ const kpiScope = await kpiScopeRepo.findOneBy({ id: updateRecord.id })
87
+
88
+ const result = await kpiScopeRepo.save({
89
+ ...kpiScope,
90
+ ...updateRecord,
91
+ updater: user
92
+ })
93
+
94
+ results.push({ ...result, cuFlag: 'M' })
95
+ }
96
+ }
97
+
98
+ return results
99
+ }
100
+
101
+ @Directive('@transaction')
102
+ @Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
103
+ @Mutation(returns => Boolean, { description: 'Delete a scope dimension definition' })
104
+ async deleteKpiScope(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
105
+ const { domain, tx } = context.state
106
+
107
+ await getRepository(KpiScope, tx).delete({ domain: { id: domain.id }, id })
108
+
109
+ return true
110
+ }
111
+
112
+ @Directive('@transaction')
113
+ @Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
114
+ @Mutation(returns => Boolean, { description: 'Delete multiple scope dimension definitions' })
115
+ async deleteKpiScopes(
116
+ @Arg('ids', type => [String]) ids: string[],
117
+ @Ctx() context: ResolverContext
118
+ ): Promise<boolean> {
119
+ const { domain, tx } = context.state
120
+
121
+ await getRepository(KpiScope, tx).delete({
122
+ domain: { id: domain.id },
123
+ id: In(ids)
124
+ })
125
+
126
+ return true
127
+ }
128
+
129
+ }
@@ -0,0 +1,63 @@
1
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
2
+ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
3
+ import { User } from '@things-factory/auth-base'
4
+ import type ResolverContext from '@things-factory/auth-base'
5
+ import { KpiScope } from './kpi-scope'
6
+ import { KpiScopeList } from './kpi-scope-type'
7
+
8
+ @Resolver(KpiScope)
9
+ export class KpiScopeQuery {
10
+ @Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
11
+ @Query(returns => KpiScope!, { nullable: true, description: 'Fetch a scope dimension definition by ID' })
12
+ async kpiScope(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<KpiScope> {
13
+ const { domain } = context.state
14
+
15
+ return await getRepository(KpiScope).findOne({
16
+ where: { domain: { id: domain.id }, id }
17
+ })
18
+ }
19
+
20
+ @Query(returns => KpiScopeList, { description: 'Fetch multiple scope dimension definitions' })
21
+ @Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
22
+ async kpiScopes(
23
+ @Args(type => ListParam) params: ListParam,
24
+ @Ctx() context: ResolverContext
25
+ ): Promise<KpiScopeList> {
26
+ const { domain } = context.state
27
+
28
+ const queryBuilder = getQueryBuilderFromListParams({
29
+ domain,
30
+ params,
31
+ repository: await getRepository(KpiScope),
32
+ searchables: ['name', 'description'],
33
+ filtersMap: {
34
+ level: { columnName: 'level' },
35
+ scopeType: { columnName: 'scopeType' },
36
+ parentLevel: { columnName: 'parentLevel' },
37
+ active: { columnName: 'active' },
38
+ includeInStatistics: { columnName: 'includeInStatistics' },
39
+ showInDashboard: { columnName: 'showInDashboard' }
40
+ }
41
+ })
42
+
43
+ const [items, total] = await queryBuilder.getManyAndCount()
44
+
45
+ return { items, total }
46
+ }
47
+
48
+
49
+ @FieldResolver(type => Domain)
50
+ async domain(@Root() kpiScope: KpiScope): Promise<Domain> {
51
+ return kpiScope.domainId && (await getRepository(Domain).findOneBy({ id: kpiScope.domainId }))
52
+ }
53
+
54
+ @FieldResolver(type => User)
55
+ async updater(@Root() kpiScope: KpiScope): Promise<User> {
56
+ return kpiScope.updaterId && (await getRepository(User).findOneBy({ id: kpiScope.updaterId }))
57
+ }
58
+
59
+ @FieldResolver(type => User)
60
+ async creator(@Root() kpiScope: KpiScope): Promise<User> {
61
+ return kpiScope.creatorId && (await getRepository(User).findOneBy({ id: kpiScope.creatorId }))
62
+ }
63
+ }
@@ -0,0 +1,96 @@
1
+ import { ScalarObject } from '@things-factory/shell'
2
+ import { ObjectType, Field, InputType, ID, Int } from 'type-graphql'
3
+ import { KpiScope, ScopeType } from './kpi-scope'
4
+
5
+ @InputType()
6
+ export class NewKpiScope {
7
+ @Field(type => Int, { description: 'Scope level (1-5) corresponding to scope01-scope05 in KpiOrgScope' })
8
+ level: number
9
+
10
+ @Field({ description: 'Display name for this scope dimension (e.g., "지역", "회사", "프로젝트규모")' })
11
+ name: string
12
+
13
+ @Field({ nullable: true, description: 'Detailed description of what this scope dimension represents' })
14
+ description?: string
15
+
16
+ @Field(type => ScopeType, { description: 'Type category of this scope dimension' })
17
+ scopeType: ScopeType
18
+
19
+ @Field(type => Int, { nullable: true, description: 'Parent scope level if this forms a hierarchy' })
20
+ parentLevel?: number
21
+
22
+ @Field(type => Int, { description: 'Order/priority for display and processing', defaultValue: 1 })
23
+ displayOrder: number
24
+
25
+ @Field(type => [String], { nullable: true, description: 'List of valid values for this scope' })
26
+ validValues?: string[]
27
+
28
+ @Field({ nullable: true, description: 'Regex pattern for validating values in this scope dimension' })
29
+ validationPattern?: string
30
+
31
+ @Field({ description: 'Whether this scope definition is active and should be used', defaultValue: true })
32
+ active: boolean
33
+
34
+ @Field({ description: 'Whether this scope should be included in statistical calculations', defaultValue: true })
35
+ includeInStatistics: boolean
36
+
37
+ @Field({ description: 'Whether this scope should be displayed in dashboard visualizations', defaultValue: false })
38
+ showInDashboard: boolean
39
+
40
+ @Field(type => ScalarObject, { nullable: true, description: 'Additional metadata for this scope dimension' })
41
+ metadata?: any
42
+ }
43
+
44
+ @InputType()
45
+ export class KpiScopePatch {
46
+ @Field(type => ID, { nullable: true })
47
+ id?: string
48
+
49
+ @Field(type => Int, { description: 'Scope level (1-5) corresponding to scope01-scope05 in KpiOrgScope' })
50
+ level: number
51
+
52
+ @Field({ description: 'Display name for this scope dimension (e.g., "지역", "회사", "프로젝트규모")' })
53
+ name: string
54
+
55
+ @Field({ nullable: true, description: 'Detailed description of what this scope dimension represents' })
56
+ description?: string
57
+
58
+ @Field(type => ScopeType, { description: 'Type category of this scope dimension' })
59
+ scopeType: ScopeType
60
+
61
+ @Field(type => Int, { nullable: true, description: 'Parent scope level if this forms a hierarchy' })
62
+ parentLevel?: number
63
+
64
+ @Field(type => Int, { description: 'Order/priority for display and processing', defaultValue: 1 })
65
+ displayOrder: number
66
+
67
+ @Field(type => [String], { nullable: true, description: 'List of valid values for this scope' })
68
+ validValues?: string[]
69
+
70
+ @Field({ nullable: true, description: 'Regex pattern for validating values in this scope dimension' })
71
+ validationPattern?: string
72
+
73
+ @Field({ description: 'Whether this scope definition is active and should be used', defaultValue: true })
74
+ active: boolean
75
+
76
+ @Field({ description: 'Whether this scope should be included in statistical calculations', defaultValue: true })
77
+ includeInStatistics: boolean
78
+
79
+ @Field({ description: 'Whether this scope should be displayed in dashboard visualizations', defaultValue: false })
80
+ showInDashboard: boolean
81
+
82
+ @Field(type => ScalarObject, { nullable: true, description: 'Additional metadata for this scope dimension' })
83
+ metadata?: any
84
+
85
+ @Field({ nullable: true })
86
+ cuFlag?: string
87
+ }
88
+
89
+ @ObjectType()
90
+ export class KpiScopeList {
91
+ @Field(type => [KpiScope])
92
+ items: KpiScope[]
93
+
94
+ @Field()
95
+ total: number
96
+ }
@@ -0,0 +1,143 @@
1
+ import {
2
+ CreateDateColumn,
3
+ UpdateDateColumn,
4
+ Entity,
5
+ Index,
6
+ Column,
7
+ RelationId,
8
+ ManyToOne,
9
+ PrimaryGeneratedColumn
10
+ } from 'typeorm'
11
+ import { ObjectType, Field, ID, registerEnumType, Int } from 'type-graphql'
12
+
13
+ import { Domain, ScalarObject } from '@things-factory/shell'
14
+ import { User } from '@things-factory/auth-base'
15
+
16
+ export enum ScopeType {
17
+ GEOGRAPHIC = 'GEOGRAPHIC', // 지리적 차원 (지역, 시도, 구군)
18
+ ORGANIZATIONAL = 'ORGANIZATIONAL', // 조직 차원 (회사, 부서, 팀)
19
+ BUSINESS = 'BUSINESS', // 비즈니스 차원 (규모, 유형, 등급)
20
+ TECHNICAL = 'TECHNICAL', // 기술적 차원 (공종, 기술, 방법)
21
+ TEMPORAL = 'TEMPORAL', // 시간적 차원 (분기, 년도, 기간)
22
+ CUSTOM = 'CUSTOM' // 사용자 정의
23
+ }
24
+
25
+ registerEnumType(ScopeType, {
26
+ name: 'ScopeType',
27
+ description: 'Types of organizational scope dimensions'
28
+ })
29
+
30
+ @Entity()
31
+ @Index('ix_kpi_scope_domain', (kpiScope: KpiScope) => [kpiScope.domain])
32
+ @Index('ix_kpi_scope_level', (kpiScope: KpiScope) => [kpiScope.domain, kpiScope.level])
33
+ @ObjectType({
34
+ description: 'Defines the meaning and metadata for each scope level (scope01~05) in KpiOrgScope'
35
+ })
36
+ export class KpiScope {
37
+ @PrimaryGeneratedColumn('uuid')
38
+ @Field(type => ID)
39
+ readonly id: string
40
+
41
+ // 스코프 레벨 (1-5)
42
+ @Column({ type: 'int' })
43
+ @Field(type => Int, { description: 'Scope level (1-5) corresponding to scope01-scope05 in KpiOrgScope' })
44
+ level: number
45
+
46
+ // 스코프 차원 이름
47
+ @Column()
48
+ @Field({ description: 'Display name for this scope dimension (e.g., "지역", "회사", "프로젝트규모")' })
49
+ name: string
50
+
51
+ // 스코프 차원 설명
52
+ @Column({ nullable: true })
53
+ @Field({ nullable: true, description: 'Detailed description of what this scope dimension represents' })
54
+ description?: string
55
+
56
+ // 스코프 타입 (지리적, 조직적, 비즈니스 등)
57
+ @Column()
58
+ @Field(type => ScopeType, { description: 'Type category of this scope dimension' })
59
+ scopeType: ScopeType
60
+
61
+ // 계층 정보
62
+ @Column({ nullable: true })
63
+ @Field(type => Int, { nullable: true, description: 'Parent scope level if this forms a hierarchy' })
64
+ parentLevel?: number
65
+
66
+ @Column({ default: 1 })
67
+ @Field(type => Int, { description: 'Order/priority for display and processing' })
68
+ displayOrder: number
69
+
70
+ // 유효한 값들 (선택사항)
71
+ @Column('simple-json', { nullable: true })
72
+ @Field(type => ScalarObject, {
73
+ nullable: true,
74
+ description: 'List of valid values for this scope (e.g., ["서울", "부산", "대구"] for regions)'
75
+ })
76
+ validValues?: string[]
77
+
78
+ // 정규표현식 검증 (선택사항)
79
+ @Column({ nullable: true })
80
+ @Field({
81
+ nullable: true,
82
+ description: 'Regex pattern for validating values in this scope dimension'
83
+ })
84
+ validationPattern?: string
85
+
86
+ // 활성화 여부
87
+ @Column({ default: true })
88
+ @Field({ description: 'Whether this scope definition is active and should be used' })
89
+ active: boolean
90
+
91
+ // 통계 계산에 사용 여부
92
+ @Column({ default: true })
93
+ @Field({ description: 'Whether this scope should be included in statistical calculations' })
94
+ includeInStatistics: boolean
95
+
96
+ // 대시보드에 표시 여부
97
+ @Column({ default: false })
98
+ @Field({ description: 'Whether this scope should be displayed in dashboard visualizations' })
99
+ showInDashboard: boolean
100
+
101
+ // 메타데이터
102
+ @Column('simple-json', { nullable: true })
103
+ @Field(type => ScalarObject, {
104
+ nullable: true,
105
+ description: 'Additional metadata for this scope dimension (colors, icons, etc.)'
106
+ })
107
+ metadata?: {
108
+ color?: string
109
+ icon?: string
110
+ unit?: string
111
+ [key: string]: any
112
+ }
113
+
114
+ // === 표준 필드들 ===
115
+ @ManyToOne(type => Domain)
116
+ @Field({ nullable: true, description: 'Domain this scope definition belongs to' })
117
+ domain?: Domain
118
+
119
+ @RelationId((kpiScope: KpiScope) => kpiScope.domain)
120
+ domainId?: string
121
+
122
+ @CreateDateColumn()
123
+ @Field({ nullable: true })
124
+ createdAt?: Date
125
+
126
+ @UpdateDateColumn()
127
+ @Field({ nullable: true })
128
+ updatedAt?: Date
129
+
130
+ @ManyToOne(type => User, { nullable: true })
131
+ @Field(type => User, { nullable: true })
132
+ creator?: User
133
+
134
+ @RelationId((kpiScope: KpiScope) => kpiScope.creator)
135
+ creatorId?: string
136
+
137
+ @ManyToOne(type => User, { nullable: true })
138
+ @Field(type => User, { nullable: true })
139
+ updater?: User
140
+
141
+ @RelationId((kpiScope: KpiScope) => kpiScope.updater)
142
+ updaterId?: string
143
+ }