@things-factory/kpi 1.0.0-alpha.5 → 9.0.9

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 (309) hide show
  1. package/README.md +74 -0
  2. package/client/pages/kpi/kpi-list-page.ts +97 -47
  3. package/client/pages/kpi/kpi-overview-sample.ts +260 -0
  4. package/client/pages/kpi/kpi-overview.ts +271 -0
  5. package/client/pages/kpi-category/kpi-category-list-page.ts +39 -50
  6. package/client/pages/kpi-dashboard/kpi-alert-panel.ts +114 -0
  7. package/client/pages/kpi-dashboard/kpi-dashboard.ts +285 -0
  8. package/client/pages/kpi-dashboard/kpi-grade-visualization.ts +75 -0
  9. package/client/pages/kpi-dashboard/kpi-history-viewer.ts +58 -0
  10. package/client/pages/kpi-dashboard/kpi-list-summary.ts +100 -0
  11. package/client/pages/kpi-dashboard/kpi-performance-summary.ts +124 -0
  12. package/client/pages/kpi-dashboard/kpi-value-entry.ts +78 -0
  13. package/client/pages/kpi-grade/kpi-grade-list-page.ts +58 -68
  14. package/client/pages/kpi-history/kpi-history-list-page.ts +146 -0
  15. package/client/pages/kpi-metric/kpi-metric-list-page.ts +67 -63
  16. package/client/pages/kpi-value/kpi-value-list-page.ts +73 -72
  17. package/client/pages/kpi-value/kpi-value-manual-entry-form.ts +168 -0
  18. package/client/pages/kpi-value/kpi-value-manual-entry-page.ts +173 -0
  19. package/client/route.ts +35 -0
  20. package/dist-client/pages/kpi/kpi-importer.js +16 -17
  21. package/dist-client/pages/kpi/kpi-importer.js.map +1 -1
  22. package/dist-client/pages/kpi/kpi-list-page.js +128 -68
  23. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
  24. package/dist-client/pages/kpi/kpi-overview-sample.d.ts +36 -0
  25. package/dist-client/pages/kpi/kpi-overview-sample.js +264 -0
  26. package/dist-client/pages/kpi/kpi-overview-sample.js.map +1 -0
  27. package/dist-client/pages/kpi/kpi-overview.d.ts +14 -0
  28. package/dist-client/pages/kpi/kpi-overview.js +290 -0
  29. package/dist-client/pages/kpi/kpi-overview.js.map +1 -0
  30. package/dist-client/pages/kpi-category/kpi-category-importer.js +16 -17
  31. package/dist-client/pages/kpi-category/kpi-category-importer.js.map +1 -1
  32. package/dist-client/pages/kpi-category/kpi-category-list-page.js +70 -71
  33. package/dist-client/pages/kpi-category/kpi-category-list-page.js.map +1 -1
  34. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.d.ts +18 -0
  35. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js +128 -0
  36. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js.map +1 -0
  37. package/dist-client/pages/kpi-dashboard/kpi-dashboard.d.ts +24 -0
  38. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +305 -0
  39. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -0
  40. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.d.ts +12 -0
  41. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js +82 -0
  42. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js.map +1 -0
  43. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.d.ts +11 -0
  44. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js +65 -0
  45. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js.map +1 -0
  46. package/dist-client/pages/kpi-dashboard/kpi-list-summary.d.ts +13 -0
  47. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js +115 -0
  48. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js.map +1 -0
  49. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.d.ts +15 -0
  50. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js +139 -0
  51. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js.map +1 -0
  52. package/dist-client/pages/kpi-dashboard/kpi-value-entry.d.ts +7 -0
  53. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js +86 -0
  54. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js.map +1 -0
  55. package/dist-client/pages/kpi-grade/kpi-grade-importer.js +16 -17
  56. package/dist-client/pages/kpi-grade/kpi-grade-importer.js.map +1 -1
  57. package/dist-client/pages/kpi-grade/kpi-grade-list-page.js +89 -89
  58. package/dist-client/pages/kpi-grade/kpi-grade-list-page.js.map +1 -1
  59. package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +16 -0
  60. package/dist-client/pages/kpi-history/kpi-history-list-page.js +155 -0
  61. package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -0
  62. package/dist-client/pages/kpi-metric/kpi-metric-importer.js +16 -17
  63. package/dist-client/pages/kpi-metric/kpi-metric-importer.js.map +1 -1
  64. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +98 -84
  65. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
  66. package/dist-client/pages/kpi-value/kpi-value-importer.js +16 -17
  67. package/dist-client/pages/kpi-value/kpi-value-importer.js.map +1 -1
  68. package/dist-client/pages/kpi-value/kpi-value-list-page.js +104 -93
  69. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  70. package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.d.ts +14 -0
  71. package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.js +201 -0
  72. package/dist-client/pages/kpi-value/kpi-value-manual-entry-form.js.map +1 -0
  73. package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.d.ts +41 -0
  74. package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.js +180 -0
  75. package/dist-client/pages/kpi-value/kpi-value-manual-entry-page.js.map +1 -0
  76. package/dist-client/route.d.ts +1 -1
  77. package/dist-client/route.js +27 -0
  78. package/dist-client/route.js.map +1 -1
  79. package/dist-client/tsconfig.tsbuildinfo +1 -1
  80. package/dist-server/index.d.ts +2 -1
  81. package/dist-server/index.js +2 -1
  82. package/dist-server/index.js.map +1 -1
  83. package/dist-server/migrations/1752188906708-SeedKpiCategory.d.ts +5 -0
  84. package/dist-server/migrations/1752188906708-SeedKpiCategory.js +56 -0
  85. package/dist-server/migrations/1752188906708-SeedKpiCategory.js.map +1 -0
  86. package/dist-server/migrations/1752190849681-SeedKpi.d.ts +5 -0
  87. package/dist-server/migrations/1752190849681-SeedKpi.js +107 -0
  88. package/dist-server/migrations/1752190849681-SeedKpi.js.map +1 -0
  89. package/dist-server/migrations/1752191090459-SeedKpiGrade.d.ts +5 -0
  90. package/dist-server/migrations/1752191090459-SeedKpiGrade.js +271 -0
  91. package/dist-server/migrations/1752191090459-SeedKpiGrade.js.map +1 -0
  92. package/dist-server/migrations/index.d.ts +1 -0
  93. package/dist-server/migrations/index.js +12 -0
  94. package/dist-server/migrations/index.js.map +1 -0
  95. package/dist-server/routes.d.ts +1 -0
  96. package/dist-server/routes.js +48 -0
  97. package/dist-server/routes.js.map +1 -1
  98. package/dist-server/service/index.d.ts +3 -4
  99. package/dist-server/service/index.js +4 -6
  100. package/dist-server/service/index.js.map +1 -1
  101. package/dist-server/service/kpi/aggregate-kpi.d.ts +8 -0
  102. package/dist-server/service/kpi/aggregate-kpi.js +88 -0
  103. package/dist-server/service/kpi/aggregate-kpi.js.map +1 -0
  104. package/dist-server/service/kpi/event-subscriber.d.ts +2 -0
  105. package/dist-server/service/kpi/event-subscriber.js +10 -0
  106. package/dist-server/service/kpi/event-subscriber.js.map +1 -1
  107. package/dist-server/service/kpi/index.d.ts +2 -1
  108. package/dist-server/service/kpi/kpi-formula.service.d.ts +24 -0
  109. package/dist-server/service/kpi/kpi-formula.service.js +64 -0
  110. package/dist-server/service/kpi/kpi-formula.service.js.map +1 -0
  111. package/dist-server/service/kpi/kpi-history.d.ts +6 -2
  112. package/dist-server/service/kpi/kpi-history.js +29 -11
  113. package/dist-server/service/kpi/kpi-history.js.map +1 -1
  114. package/dist-server/service/kpi/kpi-mutation.d.ts +2 -0
  115. package/dist-server/service/kpi/kpi-mutation.js +215 -10
  116. package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
  117. package/dist-server/service/kpi/kpi-query.d.ts +10 -0
  118. package/dist-server/service/kpi/kpi-query.js +87 -3
  119. package/dist-server/service/kpi/kpi-query.js.map +1 -1
  120. package/dist-server/service/kpi/kpi-type.d.ts +14 -3
  121. package/dist-server/service/kpi/kpi-type.js +81 -18
  122. package/dist-server/service/kpi/kpi-type.js.map +1 -1
  123. package/dist-server/service/kpi/kpi.d.ts +14 -3
  124. package/dist-server/service/kpi/kpi.js +96 -19
  125. package/dist-server/service/kpi/kpi.js.map +1 -1
  126. package/dist-server/service/kpi-alert/index.d.ts +2 -0
  127. package/dist-server/service/kpi-alert/index.js +6 -0
  128. package/dist-server/service/kpi-alert/index.js.map +1 -0
  129. package/dist-server/service/kpi-alert/kpi-alert-query.d.ts +4 -0
  130. package/dist-server/service/kpi-alert/kpi-alert-query.js +71 -0
  131. package/dist-server/service/kpi-alert/kpi-alert-query.js.map +1 -0
  132. package/dist-server/service/kpi-alert/kpi-alert-type.d.ts +8 -0
  133. package/dist-server/service/kpi-alert/kpi-alert-type.js +33 -0
  134. package/dist-server/service/kpi-alert/kpi-alert-type.js.map +1 -0
  135. package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +1 -1
  136. package/dist-server/service/kpi-category/kpi-category-mutation.js +36 -10
  137. package/dist-server/service/kpi-category/kpi-category-mutation.js.map +1 -1
  138. package/dist-server/service/kpi-category/kpi-category-query.d.ts +2 -0
  139. package/dist-server/service/kpi-category/kpi-category-query.js +18 -2
  140. package/dist-server/service/kpi-category/kpi-category-query.js.map +1 -1
  141. package/dist-server/service/kpi-category/kpi-category-type.d.ts +3 -5
  142. package/dist-server/service/kpi-category/kpi-category-type.js +16 -20
  143. package/dist-server/service/kpi-category/kpi-category-type.js.map +1 -1
  144. package/dist-server/service/kpi-category/kpi-category.d.ts +7 -9
  145. package/dist-server/service/kpi-category/kpi-category.js +40 -38
  146. package/dist-server/service/kpi-category/kpi-category.js.map +1 -1
  147. package/dist-server/service/kpi-grade/index.d.ts +1 -2
  148. package/dist-server/service/kpi-grade/index.js +2 -4
  149. package/dist-server/service/kpi-grade/index.js.map +1 -1
  150. package/dist-server/service/kpi-grade/kpi-grade-mutation.d.ts +1 -1
  151. package/dist-server/service/kpi-grade/kpi-grade-mutation.js +33 -10
  152. package/dist-server/service/kpi-grade/kpi-grade-mutation.js.map +1 -1
  153. package/dist-server/service/kpi-grade/kpi-grade-query.js +2 -2
  154. package/dist-server/service/kpi-grade/kpi-grade-query.js.map +1 -1
  155. package/dist-server/service/kpi-grade/kpi-grade-type.d.ts +13 -4
  156. package/dist-server/service/kpi-grade/kpi-grade-type.js +54 -18
  157. package/dist-server/service/kpi-grade/kpi-grade-type.js.map +1 -1
  158. package/dist-server/service/kpi-grade/kpi-grade.d.ts +8 -8
  159. package/dist-server/service/kpi-grade/kpi-grade.js +48 -40
  160. package/dist-server/service/kpi-grade/kpi-grade.js.map +1 -1
  161. package/dist-server/service/kpi-metric/aggregate-kpi-metric.d.ts +8 -0
  162. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +134 -0
  163. package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -0
  164. package/dist-server/service/kpi-metric/index.d.ts +1 -2
  165. package/dist-server/service/kpi-metric/index.js +2 -4
  166. package/dist-server/service/kpi-metric/index.js.map +1 -1
  167. package/dist-server/service/kpi-metric/kpi-metric-mutation.d.ts +1 -1
  168. package/dist-server/service/kpi-metric/kpi-metric-mutation.js +139 -13
  169. package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -1
  170. package/dist-server/service/kpi-metric/kpi-metric-query.js +3 -3
  171. package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -1
  172. package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +17 -4
  173. package/dist-server/service/kpi-metric/kpi-metric-type.js +69 -11
  174. package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -1
  175. package/dist-server/service/kpi-metric/kpi-metric.d.ts +11 -8
  176. package/dist-server/service/kpi-metric/kpi-metric.js +62 -37
  177. package/dist-server/service/kpi-metric/kpi-metric.js.map +1 -1
  178. package/dist-server/service/kpi-value/kpi-value-mutation.js +66 -11
  179. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
  180. package/dist-server/service/kpi-value/kpi-value-query.d.ts +2 -0
  181. package/dist-server/service/kpi-value/kpi-value-query.js +15 -2
  182. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  183. package/dist-server/service/kpi-value/kpi-value-type.d.ts +19 -10
  184. package/dist-server/service/kpi-value/kpi-value-type.js +87 -24
  185. package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -1
  186. package/dist-server/service/kpi-value/kpi-value.d.ts +15 -9
  187. package/dist-server/service/kpi-value/kpi-value.js +86 -32
  188. package/dist-server/service/kpi-value/kpi-value.js.map +1 -1
  189. package/dist-server/tsconfig.tsbuildinfo +1 -1
  190. package/implement-plan/01-entity-type-resolver.md +57 -0
  191. package/implement-plan/02-dataset-integration.md +35 -0
  192. package/implement-plan/03-kpivalue-automation.md +34 -0
  193. package/implement-plan/04-version-history.md +33 -0
  194. package/implement-plan/05-grade-visualization.md +33 -0
  195. package/implement-plan/06-graphql-frontend.md +30 -0
  196. package/implement-plan/07-test-docs.md +35 -0
  197. package/implement-plan/TODO.md +41 -0
  198. package/package.json +18 -6
  199. package/server/index.ts +2 -1
  200. package/server/migrations/1752188906708-SeedKpiCategory.ts +61 -0
  201. package/server/migrations/1752190849681-SeedKpi.ts +112 -0
  202. package/server/migrations/1752191090459-SeedKpiGrade.ts +270 -0
  203. package/server/migrations/index.ts +9 -0
  204. package/server/routes.ts +55 -0
  205. package/server/service/index.ts +4 -6
  206. package/server/service/kpi/aggregate-kpi.ts +82 -0
  207. package/server/service/kpi/event-subscriber.ts +12 -0
  208. package/server/service/kpi/kpi-formula.service.ts +63 -0
  209. package/server/service/kpi/kpi-history.ts +29 -21
  210. package/server/service/kpi/kpi-mutation.ts +194 -12
  211. package/server/service/kpi/kpi-query.ts +57 -2
  212. package/server/service/kpi/kpi-type.ts +72 -19
  213. package/server/service/kpi/kpi.ts +96 -20
  214. package/server/service/kpi-alert/index.ts +3 -0
  215. package/server/service/kpi-alert/kpi-alert-query.ts +59 -0
  216. package/server/service/kpi-alert/kpi-alert-type.ts +20 -0
  217. package/server/service/kpi-category/kpi-category-mutation.ts +17 -4
  218. package/server/service/kpi-category/kpi-category-query.ts +20 -3
  219. package/server/service/kpi-category/kpi-category-type.ts +17 -19
  220. package/server/service/kpi-category/kpi-category.ts +39 -37
  221. package/server/service/kpi-grade/index.ts +2 -4
  222. package/server/service/kpi-grade/kpi-grade-mutation.ts +13 -4
  223. package/server/service/kpi-grade/kpi-grade-query.ts +5 -2
  224. package/server/service/kpi-grade/kpi-grade-type.ts +46 -19
  225. package/server/service/kpi-grade/kpi-grade.ts +44 -38
  226. package/server/service/kpi-metric/aggregate-kpi-metric.ts +128 -0
  227. package/server/service/kpi-metric/index.ts +2 -4
  228. package/server/service/kpi-metric/kpi-metric-mutation.ts +123 -7
  229. package/server/service/kpi-metric/kpi-metric-query.ts +9 -3
  230. package/server/service/kpi-metric/kpi-metric-type.ts +56 -13
  231. package/server/service/kpi-metric/kpi-metric.ts +55 -35
  232. package/server/service/kpi-value/kpi-value-mutation.ts +52 -14
  233. package/server/service/kpi-value/kpi-value-query.ts +12 -2
  234. package/server/service/kpi-value/kpi-value-type.ts +80 -25
  235. package/server/service/kpi-value/kpi-value.ts +81 -29
  236. package/things-factory.config.js +12 -4
  237. package/translations/en.json +12 -1
  238. package/translations/ja.json +12 -1
  239. package/translations/ko.json +12 -1
  240. package/translations/ms.json +12 -1
  241. package/translations/zh.json +12 -1
  242. package/client/pages/kpe-metric/kpe-metric-importer.ts +0 -90
  243. package/client/pages/kpe-metric/kpe-metric-list-page.ts +0 -398
  244. package/client/pages/kpi-formula/kpi-formula-importer.ts +0 -90
  245. package/client/pages/kpi-formula/kpi-formula-list-page.ts +0 -398
  246. package/client/pages/metric/metric-importer.ts +0 -90
  247. package/client/pages/metric/metric-list-page.ts +0 -398
  248. package/dist-client/pages/kpe-metric/kpe-metric-importer.d.ts +0 -23
  249. package/dist-client/pages/kpe-metric/kpe-metric-importer.js +0 -93
  250. package/dist-client/pages/kpe-metric/kpe-metric-importer.js.map +0 -1
  251. package/dist-client/pages/kpe-metric/kpe-metric-list-page.d.ts +0 -66
  252. package/dist-client/pages/kpe-metric/kpe-metric-list-page.js +0 -370
  253. package/dist-client/pages/kpe-metric/kpe-metric-list-page.js.map +0 -1
  254. package/dist-client/pages/kpi-formula/kpi-formula-importer.d.ts +0 -23
  255. package/dist-client/pages/kpi-formula/kpi-formula-importer.js +0 -93
  256. package/dist-client/pages/kpi-formula/kpi-formula-importer.js.map +0 -1
  257. package/dist-client/pages/kpi-formula/kpi-formula-list-page.d.ts +0 -66
  258. package/dist-client/pages/kpi-formula/kpi-formula-list-page.js +0 -370
  259. package/dist-client/pages/kpi-formula/kpi-formula-list-page.js.map +0 -1
  260. package/dist-client/pages/metric/metric-importer.d.ts +0 -23
  261. package/dist-client/pages/metric/metric-importer.js +0 -93
  262. package/dist-client/pages/metric/metric-importer.js.map +0 -1
  263. package/dist-client/pages/metric/metric-list-page.d.ts +0 -66
  264. package/dist-client/pages/metric/metric-list-page.js +0 -370
  265. package/dist-client/pages/metric/metric-list-page.js.map +0 -1
  266. package/dist-server/service/kpi-formula/event-subscriber.d.ts +0 -7
  267. package/dist-server/service/kpi-formula/event-subscriber.js +0 -21
  268. package/dist-server/service/kpi-formula/event-subscriber.js.map +0 -1
  269. package/dist-server/service/kpi-formula/index.d.ts +0 -7
  270. package/dist-server/service/kpi-formula/index.js +0 -12
  271. package/dist-server/service/kpi-formula/index.js.map +0 -1
  272. package/dist-server/service/kpi-formula/kpi-formula-history.d.ts +0 -25
  273. package/dist-server/service/kpi-formula/kpi-formula-history.js +0 -128
  274. package/dist-server/service/kpi-formula/kpi-formula-history.js.map +0 -1
  275. package/dist-server/service/kpi-formula/kpi-formula-mutation.d.ts +0 -10
  276. package/dist-server/service/kpi-formula/kpi-formula-mutation.js +0 -128
  277. package/dist-server/service/kpi-formula/kpi-formula-mutation.js.map +0 -1
  278. package/dist-server/service/kpi-formula/kpi-formula-query.d.ts +0 -11
  279. package/dist-server/service/kpi-formula/kpi-formula-query.js +0 -79
  280. package/dist-server/service/kpi-formula/kpi-formula-query.js.map +0 -1
  281. package/dist-server/service/kpi-formula/kpi-formula-type.d.ts +0 -20
  282. package/dist-server/service/kpi-formula/kpi-formula-type.js +0 -77
  283. package/dist-server/service/kpi-formula/kpi-formula-type.js.map +0 -1
  284. package/dist-server/service/kpi-formula/kpi-formula.d.ts +0 -24
  285. package/dist-server/service/kpi-formula/kpi-formula.js +0 -109
  286. package/dist-server/service/kpi-formula/kpi-formula.js.map +0 -1
  287. package/dist-server/service/kpi-grade/event-subscriber.d.ts +0 -7
  288. package/dist-server/service/kpi-grade/event-subscriber.js +0 -21
  289. package/dist-server/service/kpi-grade/event-subscriber.js.map +0 -1
  290. package/dist-server/service/kpi-grade/kpi-grade-history.d.ts +0 -25
  291. package/dist-server/service/kpi-grade/kpi-grade-history.js +0 -128
  292. package/dist-server/service/kpi-grade/kpi-grade-history.js.map +0 -1
  293. package/dist-server/service/kpi-metric/event-subscriber.d.ts +0 -7
  294. package/dist-server/service/kpi-metric/event-subscriber.js +0 -21
  295. package/dist-server/service/kpi-metric/event-subscriber.js.map +0 -1
  296. package/dist-server/service/kpi-metric/kpi-metric-history.d.ts +0 -25
  297. package/dist-server/service/kpi-metric/kpi-metric-history.js +0 -128
  298. package/dist-server/service/kpi-metric/kpi-metric-history.js.map +0 -1
  299. package/server/service/kpi-formula/event-subscriber.ts +0 -17
  300. package/server/service/kpi-formula/index.ts +0 -9
  301. package/server/service/kpi-formula/kpi-formula-history.ts +0 -116
  302. package/server/service/kpi-formula/kpi-formula-mutation.ts +0 -137
  303. package/server/service/kpi-formula/kpi-formula-query.ts +0 -48
  304. package/server/service/kpi-formula/kpi-formula-type.ts +0 -55
  305. package/server/service/kpi-formula/kpi-formula.ts +0 -95
  306. package/server/service/kpi-grade/event-subscriber.ts +0 -17
  307. package/server/service/kpi-grade/kpi-grade-history.ts +0 -116
  308. package/server/service/kpi-metric/event-subscriber.ts +0 -17
  309. package/server/service/kpi-metric/kpi-metric-history.ts +0 -116
