@dssp/dkpi 1.0.0-y.0 β†’ 1.0.1

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 (213) hide show
  1. package/KPI-STATISTICS-SERVICE.md +233 -0
  2. package/_index.html +4 -9
  3. package/assets/helps/index.md +1 -1
  4. package/assets/images/project-image.png +0 -0
  5. package/assets/manifest.json +2 -2
  6. package/config/config.development.js +2 -1
  7. package/config/config.production.js +2 -1
  8. package/dist-client/bootstrap.d.ts +1 -0
  9. package/dist-client/bootstrap.js +15 -0
  10. package/dist-client/bootstrap.js.map +1 -1
  11. package/dist-client/components/kpi-2d-lookup-chart.d.ts +50 -0
  12. package/dist-client/components/kpi-2d-lookup-chart.js +263 -0
  13. package/dist-client/components/kpi-2d-lookup-chart.js.map +1 -0
  14. package/dist-client/components/kpi-boxplot-chart.d.ts +31 -0
  15. package/dist-client/components/kpi-boxplot-chart.js +306 -0
  16. package/dist-client/components/kpi-boxplot-chart.js.map +1 -0
  17. package/dist-client/components/kpi-lookup-chart.d.ts +58 -0
  18. package/dist-client/components/kpi-lookup-chart.js +464 -0
  19. package/dist-client/components/kpi-lookup-chart.js.map +1 -0
  20. package/dist-client/components/kpi-mini-trend-chart.d.ts +14 -0
  21. package/dist-client/components/kpi-mini-trend-chart.js +180 -0
  22. package/dist-client/components/kpi-mini-trend-chart.js.map +1 -0
  23. package/dist-client/components/kpi-radar-chart.d.ts +17 -0
  24. package/dist-client/components/kpi-radar-chart.js +259 -0
  25. package/dist-client/components/kpi-radar-chart.js.map +1 -0
  26. package/dist-client/components/kpi-single-boxplot-chart.d.ts +14 -2
  27. package/dist-client/components/kpi-single-boxplot-chart.js +237 -137
  28. package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -1
  29. package/dist-client/components/kpi-step-lookup-chart.d.ts +33 -0
  30. package/dist-client/components/kpi-step-lookup-chart.js +181 -0
  31. package/dist-client/components/kpi-step-lookup-chart.js.map +1 -0
  32. package/dist-client/components/kpi-trend-chart.d.ts +25 -0
  33. package/dist-client/components/kpi-trend-chart.js +241 -0
  34. package/dist-client/components/kpi-trend-chart.js.map +1 -0
  35. package/dist-client/entries/auth/checkin.d.ts +38 -0
  36. package/dist-client/entries/auth/checkin.js +551 -0
  37. package/dist-client/entries/auth/checkin.js.map +1 -0
  38. package/dist-client/google-map/common-google-map.d.ts +35 -0
  39. package/dist-client/google-map/common-google-map.js +349 -0
  40. package/dist-client/google-map/common-google-map.js.map +1 -0
  41. package/dist-client/google-map/google-map-loader.d.ts +6 -0
  42. package/dist-client/google-map/google-map-loader.js +23 -0
  43. package/dist-client/google-map/google-map-loader.js.map +1 -0
  44. package/dist-client/pages/component/project-update-header.d.ts +1 -0
  45. package/dist-client/pages/component/project-update-header.js +127 -0
  46. package/dist-client/pages/component/project-update-header.js.map +1 -0
  47. package/dist-client/pages/kpi-admin/dssp-kpi-list-page.d.ts +22 -0
  48. package/dist-client/pages/kpi-admin/dssp-kpi-list-page.js +57 -0
  49. package/dist-client/pages/kpi-admin/dssp-kpi-list-page.js.map +1 -0
  50. package/dist-client/pages/kpi-admin/dssp-kpi-overview.d.ts +47 -0
  51. package/dist-client/pages/kpi-admin/dssp-kpi-overview.js +393 -0
  52. package/dist-client/pages/kpi-admin/dssp-kpi-overview.js.map +1 -0
  53. package/dist-client/pages/kpi-admin/kpi-grade-2d-editor.d.ts +20 -0
  54. package/dist-client/pages/kpi-admin/kpi-grade-2d-editor.js +445 -0
  55. package/dist-client/pages/kpi-admin/kpi-grade-2d-editor.js.map +1 -0
  56. package/dist-client/pages/kpi-admin/kpi-system-guide.d.ts +18 -0
  57. package/dist-client/pages/kpi-admin/kpi-system-guide.js +696 -0
  58. package/dist-client/pages/kpi-admin/kpi-system-guide.js.map +1 -0
  59. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.d.ts +18 -0
  60. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js +259 -0
  61. package/dist-client/pages/kpi-dashboard/cards/kpi-level1-card.js.map +1 -0
  62. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.d.ts +22 -0
  63. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js +346 -0
  64. package/dist-client/pages/kpi-dashboard/cards/kpi-level2-comparison.js.map +1 -0
  65. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.d.ts +26 -0
  66. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js +433 -0
  67. package/dist-client/pages/kpi-dashboard/cards/kpi-level3-comparison.js.map +1 -0
  68. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.d.ts +8 -0
  69. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js +78 -0
  70. package/dist-client/pages/kpi-dashboard/components/kpi-chart-toggle.js.map +1 -0
  71. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.d.ts +46 -0
  72. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js +945 -0
  73. package/dist-client/pages/kpi-dashboard/components/kpi-left-panel.js.map +1 -0
  74. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.d.ts +34 -0
  75. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +238 -0
  76. package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -0
  77. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.d.ts +37 -0
  78. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js +689 -0
  79. package/dist-client/pages/kpi-dashboard/components/kpi-region-popup.js.map +1 -0
  80. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.d.ts +18 -0
  81. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js +131 -0
  82. package/dist-client/pages/kpi-dashboard/kpi-alert-panel.js.map +1 -0
  83. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +57 -0
  84. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +866 -0
  85. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -0
  86. package/dist-client/pages/kpi-dashboard/kpi-dashboard.d.ts +63 -0
  87. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js +1097 -0
  88. package/dist-client/pages/kpi-dashboard/kpi-dashboard.js.map +1 -0
  89. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.d.ts +12 -0
  90. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js +82 -0
  91. package/dist-client/pages/kpi-dashboard/kpi-grade-visualization.js.map +1 -0
  92. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.d.ts +11 -0
  93. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js +65 -0
  94. package/dist-client/pages/kpi-dashboard/kpi-history-viewer.js.map +1 -0
  95. package/dist-client/pages/kpi-dashboard/kpi-list-summary.d.ts +13 -0
  96. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js +115 -0
  97. package/dist-client/pages/kpi-dashboard/kpi-list-summary.js.map +1 -0
  98. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.d.ts +15 -0
  99. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js +147 -0
  100. package/dist-client/pages/kpi-dashboard/kpi-performance-summary.js.map +1 -0
  101. package/dist-client/pages/kpi-dashboard/kpi-value-entry.d.ts +7 -0
  102. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js +86 -0
  103. package/dist-client/pages/kpi-dashboard/kpi-value-entry.js.map +1 -0
  104. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +1 -2
  105. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +1 -13
  106. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -1
  107. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +1 -2
  108. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +20 -11
  109. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  110. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.d.ts +1 -2
  111. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +1 -2
  112. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -1
  113. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +1 -2
  114. package/dist-client/pages/kpi-value/kpi-value-list-page.js +22 -33
  115. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  116. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.d.ts +56 -0
  117. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +609 -67
  118. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
  119. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.d.ts +15 -3
  120. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +180 -65
  121. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
  122. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.d.ts +13 -4
  123. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js +213 -91
  124. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js.map +1 -1
  125. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.d.ts +51 -0
  126. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +693 -0
  127. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -0
  128. package/dist-client/pages/sv-project-complete.d.ts +12 -3
  129. package/dist-client/pages/sv-project-complete.js +175 -29
  130. package/dist-client/pages/sv-project-complete.js.map +1 -1
  131. package/dist-client/pages/sv-project-completed-list.d.ts +3 -0
  132. package/dist-client/pages/sv-project-completed-list.js +81 -22
  133. package/dist-client/pages/sv-project-completed-list.js.map +1 -1
  134. package/dist-client/pages/sv-project-detail.d.ts +60 -0
  135. package/dist-client/pages/sv-project-detail.js +1092 -85
  136. package/dist-client/pages/sv-project-detail.js.map +1 -1
  137. package/dist-client/pages/sv-project-list.d.ts +20 -2
  138. package/dist-client/pages/sv-project-list.js +180 -30
  139. package/dist-client/pages/sv-project-list.js.map +1 -1
  140. package/dist-client/pages/sv-project-update.d.ts +91 -0
  141. package/dist-client/pages/sv-project-update.js +1150 -0
  142. package/dist-client/pages/sv-project-update.js.map +1 -0
  143. package/dist-client/pages/sv-user-management.d.ts +1 -0
  144. package/dist-client/pages/sv-user-management.js +5 -0
  145. package/dist-client/pages/sv-user-management.js.map +1 -1
  146. package/dist-client/route.d.ts +1 -1
  147. package/dist-client/route.js +29 -2
  148. package/dist-client/route.js.map +1 -1
  149. package/dist-client/shared/complete-api.d.ts +45 -5
  150. package/dist-client/shared/complete-api.js +177 -28
  151. package/dist-client/shared/complete-api.js.map +1 -1
  152. package/dist-client/shared/func.d.ts +1 -1
  153. package/dist-client/shared/func.js.map +1 -1
  154. package/dist-client/shared/geo-group-mapping.d.ts +25 -0
  155. package/dist-client/shared/geo-group-mapping.js +189 -0
  156. package/dist-client/shared/geo-group-mapping.js.map +1 -0
  157. package/dist-client/shared/integration-fetch.d.ts +35 -0
  158. package/dist-client/shared/integration-fetch.js +53 -0
  159. package/dist-client/shared/integration-fetch.js.map +1 -0
  160. package/dist-client/shared/kpi-project-sync.d.ts +16 -0
  161. package/dist-client/shared/kpi-project-sync.js +129 -0
  162. package/dist-client/shared/kpi-project-sync.js.map +1 -0
  163. package/dist-client/tsconfig.tsbuildinfo +1 -1
  164. package/dist-client/viewparts/menu-tools.d.ts +11 -3
  165. package/dist-client/viewparts/menu-tools.js +126 -75
  166. package/dist-client/viewparts/menu-tools.js.map +1 -1
  167. package/dist-server/scripts/calculate-kpi-scores.js +65 -3
  168. package/dist-server/scripts/calculate-kpi-scores.js.map +1 -1
  169. package/dist-server/scripts/load-grade-data-migration.d.ts +4 -0
  170. package/dist-server/scripts/load-grade-data-migration.js +95 -10
  171. package/dist-server/scripts/load-grade-data-migration.js.map +1 -1
  172. package/dist-server/scripts/propagate-parent-kpi-values.d.ts +4 -0
  173. package/dist-server/scripts/propagate-parent-kpi-values.js +423 -77
  174. package/dist-server/scripts/propagate-parent-kpi-values.js.map +1 -1
  175. package/dist-server/scripts/recalculate-by-project-name.d.ts +2 -0
  176. package/dist-server/scripts/recalculate-by-project-name.js +72 -0
  177. package/dist-server/scripts/recalculate-by-project-name.js.map +1 -0
  178. package/dist-server/service/index.d.ts +1 -3
  179. package/dist-server/service/index.js +3 -4
  180. package/dist-server/service/index.js.map +1 -1
  181. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +192 -1
  182. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +993 -38
  183. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  184. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.d.ts +9 -1
  185. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +33 -8
  186. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -1
  187. package/dist-server/service/kpi-stat/index.d.ts +4 -0
  188. package/dist-server/service/kpi-stat/index.js +8 -0
  189. package/dist-server/service/kpi-stat/index.js.map +1 -0
  190. package/dist-server/service/kpi-stat/kpi-stat-query.d.ts +13 -0
  191. package/dist-server/service/kpi-stat/kpi-stat-query.js +751 -0
  192. package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -0
  193. package/dist-server/service/kpi-stat/kpi-stat-types.d.ts +32 -0
  194. package/dist-server/service/kpi-stat/kpi-stat-types.js +180 -0
  195. package/dist-server/service/kpi-stat/kpi-stat-types.js.map +1 -0
  196. package/dist-server/service/kpi-value/kpi-value-query.d.ts +2 -1
  197. package/dist-server/service/kpi-value/kpi-value-query.js +49 -6
  198. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  199. package/dist-server/tsconfig.tsbuildinfo +1 -1
  200. package/kpi-module-service-tests.md +1286 -0
  201. package/kpi-module-test-report.md +676 -0
  202. package/kpi-module-unit-test-detailed-report.md +925 -0
  203. package/kpi-module-unit-tests-detailed.md +1452 -0
  204. package/openapi/unstable.yaml +2 -2
  205. package/package.json +58 -54
  206. package/recalculate-batch.sh +64 -0
  207. package/recalculate-projects-range.sh +98 -0
  208. package/schema.graphql +1159 -55
  209. package/things-factory.config.js +6 -1
  210. package/translations/en.json +5 -1
  211. package/translations/ko.json +5 -1
  212. package/views/auth-page.html +4 -5
  213. package/views/public/home.html +5 -6
