@things-factory/kpi 9.0.22 → 9.0.24

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 (189) hide show
  1. package/client/pages/kpi/kpi-list-page.ts +180 -22
  2. package/client/pages/kpi/kpi-viz-editor.ts +1 -1
  3. package/client/pages/kpi-category/kpi-category-list-page.ts +76 -3
  4. package/client/pages/kpi-category/kpi-category-value-calculator.ts +233 -0
  5. package/client/pages/kpi-category-value/kpi-category-value-list-page.ts +404 -0
  6. package/client/pages/kpi-metric/kpi-metric-list-page.ts +13 -1
  7. package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +763 -0
  8. package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +55 -1
  9. package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.ts +3 -13
  10. package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.ts +13 -1
  11. package/client/pages/kpi-value/kpi-value-editor-page.ts +774 -0
  12. package/client/pages/kpi-value/kpi-value-list-page.ts +58 -1
  13. package/client/route.ts +16 -0
  14. package/dist-client/pages/kpi/kpi-list-page.d.ts +2 -1
  15. package/dist-client/pages/kpi/kpi-list-page.js +180 -22
  16. package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
  17. package/dist-client/pages/kpi/kpi-viz-editor.d.ts +0 -1
  18. package/dist-client/pages/kpi/kpi-viz-editor.js +1 -1
  19. package/dist-client/pages/kpi/kpi-viz-editor.js.map +1 -1
  20. package/dist-client/pages/kpi-category/kpi-category-list-page.d.ts +3 -0
  21. package/dist-client/pages/kpi-category/kpi-category-list-page.js +71 -3
  22. package/dist-client/pages/kpi-category/kpi-category-list-page.js.map +1 -1
  23. package/dist-client/pages/kpi-category/kpi-category-value-calculator.d.ts +13 -0
  24. package/dist-client/pages/kpi-category/kpi-category-value-calculator.js +256 -0
  25. package/dist-client/pages/kpi-category/kpi-category-value-calculator.js.map +1 -0
  26. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.d.ts +63 -0
  27. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js +393 -0
  28. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js.map +1 -0
  29. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +13 -1
  30. package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
  31. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +58 -0
  32. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +736 -0
  33. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -0
  34. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +5 -1
  35. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +50 -2
  36. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  37. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +3 -13
  38. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -1
  39. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js +13 -1
  40. package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-page.js.map +1 -1
  41. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +55 -0
  42. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +748 -0
  43. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -0
  44. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +10 -2
  45. package/dist-client/pages/kpi-value/kpi-value-list-page.js +57 -1
  46. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  47. package/dist-client/route.d.ts +1 -1
  48. package/dist-client/route.js +12 -0
  49. package/dist-client/route.js.map +1 -1
  50. package/dist-client/tsconfig.tsbuildinfo +1 -1
  51. package/dist-server/calculator/evaluator.d.ts +8 -0
  52. package/dist-server/calculator/evaluator.js +42 -0
  53. package/dist-server/calculator/evaluator.js.map +1 -0
  54. package/dist-server/calculator/functions.d.ts +3 -0
  55. package/dist-server/calculator/functions.js +62 -0
  56. package/dist-server/calculator/functions.js.map +1 -0
  57. package/dist-server/calculator/index.d.ts +4 -0
  58. package/dist-server/calculator/index.js +8 -0
  59. package/dist-server/calculator/index.js.map +1 -0
  60. package/dist-server/calculator/parser.d.ts +21 -0
  61. package/dist-server/calculator/parser.js +121 -0
  62. package/dist-server/calculator/parser.js.map +1 -0
  63. package/dist-server/calculator/provider.d.ts +8 -0
  64. package/dist-server/calculator/provider.js +13 -0
  65. package/dist-server/calculator/provider.js.map +1 -0
  66. package/dist-server/controllers/kpi-metric-value-provider.d.ts +11 -0
  67. package/dist-server/controllers/kpi-metric-value-provider.js +63 -0
  68. package/dist-server/controllers/kpi-metric-value-provider.js.map +1 -0
  69. package/dist-server/controllers/kpi-value-provider.d.ts +11 -0
  70. package/dist-server/controllers/kpi-value-provider.js +46 -0
  71. package/dist-server/controllers/kpi-value-provider.js.map +1 -0
  72. package/dist-server/service/index.d.ts +4 -2
  73. package/dist-server/service/index.js +5 -0
  74. package/dist-server/service/index.js.map +1 -1
  75. package/dist-server/service/kpi/aggregate-kpi.js +4 -4
  76. package/dist-server/service/kpi/aggregate-kpi.js.map +1 -1
  77. package/dist-server/service/kpi/kpi-grade.types.d.ts +11 -10
  78. package/dist-server/service/kpi/kpi-grade.types.js.map +1 -1
  79. package/dist-server/service/kpi/kpi-history.d.ts +2 -2
  80. package/dist-server/service/kpi/kpi-history.js.map +1 -1
  81. package/dist-server/service/kpi/kpi-mutation.d.ts +2 -0
  82. package/dist-server/service/kpi/kpi-mutation.js +126 -4
  83. package/dist-server/service/kpi/kpi-mutation.js.map +1 -1
  84. package/dist-server/service/kpi/kpi-type.d.ts +8 -5
  85. package/dist-server/service/kpi/kpi-type.js +22 -8
  86. package/dist-server/service/kpi/kpi-type.js.map +1 -1
  87. package/dist-server/service/kpi/kpi.d.ts +6 -3
  88. package/dist-server/service/kpi/kpi.js +29 -9
  89. package/dist-server/service/kpi/kpi.js.map +1 -1
  90. package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +3 -4
  91. package/dist-server/service/kpi-category/kpi-category-mutation.js +151 -80
  92. package/dist-server/service/kpi-category/kpi-category-mutation.js.map +1 -1
  93. package/dist-server/service/kpi-category/kpi-category-query.d.ts +5 -0
  94. package/dist-server/service/kpi-category/kpi-category-query.js +19 -1
  95. package/dist-server/service/kpi-category/kpi-category-query.js.map +1 -1
  96. package/dist-server/service/kpi-category/kpi-category-type.d.ts +3 -0
  97. package/dist-server/service/kpi-category/kpi-category-type.js +16 -1
  98. package/dist-server/service/kpi-category/kpi-category-type.js.map +1 -1
  99. package/dist-server/service/kpi-category/kpi-category.d.ts +2 -0
  100. package/dist-server/service/kpi-category/kpi-category.js +10 -1
  101. package/dist-server/service/kpi-category/kpi-category.js.map +1 -1
  102. package/dist-server/service/kpi-category-value/index.d.ts +6 -0
  103. package/dist-server/service/kpi-category-value/index.js +10 -0
  104. package/dist-server/service/kpi-category-value/index.js.map +1 -0
  105. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.d.ts +8 -0
  106. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js +102 -0
  107. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js.map +1 -0
  108. package/dist-server/service/kpi-category-value/kpi-category-value-query.d.ts +13 -0
  109. package/dist-server/service/kpi-category-value/kpi-category-value-query.js +91 -0
  110. package/dist-server/service/kpi-category-value/kpi-category-value-query.js.map +1 -0
  111. package/dist-server/service/kpi-category-value/kpi-category-value-type.d.ts +19 -0
  112. package/dist-server/service/kpi-category-value/kpi-category-value-type.js +73 -0
  113. package/dist-server/service/kpi-category-value/kpi-category-value-type.js.map +1 -0
  114. package/dist-server/service/kpi-category-value/kpi-category-value.d.ts +19 -0
  115. package/dist-server/service/kpi-category-value/kpi-category-value.js +91 -0
  116. package/dist-server/service/kpi-category-value/kpi-category-value.js.map +1 -0
  117. package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +5 -3
  118. package/dist-server/service/kpi-metric/kpi-metric-type.js +5 -3
  119. package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -1
  120. package/dist-server/service/kpi-metric/kpi-metric.d.ts +2 -8
  121. package/dist-server/service/kpi-metric/kpi-metric.js +3 -14
  122. package/dist-server/service/kpi-metric/kpi-metric.js.map +1 -1
  123. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +87 -45
  124. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  125. package/dist-server/service/kpi-metric-value/kpi-metric-value.js +3 -2
  126. package/dist-server/service/kpi-metric-value/kpi-metric-value.js.map +1 -1
  127. package/dist-server/service/kpi-value/kpi-value-mutation.d.ts +3 -1
  128. package/dist-server/service/kpi-value/kpi-value-mutation.js +174 -6
  129. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
  130. package/dist-server/service/kpi-value/kpi-value-query.d.ts +0 -2
  131. package/dist-server/service/kpi-value/kpi-value-query.js +0 -12
  132. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  133. package/dist-server/service/kpi-value/kpi-value-score.service.d.ts +26 -0
  134. package/dist-server/service/kpi-value/kpi-value-score.service.js +97 -0
  135. package/dist-server/service/kpi-value/kpi-value-score.service.js.map +1 -0
  136. package/dist-server/service/kpi-value/kpi-value-type.d.ts +2 -0
  137. package/dist-server/service/kpi-value/kpi-value-type.js +14 -0
  138. package/dist-server/service/kpi-value/kpi-value-type.js.map +1 -1
  139. package/dist-server/service/kpi-value/kpi-value.d.ts +1 -0
  140. package/dist-server/service/kpi-value/kpi-value.js +9 -1
  141. package/dist-server/service/kpi-value/kpi-value.js.map +1 -1
  142. package/dist-server/service/utils/value-date-util.d.ts +3 -0
  143. package/dist-server/service/utils/value-date-util.js +76 -0
  144. package/dist-server/service/utils/value-date-util.js.map +1 -0
  145. package/dist-server/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +5 -5
  147. package/server/calculator/evaluator.ts +45 -0
  148. package/server/calculator/functions.ts +67 -0
  149. package/server/calculator/index.ts +4 -0
  150. package/server/calculator/parser.ts +128 -0
  151. package/server/calculator/provider.ts +10 -0
  152. package/server/controllers/kpi-metric-value-provider.ts +66 -0
  153. package/server/controllers/kpi-value-provider.ts +51 -0
  154. package/server/service/index.ts +5 -0
  155. package/server/service/kpi/aggregate-kpi.ts +4 -4
  156. package/server/service/kpi/kpi-grade.types.ts +11 -10
  157. package/server/service/kpi/kpi-history.ts +2 -2
  158. package/server/service/kpi/kpi-mutation.ts +128 -4
  159. package/server/service/kpi/kpi-type.ts +21 -9
  160. package/server/service/kpi/kpi.ts +32 -10
  161. package/server/service/kpi-category/kpi-category-mutation.ts +155 -82
  162. package/server/service/kpi-category/kpi-category-query.ts +21 -1
  163. package/server/service/kpi-category/kpi-category-type.ts +17 -6
  164. package/server/service/kpi-category/kpi-category.ts +10 -1
  165. package/server/service/kpi-category-value/index.ts +7 -0
  166. package/server/service/kpi-category-value/kpi-category-value-mutation.ts +88 -0
  167. package/server/service/kpi-category-value/kpi-category-value-query.ts +62 -0
  168. package/server/service/kpi-category-value/kpi-category-value-type.ts +48 -0
  169. package/server/service/kpi-category-value/kpi-category-value.ts +79 -0
  170. package/server/service/kpi-metric/kpi-metric-type.ts +7 -5
  171. package/server/service/kpi-metric/kpi-metric.ts +3 -15
  172. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +95 -47
  173. package/server/service/kpi-metric-value/kpi-metric-value.ts +4 -2
  174. package/server/service/kpi-value/kpi-value-mutation.ts +176 -6
  175. package/server/service/kpi-value/kpi-value-query.ts +2 -8
  176. package/server/service/kpi-value/kpi-value-score.service.ts +112 -0
  177. package/server/service/kpi-value/kpi-value-type.ts +12 -0
  178. package/server/service/kpi-value/kpi-value.ts +8 -1
  179. package/server/service/utils/value-date-util.ts +72 -0
  180. package/things-factory.config.js +3 -0
  181. package/translations/en.json +3 -0
  182. package/translations/ja.json +3 -0
  183. package/translations/ko.json +3 -0
  184. package/translations/ms.json +3 -0
  185. package/translations/zh.json +3 -0
  186. package/dist-server/service/kpi-value/kpi-value-grade.service.d.ts +0 -34
  187. package/dist-server/service/kpi-value/kpi-value-grade.service.js +0 -117
  188. package/dist-server/service/kpi-value/kpi-value-grade.service.js.map +0 -1
  189. package/server/service/kpi-value/kpi-value-grade.service.ts +0 -127
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KpiCategoryValue = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
6
+ const type_graphql_1 = require("type-graphql");
7
+ const shell_1 = require("@things-factory/shell");
8
+ const kpi_category_1 = require("../kpi-category/kpi-category");
9
+ const auth_base_1 = require("@things-factory/auth-base");
10
+ let KpiCategoryValue = class KpiCategoryValue {
11
+ };
12
+ exports.KpiCategoryValue = KpiCategoryValue;
13
+ tslib_1.__decorate([
14
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
15
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Unique identifier for this KPI category value record.' }),
16
+ tslib_1.__metadata("design:type", String)
17
+ ], KpiCategoryValue.prototype, "id", void 0);
18
+ tslib_1.__decorate([
19
+ (0, typeorm_1.ManyToOne)(() => shell_1.Domain, { onDelete: 'CASCADE' }),
20
+ (0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'Domain (tenant) to which this KPI category value belongs.' }),
21
+ tslib_1.__metadata("design:type", shell_1.Domain)
22
+ ], KpiCategoryValue.prototype, "domain", void 0);
23
+ tslib_1.__decorate([
24
+ (0, typeorm_1.RelationId)((kpiCategoryValue) => kpiCategoryValue.domain),
25
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Domain (tenant) to which this KPI category value belongs.' }),
26
+ tslib_1.__metadata("design:type", String)
27
+ ], KpiCategoryValue.prototype, "domainId", void 0);
28
+ tslib_1.__decorate([
29
+ (0, typeorm_1.Column)({ default: '' }),
30
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Group key for this value (organization, line, user, etc.)' }),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], KpiCategoryValue.prototype, "group", void 0);
33
+ tslib_1.__decorate([
34
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Performance score for this category (0-1 range).' }),
35
+ (0, typeorm_1.Column)('float', { nullable: true }),
36
+ tslib_1.__metadata("design:type", Number)
37
+ ], KpiCategoryValue.prototype, "score", void 0);
38
+ tslib_1.__decorate([
39
+ (0, type_graphql_1.Field)({
40
+ nullable: true,
41
+ description: 'Date or period for which this KPI category value is recorded (e.g., day: YYYY-MM-DD, month: YYYY-MM, quarter: YYYY-Qn, range: YYYY-MM-DD~YYYY-MM-DD).'
42
+ }),
43
+ (0, typeorm_1.Column)(),
44
+ tslib_1.__metadata("design:type", String)
45
+ ], KpiCategoryValue.prototype, "valueDate", void 0);
46
+ tslib_1.__decorate([
47
+ (0, typeorm_1.ManyToOne)(() => kpi_category_1.KpiCategory, { onDelete: 'CASCADE' }),
48
+ (0, type_graphql_1.Field)(type => kpi_category_1.KpiCategory, { nullable: true, description: 'KPI category to which this value belongs.' }),
49
+ tslib_1.__metadata("design:type", kpi_category_1.KpiCategory)
50
+ ], KpiCategoryValue.prototype, "category", void 0);
51
+ tslib_1.__decorate([
52
+ (0, typeorm_1.RelationId)((kpiCategoryValue) => kpiCategoryValue.category),
53
+ (0, type_graphql_1.Field)({ nullable: true, description: 'ID of the domain (tenant) for this KPI category value.' }),
54
+ tslib_1.__metadata("design:type", String)
55
+ ], KpiCategoryValue.prototype, "categoryId", void 0);
56
+ tslib_1.__decorate([
57
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Timestamp when this KPI category value record was created.' }),
58
+ (0, typeorm_1.CreateDateColumn)(),
59
+ tslib_1.__metadata("design:type", Date)
60
+ ], KpiCategoryValue.prototype, "createdAt", void 0);
61
+ tslib_1.__decorate([
62
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Timestamp when this KPI category value record was last updated.' }),
63
+ (0, typeorm_1.UpdateDateColumn)(),
64
+ tslib_1.__metadata("design:type", Date)
65
+ ], KpiCategoryValue.prototype, "updatedAt", void 0);
66
+ tslib_1.__decorate([
67
+ (0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable: true, onDelete: 'SET NULL' }),
68
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'User who created this KPI category value record.' }),
69
+ tslib_1.__metadata("design:type", auth_base_1.User)
70
+ ], KpiCategoryValue.prototype, "creator", void 0);
71
+ tslib_1.__decorate([
72
+ (0, typeorm_1.RelationId)((kpiCategoryValue) => kpiCategoryValue.creator),
73
+ (0, type_graphql_1.Field)({ nullable: true, description: 'ID of the user who created this KPI category value record.' }),
74
+ tslib_1.__metadata("design:type", String)
75
+ ], KpiCategoryValue.prototype, "creatorId", void 0);
76
+ tslib_1.__decorate([
77
+ (0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable: true, onDelete: 'SET NULL' }),
78
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'User who last updated this KPI category value record.' }),
79
+ tslib_1.__metadata("design:type", auth_base_1.User)
80
+ ], KpiCategoryValue.prototype, "updater", void 0);
81
+ tslib_1.__decorate([
82
+ (0, typeorm_1.RelationId)((kpiCategoryValue) => kpiCategoryValue.updater),
83
+ (0, type_graphql_1.Field)({ nullable: true, description: 'ID of the user who last updated this KPI category value record.' }),
84
+ tslib_1.__metadata("design:type", String)
85
+ ], KpiCategoryValue.prototype, "updaterId", void 0);
86
+ exports.KpiCategoryValue = KpiCategoryValue = tslib_1.__decorate([
87
+ (0, typeorm_1.Entity)(),
88
+ (0, typeorm_1.Index)('ix_kpi_category_value_latest', ['domain', 'group', 'category', 'valueDate'], { unique: true }),
89
+ (0, type_graphql_1.ObjectType)({ description: 'Entity for KpiCategoryValue' })
90
+ ], KpiCategoryValue);
91
+ //# sourceMappingURL=kpi-category-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-category-value.js","sourceRoot":"","sources":["../../../server/service/kpi-category-value/kpi-category-value.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Entity,\n PrimaryGeneratedColumn,\n Column,\n Index,\n ManyToOne,\n CreateDateColumn,\n UpdateDateColumn,\n RelationId\n} from 'typeorm'\nimport { Field, ObjectType, ID, Float } from 'type-graphql'\nimport { Domain } from '@things-factory/shell'\nimport { KpiCategory } from '../kpi-category/kpi-category'\nimport { User } from '@things-factory/auth-base'\n\n@Entity()\n@Index('ix_kpi_category_value_latest', ['domain', 'group', 'category', 'valueDate'], { unique: true })\n@ObjectType({ description: 'Entity for KpiCategoryValue' })\nexport class KpiCategoryValue {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier for this KPI category value record.' })\n readonly id: string\n\n @ManyToOne(() => Domain, { onDelete: 'CASCADE' })\n @Field(type => Domain, { nullable: true, description: 'Domain (tenant) to which this KPI category value belongs.' })\n domain: Domain\n\n @RelationId((kpiCategoryValue: KpiCategoryValue) => kpiCategoryValue.domain)\n @Field({ nullable: true, description: 'Domain (tenant) to which this KPI category value belongs.' })\n domainId: string\n\n @Column({ default: '' })\n @Field({ nullable: true, description: 'Group key for this value (organization, line, user, etc.)' })\n group?: string\n\n @Field(type => Float, { nullable: true, description: 'Performance score for this category (0-1 range).' })\n @Column('float', { nullable: true })\n score?: number\n\n @Field({\n nullable: true,\n description:\n 'Date or period for which this KPI category value is recorded (e.g., day: YYYY-MM-DD, month: YYYY-MM, quarter: YYYY-Qn, range: YYYY-MM-DD~YYYY-MM-DD).'\n })\n @Column()\n valueDate: string\n\n @ManyToOne(() => KpiCategory, { onDelete: 'CASCADE' })\n @Field(type => KpiCategory, { nullable: true, description: 'KPI category to which this value belongs.' })\n category: KpiCategory\n\n @RelationId((kpiCategoryValue: KpiCategoryValue) => kpiCategoryValue.category)\n @Field({ nullable: true, description: 'ID of the domain (tenant) for this KPI category value.' })\n categoryId: string\n\n @Field({ nullable: true, description: 'Timestamp when this KPI category value record was created.' })\n @CreateDateColumn()\n createdAt: Date\n\n @Field({ nullable: true, description: 'Timestamp when this KPI category value record was last updated.' })\n @UpdateDateColumn()\n updatedAt: Date\n\n @ManyToOne(() => User, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => User, { nullable: true, description: 'User who created this KPI category value record.' })\n creator?: User\n\n @RelationId((kpiCategoryValue: KpiCategoryValue) => kpiCategoryValue.creator)\n @Field({ nullable: true, description: 'ID of the user who created this KPI category value record.' })\n creatorId?: string\n\n @ManyToOne(() => User, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => User, { nullable: true, description: 'User who last updated this KPI category value record.' })\n updater?: User\n\n @RelationId((kpiCategoryValue: KpiCategoryValue) => kpiCategoryValue.updater)\n @Field({ nullable: true, description: 'ID of the user who last updated this KPI category value record.' })\n updaterId?: string\n}\n"]}
@@ -1,5 +1,7 @@
1
1
  import type { FileUpload } from 'graphql-upload/GraphQLUpload.js';