@@ -0,0 +1,271 @@
1
+ import { html, css, LitElement } from 'lit'
2
+ import { customElement, state } from 'lit/decorators.js'
3
+ import { marked } from 'marked'
4
+ import { PageView, store } from '@operato/shell'
5
+ import { i18next, localize } from '@operato/i18n'
6
+ import { client } from '@operato/graphql'
7
+ import gql from 'graphql-tag'
8
+
9
+ const GET_KPI_OVERVIEW = gql`
10
+ query {
11
+ kpiCategories {
12
+ items {
13
+ id
14
+ name
15
+ description
16
+ active
17
+ kpis {
18
+ id
19
+ name
20
+ description
21
+ formula
22
+ active
23
+ grades {
24
+ id
25
+ name
26
+ minValue
27
+ maxValue
28
+ score
29
+ color
30
+ description
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ `
37
+
38
+ @customElement('kpi-overview')
39
+ export class KpiOverview extends PageView {
40
+ static styles = css`
41
+ .overview-container {
42
+ display: flex;
43
+ gap: 32px;
44
+ background: #f7f5fa;
45
+ border-radius: 20px;
46
+ padding: 32px;
47
+ margin-bottom: 24px;
48
+ align-items: stretch;
49
+ }
50
+ .overview-left {
51
+ flex: 1;
52
+ display: flex;
53
+ flex-direction: column;
54
+ justify-content: center;
55
+ }
56
+ .overview-title {
57
+ font-size: 2.8rem;
58
+ font-weight: bold;
59
+ margin-bottom: 24px;
60
+ }
61
+ .overview-desc {
62
+ font-size: 1.2rem;
63
+ color: #222;
64
+ line-height: 1.6;
65
+ }
66
+ .overview-right {
67
+ flex: 1;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ }
72
+ .overview-img {
73
+ width: 100%;
74
+ max-width: 420px;
75
+ border-radius: 12px;
76
+ object-fit: cover;
77
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
78
+ }
79
+ .group-tabs {
80
+ display: flex;
81
+ gap: 8px;
82
+ margin: 0 0 16px 0;
83
+ justify-content: center;
84
+ }
85
+ .group-tab {
86
+ padding: 10px 28px;
87
+ border-radius: 16px 16px 0 0;
88
+ background: #eee;
89
+ cursor: pointer;
90
+ font-size: 1.1rem;
91
+ font-weight: 500;
92
+ border: none;
93
+ outline: none;
94
+ transition: background 0.2s;
95
+ }
96
+ .group-tab[selected] {
97
+ background: #d6d6f7;
98
+ color: #222;
99
+ font-weight: bold;
100
+ }
101
+ .kpi-list {
102
+ display: flex;
103
+ gap: 8px;
104
+ margin: 0 0 32px 0;
105
+ justify-content: center;
106
+ }
107
+ .kpi-item {
108
+ padding: 8px 20px;
109
+ border-radius: 12px;
110
+ background: #f5f5f5;
111
+ cursor: pointer;
112
+ font-size: 1rem;
113
+ border: none;
114
+ outline: none;
115
+ transition: background 0.2s;
116
+ }
117
+ .kpi-item[selected] {
118
+ background: #bdf;
119
+ color: #222;
120
+ font-weight: bold;
121
+ }
122
+ .main-content {
123
+ display: flex;
124
+ gap: 32px;
125
+ margin-top: 32px;
126
+ align-items: flex-start;
127
+ justify-content: center;
128
+ }
129
+ .markdown {
130
+ background: #fff;
131
+ border-radius: 12px;
132
+ padding: 40px 32px;
133
+ min-height: 240px;
134
+ flex: 2;
135
+ font-size: 2rem;
136
+ color: #222;
137
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
138
+ }
139
+ .toc {
140
+ flex: 1;
141
+ background: #faf9fd;
142
+ border-radius: 12px;
143
+ padding: 32px 24px;
144
+ font-size: 1.1rem;
145
+ color: #444;
146
+ min-width: 220px;
147
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
148
+ }
149
+ .toc-title {
150
+ font-weight: bold;
151
+ margin-bottom: 12px;
152
+ font-size: 1.2rem;
153
+ }
154
+ .toc-list {
155
+ margin: 0 0 16px 0;
156
+ padding: 0;
157
+ list-style: none;
158
+ }
159
+ .toc-list li {
160
+ margin-bottom: 6px;
161
+ }
162
+ .toc-btn {
163
+ display: block;
164
+ margin: 12px 0;
165
+ padding: 8px 16px;
166
+ border: 1px solid #aaa;
167
+ border-radius: 8px;
168
+ background: #fff;
169
+ color: #333;
170
+ cursor: pointer;
171
+ font-size: 1rem;
172
+ text-align: left;
173
+ transition: background 0.2s;
174
+ }
175
+ .toc-btn:hover {
176
+ background: #f0f0f0;
177
+ }
178
+ `
179
+
180
+ get context() {
181
+ return {
182
+ title: i18next.t('title.kpi overview')
183
+ }
184
+ }
185
+
186
+ @state() selectedGroup = 0
187
+ @state() selectedKpi = 0
188
+ @state() kpiCategories: any[] = []
189
+ @state() loading = true
190
+ @state() error: Error | null = null
191
+
192
+ async firstUpdated() {
193
+ try {
194
+ const { data } = await client.query({ query: GET_KPI_OVERVIEW })
195
+ this.kpiCategories = data.kpiCategories.items
196
+ this.loading = false
197
+ } catch (e) {
198
+ this.error = e instanceof Error ? e : new Error(String(e))
199
+ this.loading = false
200
+ }
201
+ }
202
+
203
+ render() {
204
+ if (this.error) return html`<div>에러: ${this.error?.message}</div>`
205
+ if (!this.kpiCategories.length) return html`<div>KPI 카테고리가 없습니다.</div>`
206
+
207
+ const group = this.kpiCategories[this.selectedGroup] as any
208
+ const kpi = group?.kpis?.[this.selectedKpi] as any
209
+ const md = kpi?.description || '각 지표의 주요 소개 내용을 마크다운으로 입력하세요.'
210
+
211
+ return html`
212
+ <div class="overview-container">
213
+ <div class="overview-left">
214
+ <div class="overview-title">KPI개요</div>
215
+ <div class="overview-desc">
216
+ 건설현장 KPI 관리 시스템은 프로젝트 성과를 측정하고 모니터링하여 효율적인 공정 관리를 지원합니다.<br />
217
+ 주요 지표를 통해 현장 생산성, 품질, 안전 등을 실시간으로 파악할 수 있습니다.
218
+ </div>
219
+ </div>
220
+ <div class="overview-right">
221
+ <img
222
+ class="overview-img"
223
+ src="https://images.unsplash.com/photo-1464983953574-0892a716854b?auto=format&fit=crop&w=600&q=80"
224
+ alt="건설현장 안전"
225
+ />
226
+ </div>
227
+ </div>
228
+ <div class="group-tabs">
229
+ ${this.kpiCategories.map(
230
+ (g, i) => html`
231
+ <button
232
+ class="group-tab"
233
+ ?selected=${i === this.selectedGroup}
234
+ @click=${() => {
235
+ this.selectedGroup = i
236
+ this.selectedKpi = 0
237
+ }}
238
+ >
239
+ ${g.name}
240
+ </button>
241
+ `
242
+ )}
243
+ </div>
244
+ <div class="main-content">
245
+ <div class="markdown">
246
+ <div style="font-size:1.5rem;font-weight:bold;margin-bottom:16px;">${kpi?.name || ''}</div>
247
+ <div style="margin-bottom:16px;">${kpi?.formula ? html`<b>산식:</b> ${kpi.formula}` : ''}</div>
248
+ <div .innerHTML=${marked(md)}></div>
249
+ ${kpi?.grades?.length
250
+ ? html`<div style="margin-top:32px;">
251
+ <b>등급 구간</b>
252
+ <ul>
253
+ ${kpi.grades.map(g => html`<li>${g.name}: ${g.minValue}~${g.maxValue} (${g.description || ''})</li>`)}
254
+ </ul>
255
+ </div>`
256
+ : ''}
257
+ </div>
258
+ <div class="toc">
259
+ <div class="toc-title">목차</div>
260
+ <ul class="toc-list">
261
+ ${group?.kpis?.map(
262
+ (k, i) => html`
263
+ <li><button class="toc-btn" @click=${() => (this.selectedKpi = i)}>${k.name}</button></li>
264
+ `
265
+ )}
266
+ </ul>
267
+ </div>
268
+ </div>
269
+ `
270
+ }
271
+ }
@@ -23,7 +23,6 @@ import { KpiCategoryImporter } from './kpi-category-importer'
23
23
 