@@ -1 +1 @@
1
- {"version":3,"file":"calculate-kpi-scores.js","sourceRoot":"","sources":["../../server/scripts/calculate-kpi-scores.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env ts-node\n\nimport { createConnection } from 'typeorm'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\ninterface KpiGrade {\n name: string\n minValue: number\n maxValue: number\n score?: number\n color?: string\n description?: string\n}\n\ninterface KpiRecord {\n id: string\n name: string\n grades: KpiGrade[]\n}\n\ninterface KpiValueRecord {\n id: string\n value: number\n score?: number\n kpi: KpiRecord\n}\n\n/**\n * Calculate KPI scores based on lookup tables (grades)\n * Processes kpi-values and updates scores based on KPI grades\n */\nexport async function calculateKpiScores(specificKpiName?: string, forceRecalculate = false): Promise<void> {\n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n console.log('πŸš€ Starting KPI Score Calculation...')\n\n try {\n // Create database connection using Things-Factory pattern\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n // Register the connection with Things-Factory shell\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n console.log('βœ… Database connected')\n\n // Now we can use getRepository with the registered connection\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n // Get KPI-Value repository (assuming it exists)\n let kpiValueRepository\n try {\n const { KpiValue } = require('@things-factory/kpi')\n kpiValueRepository = getRepository(KpiValue)\n } catch (error) {\n console.error('❌ KpiValue entity not found. Please ensure it exists in @things-factory/kpi')\n return\n }\n\n // Get KPIs with grades (lookup tables)\n let kpisQuery = kpiRepository\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.domain', 'domain')\n .where('kpi.grades IS NOT NULL')\n .andWhere('domain.name = :domainName', { domainName: 'SYSTEM' })\n\n if (specificKpiName) {\n kpisQuery = kpisQuery.andWhere('kpi.name = :name', { name: specificKpiName })\n console.log(`🎯 Processing specific KPI: ${specificKpiName}`)\n } else {\n console.log('🎯 Processing all KPIs with lookup tables')\n }\n\n const kpis = await kpisQuery.getMany()\n\n if (kpis.length === 0) {\n console.log('⚠️ No KPIs found with lookup tables (grades)')\n return\n }\n\n console.log(`πŸ“Š Found ${kpis.length} KPIs with lookup tables`)\n\n let totalProcessed = 0\n let totalUpdated = 0\n let errorCount = 0\n\n for (const kpi of kpis) {\n try {\n console.log(`\\nπŸ“„ Processing KPI: ${kpi.name}`)\n \n if (!kpi.grades || !Array.isArray(kpi.grades) || kpi.grades.length === 0) {\n console.log(` ⚠️ No grades found, skipping`)\n continue\n }\n\n console.log(` πŸ“ˆ Lookup table: ${kpi.grades.length} grades`)\n\n // Get KPI values for this KPI\n let kpiValuesQuery = kpiValueRepository\n .createQueryBuilder('kpiValue')\n .leftJoinAndSelect('kpiValue.kpi', 'kpi')\n .where('kpi.id = :kpiId', { kpiId: kpi.id })\n .andWhere('kpiValue.value IS NOT NULL')\n\n if (!forceRecalculate) {\n // Only process null or 0 scores by default\n kpiValuesQuery = kpiValuesQuery.andWhere('(kpiValue.score IS NULL OR kpiValue.score = 0)')\n }\n\n const kpiValues = await kpiValuesQuery.getMany()\n\n if (kpiValues.length === 0) {\n console.log(` βœ… No null/zero scores found (all values already calculated)`)\n continue\n }\n\n console.log(` πŸ”’ Processing ${kpiValues.length} null/zero scores`)\n\n let updatedCount = 0\n\n for (const kpiValue of kpiValues) {\n const value = kpiValue.value\n const calculatedScore = calculateScoreFromGrades(value, kpi.grades)\n\n if (calculatedScore !== null) {\n // Only update if the score is actually different\n if (kpiValue.score !== calculatedScore) {\n const oldScore = kpiValue.score\n kpiValue.score = calculatedScore\n await kpiValueRepository.save(kpiValue)\n updatedCount++\n \n console.log(` πŸ“Š Value ${value} β†’ Score ${calculatedScore} (was ${oldScore || 'null'})`)\n }\n } else {\n console.log(` ⚠️ Value ${value} is below all ranges in lookup table`)\n }\n\n totalProcessed++\n }\n\n console.log(` βœ… Updated ${updatedCount}/${kpiValues.length} values`)\n totalUpdated += updatedCount\n\n } catch (kpiError) {\n console.log(` ❌ Error processing KPI ${kpi.name}: ${kpiError.message}`)\n errorCount++\n }\n }\n\n console.log(`\\nπŸŽ‰ KPI Score Calculation Complete!`)\n console.log(` πŸ“Š KPIs processed: ${kpis.length}`)\n console.log(` πŸ”’ Total values processed: ${totalProcessed}`)\n console.log(` βœ… Scores updated: ${totalUpdated}`)\n console.log(` ❌ Errors: ${errorCount}`)\n\n if (errorCount > 0) {\n console.log(`\\n⚠️ Some KPIs had errors. Check the logs above for details.`)\n }\n\n } catch (error) {\n console.error(`❌ Fatal error during score calculation:`, error)\n throw error\n } finally {\n if (connection) {\n await connection.close()\n console.log('πŸ”Œ Database connection closed')\n }\n }\n}\n\n/**\n * Calculate score from grades lookup table\n * If exact range not found, use the score of the largest minValue that is <= value\n */\nfunction calculateScoreFromGrades(value: number, grades: KpiGrade[]): number | null {\n // First try to find exact range match\n for (const grade of grades) {\n if (value >= grade.minValue && value <= grade.maxValue) {\n return grade.score || 0\n }\n }\n \n // If no exact match, find the grade with largest minValue that is <= value\n let bestGrade: KpiGrade | null = null\n let bestMinValue = -Infinity\n \n for (const grade of grades) {\n if (grade.minValue <= value && grade.minValue > bestMinValue) {\n bestGrade = grade\n bestMinValue = grade.minValue\n }\n }\n \n if (bestGrade) {\n return bestGrade.score || 0\n }\n \n return null // Value is smaller than all minValues in lookup table\n}\n\n/**\n * List KPIs that have lookup tables (grades)\n */\nexport async function listKpisWithLookupTables(): Promise<void> {\n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n try {\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n // Get KPIs with grades\n const kpis = await kpiRepository\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.domain', 'domain')\n .where('kpi.grades IS NOT NULL')\n .andWhere('domain.name = :domainName', { domainName: 'SYSTEM' })\n .getMany()\n\n console.log(`πŸ“ KPIs with lookup tables (${kpis.length}):\\n`)\n\n if (kpis.length === 0) {\n console.log(' No KPIs found with lookup tables.')\n return\n }\n\n kpis.forEach((kpi, index) => {\n const gradeCount = kpi.grades ? kpi.grades.length : 0\n console.log(` ${(index + 1).toString().padStart(2)}: ${kpi.name} (${gradeCount} grades)`)\n })\n\n console.log(`\\nπŸ“ˆ Total: ${kpis.length} KPIs with lookup tables`)\n\n } catch (error) {\n console.error('❌ Error listing KPIs:', error)\n } finally {\n if (connection) {\n await connection.close()\n }\n }\n}\n\n/**\n * CLI execution when called directly\n */\nasync function main() {\n const args = process.argv.slice(2)\n\n try {\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\n🎯 KPI Score Calculator\n\nUsage:\n ts-node server/scripts/calculate-kpi-scores.ts [options] [kpiName]\n\nOptions:\n --list, -l List KPIs that have lookup tables\n --force, -f Force recalculate all scores (not just null/zero ones)\n --help, -h Show this help\n\nExamples:\n ts-node server/scripts/calculate-kpi-scores.ts # Calculate scores for null/zero values only\n ts-node server/scripts/calculate-kpi-scores.ts --force # Recalculate ALL scores\n ts-node server/scripts/calculate-kpi-scores.ts \"X11. 연면적 λŒ€λΉ„ 곡사기간\" # Calculate for specific KPI\n ts-node server/scripts/calculate-kpi-scores.ts --list # List KPIs with lookup tables\n\nNote: By default, only processes kpi-values with null or zero scores.\n Use --force to recalculate all scores.\n `)\n return\n }\n\n if (args.includes('--list') || args.includes('-l')) {\n await listKpisWithLookupTables()\n return\n }\n\n const forceRecalculate = args.includes('--force') || args.includes('-f')\n const specificKpiName = args.find(arg => !arg.startsWith('--'))\n \n if (specificKpiName) {\n console.log(`🎯 Calculating scores for specific KPI: ${specificKpiName}`)\n console.log(` Mode: ${forceRecalculate ? 'Force recalculate ALL' : 'Only null/zero scores'}`)\n await calculateKpiScores(specificKpiName, forceRecalculate)\n } else {\n console.log(`🎯 Calculating scores for all KPIs with lookup tables`)\n console.log(` Mode: ${forceRecalculate ? 'Force recalculate ALL' : 'Only null/zero scores'}`)\n await calculateKpiScores(undefined, forceRecalculate)\n }\n\n console.log('\\n✨ Done!')\n \n } catch (error) {\n console.error('\\n❌ Script failed:', error.message)\n process.exit(1)\n }\n}\n\n// Handle uncaught errors\nprocess.on('unhandledRejection', (error: any) => {\n console.error('❌ Unhandled error:', error.message || error)\n process.exit(1)\n})\n\n// Run if called directly\nif (require.main === module) {\n main()\n}"]}
1
+ {"version":3,"file":"calculate-kpi-scores.js","sourceRoot":"","sources":["../../server/scripts/calculate-kpi-scores.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env ts-node\n\nimport { createConnection } from 'typeorm'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\ninterface KpiGrade {\n name: string\n minValue: number\n maxValue: number\n score?: number\n color?: string\n description?: string\n}\n\ninterface Grade2DRow {\n progressRate: number\n boundary5to4: number\n boundary4to3: number\n boundary3to2: number\n boundary2to1: number\n}\n\ninterface Grade2DLookup {\n type: 'PROGRESS_DEVIATION_LOOKUP'\n rows: Grade2DRow[]\n}\n\ninterface KpiRecord {\n id: string\n name: string\n grades: KpiGrade[] | Grade2DLookup | any\n}\n\ninterface KpiValueRecord {\n id: string\n value: number\n score?: number\n group?: string\n kpi: KpiRecord\n}\n\nfunction isGrade2DLookup(grades: any): grades is Grade2DLookup {\n return grades && typeof grades === 'object' && !Array.isArray(grades) && grades.type === 'PROGRESS_DEVIATION_LOOKUP'\n}\n\n/**\n * 2D lookup tableμ—μ„œ 점수 계산 (X13: 곡정λ₯  Γ— 편차 β†’ 점수)\n * @param deviationValue 편차율 (formula κ²°κ³Ό)\n * @param grades 2D lookup grades 객체\n * @param progressRate 곡정λ₯  (0~100)\n */\nfunction calculate2DScore(deviationValue: number, grades: Grade2DLookup, progressRate: number): number | null {\n if (!grades.rows || grades.rows.length === 0) return null\n\n const progressIndex = Math.min(99, Math.max(0, Math.floor(progressRate)))\n const row = grades.rows.find(r => r.progressRate === progressIndex)\n if (!row) return null\n\n if (deviationValue < row.boundary5to4) return 5\n if (deviationValue < row.boundary4to3) return 4\n if (deviationValue < row.boundary3to2) return 3\n if (deviationValue < row.boundary2to1) return 2\n return 1\n}\n\n/**\n * Calculate KPI scores based on lookup tables (grades)\n * Processes kpi-values and updates scores based on KPI grades\n */\nexport async function calculateKpiScores(specificKpiName?: string, forceRecalculate = false): Promise<void> {\n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n console.log('πŸš€ Starting KPI Score Calculation...')\n\n try {\n // Create database connection using Things-Factory pattern\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n // Register the connection with Things-Factory shell\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n console.log('βœ… Database connected')\n\n // Now we can use getRepository with the registered connection\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n // Get KPI-Value repository (assuming it exists)\n let kpiValueRepository\n try {\n const { KpiValue } = require('@things-factory/kpi')\n kpiValueRepository = getRepository(KpiValue)\n } catch (error) {\n console.error('❌ KpiValue entity not found. Please ensure it exists in @things-factory/kpi')\n return\n }\n\n // Get KPIs with grades (lookup tables)\n let kpisQuery = kpiRepository\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.domain', 'domain')\n .where('kpi.grades IS NOT NULL')\n .andWhere('domain.name = :domainName', { domainName: 'SYSTEM' })\n\n if (specificKpiName) {\n kpisQuery = kpisQuery.andWhere('kpi.name = :name', { name: specificKpiName })\n console.log(`🎯 Processing specific KPI: ${specificKpiName}`)\n } else {\n console.log('🎯 Processing all KPIs with lookup tables')\n }\n\n const kpis = await kpisQuery.getMany()\n\n if (kpis.length === 0) {\n console.log('⚠️ No KPIs found with lookup tables (grades)')\n return\n }\n\n console.log(`πŸ“Š Found ${kpis.length} KPIs with lookup tables`)\n\n let totalProcessed = 0\n let totalUpdated = 0\n let errorCount = 0\n\n // 2D lookup KPI (X13)에 ν•„μš”ν•œ Project entity μ€€λΉ„\n let projectRepository: any = null\n const progressRateCache = new Map<string, number>()\n\n try {\n const { Project } = require('@dssp/project')\n projectRepository = getRepository(Project)\n } catch {\n console.log('⚠️ @dssp/project not found β€” 2D lookup KPIs will use default progressRate')\n }\n\n for (const kpi of kpis) {\n try {\n console.log(`\\nπŸ“„ Processing KPI: ${kpi.name}`)\n\n const is2D = isGrade2DLookup(kpi.grades)\n\n if (!is2D && (!kpi.grades || !Array.isArray(kpi.grades) || kpi.grades.length === 0)) {\n console.log(` ⚠️ No grades found, skipping`)\n continue\n }\n\n if (is2D) {\n console.log(` πŸ“ˆ 2D Lookup table: ${kpi.grades.rows.length} rows`)\n } else {\n console.log(` πŸ“ˆ Lookup table: ${kpi.grades.length} grades`)\n }\n\n // Get KPI values for this KPI\n let kpiValuesQuery = kpiValueRepository\n .createQueryBuilder('kpiValue')\n .leftJoinAndSelect('kpiValue.kpi', 'kpi')\n .where('kpi.id = :kpiId', { kpiId: kpi.id })\n .andWhere('kpiValue.value IS NOT NULL')\n\n if (!forceRecalculate) {\n // Only process null or 0 scores by default\n kpiValuesQuery = kpiValuesQuery.andWhere('(kpiValue.score IS NULL OR kpiValue.score = 0)')\n }\n\n const kpiValues = await kpiValuesQuery.getMany()\n\n if (kpiValues.length === 0) {\n console.log(` βœ… No null/zero scores found (all values already calculated)`)\n continue\n }\n\n console.log(` πŸ”’ Processing ${kpiValues.length} null/zero scores`)\n\n let updatedCount = 0\n\n for (const kpiValue of kpiValues) {\n const value = kpiValue.value\n let calculatedScore: number | null\n\n if (is2D) {\n // 2D lookup: project의 totalProgress 쑰회\n let progressRate = 50 // default\n const projectId = kpiValue.group\n if (projectId && projectRepository) {\n if (progressRateCache.has(projectId)) {\n progressRate = progressRateCache.get(projectId)!\n } else {\n const project = await projectRepository.findOne({ where: { id: projectId } })\n progressRate = project?.totalProgress ?? 50\n progressRateCache.set(projectId, progressRate)\n }\n }\n calculatedScore = calculate2DScore(value, kpi.grades as Grade2DLookup, progressRate)\n } else {\n calculatedScore = calculateScoreFromGrades(value, kpi.grades as KpiGrade[])\n }\n\n if (calculatedScore !== null) {\n // Only update if the score is actually different\n if (kpiValue.score !== calculatedScore) {\n const oldScore = kpiValue.score\n kpiValue.score = calculatedScore\n await kpiValueRepository.save(kpiValue)\n updatedCount++\n\n console.log(` πŸ“Š Value ${value} β†’ Score ${calculatedScore} (was ${oldScore || 'null'})`)\n }\n } else {\n console.log(` ⚠️ Value ${value} is below all ranges in lookup table`)\n }\n\n totalProcessed++\n }\n\n console.log(` βœ… Updated ${updatedCount}/${kpiValues.length} values`)\n totalUpdated += updatedCount\n\n } catch (kpiError) {\n console.log(` ❌ Error processing KPI ${kpi.name}: ${kpiError.message}`)\n errorCount++\n }\n }\n\n console.log(`\\nπŸŽ‰ KPI Score Calculation Complete!`)\n console.log(` πŸ“Š KPIs processed: ${kpis.length}`)\n console.log(` πŸ”’ Total values processed: ${totalProcessed}`)\n console.log(` βœ… Scores updated: ${totalUpdated}`)\n console.log(` ❌ Errors: ${errorCount}`)\n\n if (errorCount > 0) {\n console.log(`\\n⚠️ Some KPIs had errors. Check the logs above for details.`)\n }\n\n } catch (error) {\n console.error(`❌ Fatal error during score calculation:`, error)\n throw error\n } finally {\n if (connection) {\n await connection.close()\n console.log('πŸ”Œ Database connection closed')\n }\n }\n}\n\n/**\n * Calculate score from grades lookup table\n * If exact range not found, use the score of the largest minValue that is <= value\n */\nfunction calculateScoreFromGrades(value: number, grades: KpiGrade[]): number | null {\n // First try to find exact range match\n for (const grade of grades) {\n if (value >= grade.minValue && value <= grade.maxValue) {\n return grade.score || 0\n }\n }\n \n // If no exact match, find the grade with largest minValue that is <= value\n let bestGrade: KpiGrade | null = null\n let bestMinValue = -Infinity\n \n for (const grade of grades) {\n if (grade.minValue <= value && grade.minValue > bestMinValue) {\n bestGrade = grade\n bestMinValue = grade.minValue\n }\n }\n \n if (bestGrade) {\n return bestGrade.score || 0\n }\n \n return null // Value is smaller than all minValues in lookup table\n}\n\n/**\n * List KPIs that have lookup tables (grades)\n */\nexport async function listKpisWithLookupTables(): Promise<void> {\n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n try {\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n // Get KPIs with grades\n const kpis = await kpiRepository\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.domain', 'domain')\n .where('kpi.grades IS NOT NULL')\n .andWhere('domain.name = :domainName', { domainName: 'SYSTEM' })\n .getMany()\n\n console.log(`πŸ“ KPIs with lookup tables (${kpis.length}):\\n`)\n\n if (kpis.length === 0) {\n console.log(' No KPIs found with lookup tables.')\n return\n }\n\n kpis.forEach((kpi, index) => {\n const gradeCount = kpi.grades ? kpi.grades.length : 0\n console.log(` ${(index + 1).toString().padStart(2)}: ${kpi.name} (${gradeCount} grades)`)\n })\n\n console.log(`\\nπŸ“ˆ Total: ${kpis.length} KPIs with lookup tables`)\n\n } catch (error) {\n console.error('❌ Error listing KPIs:', error)\n } finally {\n if (connection) {\n await connection.close()\n }\n }\n}\n\n/**\n * CLI execution when called directly\n */\nasync function main() {\n const args = process.argv.slice(2)\n\n try {\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\n🎯 KPI Score Calculator\n\nUsage:\n ts-node server/scripts/calculate-kpi-scores.ts [options] [kpiName]\n\nOptions:\n --list, -l List KPIs that have lookup tables\n --force, -f Force recalculate all scores (not just null/zero ones)\n --help, -h Show this help\n\nExamples:\n ts-node server/scripts/calculate-kpi-scores.ts # Calculate scores for null/zero values only\n ts-node server/scripts/calculate-kpi-scores.ts --force # Recalculate ALL scores\n ts-node server/scripts/calculate-kpi-scores.ts \"X11. 연면적 λŒ€λΉ„ 곡사기간\" # Calculate for specific KPI\n ts-node server/scripts/calculate-kpi-scores.ts --list # List KPIs with lookup tables\n\nNote: By default, only processes kpi-values with null or zero scores.\n Use --force to recalculate all scores.\n `)\n return\n }\n\n if (args.includes('--list') || args.includes('-l')) {\n await listKpisWithLookupTables()\n return\n }\n\n const forceRecalculate = args.includes('--force') || args.includes('-f')\n const specificKpiName = args.find(arg => !arg.startsWith('--'))\n \n if (specificKpiName) {\n console.log(`🎯 Calculating scores for specific KPI: ${specificKpiName}`)\n console.log(` Mode: ${forceRecalculate ? 'Force recalculate ALL' : 'Only null/zero scores'}`)\n await calculateKpiScores(specificKpiName, forceRecalculate)\n } else {\n console.log(`🎯 Calculating scores for all KPIs with lookup tables`)\n console.log(` Mode: ${forceRecalculate ? 'Force recalculate ALL' : 'Only null/zero scores'}`)\n await calculateKpiScores(undefined, forceRecalculate)\n }\n\n console.log('\\n✨ Done!')\n \n } catch (error) {\n console.error('\\n❌ Script failed:', error.message)\n process.exit(1)\n }\n}\n\n// Handle uncaught errors\nprocess.on('unhandledRejection', (error: any) => {\n console.error('❌ Unhandled error:', error.message || error)\n process.exit(1)\n})\n\n// Run if called directly\nif (require.main === module) {\n main()\n}"]}
@@ -4,6 +4,10 @@
4
4
  * This can be called directly from migrations or other server-side scripts