2
- import { KpiMetric, KpiMetricPeriodType, KpiMetricCollectType } from './kpi-metric';
2
+ import { KpiPeriodType } from '../kpi/kpi';
3
+ import { KpiMetricCollectType } from './kpi-metric';
4
+ import { KpiMetric } from './kpi-metric';
3
5
  export declare class NewKpiMetric {
4
6
  name: string;
5
7
  description?: string;
@@ -12,7 +14,7 @@ export declare class NewKpiMetric {
12
14
  thumbnail?: FileUpload;
13
15
  timezone?: string;
14
16
  scheduleId?: string;
15
- periodType?: KpiMetricPeriodType;
17
+ periodType?: KpiPeriodType;
16
18
  collectType?: KpiMetricCollectType;
17
19
  }
18
20
  export declare class KpiMetricPatch {
@@ -28,7 +30,7 @@ export declare class KpiMetricPatch {
28
30
  thumbnail?: FileUpload;
29
31
  timezone?: string;
30
32
  scheduleId?: string;
31
- periodType?: KpiMetricPeriodType;
33
+ periodType?: KpiPeriodType;
32
34
  cuFlag?: string;
33
35
  collectType?: KpiMetricCollectType;
34
36
  }
@@ -4,7 +4,9 @@ exports.KpiMetricList = exports.KpiMetricPatch = exports.NewKpiMetric = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const GraphQLUpload_js_1 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
6
6
  const type_graphql_1 = require("type-graphql");
7
+ const kpi_1 = require("../kpi/kpi");
7
8
  const kpi_metric_1 = require("./kpi-metric");
9
+ const kpi_metric_2 = require("./kpi-metric");
8
10
  let NewKpiMetric = class NewKpiMetric {
9
11
  };
10
12
  exports.NewKpiMetric = NewKpiMetric;
@@ -56,7 +58,7 @@ tslib_1.__decorate([
56
58
  tslib_1.__metadata("design:type", String)
57
59
  ], NewKpiMetric.prototype, "scheduleId", void 0);
58
60
  tslib_1.__decorate([
59
- (0, type_graphql_1.Field)(type => kpi_metric_1.KpiMetricPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' }),
61
+ (0, type_graphql_1.Field)(type => kpi_1.KpiPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' }),
60
62
  tslib_1.__metadata("design:type", String)
61
63
  ], NewKpiMetric.prototype, "periodType", void 0);
62
64
  tslib_1.__decorate([
@@ -121,7 +123,7 @@ tslib_1.__decorate([
121
123
  tslib_1.__metadata("design:type", String)
122
124
  ], KpiMetricPatch.prototype, "scheduleId", void 0);
123
125
  tslib_1.__decorate([
124
- (0, type_graphql_1.Field)(type => kpi_metric_1.KpiMetricPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' }),
126
+ (0, type_graphql_1.Field)(type => kpi_1.KpiPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' }),
125
127
  tslib_1.__metadata("design:type", String)
126
128
  ], KpiMetricPatch.prototype, "periodType", void 0);
127
129
  tslib_1.__decorate([
@@ -139,7 +141,7 @@ let KpiMetricList = class KpiMetricList {
139
141
  };
140
142
  exports.KpiMetricList = KpiMetricList;
141
143
  tslib_1.__decorate([
142
- (0, type_graphql_1.Field)(type => [kpi_metric_1.KpiMetric]),
144
+ (0, type_graphql_1.Field)(type => [kpi_metric_2.KpiMetric]),
143
145
  tslib_1.__metadata("design:type", Array)
144
146
  ], KpiMetricList.prototype, "items", void 0);
145
147
  tslib_1.__decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-metric-type.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { KpiMetric, KpiMetricPeriodType, KpiMetricCollectType } from './kpi-metric'\n\n@InputType({ description: 'Input type for creating a new KPI metric. Used in mutations to provide metric details.' })\nexport class NewKpiMetric {\n @Field({ description: 'Metric code, unique within the domain, used in KPI formulas.' })\n name: string\n\n @Field({ nullable: true, description: 'User-friendly name or description of the metric.' })\n description?: string\n\n @Field({ nullable: true, description: 'Unit of measurement for this metric (e.g., %, count, hours).' })\n unit?: string\n\n @Field({ nullable: true, description: 'Source of the metric data (e.g., system, method, dataset).' })\n source?: string\n\n @Field(type => ID, { nullable: true, description: 'ID of the source dataset for this metric.' })\n dataSetId?: string\n\n @Field({ nullable: true, description: 'Name of the field in the dataset this metric maps to.' })\n fieldName?: string\n\n @Field({ nullable: true, description: 'Indicates whether this metric is active and usable.' })\n active?: boolean\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this metric.' })\n thumbnail?: FileUpload\n\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Field(type => KpiMetricPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' })\n periodType?: KpiMetricPeriodType\n\n @Field(type => KpiMetricCollectType, { nullable: true, description: '데이터 수집 방식' })\n collectType?: KpiMetricCollectType\n}\n\n@InputType()\nexport class KpiMetricPatch {\n @Field(type => ID, { nullable: true })\n id?: string\n\n @Field({ nullable: true })\n name?: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field({ nullable: true })\n unit?: string\n\n @Field({ nullable: true })\n source?: string\n\n @Field(type => ID, { nullable: true })\n dataSetId?: string\n\n @Field({ nullable: true })\n fieldName?: string\n\n @Field({ nullable: true })\n active?: boolean\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field(type => GraphQLUpload, { nullable: true })\n thumbnail?: FileUpload\n\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Field(type => KpiMetricPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' })\n periodType?: KpiMetricPeriodType\n\n @Field({ nullable: true })\n cuFlag?: string\n\n @Field(type => KpiMetricCollectType, { nullable: true, description: '데이터 수집 방식' })\n collectType?: KpiMetricCollectType\n}\n\n@ObjectType()\nexport class KpiMetricList {\n @Field(type => [KpiMetric])\n items: KpiMetric[]\n\n @Field(type => Int)\n total: number\n}\n"]}
1
+ {"version":3,"file":"kpi-metric-type.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { KpiPeriodType } from '../kpi/kpi'\nimport { KpiMetricCollectType } from './kpi-metric'\nimport { KpiMetric } from './kpi-metric'\n\n@InputType({ description: 'Input type for creating a new KPI metric. Used in mutations to provide metric details.' })\nexport class NewKpiMetric {\n @Field({ description: 'Metric code, unique within the domain, used in KPI formulas.' })\n name: string\n\n @Field({ nullable: true, description: 'User-friendly name or description of the metric.' })\n description?: string\n\n @Field({ nullable: true, description: 'Unit of measurement for this metric (e.g., %, count, hours).' })\n unit?: string\n\n @Field({ nullable: true, description: 'Source of the metric data (e.g., system, method, dataset).' })\n source?: string\n\n @Field(type => ID, { nullable: true, description: 'ID of the source dataset for this metric.' })\n dataSetId?: string\n\n @Field({ nullable: true, description: 'Name of the field in the dataset this metric maps to.' })\n fieldName?: string\n\n @Field({ nullable: true, description: 'Indicates whether this metric is active and usable.' })\n active?: boolean\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this metric.' })\n thumbnail?: FileUpload\n\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Field(type => KpiPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' })\n periodType?: KpiPeriodType\n\n @Field(type => KpiMetricCollectType, { nullable: true, description: '데이터 수집 방식' })\n collectType?: KpiMetricCollectType\n}\n\n@InputType()\nexport class KpiMetricPatch {\n @Field(type => ID, { nullable: true })\n id?: string\n\n @Field({ nullable: true })\n name?: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field({ nullable: true })\n unit?: string\n\n @Field({ nullable: true })\n source?: string\n\n @Field(type => ID, { nullable: true })\n dataSetId?: string\n\n @Field({ nullable: true })\n fieldName?: string\n\n @Field({ nullable: true })\n active?: boolean\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field(type => GraphQLUpload, { nullable: true })\n thumbnail?: FileUpload\n\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Field(type => KpiPeriodType, { nullable: true, description: 'Aggregation period type for this metric.' })\n periodType?: KpiPeriodType\n\n @Field({ nullable: true })\n cuFlag?: string\n\n @Field(type => KpiMetricCollectType, { nullable: true, description: '데이터 수집 방식' })\n collectType?: KpiMetricCollectType\n}\n\n@ObjectType()\nexport class KpiMetricList {\n @Field(type => [KpiMetric])\n items: KpiMetric[]\n\n @Field(type => Int)\n total: number\n}\n"]}
@@ -1,13 +1,7 @@
1
1
  import { Domain } from '@things-factory/shell';
2
2
  import { User } from '@things-factory/auth-base';
3
3
  import { DataSet } from '@things-factory/dataset';
4
- export declare enum KpiMetricPeriodType {
5
- DAY = "DAY",
6
- WEEK = "WEEK",
7
- MONTH = "MONTH",
8
- QUARTER = "QUARTER",
9
- RANGE = "RANGE"
10
- }
4
+ import { KpiPeriodType } from '../kpi/kpi';
11
5
  export declare enum KpiMetricCollectType {
12
6
  AUTO = "AUTO",// 데이터셋 등 자동 수집
13
7
  MANUAL = "MANUAL",// 수동 입력
@@ -30,7 +24,7 @@ export declare class KpiMetric {
30
24
  scheduleId?: string;
31
25
  timezone?: string;
32
26
  collectType: KpiMetricCollectType;
33
- periodType: KpiMetricPeriodType;
27
+ periodType: KpiPeriodType;
34
28
  createdAt?: Date;
35
29
  updatedAt?: Date;
36
30
  deletedAt?: Date;
@@ -1,24 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.KpiMetric = exports.KpiMetricCollectType = exports.KpiMetricPeriodType = void 0;
3
+ exports.KpiMetric = exports.KpiMetricCollectType = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const typeorm_1 = require("typeorm");
6
6
  const type_graphql_1 = require("type-graphql");
7
7
  const shell_1 = require("@things-factory/shell");
8
8
  const auth_base_1 = require("@things-factory/auth-base");
9
9
  const dataset_1 = require("@things-factory/dataset");
10
- var KpiMetricPeriodType;
11
- (function (KpiMetricPeriodType) {
12
- KpiMetricPeriodType["DAY"] = "DAY";
13
- KpiMetricPeriodType["WEEK"] = "WEEK";
14
- KpiMetricPeriodType["MONTH"] = "MONTH";
15
- KpiMetricPeriodType["QUARTER"] = "QUARTER";
16
- KpiMetricPeriodType["RANGE"] = "RANGE";
17
- })(KpiMetricPeriodType || (exports.KpiMetricPeriodType = KpiMetricPeriodType = {}));
18
- (0, type_graphql_1.registerEnumType)(KpiMetricPeriodType, {
19
- name: 'KpiMetricPeriodType',
20
- description: 'Aggregation period type for metric (DAY, WEEK, MONTH, QUARTER, RANGE)'
21
- });
10
+ const kpi_1 = require("../kpi/kpi");
22
11
  var KpiMetricCollectType;
23
12
  (function (KpiMetricCollectType) {
24
13
  KpiMetricCollectType["AUTO"] = "AUTO";
@@ -113,7 +102,7 @@ tslib_1.__decorate([
113
102
  ], KpiMetric.prototype, "collectType", void 0);
114
103
  tslib_1.__decorate([
115
104
  (0, typeorm_1.Column)({ default: 'DAY' }),
116
- (0, type_graphql_1.Field)(type => KpiMetricPeriodType, { description: 'Aggregation period type for this metric.' }),
105
+ (0, type_graphql_1.Field)(type => kpi_1.KpiPeriodType, { description: 'Aggregation period type for this metric.' }),
117
106
  tslib_1.__metadata("design:type", String)
118
107
  ], KpiMetric.prototype, "periodType", void 0);
119
108
  tslib_1.__decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-metric.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n DeleteDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { DataSet } from '@things-factory/dataset'\n\nexport enum KpiMetricPeriodType {\n DAY = 'DAY',\n WEEK = 'WEEK',\n MONTH = 'MONTH',\n QUARTER = 'QUARTER',\n RANGE = 'RANGE'\n}\n\nregisterEnumType(KpiMetricPeriodType, {\n name: 'KpiMetricPeriodType',\n description: 'Aggregation period type for metric (DAY, WEEK, MONTH, QUARTER, RANGE)'\n})\n\nexport enum KpiMetricCollectType {\n AUTO = 'AUTO', // 데이터셋 등 자동 수집\n MANUAL = 'MANUAL', // 수동 입력\n IMPORT = 'IMPORT', // 외부 파일 등 임포트\n EXTERNAL = 'EXTERNAL' // 외부 API 등\n}\nregisterEnumType(KpiMetricCollectType, {\n name: 'KpiMetricCollectType',\n description: '방식: AUTO(자동), MANUAL(수동), IMPORT(임포트), EXTERNAL(외부API)'\n})\n\n@Entity()\n@Index('ix_kpi_metric_0', (kpiMetric: KpiMetric) => [kpiMetric.domain, kpiMetric.name], {\n where: '\"deleted_at\" IS NULL',\n unique: true\n})\n@ObjectType({ description: 'KPI metric entity. Represents a source data item used in KPI formulas.' })\nexport class KpiMetric {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier for this KPI metric.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field({ nullable: true, description: 'Domain (tenant) to which this KPI metric belongs.' })\n domain?: Domain\n\n @RelationId((metric: KpiMetric) => metric.domain)\n @Field({ nullable: true, description: 'ID of the domain (tenant) for this KPI metric.' })\n domainId?: string\n\n @Column()\n @Field({ description: 'Metric code, unique within the domain, used in KPI formulas.' })\n name: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'User-friendly name or description of the metric.' })\n description?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Unit of measurement for this metric (e.g., %, count, hours).' })\n unit?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Source of the metric data (e.g., system, method, dataset).' })\n source?: string\n\n @ManyToOne(type => DataSet, { nullable: true })\n @Field(type => DataSet, { nullable: true, description: 'Reference to the source dataset for this metric.' })\n dataSet?: DataSet\n\n @RelationId((metric: KpiMetric) => metric.dataSet)\n @Field({ nullable: true, description: 'ID of the referenced source dataset.' })\n dataSetId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Name of the field in the dataset this metric maps to.' })\n fieldName?: string\n\n @Column({ nullable: false, default: false })\n @Field({ nullable: true, description: 'Indicates whether this metric is active and usable.' })\n active?: boolean\n\n @Column({ nullable: true })\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n\n @Column({ type: 'enum', enum: KpiMetricCollectType, default: KpiMetricCollectType.AUTO })\n @Field(type => KpiMetricCollectType, { description: '데이터 수집 방식' })\n collectType: KpiMetricCollectType\n\n @Column({ default: 'DAY' })\n @Field(type => KpiMetricPeriodType, { description: 'Aggregation period type for this metric.' })\n periodType: KpiMetricPeriodType\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was created.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was last updated.' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was deleted (soft delete).' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who created this KPI metric.' })\n creator?: User\n\n @RelationId((metric: KpiMetric) => metric.creator)\n @Field({ nullable: true, description: 'ID of the user who created this KPI metric.' })\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who last updated this KPI metric.' })\n updater?: User\n\n @RelationId((metric: KpiMetric) => metric.updater)\n @Field({ nullable: true, description: 'ID of the user who last updated this KPI metric.' })\n updaterId?: string\n\n @Field(type => String, { nullable: true, description: 'Thumbnail image or file path for this KPI metric.' })\n thumbnail?: string\n}\n"]}
1
+ {"version":3,"file":"kpi-metric.js","sourceRoot":"","sources":["../../../server/service/kpi-metric/kpi-metric.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n DeleteDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { DataSet } from '@things-factory/dataset'\nimport { KpiPeriodType } from '../kpi/kpi'\n\nexport enum KpiMetricCollectType {\n AUTO = 'AUTO', // 데이터셋 등 자동 수집\n MANUAL = 'MANUAL', // 수동 입력\n IMPORT = 'IMPORT', // 외부 파일 등 임포트\n EXTERNAL = 'EXTERNAL' // 외부 API 등\n}\nregisterEnumType(KpiMetricCollectType, {\n name: 'KpiMetricCollectType',\n description: '방식: AUTO(자동), MANUAL(수동), IMPORT(임포트), EXTERNAL(외부API)'\n})\n\n@Entity()\n@Index('ix_kpi_metric_0', (kpiMetric: KpiMetric) => [kpiMetric.domain, kpiMetric.name], {\n where: '\"deleted_at\" IS NULL',\n unique: true\n})\n@ObjectType({ description: 'KPI metric entity. Represents a source data item used in KPI formulas.' })\nexport class KpiMetric {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier for this KPI metric.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field({ nullable: true, description: 'Domain (tenant) to which this KPI metric belongs.' })\n domain?: Domain\n\n @RelationId((metric: KpiMetric) => metric.domain)\n @Field({ nullable: true, description: 'ID of the domain (tenant) for this KPI metric.' })\n domainId?: string\n\n @Column()\n @Field({ description: 'Metric code, unique within the domain, used in KPI formulas.' })\n name: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'User-friendly name or description of the metric.' })\n description?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Unit of measurement for this metric (e.g., %, count, hours).' })\n unit?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Source of the metric data (e.g., system, method, dataset).' })\n source?: string\n\n @ManyToOne(type => DataSet, { nullable: true })\n @Field(type => DataSet, { nullable: true, description: 'Reference to the source dataset for this metric.' })\n dataSet?: DataSet\n\n @RelationId((metric: KpiMetric) => metric.dataSet)\n @Field({ nullable: true, description: 'ID of the referenced source dataset.' })\n dataSetId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Name of the field in the dataset this metric maps to.' })\n fieldName?: string\n\n @Column({ nullable: false, default: false })\n @Field({ nullable: true, description: 'Indicates whether this metric is active and usable.' })\n active?: boolean\n\n @Column({ nullable: true })\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Schedule ID for the registered cron job.' })\n scheduleId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Timezone for the schedule.' })\n timezone?: string\n\n @Column({ type: 'enum', enum: KpiMetricCollectType, default: KpiMetricCollectType.AUTO })\n @Field(type => KpiMetricCollectType, { description: '데이터 수집 방식' })\n collectType: KpiMetricCollectType\n\n @Column({ default: 'DAY' })\n @Field(type => KpiPeriodType, { description: 'Aggregation period type for this metric.' })\n periodType: KpiPeriodType\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was created.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was last updated.' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this KPI metric was deleted (soft delete).' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who created this KPI metric.' })\n creator?: User\n\n @RelationId((metric: KpiMetric) => metric.creator)\n @Field({ nullable: true, description: 'ID of the user who created this KPI metric.' })\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who last updated this KPI metric.' })\n updater?: User\n\n @RelationId((metric: KpiMetric) => metric.updater)\n @Field({ nullable: true, description: 'ID of the user who last updated this KPI metric.' })\n updaterId?: string\n\n @Field(type => String, { nullable: true, description: 'Thumbnail image or file path for this KPI metric.' })\n thumbnail?: string\n}\n"]}
@@ -11,46 +11,32 @@ const kpi_metric_value_1 = require("./kpi-metric-value");
11
11
  const kpi_metric_value_type_1 = require("./kpi-metric-value-type");
12
12
  const kpi_metric_1 = require("../kpi-metric/kpi-metric");
13
13
  const shell_2 = require("@things-factory/shell");
14
- function getISOWeek(date) {
15
- const tmp = new Date(date.getTime());
16
- tmp.setHours(0, 0, 0, 0);
17
- tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7));
18
- const yearStart = new Date(tmp.getFullYear(), 0, 1);
19
- const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
20
- return weekNo;
21
- }
22
- function getDefaultValueDate(periodType) {
23
- const now = new Date();
24
- switch (periodType) {
25
- case kpi_1.KpiPeriodType.DAY:
26
- return now.toISOString().slice(0, 10);
27
- case kpi_1.KpiPeriodType.MONTH:
28
- return now.toISOString().slice(0, 7);
29
- case kpi_1.KpiPeriodType.QUARTER: {
30
- const year = now.getFullYear();
31
- const quarter = Math.floor(now.getMonth() / 3) + 1;
32
- return `${year}-Q${quarter}`;
33
- }
34
- case kpi_1.KpiPeriodType.WEEK: {
35
- const year = now.getFullYear();
36
- const week = getISOWeek(now);
37
- return `${year}-W${week}`;
38
- }
39
- default:
40
- return now.toISOString().slice(0, 10);
41
- }
42
- }
14
+ const value_date_util_1 = require("../utils/value-date-util");
43
15
  let KpiMetricValueMutation = class KpiMetricValueMutation {
44
16
  async createKpiMetricValue(metricValue, context) {
45
17
  const { domain, user, tx } = context.state;
46
18
  let metric = metricValue.metricId
47
19
  ? await (0, shell_1.getRepository)(kpi_metric_1.KpiMetric).findOne({ where: { id: metricValue.metricId } })
48
20
  : undefined;
21
+ // valueDate 자동 생성/보정 로직 추가
22
+ let periodType = metricValue.periodType;
23
+ if (!periodType && metric) {
24
+ periodType = metric.periodType;
25
+ }
26
+ if (!periodType) {
27
+ periodType = kpi_1.KpiPeriodType.DAY;
28
+ }
29
+ // periodType을 string으로 변환 후 KpiPeriodType으로 강제 변환
30
+ periodType = kpi_1.KpiPeriodType[String(periodType)];
31
+ let valueDate = metricValue.valueDate;
32
+ if (!valueDate || !isValueDateValidForPeriodType(valueDate, periodType)) {
33
+ valueDate = (0, value_date_util_1.getDefaultValueDate)(periodType);
34
+ }
49
35
  const entity = {
50
36
  metric,
51
37
  metricId: metricValue.metricId,
52
- valueDate: metricValue.valueDate,
53
- periodType: metricValue.periodType,
38
+ valueDate,
39
+ periodType,
54
40
  value: metricValue.value,
55
41
  group: metricValue.group,
56
42
  unit: metricValue.unit,
@@ -67,23 +53,40 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
67
53
  if (!metric)
68
54
  throw new Error(`Metric not found: ${metricName}`);
69
55
  const periodType = metric.periodType || kpi_1.KpiPeriodType.DAY;
70
- const valueDateToUse = getDefaultValueDate(periodType);
56
+ const valueDate = (0, value_date_util_1.getDefaultValueDate)(periodType);
71
57
  if (value == null && meta == null) {
72
58
  throw new Error('Either value or meta must be provided.');
73
59
  }
74
- const entity = {
75
- metric,
76
- metricId: metric.id,
77
- value,
78
- meta,
79
- valueDate: valueDateToUse,
80
- periodType,
81
- group,
82
- domain,
83
- creator: user,
84
- updater: user
85
- };
86
- return await (0, shell_1.getRepository)(kpi_metric_value_1.KpiMetricValue, tx).save(entity);
60
+ const repo = (0, shell_1.getRepository)(kpi_metric_value_1.KpiMetricValue, tx);
61
+ let entity = await repo.findOne({
62
+ where: {
63
+ metric: { id: metric.id },
64
+ valueDate,
65
+ periodType,
66
+ group,
67
+ domain: { id: domain.id }
68
+ }
69
+ });
70
+ if (entity) {
71
+ entity.value = value;
72
+ entity.meta = meta;
73
+ entity.updater = user;
74
+ }
75
+ else {
76
+ entity = repo.create({
77
+ metric,
78
+ metricId: metric.id,
79
+ value,
80
+ meta,
81
+ valueDate,
82
+ periodType,
83
+ group,
84
+ domain,
85
+ creator: user,
86
+ updater: user
87
+ });
88
+ }
89
+ return await repo.save(entity);
87
90
  }
88
91
  async updateKpiMetricValue(id, patch, context) {
89
92
  const { domain, user, tx } = context.state;
@@ -111,8 +114,18 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
111
114
  if (_createRecords.length > 0) {
112
115
  for (let i = 0; i < _createRecords.length; i++) {
113
116
  const newRecord = _createRecords[i];
117
+ if (!newRecord.metricId) {
118
+ throw new Error('metricId is required for creating new metric value');
119
+ }
120
+ const metric = await (0, shell_1.getRepository)(kpi_metric_1.KpiMetric).findOne({
121
+ where: { domain: { id: domain.id }, id: newRecord.metricId }
122
+ });
123
+ if (!metric) {
124
+ throw new Error(`Metric not found: ${newRecord.metricId}`);
125
+ }
114
126
  const result = await metricValueRepo.save({
115
127
  ...newRecord,
128
+ metric,
116
129
  domain,
117
130
  creator: user,
118
131
  updater: user
@@ -124,9 +137,19 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
124
137
  for (let i = 0; i < _updateRecords.length; i++) {
125
138
  const updateRecord = _updateRecords[i];
126
139
  const metricValue = await metricValueRepo.findOneBy({ id: updateRecord.id });
140
+ if (!updateRecord.metricId) {
141
+ throw new Error('metricId is required for updating value');
142
+ }
143
+ const metric = await (0, shell_1.getRepository)(kpi_metric_1.KpiMetric).findOne({
144
+ where: { domain: { id: domain.id }, id: updateRecord.metricId }
145
+ });
146
+ if (!metric) {
147
+ throw new Error(`Metric not found: ${updateRecord.metricId}`);
148
+ }
127
149
  const result = await metricValueRepo.save({
128
150
  ...metricValue,
129
151
  ...updateRecord,
152
+ metric,
130
153
  updater: user
131
154
  });
132
155
  results.push({ ...result, cuFlag: 'M' });
@@ -226,4 +249,23 @@ tslib_1.__decorate([
226
249
  exports.KpiMetricValueMutation = KpiMetricValueMutation = tslib_1.__decorate([
227
250
  (0, type_graphql_1.Resolver)(kpi_metric_value_1.KpiMetricValue)
228
251
  ], KpiMetricValueMutation);
252
+ // valueDate와 periodType의 일치 여부를 검사하는 유틸리티 함수(임시, 아래에 추가)
253
+ function isValueDateValidForPeriodType(valueDate, periodType) {
254
+ if (!valueDate)
255
+ return false;
256
+ switch (periodType) {
257
+ case kpi_1.KpiPeriodType.DAY:
258
+ return /^\d{4}-\d{2}-\d{2}$/.test(valueDate);
259
+ case kpi_1.KpiPeriodType.MONTH:
260
+ return /^\d{4}-\d{2}$/.test(valueDate);
261
+ case kpi_1.KpiPeriodType.QUARTER:
262
+ return /^\d{4}-Q[1-4]$/.test(valueDate);
263
+ case kpi_1.KpiPeriodType.WEEK:
264
+ return /^\d{4}-W\d{1,2}$/.test(valueDate);
265
+ case kpi_1.KpiPeriodType.ALLTIME:
266
+ return valueDate === 'ALLTIME';
267
+ default:
268
+ return true;
269
+ }
270
+ }
229
271
  //# sourceMappingURL=kpi-metric-value-mutation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-metric-value-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { In } from 'typeorm'\nimport { getRepository } from '@things-factory/shell'\nimport { Float } from 'type-graphql'\nimport { KpiPeriodType } from '../kpi/kpi'\n\nimport { KpiMetricValue } from './kpi-metric-value'\nimport { NewKpiMetricValue, KpiMetricValuePatch } from './kpi-metric-value-type'\nimport { KpiMetric } from '../kpi-metric/kpi-metric'\nimport { ScalarObject } from '@things-factory/shell'\n\nfunction getISOWeek(date: Date): number {\n const tmp = new Date(date.getTime())\n tmp.setHours(0, 0, 0, 0)\n tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7))\n const yearStart = new Date(tmp.getFullYear(), 0, 1)\n const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 86400000 + 1) / 7)\n return weekNo\n}\n\nfunction getDefaultValueDate(periodType: KpiPeriodType): string {\n const now = new Date()\n switch (periodType) {\n case KpiPeriodType.DAY:\n return now.toISOString().slice(0, 10)\n case KpiPeriodType.MONTH:\n return now.toISOString().slice(0, 7)\n case KpiPeriodType.QUARTER: {\n const year = now.getFullYear()\n const quarter = Math.floor(now.getMonth() / 3) + 1\n return `${year}-Q${quarter}`\n }\n case KpiPeriodType.WEEK: {\n const year = now.getFullYear()\n const week = getISOWeek(now)\n return `${year}-W${week}`\n }\n default:\n return now.toISOString().slice(0, 10)\n }\n}\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueMutation {\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'Create a new metric value with the provided details.' })\n async createKpiMetricValue(\n @Arg('metricValue', { description: 'Input object containing details for the new metric value.' })\n metricValue: NewKpiMetricValue,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n\n let metric = metricValue.metricId\n ? await getRepository(KpiMetric).findOne({ where: { id: metricValue.metricId } })\n : undefined\n\n const entity: Partial<KpiMetricValue> = {\n metric,\n metricId: metricValue.metricId,\n valueDate: metricValue.valueDate,\n periodType: metricValue.periodType,\n value: metricValue.value,\n group: metricValue.group,\n unit: metricValue.unit,\n meta: metricValue.meta,\n domain: domain,\n creator: user,\n updater: user\n }\n\n return await getRepository(KpiMetricValue, tx).save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'Record a metric value by metric name, value, meta, and group.' })\n async recordKpiMetricValue(\n @Arg('metricName', { description: 'Metric code/name.' }) metricName: string,\n @Arg('value', type => Float, { nullable: true, description: 'Metric value (number).' }) value: number | null,\n @Arg('meta', type => ScalarObject, { nullable: true, description: 'Extended or non-numeric information (JSON).' })\n meta: any,\n @Arg('group', { nullable: true, description: 'Group key for this value (organization, line, user, etc.)' })\n group: string | null,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n const metric = await getRepository(KpiMetric).findOne({ where: { name: metricName, domain: { id: domain.id } } })\n if (!metric) throw new Error(`Metric not found: ${metricName}`)\n const periodType = (metric.periodType as unknown as KpiPeriodType) || KpiPeriodType.DAY\n const valueDateToUse = getDefaultValueDate(periodType)\n if (value == null && meta == null) {\n throw new Error('Either value or meta must be provided.')\n }\n const entity: Partial<KpiMetricValue> = {\n metric,\n metricId: metric.id,\n value,\n meta,\n valueDate: valueDateToUse,\n periodType,\n group,\n domain,\n creator: user,\n updater: user\n }\n return await getRepository(KpiMetricValue, tx).save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'To modify KpiMetricValue information' })\n async updateKpiMetricValue(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiMetricValuePatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(KpiMetricValue, tx)\n const metricValue = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n let metric = patch.metricId\n ? await getRepository(KpiMetric).findOne({ where: { id: patch.metricId } })\n : metricValue.metric\n\n const entity: any = {\n ...metricValue,\n ...patch,\n metric,\n updater: user\n }\n\n return await repository.save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple KpiMetricValues' information\" })\n async updateMultipleKpiMetricValue(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag && patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag && patch.cuFlag.toUpperCase() === 'M')\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n const result = await metricValueRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n } as any)\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const metricValue = await metricValueRepo.findOneBy({ id: updateRecord.id })\n const result = await metricValueRepo.save({\n ...metricValue,\n ...updateRecord,\n updater: user\n } as any)\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete KpiMetricValue' })\n async deleteKpiMetricValue(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n await getRepository(KpiMetricValue, tx).delete({ domain: { id: domain.id }, id })\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete multiple KpiMetricValues' })\n async deleteKpiMetricValues(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n await getRepository(KpiMetricValue, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To import multiple KpiMetricValues' })\n async importKpiMetricValues(\n @Arg('metricValues', type => [KpiMetricValuePatch]) metricValues: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n await Promise.all(\n metricValues.map(async (metricValue: KpiMetricValuePatch) => {\n await getRepository(KpiMetricValue, tx).save({ domain, ...metricValue } as any)\n })\n )\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-metric-value-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAAsE;AACtE,qCAA4B;AAC5B,iDAAqD;AACrD,+CAAoC;AACpC,oCAA0C;AAE1C,yDAAmD;AACnD,mEAAgF;AAChF,yDAAoD;AACpD,iDAAoD;AACpD,8DAA8D;AAGvD,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAG3B,AAAN,KAAK,CAAC,oBAAoB,CAExB,WAA8B,EACvB,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,IAAI,MAAM,GAAG,WAAW,CAAC,QAAQ;YAC/B,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;YACjF,CAAC,CAAC,SAAS,CAAA;QAEb,2BAA2B;QAC3B,IAAI,UAAU,GAAG,WAAW,CAAC,UAAU,CAAA;QACvC,IAAI,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC;YAC1B,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;QAChC,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,mBAAa,CAAC,GAAG,CAAA;QAChC,CAAC;QACD,kDAAkD;QAClD,UAAU,GAAG,mBAAa,CAAC,MAAM,CAAC,UAAU,CAA+B,CAAC,CAAA;QAC5E,IAAI,SAAS,GAAG,WAAW,CAAC,SAAS,CAAA;QACrC,IAAI,CAAC,SAAS,IAAI,CAAC,6BAA6B,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACxE,SAAS,GAAG,IAAA,qCAAmB,EAAC,UAAU,CAAC,CAAA;QAC7C,CAAC;QAED,MAAM,MAAM,GAA4B;YACtC,MAAM;YACN,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,SAAS;YACT,UAAU;YACV,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;SACd,CAAA;QAED,OAAO,MAAM,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7D,CAAC;IAIK,AAAN,KAAK,CAAC,oBAAoB,CACiC,UAAkB,EACa,KAAoB,EAE5G,IAAS,EAET,KAAoB,EACb,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACjH,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAA;QAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAa,CAAC,GAAG,CAAA;QACzD,MAAM,SAAS,GAAG,IAAA,qCAAmB,EAAC,UAAU,CAAC,CAAA;QACjD,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAA;QAC9C,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;YAC9B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;gBACzB,SAAS;gBACT,UAAU;gBACV,KAAK;gBACL,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;aAC1B;SACF,CAAC,CAAA;QACF,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;YACpB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAA;YAClB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;gBACnB,MAAM;gBACN,QAAQ,EAAE,MAAM,CAAC,EAAE;gBACnB,KAAK;gBACL,IAAI;gBACJ,SAAS;gBACT,UAAU;gBACV,KAAK;gBACL,MAAM;gBACN,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;aACd,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChC,CAAC;IAIK,AAAN,KAAK,CAAC,oBAAoB,CACb,EAAU,EACP,KAA0B,EACjC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAA;QACpD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;YAC3C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;SACzC,CAAC,CAAA;QAEF,IAAI,MAAM,GAAG,KAAK,CAAC,QAAQ;YACzB,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3E,CAAC,CAAC,WAAW,CAAC,MAAM,CAAA;QAEtB,MAAM,MAAM,GAAQ;YAClB,GAAG,WAAW;YACd,GAAG,KAAK;YACR,MAAM;YACN,OAAO,EAAE,IAAI;SACd,CAAA;QAED,OAAO,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACtC,CAAC;IAIK,AAAN,KAAK,CAAC,4BAA4B,CACe,OAA8B,EACtE,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAA;QACzG,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAA;QACzG,MAAM,eAAe,GAAG,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAA;QAEzD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;gBAEnC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACxB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;gBACvE,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC;oBACpD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,QAAQ,EAAE;iBAC7D,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAC5D,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC;oBACxC,GAAG,SAAS;oBACZ,MAAM;oBACN,MAAM;oBACN,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,IAAI;iBACP,CAAC,CAAA;gBACT,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;gBACtC,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAA;gBAE5E,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;oBAC3B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;gBAC5D,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,CAAC;oBACpD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,CAAC,QAAQ,EAAE;iBAChE,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAA;gBAC/D,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC;oBACxC,GAAG,WAAW;oBACd,GAAG,YAAY;oBACf,MAAM;oBACN,OAAO,EAAE,IAAI;iBACP,CAAC,CAAA;gBACT,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAIK,AAAN,KAAK,CAAC,oBAAoB,CAAY,EAAU,EAAS,OAAwB;QAC/E,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACpC,MAAM,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACjF,OAAO,IAAI,CAAA;IACb,CAAC;IAIK,AAAN,KAAK,CAAC,qBAAqB,CACK,GAAa,EACpC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACpC,MAAM,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;YAC7C,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;YACzB,EAAE,EAAE,IAAA,YAAE,EAAC,GAAG,CAAC;SACZ,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAIK,AAAN,KAAK,CAAC,qBAAqB,CAC2B,YAAmC,EAChF,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACpC,MAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,WAAgC,EAAE,EAAE;YAC1D,MAAM,IAAA,qBAAa,EAAC,iCAAc,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,EAAS,CAAC,CAAA;QACjF,CAAC,CAAC,CACH,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF,CAAA;AAtOY,wDAAsB;AAG3B;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,iCAAc,EAAE,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC;IAE1G,mBAAA,IAAA,kBAAG,EAAC,aAAa,EAAE,EAAE,WAAW,EAAE,2DAA2D,EAAE,CAAC,CAAA;IAEhG,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CADO,yCAAiB;;kEAuC/B;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,iCAAc,EAAE,EAAE,WAAW,EAAE,+DAA+D,EAAE,CAAC;IAEnH,mBAAA,IAAA,kBAAG,EAAC,YAAY,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAA;IACvD,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC,CAAA;IACtF,mBAAA,IAAA,kBAAG,EAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,oBAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC,CAAA;IAEjH,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2DAA2D,EAAE,CAAC,CAAA;IAE1G,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;kEAuCP;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,iCAAc,EAAE,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;IAE1F,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IACT,mBAAA,IAAA,kBAAG,EAAC,OAAO,CAAC,CAAA;IACZ,mBAAA,IAAA,kBAAG,GAAE,CAAA;;qDADe,2CAAmB;;kEAsBzC;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,iCAAc,CAAC,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IAEvG,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,2CAAmB,CAAC,CAAC,CAAA;IAC7C,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAgEP;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;IAC9C,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;kEAIvD;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;IAEjF,mBAAA,IAAA,kBAAG,EAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;mEAQP;AAIK;IAFL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;IAEjF,mBAAA,IAAA,kBAAG,EAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,2CAAmB,CAAC,CAAC,CAAA;IAClD,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;mEASP;iCArOU,sBAAsB;IADlC,IAAA,uBAAQ,EAAC,iCAAc,CAAC;GACZ,sBAAsB,CAsOlC;AAED,yDAAyD;AACzD,SAAS,6BAA6B,CAAC,SAAiB,EAAE,UAAyB;IACjF,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IAC5B,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,mBAAa,CAAC,GAAG;YACpB,OAAO,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC9C,KAAK,mBAAa,CAAC,KAAK;YACtB,OAAO,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,KAAK,mBAAa,CAAC,OAAO;YACxB,OAAO,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACzC,KAAK,mBAAa,CAAC,IAAI;YACrB,OAAO,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3C,KAAK,mBAAa,CAAC,OAAO;YACxB,OAAO,SAAS,KAAK,SAAS,CAAA;QAChC;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { In } from 'typeorm'\nimport { getRepository } from '@things-factory/shell'\nimport { Float } from 'type-graphql'\nimport { KpiPeriodType } from '../kpi/kpi'\n\nimport { KpiMetricValue } from './kpi-metric-value'\nimport { NewKpiMetricValue, KpiMetricValuePatch } from './kpi-metric-value-type'\nimport { KpiMetric } from '../kpi-metric/kpi-metric'\nimport { ScalarObject } from '@things-factory/shell'\nimport { getDefaultValueDate } from '../utils/value-date-util'\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueMutation {\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'Create a new metric value with the provided details.' })\n async createKpiMetricValue(\n @Arg('metricValue', { description: 'Input object containing details for the new metric value.' })\n metricValue: NewKpiMetricValue,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n\n let metric = metricValue.metricId\n ? await getRepository(KpiMetric).findOne({ where: { id: metricValue.metricId } })\n : undefined\n\n // valueDate 자동 생성/보정 로직 추가\n let periodType = metricValue.periodType\n if (!periodType && metric) {\n periodType = metric.periodType\n }\n if (!periodType) {\n periodType = KpiPeriodType.DAY\n }\n // periodType을 string으로 변환 후 KpiPeriodType으로 강제 변환\n periodType = KpiPeriodType[String(periodType) as keyof typeof KpiPeriodType]\n let valueDate = metricValue.valueDate\n if (!valueDate || !isValueDateValidForPeriodType(valueDate, periodType)) {\n valueDate = getDefaultValueDate(periodType)\n }\n\n const entity: Partial<KpiMetricValue> = {\n metric,\n metricId: metricValue.metricId,\n valueDate,\n periodType,\n value: metricValue.value,\n group: metricValue.group,\n unit: metricValue.unit,\n meta: metricValue.meta,\n domain: domain,\n creator: user,\n updater: user\n }\n\n return await getRepository(KpiMetricValue, tx).save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'Record a metric value by metric name, value, meta, and group.' })\n async recordKpiMetricValue(\n @Arg('metricName', { description: 'Metric code/name.' }) metricName: string,\n @Arg('value', type => Float, { nullable: true, description: 'Metric value (number).' }) value: number | null,\n @Arg('meta', type => ScalarObject, { nullable: true, description: 'Extended or non-numeric information (JSON).' })\n meta: any,\n @Arg('group', { nullable: true, description: 'Group key for this value (organization, line, user, etc.)' })\n group: string | null,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n const metric = await getRepository(KpiMetric).findOne({ where: { name: metricName, domain: { id: domain.id } } })\n if (!metric) throw new Error(`Metric not found: ${metricName}`)\n const periodType = metric.periodType || KpiPeriodType.DAY\n const valueDate = getDefaultValueDate(periodType)\n if (value == null && meta == null) {\n throw new Error('Either value or meta must be provided.')\n }\n const repo = getRepository(KpiMetricValue, tx)\n let entity = await repo.findOne({\n where: {\n metric: { id: metric.id },\n valueDate,\n periodType,\n group,\n domain: { id: domain.id }\n }\n })\n if (entity) {\n entity.value = value\n entity.meta = meta\n entity.updater = user\n } else {\n entity = repo.create({\n metric,\n metricId: metric.id,\n value,\n meta,\n valueDate,\n periodType,\n group,\n domain,\n creator: user,\n updater: user\n })\n }\n return await repo.save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiMetricValue, { description: 'To modify KpiMetricValue information' })\n async updateKpiMetricValue(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiMetricValuePatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(KpiMetricValue, tx)\n const metricValue = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n let metric = patch.metricId\n ? await getRepository(KpiMetric).findOne({ where: { id: patch.metricId } })\n : metricValue.metric\n\n const entity: any = {\n ...metricValue,\n ...patch,\n metric,\n updater: user\n }\n\n return await repository.save(entity)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple KpiMetricValues' information\" })\n async updateMultipleKpiMetricValue(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag && patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag && patch.cuFlag.toUpperCase() === 'M')\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n if (!newRecord.metricId) {\n throw new Error('metricId is required for creating new metric value')\n }\n\n const metric = await getRepository(KpiMetric).findOne({\n where: { domain: { id: domain.id }, id: newRecord.metricId }\n })\n\n if (!metric) {\n throw new Error(`Metric not found: ${newRecord.metricId}`)\n }\n\n const result = await metricValueRepo.save({\n ...newRecord,\n metric,\n domain,\n creator: user,\n updater: user\n } as any)\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const metricValue = await metricValueRepo.findOneBy({ id: updateRecord.id })\n\n if (!updateRecord.metricId) {\n throw new Error('metricId is required for updating value')\n }\n\n const metric = await getRepository(KpiMetric).findOne({\n where: { domain: { id: domain.id }, id: updateRecord.metricId }\n })\n\n if (!metric) {\n throw new Error(`Metric not found: ${updateRecord.metricId}`)\n }\n\n const result = await metricValueRepo.save({\n ...metricValue,\n ...updateRecord,\n metric,\n updater: user\n } as any)\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete KpiMetricValue' })\n async deleteKpiMetricValue(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n await getRepository(KpiMetricValue, tx).delete({ domain: { id: domain.id }, id })\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete multiple KpiMetricValues' })\n async deleteKpiMetricValues(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n await getRepository(KpiMetricValue, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To import multiple KpiMetricValues' })\n async importKpiMetricValues(\n @Arg('metricValues', type => [KpiMetricValuePatch]) metricValues: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n await Promise.all(\n metricValues.map(async (metricValue: KpiMetricValuePatch) => {\n await getRepository(KpiMetricValue, tx).save({ domain, ...metricValue } as any)\n })\n )\n return true\n }\n}\n\n// valueDate와 periodType의 일치 여부를 검사하는 유틸리티 함수(임시, 아래에 추가)\nfunction isValueDateValidForPeriodType(valueDate: string, periodType: KpiPeriodType): boolean {\n if (!valueDate) return false\n switch (periodType) {\n case KpiPeriodType.DAY:\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(valueDate)\n case KpiPeriodType.MONTH:\n return /^\\d{4}-\\d{2}$/.test(valueDate)\n case KpiPeriodType.QUARTER:\n return /^\\d{4}-Q[1-4]$/.test(valueDate)\n case KpiPeriodType.WEEK:\n return /^\\d{4}-W\\d{1,2}$/.test(valueDate)\n case KpiPeriodType.ALLTIME:\n return valueDate === 'ALLTIME'\n default:\n return true\n }\n}\n"]}
@@ -48,7 +48,7 @@ tslib_1.__decorate([
48
48
  tslib_1.__metadata("design:type", String)
49
49
  ], KpiMetricValue.prototype, "unit", void 0);
50
50
  tslib_1.__decorate([
51
- (0, typeorm_1.Column)({ type: 'varchar', length: 20 }),
51
+ (0, typeorm_1.Column)(),
52
52
  (0, type_graphql_1.Field)({
53
53
  description: 'Date or period for which this metric value is recorded (e.g., day: YYYY-MM-DD, month: YYYY-MM, range: YYYY-MM-DD~YYYY-MM-DD).'
54
54
  }),
@@ -60,7 +60,7 @@ tslib_1.__decorate([
60
60
  tslib_1.__metadata("design:type", String)
61
61
  ], KpiMetricValue.prototype, "periodType", void 0);
62
62
  tslib_1.__decorate([
63
- (0, typeorm_1.Column)({ nullable: true }),
63
+ (0, typeorm_1.Column)({ default: '' }),
64
64
  (0, type_graphql_1.Field)({ nullable: true, description: 'Group key for this value (organization, line, user, etc.)' }),
65
65
  tslib_1.__metadata("design:type", String)
66
66
  ], KpiMetricValue.prototype, "group", void 0);
@@ -101,6 +101,7 @@ tslib_1.__decorate([
101
101
  ], KpiMetricValue.prototype, "updaterId", void 0);
102
102
  exports.KpiMetricValue = KpiMetricValue = tslib_1.__decorate([
103
103
  (0, typeorm_1.Entity)(),
104
+ (0, typeorm_1.Index)('ix_kpi_metric_value_latest', ['domain', 'metric', 'valueDate', 'group'], { unique: true }),
104
105
  (0, type_graphql_1.ObjectType)({ description: 'Current value for each KPI metric (can be used for both state and history).' })
105
106
  ], KpiMetricValue);
106
107
  //# sourceMappingURL=kpi-metric-value.js.map