24
24
  @customElement('kpi-category-list-page')
25
25
  export class KpiCategoryListPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
26
-
27
26
  static styles = [
28
27
  ScrollbarStyles,
29
28
  CommonGristStyles,
@@ -34,8 +33,8 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
34
33
 
35
34
  width: 100%;
36
35
 
37
- --grid-record-emphasized-background-color: #8B0000;
38
- --grid-record-emphasized-color: #FF6B6B;
36
+ --grid-record-emphasized-background-color: #8b0000;
37
+ --grid-record-emphasized-color: #ff6b6b;
39
38
  }
40
39
 
41
40
  ox-grist {
@@ -62,7 +61,7 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
62
61
 
63
62
  get context() {
64
63
  return {
65
- title: i18next.t('title.kpi-category list'),
64
+ title: i18next.t('title.kpi category list'),
66
65
  search: {
67
66
  handler: (search: string) => {
68
67
  this.grist.searchText = search
@@ -88,7 +87,7 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
88
87
  }
89
88
  ],
90
89
  exportable: {
91
- name: i18next.t('title.kpi-category list'),
90
+ name: i18next.t('title.kpi category list'),
92
91
  data: this.exportHandler.bind(this)
93
92
  },
94
93
  importable: {
@@ -101,11 +100,7 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
101
100
  const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
102
101
 
103
102
  return html`
104
- <ox-grist
105
- .mode=${mode}
106
- .config=${this.gristConfig}
107
- .fetchHandler=${this.fetchHandler.bind(this)}
108
- >
103
+ <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
109
104
  <div slot="headroom" class="header">
110
105
  <div class="filters">
111
106
  <ox-filters-form autofocus without-search></ox-filters-form>
@@ -121,7 +116,6 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
121
116
  <md-icon>add</md-icon>
122
117
  </button>
123
118
  </ox-record-creator>
124
-
125
119
  </div>
126
120
  </div>
127
121
  </ox-grist>
@@ -131,8 +125,8 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
131
125
  async pageInitialized(lifecycle: any) {
132
126
  this.gristConfig = {
133
127
  list: {
134
- fields: ['name', 'description'],
135
- details: ['active', 'updatedAt']
128
+ fields: ['name', 'description', 'active', 'parent', 'createdAt', 'updatedAt', 'creator', 'updater'],
129
+ details: ['name', 'description', 'active', 'parent', 'createdAt', 'updatedAt', 'creator', 'updater']
136
130
  },
137
131
  columns: [
138
132
  { type: 'gutter', gutterName: 'sequence' },
@@ -140,55 +134,60 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
140
134
  {
141
135
  type: 'string',
142
136
  name: 'name',
143
- header: i18next.t('field.name'),
144
- record: {
145
- editable: true
146
- },
137
+ header: '이름',
138
+ record: { editable: true },
147
139
  filter: 'search',
148
140
  sortable: true,
149
- width: 150
141
+ width: 120
150
142
  },
151
143
  {
152
144
  type: 'string',
153
145
  name: 'description',
154
146
  header: i18next.t('field.description'),
155
- record: {
156
- editable: true
157
- },
147
+ record: { editable: true },
158
148
  filter: 'search',
159
149
  width: 200
160
150
  },
151
+ {
152
+ type: 'string',
153
+ name: 'parent',
154
+ header: '상위분류',
155
+ record: { editable: false, renderer: (v, c, r) => r.parent?.name },
156
+ width: 120
157
+ },
161
158
  {
162
159
  type: 'checkbox',
163
160
  name: 'active',
164
161
  label: true,
165
162
  header: i18next.t('field.active'),
166
- record: {
167
- editable: true
168
- },
163
+ record: { editable: true },
169
164
  filter: true,
170
165
  sortable: true,
171
166
  width: 60
172
167
  },
173
- {
174
- type: 'resource-object',
175
- name: 'updater',
176
- header: i18next.t('field.updater'),
177
- record: {
178
- editable: false
179
- },
180
- sortable: true,
181
- width: 120
182
- },
168
+ { type: 'datetime', name: 'createdAt', header: '생성일', record: { editable: false }, width: 180 },
183
169
  {
184
170
  type: 'datetime',
185
171
  name: 'updatedAt',
186
172
  header: i18next.t('field.updated_at'),
187
- record: {
188
- editable: false
189
- },
173
+ record: { editable: false },
190
174
  sortable: true,
191
175
  width: 180
176
+ },
177
+ {
178
+ type: 'resource-object',
179
+ name: 'creator',
180
+ header: '생성자',
181
+ record: { editable: false, renderer: (v, c, r) => r.creator?.name },
182
+ width: 120
183
+ },
184
+ {
185
+ type: 'resource-object',
186
+ name: 'updater',
187
+ header: i18next.t('field.updater'),
188
+ record: { editable: false, renderer: (v, c, r) => r.updater?.name },
189
+ sortable: true,
190
+ width: 120
192
191
  }
193
192
  ],
194
193
  rows: {
@@ -197,11 +196,7 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
197
196
  multiple: true
198
197
  }
199
198
  },
200
- sorters: [
201
- {
202
- name: 'name'
203
- }
204
- ]
199
+ sorters: [{ name: 'name' }]
205
200
  }
206
201
  }
207
202
 
@@ -355,12 +350,7 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
355
350
 
356
351
  async exportHandler() {
357
352
  const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records
358
- const targetFieldSet = new Set([
359
- 'id',
360
- 'name',
361
- 'description',
362
- 'active'
363
- ])
353
+ const targetFieldSet = new Set(['id', 'name', 'description', 'active'])
364
354
 
365
355
  return exportTargets.map(kpiCategory => {
366
356
  let tempObj = {}
@@ -389,10 +379,9 @@ export class KpiCategoryListPage extends connect(store)(localize(i18next)(Scoped
389
379
  title: i18next.t('title.import kpi-category')
390
380
  }
391
381
  )
392
-
382
+
393
383
  popup.onclosed = () => {
394
384
  this.grist.fetch()
395
385
  }
396
386
  }
397
387
  }
398
-
@@ -0,0 +1,114 @@
1
+ import { html, css, LitElement } from 'lit'
2
+ import { customElement, state } from 'lit/decorators.js'
3
+ import { client } from '@operato/graphql'
4
+ import gql from 'graphql-tag'
5
+
6
+ @customElement('kpi-alert-panel')
7
+ export class KpiAlertPanel extends LitElement {
8
+ static styles = css`
9
+ .alert-container {
10
+ background: #fff;
11
+ border-radius: 16px;
12
+ padding: 32px;
13
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
14
+ margin-bottom: 16px;
15
+ }
16
+ .alert-title {
17
+ font-size: 1.5rem;
18
+ font-weight: bold;
19
+ margin-bottom: 16px;
20
+ }
21
+ .alert-list {
22
+ list-style: none;
23
+ padding: 0;
24
+ margin: 0;
25
+ }
26
+ .alert-item {
27
+ padding: 10px 0;
28
+ border-bottom: 1px solid #eee;
29
+ font-size: 1.1rem;
30
+ color: #d32f2f;
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 8px;
34
+ }
35
+ .alert-icon {
36
+ font-size: 1.3rem;
37
+ color: #d32f2f;
38
+ }
39
+ `
40
+
41
+ @state() alerts: Array<{ level: string; message: string; kpi?: { name: string }; createdAt: string }> = []
42
+ @state() loading = true
43
+ @state() error = ''
44
+
45
+ connectedCallback() {
46
+ super.connectedCallback()
47
+ this.fetchAlerts()
48
+ }
49
+
50
+ async fetchAlerts() {
51
+ this.loading = true
52
+ this.error = ''
53
+ try {
54
+ const response = await client.query({
55
+ query: gql`
56
+ query {
57
+ kpiAlerts {
58
+ id
59
+ message
60
+ level
61
+ createdAt
62
+ kpi {
63
+ name
64
+ }
65
+ }
66
+ }
67
+ `
68
+ })
69
+ this.alerts = response.data.kpiAlerts || []
70
+ } catch (e) {
71
+ this.error = 'KPI 알림 데이터를 불러오지 못했습니다.'
72
+ } finally {
73
+ this.loading = false
74
+ }
75
+ }
76
+
77
+ getIcon(level: string) {
78
+ switch (level) {
79
+ case 'critical':
80
+ return '❗'
81
+ case 'warning':
82
+ return '⚠️'
83
+ case 'info':
84
+ default:
85
+ return 'ℹ️'
86
+ }
87
+ }
88
+
89
+ render() {
90
+ if (this.loading) {
91
+ return html`<div class="alert-container">로딩 중...</div>`
92
+ }
93
+ if (this.error) {
94
+ return html`<div class="alert-container">${this.error}</div>`
95
+ }
96
+ return html`
97
+ <div class="alert-container">
98
+ <div class="alert-title">KPI 알림/상태/이상감지</div>
99
+ <ul class="alert-list">
100
+ ${this.alerts.length === 0
101
+ ? html`<li class="alert-item"><span class="alert-icon">✅</span> <span>이상/경고 없음</span></li>`
102
+ : this.alerts.map(
103
+ a => html`
104
+ <li class="alert-item">
105
+ <span class="alert-icon">${this.getIcon(a.level)}</span>
106
+ <span>${a.kpi?.name ? `[${a.kpi.name}] ` : ''}${a.message}</span>
107
+ </li>
108
+ `
109
+ )}
110
+ </ul>
111
+ </div>
112
+ `
113
+ }
114
+ }