5
5
  */
6
6
  export declare function loadKpiGradeData(specificFile?: string): Promise<void>;
7
+ /**
8
+ * X31/X32 KPIλ₯Ό λΉ„ν™œμ„±ν™” (active = false, grades = null)
9
+ */
10
+ export declare function deactivateDeletedKpis(): Promise<void>;
7
11
  /**
8
12
  * List available grade data files
9
13
  */
@@ -2,11 +2,26 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.loadKpiGradeData = loadKpiGradeData;
5
+ exports.deactivateDeletedKpis = deactivateDeletedKpis;
5
6
  exports.listGradeDataFiles = listGradeDataFiles;
6
7
  const tslib_1 = require("tslib");
7
8
  const typeorm_1 = require("typeorm");
8
9
  const fs = tslib_1.__importStar(require("fs"));
9
10
  const path = tslib_1.__importStar(require("path"));
11
+ /** X31/X32 λΉ„ν™œμ„±ν™” λŒ€μƒ KPI 이름 */
12
+ const DEACTIVATE_KPI_NAMES = ['X31. ν’ˆμ§ˆμ‹œν—˜ λΆˆν•©κ²©λ₯ ', 'X32. κ²€μˆ˜μžμž¬ λΆˆν•©κ²©λ₯ '];
13
+ function isGrade2DLookup(grades) {
14
+ return grades && typeof grades === 'object' && !Array.isArray(grades) && (grades.type === 'PROGRESS_DEVIATION_LOOKUP' || grades.type === 'PROGRESS_DEVIATION_LOOKUP');
15
+ }
16
+ function normalize2DGrades(grades) {
17
+ return Object.assign(Object.assign({}, grades), { type: 'PROGRESS_DEVIATION_LOOKUP' });
18
+ }
19
+ function getGradeCount(grades) {
20
+ if (isGrade2DLookup(grades)) {
21
+ return grades.rows.length;
22
+ }
23
+ return Array.isArray(grades) ? grades.length : 0;
24
+ }
10
25
  /**
11
26
  * Load KPI grade data from JSON files - Migration Style
12
27
  * This can be called directly from migrations or other server-side scripts
@@ -66,26 +81,40 @@ async function loadKpiGradeData(specificFile) {
66
81
  const filePath = path.join(gradeDataPath, file);
67
82
  const fileContent = fs.readFileSync(filePath, 'utf8');
68
83
  const gradeData = JSON.parse(fileContent);
69
- // Validate grade data structure
70
- if (!gradeData.kpiName || !gradeData.grades || !Array.isArray(gradeData.grades)) {
84
+ // Validate grade data structure (1D array or 2D lookup object)
85
+ if (!gradeData.kpiName || !gradeData.grades) {
71
86
  console.log(` ❌ Invalid structure - missing kpiName or grades`);
72
87
  errorCount++;
73
88
  continue;
74
89
  }
90
+ const is2D = isGrade2DLookup(gradeData.grades);
91
+ if (!is2D && !Array.isArray(gradeData.grades)) {
92
+ console.log(` ❌ Invalid grades format - expected array or 2d-lookup object`);
93
+ errorCount++;
94
+ continue;
95
+ }
96
+ const gradeCount = getGradeCount(gradeData.grades);
75
97
  console.log(` πŸ” KPI Name: ${gradeData.kpiName}`);
76
- console.log(` πŸ“Š Grades: ${gradeData.grades.length} entries`);
98
+ console.log(` πŸ“Š Grades: ${gradeCount} entries${is2D ? ' (2D lookup)' : ''}`);
77
99
  // Find KPI by name in SYSTEM domain
78
100
  const kpi = await kpiRepository.findOne({
79
101
  where: { name: gradeData.kpiName, domain: { name: 'SYSTEM' } },
80
102
  relations: ['domain']
81
103
  });
82
104
  if (kpi) {
83
- // Update grades data
84
- const originalGradesCount = kpi.grades ? kpi.grades.length : 0;
85
- kpi.grades = gradeData.grades;
105
+ // Update grades data (normalize 2D type string to 'PROGRESS_DEVIATION_LOOKUP')
106
+ const originalGradesCount = kpi.grades ? getGradeCount(kpi.grades) : 0;
107
+ if (is2D) {
108
+ kpi.grades = normalize2DGrades(gradeData.grades);
109
+ kpi.scoreType = 'CUSTOM';
110
+ }
111
+ else {
112
+ kpi.grades = gradeData.grades;
113
+ kpi.scoreType = 'LOOKUP';
114
+ }
86
115
  await kpiRepository.save(kpi);
87
- console.log(` βœ… Updated successfully`);
88
- console.log(` πŸ“ˆ Grades: ${originalGradesCount} β†’ ${gradeData.grades.length}`);
116
+ console.log(` βœ… Updated successfully (scoreType: ${kpi.scoreType})`);
117
+ console.log(` πŸ“ˆ Grades: ${originalGradesCount} β†’ ${gradeCount}`);
89
118
  successCount++;
90
119
  }
91
120
  else {
@@ -117,6 +146,54 @@ async function loadKpiGradeData(specificFile) {
117
146
  }
118
147
  }
119
148
  }
149
+ /**
150
+ * X31/X32 KPIλ₯Ό λΉ„ν™œμ„±ν™” (active = false, grades = null)
151
+ */
152
+ async function deactivateDeletedKpis() {
153
+ if (!process.env.NODE_ENV) {
154
+ process.env.NODE_ENV = 'development';
155
+ }
156
+ const { config } = require('@things-factory/env');
157
+ const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js');
158
+ const connectionConfig = config.get('ormconfig');
159
+ let connection;
160
+ console.log('🚫 Deactivating deleted KPIs (X31, X32)...');
161
+ try {
162
+ console.log('πŸ”Œ Connecting to database...');
163
+ connection = await (0, typeorm_1.createConnection)(Object.assign(Object.assign(Object.assign({}, ormconfig), connectionConfig), { logging: false }));
164
+ const { addDataSource } = require('@things-factory/shell');
165
+ addDataSource('default', connection);
166
+ const { getRepository } = require('@things-factory/shell');
167
+ const { Kpi } = require('@things-factory/kpi');
168
+ const kpiRepository = getRepository(Kpi);
169
+ for (const kpiName of DEACTIVATE_KPI_NAMES) {
170
+ const kpi = await kpiRepository.findOne({
171
+ where: { name: kpiName, domain: { name: 'SYSTEM' } },
172
+ relations: ['domain']
173
+ });
174
+ if (kpi) {
175
+ kpi.active = false;
176
+ kpi.grades = null;
177
+ await kpiRepository.save(kpi);
178
+ console.log(` βœ… Deactivated: ${kpiName}`);
179
+ }
180
+ else {
181
+ console.log(` ⚠️ KPI not found: ${kpiName}`);
182
+ }
183
+ }
184
+ console.log('\nπŸŽ‰ Deactivation complete!');
185
+ }
186
+ catch (error) {
187
+ console.error('❌ Error deactivating KPIs:', error);
188
+ throw error;
189
+ }
190
+ finally {
191
+ if (connection) {
192
+ await connection.close();
193
+ console.log('πŸ”Œ Database connection closed');
194
+ }
195
+ }
196
+ }
120
197
  /**
121
198
  * List available grade data files
122
199
  */
