@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.
- package/README.md +1 -2
- package/client/charts/kpi-boxplot-chart.ts +182 -42
- package/client/charts/kpi-radar-chart.ts +9 -9
- package/client/pages/kpi/kpi-list-page.ts +196 -32
- package/client/pages/kpi/kpi-overview.ts +9 -11
- package/client/pages/kpi/kpi-tree-page.ts +409 -0
- package/client/pages/kpi/kpi-view.ts +187 -0
- package/client/pages/kpi-dashboard/cards/kpi-level1-card.ts +1 -1
- package/client/pages/kpi-dashboard/cards/kpi-level2-comparison.ts +1 -1
- package/client/pages/kpi-dashboard/cards/kpi-level3-comparison.ts +1 -1
- package/client/pages/kpi-dashboard/components/kpi-left-panel.ts +198 -160
- package/client/pages/kpi-dashboard/components/kpi-map-panel.ts +133 -0
- package/client/pages/kpi-dashboard/components/kpi-region-popup.ts +3 -2
- package/client/pages/kpi-dashboard/kpi-dashboard-map.ts +291 -48
- package/client/pages/kpi-dashboard/kpi-dashboard.ts +28 -30
- package/client/pages/kpi-history/kpi-history-list-page.ts +11 -11
- package/client/pages/kpi-metric/kpi-metric-list-page.ts +10 -2
- package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +7 -7
- package/client/pages/kpi-metric-value/kpi-metric-value-importer.ts +2 -2
- package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +16 -8
- package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.ts +5 -5
- package/client/pages/kpi-statistic/kpi-statistic-editor-page.ts +1 -2
- package/client/pages/kpi-statistic/kpi-statistic-list-page.ts +10 -2
- package/client/pages/kpi-value/kpi-value-editor-page.ts +11 -7
- package/client/pages/kpi-value/kpi-value-list-page.ts +31 -7
- package/client/route.ts +2 -9
- package/design-entities.md +8 -12
- package/dist-client/charts/kpi-boxplot-chart.d.ts +2 -0
- package/dist-client/charts/kpi-boxplot-chart.js +168 -42
- package/dist-client/charts/kpi-boxplot-chart.js.map +1 -1
- package/dist-client/charts/kpi-radar-chart.js +9 -9
- package/dist-client/charts/kpi-radar-chart.js.map +1 -1
- package/dist-client/pages/kpi/kpi-list-page.d.ts +19 -3
- package/dist-client/pages/kpi/kpi-list-page.js +188 -32
- package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
- package/dist-client/pages/kpi/kpi-overview.js +9 -11
- package/dist-client/pages/kpi/kpi-overview.js.map +1 -1
- package/dist-client/pages/kpi/kpi-tree-page.d.ts +59 -0
- package/dist-client/pages/kpi/kpi-tree-page.js +403 -0
- package/dist-client/pages/kpi/kpi-tree-page.js.map +1 -0
- package/dist-client/pages/kpi/kpi-view.d.ts +12 -0
- package/dist-client/pages/kpi/kpi-view.js +191 -0
- package/dist-client/pages/kpi/kpi-view.js.map +1 -0
- package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js +1 -1
- package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js +1 -1
- package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js +1 -1
- package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +3 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +197 -161
- package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +5 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +146 -0
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +3 -2
- package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +3 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +268 -46
- package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +28 -30
- package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -1
- package/dist-client/pages/kpi-history/kpi-history-list-page.d.ts +6 -1
- package/dist-client/pages/kpi-history/kpi-history-list-page.js +11 -11
- package/dist-client/pages/kpi-history/kpi-history-list-page.js.map +1 -1
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.d.ts +5 -0
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +10 -2
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +8 -8
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js +2 -2
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-importer.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +5 -0
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +16 -8
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.d.ts +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +6 -6
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -1
- package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js +1 -2
- package/dist-client/pages/kpi-statistic/kpi-statistic-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.d.ts +5 -0
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js +10 -2
- package/dist-client/pages/kpi-statistic/kpi-statistic-list-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +2 -1
- package/dist-client/pages/kpi-value/kpi-value-editor-page.js +16 -8
- package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -1
- package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +5 -0
- package/dist-client/pages/kpi-value/kpi-value-list-page.js +31 -7
- package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +2 -8
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/kpi-metric-value-provider.d.ts +1 -1
- package/dist-server/controllers/kpi-metric-value-provider.js +4 -4
- package/dist-server/controllers/kpi-metric-value-provider.js.map +1 -1
- package/dist-server/controllers/kpi-value-provider.d.ts +1 -1
- package/dist-server/controllers/kpi-value-provider.js +3 -3
- package/dist-server/controllers/kpi-value-provider.js.map +1 -1
- package/dist-server/migrations/1752190849680-seed-kpi-metrics.d.ts +6 -0
- package/dist-server/migrations/1752190849680-seed-kpi-metrics.js +101 -0
- package/dist-server/migrations/1752190849680-seed-kpi-metrics.js.map +1 -0
- package/dist-server/migrations/1752190849681-seed-kpi.d.ts +5 -0
- package/dist-server/migrations/1752190849681-seed-kpi.js +315 -0
- package/dist-server/migrations/1752190849681-seed-kpi.js.map +1 -0
- package/dist-server/migrations/1752192090123-add-grades-to-kpi.d.ts +7 -0
- package/dist-server/migrations/1752192090123-add-grades-to-kpi.js +51 -0
- package/dist-server/migrations/1752192090123-add-grades-to-kpi.js.map +1 -0
- package/dist-server/migrations/1752192090124-add-kpi-statistics.d.ts +5 -0
- package/dist-server/migrations/1752192090124-add-kpi-statistics.js +710 -0
- package/dist-server/migrations/1752192090124-add-kpi-statistics.js.map +1 -0
- package/dist-server/migrations/1752192090128-seed-kpi-org-scope.d.ts +6 -0
- package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js +111 -0
- package/dist-server/migrations/1752192090128-seed-kpi-org-scope.js.map +1 -0
- package/dist-server/migrations/1752192090129-seed-kpi-values.d.ts +6 -0
- package/dist-server/migrations/1752192090129-seed-kpi-values.js +187 -0
- package/dist-server/migrations/1752192090129-seed-kpi-values.js.map +1 -0
- package/dist-server/migrations/grade-data/x11-performance-table.json +962 -0
- package/dist-server/migrations/grade-data/x12-performance-table.json +611 -0
- package/dist-server/migrations/grade-data/x14-performance-table.json +42 -0
- package/dist-server/migrations/grade-data/x21-performance-table.json +889 -0
- package/dist-server/migrations/grade-data/x22-performance-table.json +1064 -0
- package/dist-server/migrations/grade-data/x23-performance-table.json +42 -0
- package/dist-server/migrations/grade-data/x31-performance-table.json +644 -0
- package/dist-server/migrations/grade-data/x32-performance-table.json +993 -0
- package/dist-server/migrations/grade-data/x33-performance-table.json +195 -0
- package/dist-server/migrations/grade-data/x34-performance-table.json +12 -0
- package/dist-server/migrations/grade-data/x35-performance-table.json +42 -0
- package/dist-server/migrations/grade-data/x41-performance-table.json +825 -0
- package/dist-server/migrations/grade-data/x42-performance-table.json +786 -0
- package/dist-server/migrations/grade-data/x43-performance-table.json +12 -0
- package/dist-server/migrations/grade-data/x44-performance-table.json +42 -0
- package/dist-server/migrations/grade-data/x51-performance-table.json +924 -0
- package/dist-server/migrations/grade-data/x52-performance-table.json +42 -0
- package/dist-server/migrations/grade-data/x61-performance-table.json +261 -0
- package/dist-server/migrations/grade-data/x62-performance-table.json +42 -0
- package/dist-server/migrations/seed-data/kpi-metrics-seed.json +454 -0
- package/dist-server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
- package/dist-server/migrations/seed-data/kpi-scopes-seed.json +121 -0
- package/dist-server/migrations/seed-data/kpi-values-seed.json +402 -0
- package/dist-server/migrations/seed-data/kpis-seed.json +488 -0
- package/dist-server/migrations/seed-data/scope-definitions-seed.json +90 -0
- package/dist-server/service/index.d.ts +4 -7
- package/dist-server/service/index.js +10 -13
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/kpi/aggregate-kpi.js +30 -13
- package/dist-server/service/kpi/aggregate-kpi.js.map +1 -1
- package/dist-server/service/kpi/kpi-formula.service.d.ts +15 -0
- package/dist-server/service/kpi/kpi-formula.service.js +90 -0
- package/dist-server/service/kpi/kpi-formula.service.js.map +1 -1
- package/dist-server/service/kpi/kpi-history.d.ts +0 -3
- package/dist-server/service/kpi/kpi-history.js +0 -10
- package/dist-server/service/kpi/kpi-history.js.map +1 -1
- package/dist-server/service/kpi/kpi-mutation.d.ts +1 -1
- package/dist-server/service/kpi/kpi-mutation.js +57 -20
- package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
- package/dist-server/service/kpi/kpi-query.d.ts +7 -3
- package/dist-server/service/kpi/kpi-query.js +126 -10
- package/dist-server/service/kpi/kpi-query.js.map +1 -1
- package/dist-server/service/kpi/kpi-type.d.ts +4 -2
- package/dist-server/service/kpi/kpi-type.js +12 -4
- package/dist-server/service/kpi/kpi-type.js.map +1 -1
- package/dist-server/service/kpi/kpi.d.ts +4 -3
- package/dist-server/service/kpi/kpi.js +20 -8
- package/dist-server/service/kpi/kpi.js.map +1 -1
- package/dist-server/service/kpi-metric/aggregate-kpi-metric.js +46 -11
- package/dist-server/service/kpi-metric/aggregate-kpi-metric.js.map +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +6 -6
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value-type.d.ts +2 -2
- package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js +4 -4
- package/dist-server/service/kpi-metric-value/kpi-metric-value-type.js.map +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value.d.ts +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value.js +3 -3
- package/dist-server/service/kpi-metric-value/kpi-metric-value.js.map +1 -1
- package/dist-server/service/kpi-org-scope/index.d.ts +5 -0
- package/dist-server/service/kpi-org-scope/index.js +9 -0
- package/dist-server/service/kpi-org-scope/index.js.map +1 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.d.ts +8 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js +170 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-mutation.js.map +1 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-query.d.ts +14 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js +152 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-query.js.map +1 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-type.d.ts +26 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js +101 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope-type.js.map +1 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope.d.ts +26 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope.js +135 -0
- package/dist-server/service/kpi-org-scope/kpi-org-scope.js.map +1 -0
- package/dist-server/service/kpi-scope/index.d.ts +9 -0
- package/dist-server/service/kpi-scope/index.js +14 -0
- package/dist-server/service/kpi-scope/index.js.map +1 -0
- package/dist-server/service/kpi-scope/kpi-scope-mutation.d.ts +9 -0
- package/dist-server/service/kpi-scope/kpi-scope-mutation.js +135 -0
- package/dist-server/service/kpi-scope/kpi-scope-mutation.js.map +1 -0
- package/dist-server/service/kpi-scope/kpi-scope-query.d.ts +11 -0
- package/dist-server/service/kpi-scope/kpi-scope-query.js +89 -0
- package/dist-server/service/kpi-scope/kpi-scope-query.js.map +1 -0
- package/dist-server/service/kpi-scope/kpi-scope-type.d.ts +35 -0
- package/dist-server/service/kpi-scope/kpi-scope-type.js +138 -0
- package/dist-server/service/kpi-scope/kpi-scope-type.js.map +1 -0
- package/dist-server/service/kpi-scope/kpi-scope.d.ts +38 -0
- package/dist-server/service/kpi-scope/kpi-scope.js +144 -0
- package/dist-server/service/kpi-scope/kpi-scope.js.map +1 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.d.ts +43 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js +181 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js.map +1 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.d.ts +50 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js +324 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js.map +1 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +4 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +76 -0
- package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -1
- package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +5 -1
- package/dist-server/service/kpi-statistic/kpi-statistic-query.js +92 -1
- package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -1
- package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +4 -0
- package/dist-server/service/kpi-statistic/kpi-statistic.js +33 -0
- package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-mutation.js +71 -7
- package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-type.d.ts +4 -2
- package/dist-server/service/kpi-value/kpi-value-type.js +12 -4
- package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value.d.ts +3 -1
- package/dist-server/service/kpi-value/kpi-value.js +11 -5
- package/dist-server/service/kpi-value/kpi-value.js.map +1 -1
- package/dist-server/service/utils/value-date-util.d.ts +1 -0
- package/dist-server/service/utils/value-date-util.js +41 -0
- package/dist-server/service/utils/value-date-util.js.map +1 -1
- package/dist-server/tsconfig.json +10 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/server/@types/index.d.ts +11 -0
- package/server/controllers/kpi-metric-value-provider.ts +5 -5
- package/server/controllers/kpi-value-provider.ts +4 -4
- package/server/migrations/1752190849680-seed-kpi-metrics.ts +124 -0
- package/server/migrations/1752190849681-seed-kpi.ts +356 -0
- package/server/migrations/1752192090123-add-grades-to-kpi.ts +67 -0
- package/server/migrations/1752192090124-add-kpi-statistics.ts +719 -0
- package/server/migrations/1752192090128-seed-kpi-org-scope.ts +132 -0
- package/server/migrations/1752192090129-seed-kpi-values.ts +207 -0
- package/server/migrations/grade-data/x11-performance-table.json +962 -0
- package/server/migrations/grade-data/x12-performance-table.json +611 -0
- package/server/migrations/grade-data/x14-performance-table.json +42 -0
- package/server/migrations/grade-data/x21-performance-table.json +889 -0
- package/server/migrations/grade-data/x22-performance-table.json +1064 -0
- package/server/migrations/grade-data/x23-performance-table.json +42 -0
- package/server/migrations/grade-data/x31-performance-table.json +644 -0
- package/server/migrations/grade-data/x32-performance-table.json +993 -0
- package/server/migrations/grade-data/x33-performance-table.json +195 -0
- package/server/migrations/grade-data/x34-performance-table.json +12 -0
- package/server/migrations/grade-data/x35-performance-table.json +42 -0
- package/server/migrations/grade-data/x41-performance-table.json +825 -0
- package/server/migrations/grade-data/x42-performance-table.json +786 -0
- package/server/migrations/grade-data/x43-performance-table.json +12 -0
- package/server/migrations/grade-data/x44-performance-table.json +42 -0
- package/server/migrations/grade-data/x51-performance-table.json +924 -0
- package/server/migrations/grade-data/x52-performance-table.json +42 -0
- package/server/migrations/grade-data/x61-performance-table.json +261 -0
- package/server/migrations/grade-data/x62-performance-table.json +42 -0
- package/server/migrations/seed-data/kpi-metrics-seed.json +454 -0
- package/server/migrations/seed-data/kpi-org-scope-seed.json +1676 -0
- package/server/migrations/seed-data/kpi-scopes-seed.json +121 -0
- package/server/migrations/seed-data/kpi-values-seed.json +402 -0
- package/server/migrations/seed-data/kpis-seed.json +488 -0
- package/server/migrations/seed-data/scope-definitions-seed.json +90 -0
- package/server/service/index.ts +10 -13
- package/server/service/kpi/aggregate-kpi.ts +31 -13
- package/server/service/kpi/kpi-formula.service.ts +101 -0
- package/server/service/kpi/kpi-history.ts +0 -8
- package/server/service/kpi/kpi-mutation.ts +59 -19
- package/server/service/kpi/kpi-query.ts +119 -8
- package/server/service/kpi/kpi-type.ts +10 -4
- package/server/service/kpi/kpi.ts +17 -7
- package/server/service/kpi-metric/aggregate-kpi-metric.ts +55 -11
- package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +6 -6
- package/server/service/kpi-metric-value/kpi-metric-value-type.ts +4 -4
- package/server/service/kpi-metric-value/kpi-metric-value.ts +3 -3
- package/server/service/kpi-org-scope/index.ts +6 -0
- package/server/service/kpi-org-scope/kpi-org-scope-mutation.ts +173 -0
- package/server/service/kpi-org-scope/kpi-org-scope-query.ts +127 -0
- package/server/service/kpi-org-scope/kpi-org-scope-type.ts +68 -0
- package/server/service/kpi-org-scope/kpi-org-scope.ts +123 -0
- package/server/service/kpi-scope/index.ts +11 -0
- package/server/service/kpi-scope/kpi-scope-mutation.ts +129 -0
- package/server/service/kpi-scope/kpi-scope-query.ts +63 -0
- package/server/service/kpi-scope/kpi-scope-type.ts +96 -0
- package/server/service/kpi-scope/kpi-scope.ts +143 -0
- package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +231 -0
- package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +410 -0
- package/server/service/kpi-statistic/kpi-statistic-mutation.ts +97 -0
- package/server/service/kpi-statistic/kpi-statistic-query.ts +89 -2
- package/server/service/kpi-statistic/kpi-statistic.ts +32 -0
- package/server/service/kpi-value/kpi-value-mutation.ts +73 -7
- package/server/service/kpi-value/kpi-value-type.ts +10 -4
- package/server/service/kpi-value/kpi-value.ts +10 -5
- package/server/service/utils/value-date-util.ts +47 -0
- package/server/types/global.d.ts +8 -0
- package/things-factory.config.js +1 -0
- package/translations/en.json +15 -3
- package/translations/ja.json +13 -3
- package/translations/ko.json +15 -3
- package/translations/ms.json +13 -3
- package/translations/zh.json +13 -3
- package/client/pages/kpi-category/kpi-category-importer.ts +0 -90
- package/client/pages/kpi-category/kpi-category-list-page.ts +0 -537
- package/client/pages/kpi-category/kpi-category-value-calculator.ts +0 -233
- package/client/pages/kpi-category-value/kpi-category-value-list-page.ts +0 -404
- package/dist-client/pages/kpi-category/kpi-category-importer.d.ts +0 -23
- package/dist-client/pages/kpi-category/kpi-category-importer.js +0 -92
- package/dist-client/pages/kpi-category/kpi-category-importer.js.map +0 -1
- package/dist-client/pages/kpi-category/kpi-category-list-page.d.ts +0 -74
- package/dist-client/pages/kpi-category/kpi-category-list-page.js +0 -517
- package/dist-client/pages/kpi-category/kpi-category-list-page.js.map +0 -1
- package/dist-client/pages/kpi-category/kpi-category-value-calculator.d.ts +0 -13
- package/dist-client/pages/kpi-category/kpi-category-value-calculator.js +0 -256
- package/dist-client/pages/kpi-category/kpi-category-value-calculator.js.map +0 -1
- package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.d.ts +0 -63
- package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js +0 -393
- package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js.map +0 -1
- package/dist-server/service/kpi-category/index.d.ts +0 -6
- package/dist-server/service/kpi-category/index.js +0 -10
- package/dist-server/service/kpi-category/index.js.map +0 -1
- package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +0 -9
- package/dist-server/service/kpi-category/kpi-category-mutation.js +0 -221
- package/dist-server/service/kpi-category/kpi-category-mutation.js.map +0 -1
- package/dist-server/service/kpi-category/kpi-category-query.d.ts +0 -18
- package/dist-server/service/kpi-category/kpi-category-query.js +0 -115
- package/dist-server/service/kpi-category/kpi-category-query.js.map +0 -1
- package/dist-server/service/kpi-category/kpi-category-type.d.ts +0 -24
- package/dist-server/service/kpi-category/kpi-category-type.js +0 -100
- package/dist-server/service/kpi-category/kpi-category-type.js.map +0 -1
- package/dist-server/service/kpi-category/kpi-category.d.ts +0 -22
- package/dist-server/service/kpi-category/kpi-category.js +0 -106
- package/dist-server/service/kpi-category/kpi-category.js.map +0 -1
- package/dist-server/service/kpi-category-value/index.d.ts +0 -6
- package/dist-server/service/kpi-category-value/index.js +0 -10
- package/dist-server/service/kpi-category-value/index.js.map +0 -1
- package/dist-server/service/kpi-category-value/kpi-category-value-mutation.d.ts +0 -8
- package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js +0 -102
- package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js.map +0 -1
- package/dist-server/service/kpi-category-value/kpi-category-value-query.d.ts +0 -13
- package/dist-server/service/kpi-category-value/kpi-category-value-query.js +0 -91
- package/dist-server/service/kpi-category-value/kpi-category-value-query.js.map +0 -1
- package/dist-server/service/kpi-category-value/kpi-category-value-type.d.ts +0 -19
- package/dist-server/service/kpi-category-value/kpi-category-value-type.js +0 -73
- package/dist-server/service/kpi-category-value/kpi-category-value-type.js.map +0 -1
- package/dist-server/service/kpi-category-value/kpi-category-value.d.ts +0 -19
- package/dist-server/service/kpi-category-value/kpi-category-value.js +0 -91
- package/dist-server/service/kpi-category-value/kpi-category-value.js.map +0 -1
- package/helps/kpi/kpi-category.md +0 -160
- package/server/service/kpi-category/index.ts +0 -7
- package/server/service/kpi-category/kpi-category-mutation.ts +0 -217
- package/server/service/kpi-category/kpi-category-query.ts +0 -87
- package/server/service/kpi-category/kpi-category-type.ts +0 -73
- package/server/service/kpi-category/kpi-category.ts +0 -95
- package/server/service/kpi-category-value/index.ts +0 -7
- package/server/service/kpi-category-value/kpi-category-value-mutation.ts +0 -88
- package/server/service/kpi-category-value/kpi-category-value-query.ts +0 -62
- package/server/service/kpi-category-value/kpi-category-value-type.ts +0 -48
- package/server/service/kpi-category-value/kpi-category-value.ts +0 -79
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { getRepository } from '@things-factory/shell'
|
|
2
|
+
import type ResolverContext from '@things-factory/auth-base'
|
|
2
3
|
import { DataSummary } from '@things-factory/dataset'
|
|
3
4
|
import { finalizeLatestDataCollection } from '@things-factory/dataset/dist-server/controllers/finalize-data-collection'
|
|
4
5
|
import { KpiMetric } from './kpi-metric'
|
|
5
6
|
import { KpiValue, KpiValueInputType } from '../kpi-value/kpi-value'
|
|
6
7
|
import { Kpi } from '../kpi/kpi'
|
|
8
|
+
import { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope'
|
|
7
9
|
import { KpiFormulaService } from '../kpi/kpi-formula.service'
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -38,7 +40,7 @@ export async function aggregateKpiMetricValue(metricId: string, domainId: string
|
|
|
38
40
|
date: summary.date,
|
|
39
41
|
period: summary.period,
|
|
40
42
|
value: summary.summary[metric.fieldName],
|
|
41
|
-
|
|
43
|
+
org: {
|
|
42
44
|
key01: summary.key01,
|
|
43
45
|
key02: summary.key02,
|
|
44
46
|
key03: summary.key03,
|
|
@@ -56,32 +58,74 @@ export async function aggregateKpiMetricValue(metricId: string, domainId: string
|
|
|
56
58
|
const kpi = await getRepository(Kpi).findOne({ where: { name: metric.name, domain: { id: domainId } } })
|
|
57
59
|
if (!kpi) throw new Error('KPI 정보 없음 (metric.name과 동일한 KPI name 기준, 실제 연동 구조에 맞게 보완 필요)')
|
|
58
60
|
|
|
59
|
-
// KPI Value version, valueDate,
|
|
61
|
+
// KPI Value version, valueDate, org 등 매핑
|
|
60
62
|
const savedValues = []
|
|
63
|
+
const kpiOrgScopeRepo = getRepository(KpiOrgScope, context.state?.tx)
|
|
64
|
+
const kpiValueRepo = getRepository(KpiValue, context.state?.tx)
|
|
65
|
+
|
|
61
66
|
for (const v of values) {
|
|
62
67
|
const valueDate = v.date
|
|
63
|
-
const
|
|
68
|
+
const orgData = v.org
|
|
64
69
|
const version = kpi.version || 1
|
|
65
70
|
const value = v.value
|
|
66
71
|
if (value == null || isNaN(value)) continue
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
|
|
73
|
+
// KpiOrgScope 찾기 또는 생성
|
|
74
|
+
let kpiOrgScope: KpiOrgScope | null = null
|
|
75
|
+
|
|
76
|
+
// key들로 조합된 org 식별자 생성
|
|
77
|
+
const orgIdentifier =
|
|
78
|
+
[orgData.key01, orgData.key02, orgData.key03, orgData.key04, orgData.key05].filter(Boolean).join('-') ||
|
|
79
|
+
'unknown-org'
|
|
80
|
+
|
|
81
|
+
// 기존 KpiOrgScope 조회 (entityName 기준)
|
|
82
|
+
kpiOrgScope = await kpiOrgScopeRepo.findOne({
|
|
83
|
+
where: { entityName: orgIdentifier, domain: { id: domainId } }
|
|
71
84
|
})
|
|
72
|
-
|
|
85
|
+
|
|
86
|
+
// 없으면 새로 생성
|
|
87
|
+
if (!kpiOrgScope) {
|
|
88
|
+
kpiOrgScope = await kpiOrgScopeRepo.save({
|
|
89
|
+
entityType: 'DataSummary', // DataSummary에서 온 데이터임을 표시
|
|
90
|
+
entityId: `datasummary-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
91
|
+
entityName: orgIdentifier,
|
|
92
|
+
org: orgIdentifier, // legacy field
|
|
93
|
+
scope01: orgData.key01,
|
|
94
|
+
scope02: orgData.key02,
|
|
95
|
+
scope03: orgData.key03,
|
|
96
|
+
scope04: orgData.key04,
|
|
97
|
+
scope05: orgData.key05,
|
|
98
|
+
domain: kpi.domain,
|
|
99
|
+
creator: context.state?.user,
|
|
100
|
+
updater: context.state?.user
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// upsert KpiValue (동일 KPI, valueDate, kpiOrgScope, version 기준)
|
|
105
|
+
const existing = await kpiValueRepo.findOne({
|
|
106
|
+
where: {
|
|
107
|
+
kpi: { id: kpi.id },
|
|
108
|
+
valueDate,
|
|
109
|
+
kpiOrgScope: { id: kpiOrgScope.id },
|
|
110
|
+
version,
|
|
111
|
+
domain: { id: domainId }
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
let entity = existing || kpiValueRepo.create()
|
|
73
116
|
entity.kpi = kpi
|
|
74
117
|
entity.kpiId = kpi.id
|
|
75
118
|
entity.version = version
|
|
76
119
|
entity.valueDate = valueDate
|
|
77
120
|
entity.value = value
|
|
78
|
-
entity.
|
|
121
|
+
entity.kpiOrgScope = kpiOrgScope
|
|
122
|
+
entity.kpiOrgScopeId = kpiOrgScope.id
|
|
79
123
|
entity.inputType = KpiValueInputType.AUTO
|
|
80
|
-
entity.source = 'AUTO'
|
|
124
|
+
entity.source = 'AUTO-AGGREGATE'
|
|
81
125
|
entity.domain = kpi.domain
|
|
82
126
|
entity.creator = context.state?.user
|
|
83
127
|
entity.updater = context.state?.user
|
|
84
|
-
entity = await
|
|
128
|
+
entity = await kpiValueRepo.save(entity)
|
|
85
129
|
savedValues.push(entity)
|
|
86
130
|
}
|
|
87
131
|
return savedValues
|
|
@@ -47,7 +47,7 @@ export class KpiMetricValueMutation {
|
|
|
47
47
|
valueDate,
|
|
48
48
|
periodType,
|
|
49
49
|
value: metricValue.value,
|
|
50
|
-
|
|
50
|
+
org: metricValue.org,
|
|
51
51
|
unit: metricValue.unit,
|
|
52
52
|
meta: metricValue.meta,
|
|
53
53
|
domain: domain,
|
|
@@ -60,14 +60,14 @@ export class KpiMetricValueMutation {
|
|
|
60
60
|
|
|
61
61
|
@Directive('@transaction')
|
|
62
62
|
@Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
63
|
-
@Mutation(returns => KpiMetricValue, { description: 'Record a metric value by metric name, value, meta, and
|
|
63
|
+
@Mutation(returns => KpiMetricValue, { description: 'Record a metric value by metric name, value, meta, and org.' })
|
|
64
64
|
async recordKpiMetricValue(
|
|
65
65
|
@Arg('metricName', { description: 'Metric code/name.' }) metricName: string,
|
|
66
66
|
@Arg('value', type => Float, { nullable: true, description: 'Metric value (number).' }) value: number | null,
|
|
67
67
|
@Arg('meta', type => ScalarObject, { nullable: true, description: 'Extended or non-numeric information (JSON).' })
|
|
68
68
|
meta: any,
|
|
69
|
-
@Arg('
|
|
70
|
-
|
|
69
|
+
@Arg('org', { nullable: true, description: 'Organizational unit for this value (project, department, company, employee, etc.)' })
|
|
70
|
+
org: string | null,
|
|
71
71
|
@Ctx() context: ResolverContext
|
|
72
72
|
): Promise<KpiMetricValue> {
|
|
73
73
|
const { domain, user, tx } = context.state
|
|
@@ -84,7 +84,7 @@ export class KpiMetricValueMutation {
|
|
|
84
84
|
metric: { id: metric.id },
|
|
85
85
|
valueDate,
|
|
86
86
|
periodType,
|
|
87
|
-
|
|
87
|
+
org,
|
|
88
88
|
domain: { id: domain.id }
|
|
89
89
|
}
|
|
90
90
|
})
|
|
@@ -100,7 +100,7 @@ export class KpiMetricValueMutation {
|
|
|
100
100
|
meta,
|
|
101
101
|
valueDate,
|
|
102
102
|
periodType,
|
|
103
|
-
|
|
103
|
+
org,
|
|
104
104
|
domain,
|
|
105
105
|
creator: user,
|
|
106
106
|
updater: user
|
|
@@ -29,8 +29,8 @@ export class NewKpiMetricValue {
|
|
|
29
29
|
})
|
|
30
30
|
meta?: any
|
|
31
31
|
|
|
32
|
-
@Field({ nullable: true, description: '
|
|
33
|
-
|
|
32
|
+
@Field({ nullable: true, description: 'Organizational unit for this value (project, department, company, employee, etc.)' })
|
|
33
|
+
org?: string
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
@InputType({
|
|
@@ -65,8 +65,8 @@ export class KpiMetricValuePatch {
|
|
|
65
65
|
})
|
|
66
66
|
meta?: any
|
|
67
67
|
|
|
68
|
-
@Field({ nullable: true, description: '
|
|
69
|
-
|
|
68
|
+
@Field({ nullable: true, description: 'Organizational unit for this value (project, department, company, employee, etc.)' })
|
|
69
|
+
org?: string
|
|
70
70
|
|
|
71
71
|
@Field({ nullable: true, description: 'Custom flag for update operations (internal use).' })
|
|
72
72
|
cuFlag?: string
|
|
@@ -16,7 +16,7 @@ import { KpiPeriodType } from '../kpi/kpi'
|
|
|
16
16
|
import { User } from '@things-factory/auth-base'
|
|
17
17
|
|
|
18
18
|
@Entity()
|
|
19
|
-
@Index('ix_kpi_metric_value_latest', ['domain', 'metric', 'valueDate', '
|
|
19
|
+
@Index('ix_kpi_metric_value_latest', ['domain', 'metric', 'valueDate', 'org'], { unique: true })
|
|
20
20
|
@ObjectType({ description: 'Current value for each KPI metric (can be used for both state and history).' })
|
|
21
21
|
export class KpiMetricValue {
|
|
22
22
|
@PrimaryGeneratedColumn('uuid')
|
|
@@ -60,8 +60,8 @@ export class KpiMetricValue {
|
|
|
60
60
|
periodType: KpiPeriodType
|
|
61
61
|
|
|
62
62
|
@Column({ default: '' })
|
|
63
|
-
@Field({ nullable: true, description: '
|
|
64
|
-
|
|
63
|
+
@Field({ nullable: true, description: 'Organizational unit for this value (project, department, company, employee, etc.)' })
|
|
64
|
+
org?: string
|
|
65
65
|
|
|
66
66
|
@Column({ type: 'simple-json', nullable: true })
|
|
67
67
|
@Field(type => ScalarObject, { nullable: true })
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { KpiOrgScope } from './kpi-org-scope'
|
|
2
|
+
import { KpiOrgScopeQuery } from './kpi-org-scope-query'
|
|
3
|
+
import { KpiOrgScopeMutation } from './kpi-org-scope-mutation'
|
|
4
|
+
|
|
5
|
+
export const entities = [KpiOrgScope]
|
|
6
|
+
export const resolvers = [KpiOrgScopeQuery, KpiOrgScopeMutation]
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
+
import { In } from 'typeorm'
|
|
3
|
+
import { getRepository } from '@things-factory/shell'
|
|
4
|
+
|
|
5
|
+
import { KpiOrgScope } from './kpi-org-scope'
|
|
6
|
+
import { NewKpiOrgScope, KpiOrgScopePatch } from './kpi-org-scope-type'
|
|
7
|
+
|
|
8
|
+
@Resolver(KpiOrgScope)
|
|
9
|
+
export class KpiOrgScopeMutation {
|
|
10
|
+
@Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
11
|
+
@Directive('@transaction')
|
|
12
|
+
@Mutation(returns => KpiOrgScope, { description: 'Create a new KPI org-scope mapping with the provided details.' })
|
|
13
|
+
async createKpiOrgScope(
|
|
14
|
+
@Arg('kpiOrgScope', { description: 'Input object containing details for the new org-scope mapping.' })
|
|
15
|
+
kpiOrgScope: NewKpiOrgScope,
|
|
16
|
+
@Ctx() context: ResolverContext
|
|
17
|
+
): Promise<KpiOrgScope> {
|
|
18
|
+
const { domain, user, tx } = context.state
|
|
19
|
+
|
|
20
|
+
// Check if org already exists for this domain
|
|
21
|
+
const existingOrgScope = await getRepository(KpiOrgScope, tx).findOne({
|
|
22
|
+
where: { domain: { id: domain.id }, org: kpiOrgScope.org }
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
if (existingOrgScope) {
|
|
26
|
+
throw new Error(`Organization '${kpiOrgScope.org}' already has a scope mapping in this domain`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const entity: Partial<KpiOrgScope> = {
|
|
30
|
+
...kpiOrgScope,
|
|
31
|
+
domain,
|
|
32
|
+
creator: user,
|
|
33
|
+
updater: user
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return await getRepository(KpiOrgScope, tx).save(entity)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
40
|
+
@Directive('@transaction')
|
|
41
|
+
@Mutation(returns => [KpiOrgScope], {
|
|
42
|
+
description: 'Update multiple KPI org-scope mappings with the provided patches.'
|
|
43
|
+
})
|
|
44
|
+
async updateMultipleKpiOrgScope(
|
|
45
|
+
@Arg('patches', type => [KpiOrgScopePatch], {
|
|
46
|
+
description: 'Array of patch objects for updating org-scope mappings.'
|
|
47
|
+
})
|
|
48
|
+
patches: KpiOrgScopePatch[],
|
|
49
|
+
@Ctx() context: ResolverContext
|
|
50
|
+
): Promise<KpiOrgScope[]> {
|
|
51
|
+
const { domain, user, tx } = context.state
|
|
52
|
+
|
|
53
|
+
const ids = patches.map(patch => patch.id)
|
|
54
|
+
const existingOrgScopes = await getRepository(KpiOrgScope, tx).find({
|
|
55
|
+
where: {
|
|
56
|
+
domain: { id: domain.id },
|
|
57
|
+
id: In(ids)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
if (existingOrgScopes.length !== patches.length) {
|
|
62
|
+
throw new Error('Some org-scope mappings not found or not accessible')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const updatedOrgScopes: KpiOrgScope[] = []
|
|
66
|
+
|
|
67
|
+
for (const patch of patches) {
|
|
68
|
+
const existingOrgScope = existingOrgScopes.find(os => os.id === patch.id)
|
|
69
|
+
if (!existingOrgScope) continue
|
|
70
|
+
|
|
71
|
+
// Check if org is being changed and if new org already exists
|
|
72
|
+
if (patch.org && patch.org !== existingOrgScope.org) {
|
|
73
|
+
const duplicateOrgScope = await getRepository(KpiOrgScope, tx).findOne({
|
|
74
|
+
where: {
|
|
75
|
+
domain: { id: domain.id },
|
|
76
|
+
org: patch.org,
|
|
77
|
+
id: In(ids.filter(id => id !== patch.id))
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
if (duplicateOrgScope) {
|
|
81
|
+
throw new Error(`Organization '${patch.org}' already has a scope mapping in this domain`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const updatedEntity: Partial<KpiOrgScope> = {
|
|
86
|
+
...existingOrgScope,
|
|
87
|
+
...patch,
|
|
88
|
+
updater: user,
|
|
89
|
+
updatedAt: new Date()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const savedOrgScope = await getRepository(KpiOrgScope, tx).save(updatedEntity)
|
|
93
|
+
updatedOrgScopes.push(savedOrgScope)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return updatedOrgScopes
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
100
|
+
@Directive('@transaction')
|
|
101
|
+
@Mutation(returns => Boolean, { description: 'Delete KPI org-scope mappings by their IDs.' })
|
|
102
|
+
async deleteKpiOrgScopes(
|
|
103
|
+
@Arg('ids', type => [String], { description: 'Array of org-scope mapping IDs to delete.' }) ids: string[],
|
|
104
|
+
@Ctx() context: ResolverContext
|
|
105
|
+
): Promise<boolean> {
|
|
106
|
+
const { domain, tx } = context.state
|
|
107
|
+
|
|
108
|
+
const existingOrgScopes = await getRepository(KpiOrgScope, tx).find({
|
|
109
|
+
where: {
|
|
110
|
+
domain: { id: domain.id },
|
|
111
|
+
id: In(ids)
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
if (existingOrgScopes.length === 0) {
|
|
116
|
+
throw new Error('No org-scope mappings found to delete')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Soft delete
|
|
120
|
+
await getRepository(KpiOrgScope, tx).softDelete(existingOrgScopes.map(os => os.id))
|
|
121
|
+
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@Directive('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
126
|
+
@Directive('@transaction')
|
|
127
|
+
@Mutation(returns => [KpiOrgScope], { description: 'Bulk create or update KPI org-scope mappings.' })
|
|
128
|
+
async bulkUpsertKpiOrgScopes(
|
|
129
|
+
@Arg('orgScopes', type => [NewKpiOrgScope], { description: 'Array of org-scope mapping data for bulk upsert.' })
|
|
130
|
+
orgScopes: NewKpiOrgScope[],
|
|
131
|
+
@Ctx() context: ResolverContext
|
|
132
|
+
): Promise<KpiOrgScope[]> {
|
|
133
|
+
const { domain, user, tx } = context.state
|
|
134
|
+
|
|
135
|
+
const orgs = orgScopes.map(os => os.org)
|
|
136
|
+
const existingOrgScopes = await getRepository(KpiOrgScope, tx).find({
|
|
137
|
+
where: {
|
|
138
|
+
domain: { id: domain.id },
|
|
139
|
+
org: In(orgs)
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const results: KpiOrgScope[] = []
|
|
144
|
+
|
|
145
|
+
for (const orgScopeData of orgScopes) {
|
|
146
|
+
const existing = existingOrgScopes.find(os => os.org === orgScopeData.org)
|
|
147
|
+
|
|
148
|
+
if (existing) {
|
|
149
|
+
// Update existing
|
|
150
|
+
const updatedEntity: Partial<KpiOrgScope> = {
|
|
151
|
+
...existing,
|
|
152
|
+
...orgScopeData,
|
|
153
|
+
updater: user,
|
|
154
|
+
updatedAt: new Date()
|
|
155
|
+
}
|
|
156
|
+
const updated = await getRepository(KpiOrgScope, tx).save(updatedEntity)
|
|
157
|
+
results.push(updated)
|
|
158
|
+
} else {
|
|
159
|
+
// Create new
|
|
160
|
+
const newEntity: Partial<KpiOrgScope> = {
|
|
161
|
+
...orgScopeData,
|
|
162
|
+
domain,
|
|
163
|
+
creator: user,
|
|
164
|
+
updater: user
|
|
165
|
+
}
|
|
166
|
+
const saved = await getRepository(KpiOrgScope, tx).save(newEntity)
|
|
167
|
+
results.push(saved)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return results
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
|
|
5
|
+
import { KpiOrgScope } from './kpi-org-scope'
|
|
6
|
+
import { KpiOrgScopeList } from './kpi-org-scope-type'
|
|
7
|
+
|
|
8
|
+
@Resolver(KpiOrgScope)
|
|
9
|
+
export class KpiOrgScopeQuery {
|
|
10
|
+
@Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
|
11
|
+
@Query(returns => KpiOrgScope!, {
|
|
12
|
+
nullable: true,
|
|
13
|
+
description: 'Fetch a single KPI org-scope mapping by its unique identifier.'
|
|
14
|
+
})
|
|
15
|
+
async kpiOrgScope(
|
|
16
|
+
@Arg('id', { description: 'Unique identifier of the org-scope mapping to fetch.' }) id: string,
|
|
17
|
+
@Ctx() context: ResolverContext
|
|
18
|
+
): Promise<KpiOrgScope> {
|
|
19
|
+
const { domain } = context.state
|
|
20
|
+
|
|
21
|
+
return await getRepository(KpiOrgScope).findOne({
|
|
22
|
+
where: { domain: { id: domain.id }, id }
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
|
27
|
+
@Query(returns => KpiOrgScopeList, {
|
|
28
|
+
description: 'Fetch multiple KPI org-scope mappings with filters and pagination'
|
|
29
|
+
})
|
|
30
|
+
async kpiOrgScopes(
|
|
31
|
+
@Args(type => ListParam) params: ListParam,
|
|
32
|
+
@Ctx() context: ResolverContext
|
|
33
|
+
): Promise<KpiOrgScopeList> {
|
|
34
|
+
const { domain } = context.state
|
|
35
|
+
|
|
36
|
+
const queryBuilder = getQueryBuilderFromListParams({
|
|
37
|
+
domain,
|
|
38
|
+
params,
|
|
39
|
+
repository: await getRepository(KpiOrgScope),
|
|
40
|
+
searchables: ['org', 'scope01', 'scope02', 'scope03', 'scope04', 'scope05']
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const [items, total] = await queryBuilder.getManyAndCount()
|
|
44
|
+
|
|
45
|
+
return { items, total }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
|
49
|
+
@Query(returns => [String], { description: 'Get distinct values for a specific scope field' })
|
|
50
|
+
async kpiOrgScopeValues(
|
|
51
|
+
@Arg('scopeField', { description: 'Scope field to get distinct values from' })
|
|
52
|
+
scopeField: 'scope01' | 'scope02' | 'scope03' | 'scope04' | 'scope05',
|
|
53
|
+
@Ctx() context: ResolverContext,
|
|
54
|
+
@Arg('searchTerm', { nullable: true, description: 'Optional search term to filter values' }) searchTerm?: string
|
|
55
|
+
): Promise<string[]> {
|
|
56
|
+
const { domain } = context.state
|
|
57
|
+
|
|
58
|
+
const queryBuilder = getRepository(KpiOrgScope)
|
|
59
|
+
.createQueryBuilder('orgScope')
|
|
60
|
+
.select(`DISTINCT orgScope.${scopeField}`, 'value')
|
|
61
|
+
.where('orgScope.domain_id = :domainId', { domainId: domain.id })
|
|
62
|
+
.andWhere(`orgScope.${scopeField} IS NOT NULL`)
|
|
63
|
+
.andWhere(`orgScope.${scopeField} != ''`)
|
|
64
|
+
.andWhere('orgScope.active = true')
|
|
65
|
+
|
|
66
|
+
if (searchTerm) {
|
|
67
|
+
queryBuilder.andWhere(`orgScope.${scopeField} ILIKE :searchTerm`, {
|
|
68
|
+
searchTerm: `%${searchTerm}%`
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const results = await queryBuilder.getRawMany()
|
|
73
|
+
return results.map(r => r.value).filter(v => v)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
|
77
|
+
@Query(returns => [String], { description: 'Get distinct org values' })
|
|
78
|
+
async kpiOrgValues(
|
|
79
|
+
@Ctx() context: ResolverContext,
|
|
80
|
+
@Arg('searchTerm', { nullable: true, description: 'Optional search term to filter org values' }) searchTerm?: string
|
|
81
|
+
): Promise<string[]> {
|
|
82
|
+
const { domain } = context.state
|
|
83
|
+
|
|
84
|
+
const queryBuilder = getRepository(KpiOrgScope)
|
|
85
|
+
.createQueryBuilder('orgScope')
|
|
86
|
+
.select('DISTINCT orgScope.org', 'value')
|
|
87
|
+
.where('orgScope.domain_id = :domainId', { domainId: domain.id })
|
|
88
|
+
.andWhere('orgScope.active = true')
|
|
89
|
+
|
|
90
|
+
if (searchTerm) {
|
|
91
|
+
queryBuilder.andWhere('orgScope.org ILIKE :searchTerm', {
|
|
92
|
+
searchTerm: `%${searchTerm}%`
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const results = await queryBuilder.getRawMany()
|
|
97
|
+
return results.map(r => r.value)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Directive('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)')
|
|
101
|
+
@Query(returns => KpiOrgScope, { nullable: true, description: 'Find org-scope mapping by org identifier' })
|
|
102
|
+
async kpiOrgScopeByOrg(
|
|
103
|
+
@Arg('org', { description: 'Organization identifier to search for' }) org: string,
|
|
104
|
+
@Ctx() context: ResolverContext
|
|
105
|
+
): Promise<KpiOrgScope | undefined> {
|
|
106
|
+
const { domain } = context.state
|
|
107
|
+
|
|
108
|
+
return await getRepository(KpiOrgScope).findOne({
|
|
109
|
+
where: { domain: { id: domain.id }, org }
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@FieldResolver(type => Domain)
|
|
114
|
+
async domain(@Root() kpiOrgScope: KpiOrgScope): Promise<Domain> {
|
|
115
|
+
return kpiOrgScope.domainId && (await getRepository(Domain).findOneBy({ id: kpiOrgScope.domainId }))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@FieldResolver(type => User)
|
|
119
|
+
async creator(@Root() kpiOrgScope: KpiOrgScope): Promise<User> {
|
|
120
|
+
return kpiOrgScope.creatorId && (await getRepository(User).findOneBy({ id: kpiOrgScope.creatorId }))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@FieldResolver(type => User)
|
|
124
|
+
async updater(@Root() kpiOrgScope: KpiOrgScope): Promise<User> {
|
|
125
|
+
return kpiOrgScope.updaterId && (await getRepository(User).findOneBy({ id: kpiOrgScope.updaterId }))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { InputType, Field, ID, ObjectType, Int } from 'type-graphql'
|
|
2
|
+
import { KpiOrgScope } from './kpi-org-scope'
|
|
3
|
+
|
|
4
|
+
@InputType({ description: 'Input type for creating a new KPI org-scope mapping' })
|
|
5
|
+
export class NewKpiOrgScope {
|
|
6
|
+
@Field({ description: 'Organizational unit identifier' })
|
|
7
|
+
org: string
|
|
8
|
+
|
|
9
|
+
@Field({ nullable: true, description: 'First scope dimension' })
|
|
10
|
+
scope01?: string
|
|
11
|
+
|
|
12
|
+
@Field({ nullable: true, description: 'Second scope dimension' })
|
|
13
|
+
scope02?: string
|
|
14
|
+
|
|
15
|
+
@Field({ nullable: true, description: 'Third scope dimension' })
|
|
16
|
+
scope03?: string
|
|
17
|
+
|
|
18
|
+
@Field({ nullable: true, description: 'Fourth scope dimension' })
|
|
19
|
+
scope04?: string
|
|
20
|
+
|
|
21
|
+
@Field({ nullable: true, description: 'Fifth scope dimension' })
|
|
22
|
+
scope05?: string
|
|
23
|
+
|
|
24
|
+
@Field({ nullable: true, description: 'Human-readable name or description' })
|
|
25
|
+
displayName?: string
|
|
26
|
+
|
|
27
|
+
@Field({ nullable: true, description: 'Active status' })
|
|
28
|
+
active?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@InputType({ description: 'Input type for updating an existing KPI org-scope mapping' })
|
|
32
|
+
export class KpiOrgScopePatch {
|
|
33
|
+
@Field(type => ID, { description: 'ID of the org-scope mapping to update' })
|
|
34
|
+
id: string
|
|
35
|
+
|
|
36
|
+
@Field({ nullable: true, description: 'Organizational unit identifier' })
|
|
37
|
+
org?: string
|
|
38
|
+
|
|
39
|
+
@Field({ nullable: true, description: 'First scope dimension' })
|
|
40
|
+
scope01?: string
|
|
41
|
+
|
|
42
|
+
@Field({ nullable: true, description: 'Second scope dimension' })
|
|
43
|
+
scope02?: string
|
|
44
|
+
|
|
45
|
+
@Field({ nullable: true, description: 'Third scope dimension' })
|
|
46
|
+
scope03?: string
|
|
47
|
+
|
|
48
|
+
@Field({ nullable: true, description: 'Fourth scope dimension' })
|
|
49
|
+
scope04?: string
|
|
50
|
+
|
|
51
|
+
@Field({ nullable: true, description: 'Fifth scope dimension' })
|
|
52
|
+
scope05?: string
|
|
53
|
+
|
|
54
|
+
@Field({ nullable: true, description: 'Human-readable name or description' })
|
|
55
|
+
displayName?: string
|
|
56
|
+
|
|
57
|
+
@Field({ nullable: true, description: 'Active status' })
|
|
58
|
+
active?: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ObjectType({ description: 'List of KPI org-scope mappings with pagination' })
|
|
62
|
+
export class KpiOrgScopeList {
|
|
63
|
+
@Field(type => [KpiOrgScope], { description: 'Array of KPI org-scope mappings' })
|
|
64
|
+
items: KpiOrgScope[]
|
|
65
|
+
|
|
66
|
+
@Field(type => Int, { description: 'Total count of items' })
|
|
67
|
+
total: number
|
|
68
|
+
}
|