@@ -154,16 +231,19 @@ Usage:
154
231
  ts-node server/scripts/load-grade-data-migration.ts [options] [fileName]
155
232
 
156
233
  Options:
157
- --list, -l List available grade data files
158
- --help, -h Show this help
234
+ --list, -l List available grade data files
235
+ --deactivate Deactivate X31/X32 KPIs (set active=false, grades=null)
236
+ --help, -h Show this help
159
237
 
160
238
  Examples:
161
239
  ts-node server/scripts/load-grade-data-migration.ts # Load all files
162
240
  ts-node server/scripts/load-grade-data-migration.ts x11-performance-table.json # Load specific file
163
241
  ts-node server/scripts/load-grade-data-migration.ts --list # List files
242
+ ts-node server/scripts/load-grade-data-migration.ts --deactivate # Deactivate X31/X32
164
243
 
165
244
  Note: This script connects to the database using the current Things-Factory configuration.
166
245
  Make sure the application is properly configured before running.
246
+ Supports both 1D array grades and 2D lookup grades (X13).
167
247
  `);
168
248
  return;
169
249
  }
@@ -171,6 +251,11 @@ Note: This script connects to the database using the current Things-Factory conf
171
251
  listGradeDataFiles();
172
252
  return;
173
253
  }
254
+ if (args.includes('--deactivate')) {
255
+ await deactivateDeletedKpis();
256
+ console.log('\n✨ Done!');
257
+ return;
258
+ }
174
259
  const specificFile = args.find(arg => !arg.startsWith('--'));
175
260
  if (specificFile) {
176
261
  console.log(`🎯 Loading specific file: ${specificFile}`);
@@ -1 +1 @@
1
- {"version":3,"file":"load-grade-data-migration.js","sourceRoot":"","sources":["../../server/scripts/load-grade-data-migration.ts"],"names":[],"mappings":";;;AAwBA,4CA+HC;AAKD,gDAsBC;;AAhLD,qCAA0C;AAC1C,+CAAwB;AACxB,mDAA4B;AAgB5B;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CAAC,YAAqB;IAC1D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAExD,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,aAAa,CAAA;IACtC,CAAC;IAED,wCAAwC;IACxC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,6DAA6D,CAAC,CAAA;IACxF,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAEhD,IAAI,UAAU,CAAA;IAEd,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;IAC3C,OAAO,CAAC,GAAG,CAAC,wBAAwB,aAAa,EAAE,CAAC,CAAA;IAEpD,IAAI,CAAC;QACH,0DAA0D;QAC1D,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC3C,UAAU,GAAG,MAAM,IAAA,0BAAgB,gDAC9B,SAAS,GACT,gBAAgB,KACnB,OAAO,EAAE,KAAK,IACd,CAAA;QAEF,oDAAoD;QACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;QAC1D,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QAEpC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;QAEnC,uCAAuC;QACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,qCAAqC,aAAa,EAAE,CAAC,CAAA;YACnE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAe,CAAA;QACnB,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC;gBAC3D,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAA;YACpD,CAAC;YACD,KAAK,GAAG,CAAC,YAAY,CAAC,CAAA;YACtB,OAAO,CAAC,GAAG,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YAC5E,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAA;QAC1D,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,CAAA;QACpB,IAAI,UAAU,GAAG,CAAC,CAAA;QAElB,8DAA8D;QAC9D,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;QAC1D,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;QAC9C,MAAM,aAAa,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QAExC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAA;gBAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;gBAC/C,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;gBACrD,MAAM,SAAS,GAAc,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;gBAEpD,gCAAgC;gBAChC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;oBAChF,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;oBACjE,UAAU,EAAE,CAAA;oBACZ,SAAQ;gBACV,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;gBACnD,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,CAAA;gBAE/D,oCAAoC;gBACpC,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC;oBACtC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBAC9D,SAAS,EAAE,CAAC,QAAQ,CAAC;iBACtB,CAAC,CAAA;gBAEF,IAAI,GAAG,EAAE,CAAC;oBACR,qBAAqB;oBACrB,MAAM,mBAAmB,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;oBAC9D,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAA;oBAC7B,MAAM,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBAE7B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;oBACxC,OAAO,CAAC,GAAG,CAAC,iBAAiB,mBAAmB,MAAM,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;oBAChF,YAAY,EAAE,CAAA;gBAChB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,0CAA0C,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC1E,UAAU,EAAE,CAAA;gBACd,CAAC;YAEH,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,+BAA+B,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC/D,UAAU,EAAE,CAAA;YACd,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAA;QACpD,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,GAAG,CAAC,oBAAoB,YAAY,EAAE,CAAC,CAAA;QAC/C,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAA;QAEzC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAA;QAC/E,CAAC;IAEH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAA;QAChE,MAAM,KAAK,CAAA;IACb,CAAC;YAAS,CAAC;QACT,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,UAAU,CAAC,KAAK,EAAE,CAAA;YACxB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAExD,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAA;YAChD,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QAElF,OAAO,CAAC,GAAG,CAAC,oCAAoC,aAAa,KAAK,CAAC,CAAA;QACnE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QAClE,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAA;QAEhD,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;QAC7D,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAElC,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;OAiBX,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,kBAAkB,EAAE,CAAA;YACpB,OAAM;QACR,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;QAE5D,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,6BAA6B,YAAY,EAAE,CAAC,CAAA;YACxD,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAA;YAC9C,MAAM,gBAAgB,EAAE,CAAA;QAC1B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAE1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,yBAAyB;AACzB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAA;AACR,CAAC","sourcesContent":["#!/usr/bin/env ts-node\n\nimport { createConnection } from 'typeorm'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\ninterface GradeData {\n kpiName: string\n version: number\n description: string\n grades: Array<{\n name: string\n minValue: number\n maxValue: number\n score?: number\n color?: string\n description?: string\n }>\n}\n\n/**\n * Load KPI grade data from JSON files - Migration Style\n * This can be called directly from migrations or other server-side scripts\n */\nexport async function loadKpiGradeData(specificFile?: string): Promise<void> {\n const gradeDataPath = path.join(__dirname, 'grade-data')\n \n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n console.log('πŸš€ Loading KPI Grade Data...')\n console.log(`πŸ“ Source directory: ${gradeDataPath}`)\n\n try {\n // Create database connection using Things-Factory pattern\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n // Register the connection with Things-Factory shell\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n console.log('βœ… Database connected')\n\n // Check if grade-data directory exists\n if (!fs.existsSync(gradeDataPath)) {\n console.error(`❌ Grade data directory not found: ${gradeDataPath}`)\n throw new Error('Grade data directory not found')\n }\n\n // Get files to process\n let files: string[]\n if (specificFile) {\n if (!fs.existsSync(path.join(gradeDataPath, specificFile))) {\n throw new Error(`File not found: ${specificFile}`)\n }\n files = [specificFile]\n console.log(`πŸ“„ Processing single file: ${specificFile}`)\n } else {\n files = fs.readdirSync(gradeDataPath).filter(file => file.endsWith('.json'))\n console.log(`πŸ“ Found ${files.length} grade data files`)\n }\n\n if (files.length === 0) {\n console.log('⚠️ No JSON files found to process')\n return\n }\n\n let successCount = 0\n let errorCount = 0\n\n // Now we can use getRepository with the registered connection\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n for (const file of files) {\n try {\n console.log(`\\nπŸ“„ Processing: ${file}`)\n \n const filePath = path.join(gradeDataPath, file)\n const fileContent = fs.readFileSync(filePath, 'utf8')\n const gradeData: GradeData = JSON.parse(fileContent)\n\n // Validate grade data structure\n if (!gradeData.kpiName || !gradeData.grades || !Array.isArray(gradeData.grades)) {\n console.log(` ❌ Invalid structure - missing kpiName or grades`)\n errorCount++\n continue\n }\n\n console.log(` πŸ” KPI Name: ${gradeData.kpiName}`)\n console.log(` πŸ“Š Grades: ${gradeData.grades.length} entries`)\n\n // Find KPI by name in SYSTEM domain\n const kpi = await kpiRepository.findOne({\n where: { name: gradeData.kpiName, domain: { name: 'SYSTEM' } },\n relations: ['domain']\n })\n\n if (kpi) {\n // Update grades data\n const originalGradesCount = kpi.grades ? kpi.grades.length : 0\n kpi.grades = gradeData.grades\n await kpiRepository.save(kpi)\n \n console.log(` βœ… Updated successfully`)\n console.log(` πŸ“ˆ Grades: ${originalGradesCount} β†’ ${gradeData.grades.length}`)\n successCount++\n } else {\n console.log(` ⚠️ KPI not found in SYSTEM domain: ${gradeData.kpiName}`)\n errorCount++\n }\n \n } catch (fileError) {\n console.log(` ❌ File processing error: ${fileError.message}`)\n errorCount++\n }\n }\n\n console.log(`\\nπŸŽ‰ KPI Grade Data Loading Complete!`)\n console.log(` πŸ“Š Total files: ${files.length}`)\n console.log(` βœ… Successful: ${successCount}`)\n console.log(` ❌ Errors: ${errorCount}`)\n\n if (errorCount > 0) {\n console.log(`\\n⚠️ Some files had errors. Check the logs above for details.`)\n }\n\n } catch (error) {\n console.error(`❌ Fatal error during grade data loading:`, error)\n throw error\n } finally {\n if (connection) {\n await connection.close()\n console.log('πŸ”Œ Database connection closed')\n }\n }\n}\n\n/**\n * List available grade data files\n */\nexport function listGradeDataFiles(): string[] {\n const gradeDataPath = path.join(__dirname, 'grade-data')\n \n try {\n if (!fs.existsSync(gradeDataPath)) {\n console.log('πŸ“ Grade data directory not found')\n return []\n }\n \n const files = fs.readdirSync(gradeDataPath).filter(file => file.endsWith('.json'))\n \n console.log(`πŸ“ Available grade data files in ${gradeDataPath}:\\n`)\n files.forEach((file, index) => {\n console.log(` ${(index + 1).toString().padStart(2)}: ${file}`)\n })\n console.log(`\\nπŸ“ˆ Total: ${files.length} files`)\n \n return files\n } catch (error) {\n console.error('❌ Error reading grade data directory:', error)\n return []\n }\n}\n\n/**\n * CLI execution when called directly\n */\nasync function main() {\n const args = process.argv.slice(2)\n\n try {\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\n🎯 KPI Grade Data Loader (Migration Style)\n\nUsage:\n ts-node server/scripts/load-grade-data-migration.ts [options] [fileName]\n\nOptions:\n --list, -l List available grade data files\n --help, -h Show this help\n\nExamples:\n ts-node server/scripts/load-grade-data-migration.ts # Load all files\n ts-node server/scripts/load-grade-data-migration.ts x11-performance-table.json # Load specific file\n ts-node server/scripts/load-grade-data-migration.ts --list # List files\n\nNote: This script connects to the database using the current Things-Factory configuration.\n Make sure the application is properly configured before running.\n `)\n return\n }\n\n if (args.includes('--list') || args.includes('-l')) {\n listGradeDataFiles()\n return\n }\n\n const specificFile = args.find(arg => !arg.startsWith('--'))\n \n if (specificFile) {\n console.log(`🎯 Loading specific file: ${specificFile}`)\n await loadKpiGradeData(specificFile)\n } else {\n console.log(`🎯 Loading all grade data files`)\n await loadKpiGradeData()\n }\n\n console.log('\\n✨ Done!')\n \n } catch (error) {\n console.error('\\n❌ Script failed:', error.message)\n process.exit(1)\n }\n}\n\n// Run if called directly\nif (require.main === module) {\n main()\n}"]}
1
+ {"version":3,"file":"load-grade-data-migration.js","sourceRoot":"","sources":["../../server/scripts/load-grade-data-migration.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env ts-node\n\nimport { createConnection } from 'typeorm'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\ninterface GradeEntry {\n name: string\n minValue: number\n maxValue: number\n score?: number\n color?: string\n description?: string\n}\n\ninterface Grade2DLookup {\n type: 'PROGRESS_DEVIATION_LOOKUP' | 'PROGRESS_DEVIATION_LOOKUP'\n description?: string\n rows: Array<{\n progressRate: number\n boundary5to4: number\n boundary4to3: number\n boundary3to2: number\n boundary2to1: number\n }>\n}\n\ninterface GradeData {\n kpiName: string\n version: number\n description: string\n grades: GradeEntry[] | Grade2DLookup\n}\n\n/** X31/X32 λΉ„ν™œμ„±ν™” λŒ€μƒ KPI 이름 */\nconst DEACTIVATE_KPI_NAMES = ['X31. ν’ˆμ§ˆμ‹œν—˜ λΆˆν•©κ²©λ₯ ', 'X32. κ²€μˆ˜μžμž¬ λΆˆν•©κ²©λ₯ ']\n\nfunction isGrade2DLookup(grades: any): grades is Grade2DLookup {\n return grades && typeof grades === 'object' && !Array.isArray(grades) && (grades.type === 'PROGRESS_DEVIATION_LOOKUP' || grades.type === 'PROGRESS_DEVIATION_LOOKUP')\n}\n\nfunction normalize2DGrades(grades: Grade2DLookup): Grade2DLookup {\n return { ...grades, type: 'PROGRESS_DEVIATION_LOOKUP' }\n}\n\nfunction getGradeCount(grades: GradeEntry[] | Grade2DLookup): number {\n if (isGrade2DLookup(grades)) {\n return grades.rows.length\n }\n return Array.isArray(grades) ? grades.length : 0\n}\n\n/**\n * Load KPI grade data from JSON files - Migration Style\n * This can be called directly from migrations or other server-side scripts\n */\nexport async function loadKpiGradeData(specificFile?: string): Promise<void> {\n const gradeDataPath = path.join(__dirname, 'grade-data')\n \n // Set NODE_ENV if not set\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n // Initialize Things-Factory environment\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n console.log('πŸš€ Loading KPI Grade Data...')\n console.log(`πŸ“ Source directory: ${gradeDataPath}`)\n\n try {\n // Create database connection using Things-Factory pattern\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n // Register the connection with Things-Factory shell\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n console.log('βœ… Database connected')\n\n // Check if grade-data directory exists\n if (!fs.existsSync(gradeDataPath)) {\n console.error(`❌ Grade data directory not found: ${gradeDataPath}`)\n throw new Error('Grade data directory not found')\n }\n\n // Get files to process\n let files: string[]\n if (specificFile) {\n if (!fs.existsSync(path.join(gradeDataPath, specificFile))) {\n throw new Error(`File not found: ${specificFile}`)\n }\n files = [specificFile]\n console.log(`πŸ“„ Processing single file: ${specificFile}`)\n } else {\n files = fs.readdirSync(gradeDataPath).filter(file => file.endsWith('.json'))\n console.log(`πŸ“ Found ${files.length} grade data files`)\n }\n\n if (files.length === 0) {\n console.log('⚠️ No JSON files found to process')\n return\n }\n\n let successCount = 0\n let errorCount = 0\n\n // Now we can use getRepository with the registered connection\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n for (const file of files) {\n try {\n console.log(`\\nπŸ“„ Processing: ${file}`)\n \n const filePath = path.join(gradeDataPath, file)\n const fileContent = fs.readFileSync(filePath, 'utf8')\n const gradeData: GradeData = JSON.parse(fileContent)\n\n // Validate grade data structure (1D array or 2D lookup object)\n if (!gradeData.kpiName || !gradeData.grades) {\n console.log(` ❌ Invalid structure - missing kpiName or grades`)\n errorCount++\n continue\n }\n\n const is2D = isGrade2DLookup(gradeData.grades)\n if (!is2D && !Array.isArray(gradeData.grades)) {\n console.log(` ❌ Invalid grades format - expected array or 2d-lookup object`)\n errorCount++\n continue\n }\n\n const gradeCount = getGradeCount(gradeData.grades)\n console.log(` πŸ” KPI Name: ${gradeData.kpiName}`)\n console.log(` πŸ“Š Grades: ${gradeCount} entries${is2D ? ' (2D lookup)' : ''}`)\n\n // Find KPI by name in SYSTEM domain\n const kpi = await kpiRepository.findOne({\n where: { name: gradeData.kpiName, domain: { name: 'SYSTEM' } },\n relations: ['domain']\n })\n\n if (kpi) {\n // Update grades data (normalize 2D type string to 'PROGRESS_DEVIATION_LOOKUP')\n const originalGradesCount = kpi.grades ? getGradeCount(kpi.grades) : 0\n if (is2D) {\n kpi.grades = normalize2DGrades(gradeData.grades as Grade2DLookup) as any\n kpi.scoreType = 'CUSTOM'\n } else {\n kpi.grades = gradeData.grades as any\n kpi.scoreType = 'LOOKUP'\n }\n await kpiRepository.save(kpi)\n\n console.log(` βœ… Updated successfully (scoreType: ${kpi.scoreType})`)\n console.log(` πŸ“ˆ Grades: ${originalGradesCount} β†’ ${gradeCount}`)\n successCount++\n } else {\n console.log(` ⚠️ KPI not found in SYSTEM domain: ${gradeData.kpiName}`)\n errorCount++\n }\n \n } catch (fileError) {\n console.log(` ❌ File processing error: ${fileError.message}`)\n errorCount++\n }\n }\n\n console.log(`\\nπŸŽ‰ KPI Grade Data Loading Complete!`)\n console.log(` πŸ“Š Total files: ${files.length}`)\n console.log(` βœ… Successful: ${successCount}`)\n console.log(` ❌ Errors: ${errorCount}`)\n\n if (errorCount > 0) {\n console.log(`\\n⚠️ Some files had errors. Check the logs above for details.`)\n }\n\n } catch (error) {\n console.error(`❌ Fatal error during grade data loading:`, error)\n throw error\n } finally {\n if (connection) {\n await connection.close()\n console.log('πŸ”Œ Database connection closed')\n }\n }\n}\n\n/**\n * X31/X32 KPIλ₯Ό λΉ„ν™œμ„±ν™” (active = false, grades = null)\n */\nexport async function deactivateDeletedKpis(): Promise<void> {\n if (!process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development'\n }\n\n const { config } = require('@things-factory/env')\n const ormconfig = require('@things-factory/shell/dist-server/initializers/ormconfig.js')\n const connectionConfig = config.get('ormconfig')\n\n let connection\n\n console.log('🚫 Deactivating deleted KPIs (X31, X32)...')\n\n try {\n console.log('πŸ”Œ Connecting to database...')\n connection = await createConnection({\n ...ormconfig,\n ...connectionConfig,\n logging: false\n })\n\n const { addDataSource } = require('@things-factory/shell')\n addDataSource('default', connection)\n\n const { getRepository } = require('@things-factory/shell')\n const { Kpi } = require('@things-factory/kpi')\n const kpiRepository = getRepository(Kpi)\n\n for (const kpiName of DEACTIVATE_KPI_NAMES) {\n const kpi = await kpiRepository.findOne({\n where: { name: kpiName, domain: { name: 'SYSTEM' } },\n relations: ['domain']\n })\n\n if (kpi) {\n kpi.active = false\n kpi.grades = null\n await kpiRepository.save(kpi)\n console.log(` βœ… Deactivated: ${kpiName}`)\n } else {\n console.log(` ⚠️ KPI not found: ${kpiName}`)\n }\n }\n\n console.log('\\nπŸŽ‰ Deactivation complete!')\n } catch (error) {\n console.error('❌ Error deactivating KPIs:', error)\n throw error\n } finally {\n if (connection) {\n await connection.close()\n console.log('πŸ”Œ Database connection closed')\n }\n }\n}\n\n/**\n * List available grade data files\n */\nexport function listGradeDataFiles(): string[] {\n const gradeDataPath = path.join(__dirname, 'grade-data')\n \n try {\n if (!fs.existsSync(gradeDataPath)) {\n console.log('πŸ“ Grade data directory not found')\n return []\n }\n \n const files = fs.readdirSync(gradeDataPath).filter(file => file.endsWith('.json'))\n \n console.log(`πŸ“ Available grade data files in ${gradeDataPath}:\\n`)\n files.forEach((file, index) => {\n console.log(` ${(index + 1).toString().padStart(2)}: ${file}`)\n })\n console.log(`\\nπŸ“ˆ Total: ${files.length} files`)\n \n return files\n } catch (error) {\n console.error('❌ Error reading grade data directory:', error)\n return []\n }\n}\n\n/**\n * CLI execution when called directly\n */\nasync function main() {\n const args = process.argv.slice(2)\n\n try {\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\n🎯 KPI Grade Data Loader (Migration Style)\n\nUsage:\n ts-node server/scripts/load-grade-data-migration.ts [options] [fileName]\n\nOptions:\n --list, -l List available grade data files\n --deactivate Deactivate X31/X32 KPIs (set active=false, grades=null)\n --help, -h Show this help\n\nExamples:\n ts-node server/scripts/load-grade-data-migration.ts # Load all files\n ts-node server/scripts/load-grade-data-migration.ts x11-performance-table.json # Load specific file\n ts-node server/scripts/load-grade-data-migration.ts --list # List files\n ts-node server/scripts/load-grade-data-migration.ts --deactivate # Deactivate X31/X32\n\nNote: This script connects to the database using the current Things-Factory configuration.\n Make sure the application is properly configured before running.\n Supports both 1D array grades and 2D lookup grades (X13).\n `)\n return\n }\n\n if (args.includes('--list') || args.includes('-l')) {\n listGradeDataFiles()\n return\n }\n\n if (args.includes('--deactivate')) {\n await deactivateDeletedKpis()\n console.log('\\n✨ Done!')\n return\n }\n\n const specificFile = args.find(arg => !arg.startsWith('--'))\n \n if (specificFile) {\n console.log(`🎯 Loading specific file: ${specificFile}`)\n await loadKpiGradeData(specificFile)\n } else {\n console.log(`🎯 Loading all grade data files`)\n await loadKpiGradeData()\n }\n\n console.log('\\n✨ Done!')\n \n } catch (error) {\n console.error('\\n❌ Script failed:', error.message)\n process.exit(1)\n }\n}\n\n// Run if called directly\nif (require.main === module) {\n main()\n}"]}
@@ -1,4 +1,8 @@
1
1
  #!/usr/bin/env ts-node
2
+ /**
3
+ * Batch process multiple organizations with single initialization (optimized for performance)
4
+ */
5
+ export declare function propagateParentKpiValuesBatch(orgScopes: string[], specificKpiName?: string, forceRecalculate?: boolean, targetDate?: string, version?: number): Promise<void>;
2
6
  /**
3
7
  * Propagate parent KPI values based on child KPI scores and weights
4
8
  * Processes hierarchy from leaf to root, calculating weighted averages