@things-factory/kpi 9.0.23 → 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 (76) hide show
  1. package/client/pages/kpi/kpi-viz-editor.ts +1 -1
  2. package/client/pages/kpi-category-value/kpi-category-value-list-page.ts +404 -0
  3. package/client/pages/kpi-metric-value/kpi-metric-value-editor-page.ts +763 -0
  4. package/client/pages/kpi-metric-value/kpi-metric-value-list-page.ts +12 -0
  5. package/client/pages/kpi-value/kpi-value-editor-page.ts +774 -0
  6. package/client/pages/kpi-value/kpi-value-list-page.ts +13 -0
  7. package/client/route.ts +16 -0
  8. package/dist-client/pages/kpi/kpi-viz-editor.d.ts +0 -1
  9. package/dist-client/pages/kpi/kpi-viz-editor.js +1 -1
  10. package/dist-client/pages/kpi/kpi-viz-editor.js.map +1 -1
  11. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.d.ts +63 -0
  12. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js +393 -0
  13. package/dist-client/pages/kpi-category-value/kpi-category-value-list-page.js.map +1 -0
  14. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.d.ts +58 -0
  15. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js +736 -0
  16. package/dist-client/pages/kpi-metric-value/kpi-metric-value-editor-page.js.map +1 -0
  17. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +1 -0
  18. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +11 -0
  19. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  20. package/dist-client/pages/kpi-value/kpi-value-editor-page.d.ts +55 -0
  21. package/dist-client/pages/kpi-value/kpi-value-editor-page.js +748 -0
  22. package/dist-client/pages/kpi-value/kpi-value-editor-page.js.map +1 -0
  23. package/dist-client/pages/kpi-value/kpi-value-list-page.d.ts +9 -2
  24. package/dist-client/pages/kpi-value/kpi-value-list-page.js +12 -0
  25. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  26. package/dist-client/route.d.ts +1 -1
  27. package/dist-client/route.js +12 -0
  28. package/dist-client/route.js.map +1 -1
  29. package/dist-client/tsconfig.tsbuildinfo +1 -1
  30. package/dist-server/service/index.d.ts +4 -2
  31. package/dist-server/service/index.js +5 -0
  32. package/dist-server/service/index.js.map +1 -1
  33. package/dist-server/service/kpi-category/kpi-category-mutation.d.ts +2 -3
  34. package/dist-server/service/kpi-category/kpi-category-mutation.js +149 -78
  35. package/dist-server/service/kpi-category/kpi-category-mutation.js.map +1 -1
  36. package/dist-server/service/kpi-category/kpi-category-query.d.ts +1 -9
  37. package/dist-server/service/kpi-category/kpi-category-query.js +3 -165
  38. package/dist-server/service/kpi-category/kpi-category-query.js.map +1 -1
  39. package/dist-server/service/kpi-category-value/index.d.ts +6 -0
  40. package/dist-server/service/kpi-category-value/index.js +10 -0
  41. package/dist-server/service/kpi-category-value/index.js.map +1 -0
  42. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.d.ts +8 -0
  43. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js +102 -0
  44. package/dist-server/service/kpi-category-value/kpi-category-value-mutation.js.map +1 -0
  45. package/dist-server/service/kpi-category-value/kpi-category-value-query.d.ts +13 -0
  46. package/dist-server/service/kpi-category-value/kpi-category-value-query.js +91 -0
  47. package/dist-server/service/kpi-category-value/kpi-category-value-query.js.map +1 -0
  48. package/dist-server/service/kpi-category-value/kpi-category-value-type.d.ts +19 -0
  49. package/dist-server/service/kpi-category-value/kpi-category-value-type.js +73 -0
  50. package/dist-server/service/kpi-category-value/kpi-category-value-type.js.map +1 -0
  51. package/dist-server/service/kpi-category-value/kpi-category-value.d.ts +19 -0
  52. package/dist-server/service/kpi-category-value/kpi-category-value.js +91 -0
  53. package/dist-server/service/kpi-category-value/kpi-category-value.js.map +1 -0
  54. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +20 -0
  55. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  56. package/dist-server/service/kpi-value/kpi-value-mutation.d.ts +1 -0
  57. package/dist-server/service/kpi-value/kpi-value-mutation.js +60 -0
  58. package/dist-server/service/kpi-value/kpi-value-mutation.js.map +1 -1
  59. package/dist-server/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +5 -5
  61. package/server/service/index.ts +5 -0
  62. package/server/service/kpi-category/kpi-category-mutation.ts +154 -81
  63. package/server/service/kpi-category/kpi-category-query.ts +1 -155
  64. package/server/service/kpi-category-value/index.ts +7 -0
  65. package/server/service/kpi-category-value/kpi-category-value-mutation.ts +88 -0
  66. package/server/service/kpi-category-value/kpi-category-value-query.ts +62 -0
  67. package/server/service/kpi-category-value/kpi-category-value-type.ts +48 -0
  68. package/server/service/kpi-category-value/kpi-category-value.ts +79 -0
  69. package/server/service/kpi-metric-value/kpi-metric-value-mutation.ts +28 -0
  70. package/server/service/kpi-value/kpi-value-mutation.ts +66 -0
  71. package/things-factory.config.js +3 -0
  72. package/translations/en.json +3 -0
  73. package/translations/ja.json +3 -0
  74. package/translations/ko.json +3 -0
  75. package/translations/ms.json +3 -0
  76. package/translations/zh.json +3 -0
@@ -2,6 +2,8 @@ export * from './kpi/kpi';
2
2
  export * from './kpi/kpi-type';
3
3
  export * from './kpi-category/kpi-category';
4
4
  export * from './kpi-category/kpi-category-type';
5
+ export * from './kpi-category-value/kpi-category-value';
6
+ export * from './kpi-category-value/kpi-category-value-type';
5
7
  export * from './kpi-value/kpi-value';
6
8
  export * from './kpi-value/kpi-value-type';
7
9
  export * from './kpi-metric/kpi-metric';
@@ -9,7 +11,7 @@ export * from './kpi-metric/kpi-metric-type';
9
11
  export * from './kpi-metric-value/kpi-metric-value';
10
12
  export * from './kpi-metric-value/kpi-metric-value-type';
11
13
  export * from './kpi-alert';
12
- export declare const entities: (typeof import("./kpi-category/kpi-category").KpiCategory | typeof import("./kpi/kpi").Kpi | typeof import("./kpi-value/kpi-value").KpiValue | typeof import("./kpi-metric/kpi-metric").KpiMetric | typeof import("./kpi-metric-value/kpi-metric-value").KpiMetricValue | typeof import("./kpi/kpi-history").KpiHistory)[];
14
+ export declare const entities: (typeof import("./kpi-category/kpi-category").KpiCategory | typeof import("./kpi/kpi").Kpi | typeof import("./kpi-category-value/kpi-category-value").KpiCategoryValue | typeof import("./kpi-value/kpi-value").KpiValue | typeof import("./kpi-metric/kpi-metric").KpiMetric | typeof import("./kpi-metric-value/kpi-metric-value").KpiMetricValue | typeof import("./kpi/kpi-history").KpiHistory)[];
13
15
  export declare const schema: {
14
- resolverClasses: (typeof import("./kpi-alert/kpi-alert-query").KpiAlertQuery | typeof import("./kpi/kpi-query").KpiQuery | typeof import("./kpi/kpi-mutation").KpiMutation | typeof import("./kpi-category/kpi-category-query").KpiCategoryQuery | typeof import("./kpi-category/kpi-category-mutation").KpiCategoryMutation | typeof import("./kpi-value/kpi-value-query").KpiValueQuery | typeof import("./kpi-value/kpi-value-mutation").KpiValueMutation | typeof import("./kpi-metric/kpi-metric-query").KpiMetricQuery | typeof import("./kpi-metric/kpi-metric-mutation").KpiMetricMutation | typeof import("./kpi-metric-value/kpi-metric-value-query").KpiMetricValueQuery | typeof import("./kpi-metric-value/kpi-metric-value-mutation").KpiMetricValueMutation)[];
16
+ resolverClasses: (typeof import("./kpi-alert/kpi-alert-query").KpiAlertQuery | typeof import("./kpi/kpi-query").KpiQuery | typeof import("./kpi/kpi-mutation").KpiMutation | typeof import("./kpi-category/kpi-category-query").KpiCategoryQuery | typeof import("./kpi-category/kpi-category-mutation").KpiCategoryMutation | typeof import("./kpi-category-value/kpi-category-value-query").KpiCategoryValueQuery | typeof import("./kpi-category-value/kpi-category-value-mutation").KpiCategoryValueMutation | typeof import("./kpi-value/kpi-value-query").KpiValueQuery | typeof import("./kpi-value/kpi-value-mutation").KpiValueMutation | typeof import("./kpi-metric/kpi-metric-query").KpiMetricQuery | typeof import("./kpi-metric/kpi-metric-mutation").KpiMetricMutation | typeof import("./kpi-metric-value/kpi-metric-value-query").KpiMetricValueQuery | typeof import("./kpi-metric-value/kpi-metric-value-mutation").KpiMetricValueMutation)[];
15
17
  };
@@ -7,6 +7,8 @@ tslib_1.__exportStar(require("./kpi/kpi"), exports);
7
7
  tslib_1.__exportStar(require("./kpi/kpi-type"), exports);
8
8
  tslib_1.__exportStar(require("./kpi-category/kpi-category"), exports);
9
9
  tslib_1.__exportStar(require("./kpi-category/kpi-category-type"), exports);
10
+ tslib_1.__exportStar(require("./kpi-category-value/kpi-category-value"), exports);
11
+ tslib_1.__exportStar(require("./kpi-category-value/kpi-category-value-type"), exports);
10
12
  tslib_1.__exportStar(require("./kpi-value/kpi-value"), exports);
11
13
  tslib_1.__exportStar(require("./kpi-value/kpi-value-type"), exports);
12
14
  tslib_1.__exportStar(require("./kpi-metric/kpi-metric"), exports);
@@ -17,6 +19,7 @@ tslib_1.__exportStar(require("./kpi-alert"), exports);
17
19
  /* IMPORT ENTITIES AND RESOLVERS */
18
20
  const kpi_1 = require("./kpi");
19
21
  const kpi_category_1 = require("./kpi-category");
22
+ const kpi_category_value_1 = require("./kpi-category-value");
20
23
  const kpi_value_1 = require("./kpi-value");
21
24
  const kpi_metric_1 = require("./kpi-metric");
22
25
  const kpi_metric_value_1 = require("./kpi-metric-value");
@@ -25,6 +28,7 @@ exports.entities = [
25
28
  /* ENTITIES */
26
29
  ...kpi_1.entities,
27
30
  ...kpi_category_1.entities,
31
+ ...kpi_category_value_1.entities,
28
32
  ...kpi_value_1.entities,
29
33
  ...kpi_metric_1.entities,
30
34
  ...kpi_metric_value_1.entities
@@ -34,6 +38,7 @@ exports.schema = {
34
38
  /* RESOLVER CLASSES */
35
39
  ...kpi_1.resolvers,
36
40
  ...kpi_category_1.resolvers,
41
+ ...kpi_category_value_1.resolvers,
37
42
  ...kpi_value_1.resolvers,
38
43
  ...kpi_metric_1.resolvers,
39
44
  ...kpi_metric_value_1.resolvers,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yBAAyB;AACzB,oDAAyB;AACzB,yDAA8B;AAC9B,sEAA2C;AAC3C,2EAAgD;AAChD,gEAAqC;AACrC,qEAA0C;AAC1C,kEAAuC;AACvC,uEAA4C;AAC5C,8EAAmD;AACnD,mFAAwD;AACxD,sDAA2B;AAE3B,mCAAmC;AACnC,+BAA0E;AAC1E,iDAAmG;AACnG,2CAA0F;AAC1F,6CAA6F;AAC7F,yDAA6G;AAC7G,2CAA4D;AAE/C,QAAA,QAAQ,GAAG;IACtB,cAAc;IACd,GAAG,cAAW;IACd,GAAG,uBAAmB;IACtB,GAAG,oBAAgB;IACnB,GAAG,qBAAiB;IACpB,GAAG,2BAAsB;CAC1B,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACtB,GAAG,eAAY;QACf,GAAG,wBAAoB;QACvB,GAAG,qBAAiB;QACpB,GAAG,sBAAkB;QACrB,GAAG,4BAAuB;QAC1B,GAAG,qBAAiB;KACrB;CACF,CAAA","sourcesContent":["/* EXPORT ENTITY TYPES */\nexport * from './kpi/kpi'\nexport * from './kpi/kpi-type'\nexport * from './kpi-category/kpi-category'\nexport * from './kpi-category/kpi-category-type'\nexport * from './kpi-value/kpi-value'\nexport * from './kpi-value/kpi-value-type'\nexport * from './kpi-metric/kpi-metric'\nexport * from './kpi-metric/kpi-metric-type'\nexport * from './kpi-metric-value/kpi-metric-value'\nexport * from './kpi-metric-value/kpi-metric-value-type'\nexport * from './kpi-alert'\n\n/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as KpiEntities, resolvers as KpiResolvers } from './kpi'\nimport { entities as KpiCategoryEntities, resolvers as KpiCategoryResolvers } from './kpi-category'\nimport { entities as KpiValueEntities, resolvers as KpiValueResolvers } from './kpi-value'\nimport { entities as KpiMetricEntities, resolvers as KpiMetricResolvers } from './kpi-metric'\nimport { entities as KpiMetricValueEntities, resolvers as KpiMetricValueResolvers } from './kpi-metric-value'\nimport { resolvers as KpiAlertResolvers } from './kpi-alert'\n\nexport const entities = [\n /* ENTITIES */\n ...KpiEntities,\n ...KpiCategoryEntities,\n ...KpiValueEntities,\n ...KpiMetricEntities,\n ...KpiMetricValueEntities\n]\n\nexport const schema = {\n resolverClasses: [\n /* RESOLVER CLASSES */\n ...KpiResolvers,\n ...KpiCategoryResolvers,\n ...KpiValueResolvers,\n ...KpiMetricResolvers,\n ...KpiMetricValueResolvers,\n ...KpiAlertResolvers\n ]\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yBAAyB;AACzB,oDAAyB;AACzB,yDAA8B;AAC9B,sEAA2C;AAC3C,2EAAgD;AAChD,kFAAuD;AACvD,uFAA4D;AAC5D,gEAAqC;AACrC,qEAA0C;AAC1C,kEAAuC;AACvC,uEAA4C;AAC5C,8EAAmD;AACnD,mFAAwD;AACxD,sDAA2B;AAE3B,mCAAmC;AACnC,+BAA0E;AAC1E,iDAAmG;AACnG,6DAAmH;AACnH,2CAA0F;AAC1F,6CAA6F;AAC7F,yDAA6G;AAC7G,2CAA4D;AAE/C,QAAA,QAAQ,GAAG;IACtB,cAAc;IACd,GAAG,cAAW;IACd,GAAG,uBAAmB;IACtB,GAAG,6BAAwB;IAC3B,GAAG,oBAAgB;IACnB,GAAG,qBAAiB;IACpB,GAAG,2BAAsB;CAC1B,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACtB,GAAG,eAAY;QACf,GAAG,wBAAoB;QACvB,GAAG,8BAAyB;QAC5B,GAAG,qBAAiB;QACpB,GAAG,sBAAkB;QACrB,GAAG,4BAAuB;QAC1B,GAAG,qBAAiB;KACrB;CACF,CAAA","sourcesContent":["/* EXPORT ENTITY TYPES */\nexport * from './kpi/kpi'\nexport * from './kpi/kpi-type'\nexport * from './kpi-category/kpi-category'\nexport * from './kpi-category/kpi-category-type'\nexport * from './kpi-category-value/kpi-category-value'\nexport * from './kpi-category-value/kpi-category-value-type'\nexport * from './kpi-value/kpi-value'\nexport * from './kpi-value/kpi-value-type'\nexport * from './kpi-metric/kpi-metric'\nexport * from './kpi-metric/kpi-metric-type'\nexport * from './kpi-metric-value/kpi-metric-value'\nexport * from './kpi-metric-value/kpi-metric-value-type'\nexport * from './kpi-alert'\n\n/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as KpiEntities, resolvers as KpiResolvers } from './kpi'\nimport { entities as KpiCategoryEntities, resolvers as KpiCategoryResolvers } from './kpi-category'\nimport { entities as KpiCategoryValueEntities, resolvers as KpiCategoryValueResolvers } from './kpi-category-value'\nimport { entities as KpiValueEntities, resolvers as KpiValueResolvers } from './kpi-value'\nimport { entities as KpiMetricEntities, resolvers as KpiMetricResolvers } from './kpi-metric'\nimport { entities as KpiMetricValueEntities, resolvers as KpiMetricValueResolvers } from './kpi-metric-value'\nimport { resolvers as KpiAlertResolvers } from './kpi-alert'\n\nexport const entities = [\n /* ENTITIES */\n ...KpiEntities,\n ...KpiCategoryEntities,\n ...KpiCategoryValueEntities,\n ...KpiValueEntities,\n ...KpiMetricEntities,\n ...KpiMetricValueEntities\n]\n\nexport const schema = {\n resolverClasses: [\n /* RESOLVER CLASSES */\n ...KpiResolvers,\n ...KpiCategoryResolvers,\n ...KpiCategoryValueResolvers,\n ...KpiValueResolvers,\n ...KpiMetricResolvers,\n ...KpiMetricValueResolvers,\n ...KpiAlertResolvers\n ]\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import { KpiCategory } from './kpi-category';
2
2
  import { NewKpiCategory, KpiCategoryPatch } from './kpi-category-type';
3
+ import { KpiCategoryValueResult } from './kpi-category-query';
3
4
  export declare class KpiCategoryMutation {
4
5
  createKpiCategory(kpiCategory: NewKpiCategory, context: ResolverContext): Promise<KpiCategory>;
5
6
  updateKpiCategory(id: string, patch: KpiCategoryPatch, context: ResolverContext): Promise<KpiCategory>;
6
- updateMultipleKpiCategory(patches: KpiCategoryPatch[], context: ResolverContext): Promise<KpiCategory[]>;
7
7
  deleteKpiCategory(id: string, context: ResolverContext): Promise<boolean>;
8
- deleteKpiCategories(ids: string[], context: ResolverContext): Promise<boolean>;
9
- importKpiCategories(kpiCategories: KpiCategoryPatch[], context: ResolverContext): Promise<boolean>;
8
+ calculateKpiValue(categoryId: string, valueDate: string, group: string, context: ResolverContext): Promise<KpiCategoryValueResult>;
10
9
  }
@@ -3,10 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KpiCategoryMutation = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const type_graphql_1 = require("type-graphql");
6
- const typeorm_1 = require("typeorm");
7
6
  const shell_1 = require("@things-factory/shell");
8
7
  const kpi_category_1 = require("./kpi-category");
9
8
  const kpi_category_type_1 = require("./kpi-category-type");
9
+ const kpi_category_query_1 = require("./kpi-category-query");
10
+ const parser_1 = require("../../calculator/parser");
11
+ const evaluator_1 = require("../../calculator/evaluator");
12
+ const functions_1 = require("../../calculator/functions");
13
+ const kpi_value_provider_1 = require("../../controllers/kpi-value-provider");
14
+ const value_date_util_1 = require("../utils/value-date-util");
15
+ const kpi_1 = require("../kpi/kpi");
16
+ const kpi_value_score_service_1 = require("../kpi-value/kpi-value-score.service");
17
+ const kpi_category_value_1 = require("../kpi-category-value/kpi-category-value");
10
18
  let KpiCategoryMutation = class KpiCategoryMutation {
11
19
  async createKpiCategory(kpiCategory, context) {
12
20
  const { domain, user, tx } = context.state;
@@ -20,75 +28,154 @@ let KpiCategoryMutation = class KpiCategoryMutation {
20
28
  }
21
29
  async updateKpiCategory(id, patch, context) {
22
30
  const { domain, user, tx } = context.state;
23
- const repository = (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx);
24
- const kpiCategory = await repository.findOne({
25
- where: { domain: { id: domain.id }, id }
31
+ const kpiCategory = await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).findOne({
32
+ where: { id, domain: { id: domain.id } }
26
33
  });
27
- const result = await repository.save({
28
- ...kpiCategory,
34
+ if (!kpiCategory) {
35
+ throw new Error(`KPI category with id ${id} not found`);
36
+ }
37
+ Object.assign(kpiCategory, {
29
38
  ...patch,
30
39
  updater: user
31
40
  });
32
- return result;
41
+ return await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).save(kpiCategory);
42
+ }
43
+ async deleteKpiCategory(id, context) {
44
+ const { domain, tx } = context.state;
45
+ const kpiCategory = await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).findOne({
46
+ where: { id, domain: { id: domain.id } }
47
+ });
48
+ if (!kpiCategory) {
49
+ throw new Error(`KPI category with id ${id} not found`);
50
+ }
51
+ await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).remove(kpiCategory);
52
+ return true;
33
53
  }
34
- async updateMultipleKpiCategory(patches, context) {
54
+ async calculateKpiValue(categoryId, valueDate, group, context) {
35
55
  const { domain, user, tx } = context.state;
36
- let results = [];
37
- const _createRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === '+');
38
- const _updateRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === 'M');
39
- const kpiCategoryRepo = (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx);
40
- if (_createRecords.length > 0) {
41
- for (let i = 0; i < _createRecords.length; i++) {
42
- const newRecord = _createRecords[i];
43
- const result = await kpiCategoryRepo.save({
44
- ...newRecord,
45
- domain,
46
- creator: user,
47
- updater: user
56
+ // 1. 카테고리 정보 조회
57
+ const category = await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).findOne({
58
+ where: { id: categoryId, domain: { id: domain.id } }
59
+ });
60
+ if (!category)
61
+ return { score: null };
62
+ // 기본 계산 기준일 설정 (카테고리 periodType 사용)
63
+ const defaultDate = valueDate || (0, value_date_util_1.getDefaultValueDate)(category.periodType || kpi_1.KpiPeriodType.DAY, 'last');
64
+ // 2. 카테고리 formula가 있으면 formula로 계산
65
+ if (category.formula) {
66
+ const ast = (0, parser_1.parseFormula)(category.formula);
67
+ const provider = new kpi_value_provider_1.KpiValueProvider({
68
+ valueDate: defaultDate,
69
+ group,
70
+ domainId: domain.id,
71
+ tx
72
+ });
73
+ const evalContext = { functions: functions_1.builtinFunctions, provider };
74
+ const value = await (0, evaluator_1.evaluateFormula)(ast, evalContext);
75
+ // 카테고리 formula 결과를 score로 변환 (0-1 범위)
76
+ const score = value !== null && value !== undefined && !isNaN(value) ? Math.max(0, Math.min(1, value)) : null;
77
+ // KpiCategoryValue에 저장 (for formula case)
78
+ const kpiCategoryValue = (0, shell_1.getRepository)(kpi_category_value_1.KpiCategoryValue, tx).create({
79
+ domainId: domain.id,
80
+ categoryId: categoryId,
81
+ valueDate: defaultDate,
82
+ group,
83
+ score,
84
+ creator: user,
85
+ updater: user
86
+ });
87
+ await (0, shell_1.getRepository)(kpi_category_value_1.KpiCategoryValue, tx).save(kpiCategoryValue);
88
+ return {
89
+ score,
90
+ valueDate: defaultDate,
91
+ group
92
+ };
93
+ }
94
+ // 3. formula가 없으면 KPI score들의 가중 평균으로 category score 계산
95
+ const { Kpi } = require('../kpi/kpi');
96
+ const kpis = await (0, shell_1.getRepository)(Kpi, tx).find({
97
+ where: { domain: { id: domain.id }, category: { id: categoryId } }
98
+ });
99
+ if (!kpis.length)
100
+ return { score: null };
101
+ // 가중치 정규화를 위한 전체 가중치 합 계산
102
+ let totalWeightSum = 0;
103
+ for (const kpi of kpis) {
104
+ const weight = kpi.weight ?? 1;
105
+ totalWeightSum += weight;
106
+ }
107
+ // 가중치가 0이면 기본값 1로 설정
108
+ if (totalWeightSum === 0) {
109
+ totalWeightSum = kpis.length;
110
+ }
111
+ let weightedScoreSum = 0;
112
+ for (const kpi of kpis) {
113
+ // KPI value 계산
114
+ let value = null;
115
+ if (kpi.formula) {
116
+ const ast = (0, parser_1.parseFormula)(kpi.formula);
117
+ const provider = new kpi_value_provider_1.KpiValueProvider({
118
+ valueDate: defaultDate,
119
+ group,
120
+ domainId: domain.id,
121
+ tx
48
122
  });
49
- results.push({ ...result, cuFlag: '+' });
123
+ const evalContext = { functions: functions_1.builtinFunctions, provider };
124
+ value = await (0, evaluator_1.evaluateFormula)(ast, evalContext);
50
125
  }
51
- }
52
- if (_updateRecords.length > 0) {
53
- for (let i = 0; i < _updateRecords.length; i++) {
54
- const updateRecord = _updateRecords[i];
55
- const kpiCategory = await kpiCategoryRepo.findOneBy({ id: updateRecord.id });
56
- const result = await kpiCategoryRepo.save({
57
- ...kpiCategory,
58
- ...updateRecord,
59
- updater: user
126
+ else {
127
+ const { KpiValue } = require('../kpi-value/kpi-value');
128
+ const kpiValue = await (0, shell_1.getRepository)(KpiValue, tx).findOne({
129
+ where: {
130
+ kpi: { id: kpi.id },
131
+ valueDate: defaultDate,
132
+ group: group ?? '',
133
+ domain: { id: domain.id }
134
+ }
60
135
  });
61
- results.push({ ...result, cuFlag: 'M' });
136
+ value = kpiValue?.value ?? 0;
137
+ }
138
+ // KPI score 계산
139
+ const scoreService = new kpi_value_score_service_1.KpiValueScoreService();
140
+ let kpiScore = null;
141
+ if (value !== null && value !== undefined) {
142
+ let scoreResult = await scoreService.calculateScoreFromFormula(kpi, value);
143
+ if (!scoreResult) {
144
+ scoreResult = scoreService.calculateScoreFromLookup(kpi, value);
145
+ }
146
+ kpiScore = scoreResult?.score ?? null;
147
+ }
148
+ // 정규화된 가중치 계산 (전체 가중치 합으로 나누어 비율로 변환)
149
+ const normalizedWeight = (kpi.weight ?? 1) / totalWeightSum;
150
+ if (kpiScore !== null) {
151
+ weightedScoreSum += kpiScore * normalizedWeight;
62
152
  }
63
153
  }
64
- return results;
65
- }
66
- async deleteKpiCategory(id, context) {
67
- const { domain, tx } = context.state;
68
- await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).delete({ domain: { id: domain.id }, id });
69
- return true;
70
- }
71
- async deleteKpiCategories(ids, context) {
72
- const { domain, tx } = context.state;
73
- await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).delete({
74
- domain: { id: domain.id },
75
- id: (0, typeorm_1.In)(ids)
154
+ // category score 계산 (정규화된 가중치로 계산된 결과)
155
+ const categoryScore = weightedScoreSum;
156
+ // KpiCategoryValue에 저장
157
+ const kpiCategoryValue = (0, shell_1.getRepository)(kpi_category_value_1.KpiCategoryValue, tx).create({
158
+ domainId: domain.id,
159
+ categoryId: categoryId,
160
+ valueDate: defaultDate,
161
+ group,
162
+ score: categoryScore,
163
+ creator: user,
164
+ updater: user
76
165
  });
77
- return true;
78
- }
79
- async importKpiCategories(kpiCategories, context) {
80
- const { domain, tx } = context.state;
81
- await Promise.all(kpiCategories.map(async (kpiCategory) => {
82
- const createdKpiCategory = await (0, shell_1.getRepository)(kpi_category_1.KpiCategory, tx).save({ domain, ...kpiCategory });
83
- }));
84
- return true;
166
+ await (0, shell_1.getRepository)(kpi_category_value_1.KpiCategoryValue, tx).save(kpiCategoryValue);
167
+ return {
168
+ score: categoryScore,
169
+ valueDate: defaultDate,
170
+ group
171
+ };
85
172
  }
86
173
  };
87
174
  exports.KpiCategoryMutation = KpiCategoryMutation;
88
175
  tslib_1.__decorate([
89
176
  (0, type_graphql_1.Directive)('@transaction'),
90
- (0, type_graphql_1.Mutation)(returns => kpi_category_1.KpiCategory, { description: 'Create a new KPI category with the provided details.' }),
91
- tslib_1.__param(0, (0, type_graphql_1.Arg)('kpiCategory', { description: 'Input object containing details for the new KPI category.' })),
177
+ (0, type_graphql_1.Mutation)(returns => kpi_category_1.KpiCategory, { description: 'Create a new KPI category.' }),
178
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('kpiCategory')),
92
179
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
93
180
  tslib_1.__metadata("design:type", Function),
94
181
  tslib_1.__metadata("design:paramtypes", [kpi_category_type_1.NewKpiCategory, Object]),
@@ -96,7 +183,7 @@ tslib_1.__decorate([
96
183
  ], KpiCategoryMutation.prototype, "createKpiCategory", null);
97
184
  tslib_1.__decorate([
98
185
  (0, type_graphql_1.Directive)('@transaction'),
99
- (0, type_graphql_1.Mutation)(returns => kpi_category_1.KpiCategory, { description: 'To modify KpiCategory information' }),
186
+ (0, type_graphql_1.Mutation)(returns => kpi_category_1.KpiCategory, { description: 'Update an existing KPI category.' }),
100
187
  tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
101
188
  tslib_1.__param(1, (0, type_graphql_1.Arg)('patch')),
102
189
  tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
@@ -106,16 +193,7 @@ tslib_1.__decorate([
106
193
  ], KpiCategoryMutation.prototype, "updateKpiCategory", null);
107
194
  tslib_1.__decorate([
108
195
  (0, type_graphql_1.Directive)('@transaction'),
109
- (0, type_graphql_1.Mutation)(returns => [kpi_category_1.KpiCategory], { description: "To modify multiple KpiCategories' information" }),
110
- tslib_1.__param(0, (0, type_graphql_1.Arg)('patches', type => [kpi_category_type_1.KpiCategoryPatch])),
111
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
112
- tslib_1.__metadata("design:type", Function),
113
- tslib_1.__metadata("design:paramtypes", [Array, Object]),
114
- tslib_1.__metadata("design:returntype", Promise)
115
- ], KpiCategoryMutation.prototype, "updateMultipleKpiCategory", null);
116
- tslib_1.__decorate([
117
- (0, type_graphql_1.Directive)('@transaction'),
118
- (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete KpiCategory' }),
196
+ (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'Delete a KPI category.' }),
119
197
  tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
120
198
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
121
199
  tslib_1.__metadata("design:type", Function),
@@ -124,22 +202,15 @@ tslib_1.__decorate([
124
202
  ], KpiCategoryMutation.prototype, "deleteKpiCategory", null);
125
203
  tslib_1.__decorate([
126
204
  (0, type_graphql_1.Directive)('@transaction'),
127
- (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To delete multiple KpiCategories' }),
128
- tslib_1.__param(0, (0, type_graphql_1.Arg)('ids', type => [String])),
129
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
130
- tslib_1.__metadata("design:type", Function),
131
- tslib_1.__metadata("design:paramtypes", [Array, Object]),
132
- tslib_1.__metadata("design:returntype", Promise)
133
- ], KpiCategoryMutation.prototype, "deleteKpiCategories", null);
134
- tslib_1.__decorate([
135
- (0, type_graphql_1.Directive)('@transaction'),
136
- (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To import multiple KpiCategories' }),
137
- tslib_1.__param(0, (0, type_graphql_1.Arg)('kpiCategories', type => [kpi_category_type_1.KpiCategoryPatch])),
138
- tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
205
+ (0, type_graphql_1.Mutation)(returns => kpi_category_query_1.KpiCategoryValueResult, { description: 'Calculate KPI category value and score.' }),
206
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('categoryId')),
207
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('valueDate', { nullable: true })),
208
+ tslib_1.__param(2, (0, type_graphql_1.Arg)('group', { nullable: true })),
209
+ tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
139
210
  tslib_1.__metadata("design:type", Function),
140
- tslib_1.__metadata("design:paramtypes", [Array, Object]),
211
+ tslib_1.__metadata("design:paramtypes", [String, String, String, Object]),
141
212
  tslib_1.__metadata("design:returntype", Promise)
142
- ], KpiCategoryMutation.prototype, "importKpiCategories", null);
213
+ ], KpiCategoryMutation.prototype, "calculateKpiValue", null);
143
214
  exports.KpiCategoryMutation = KpiCategoryMutation = tslib_1.__decorate([
144
215
  (0, type_graphql_1.Resolver)(kpi_category_1.KpiCategory)
145
216
  ], KpiCategoryMutation);
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-category-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-category/kpi-category-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'\n\nimport { KpiCategory } from './kpi-category'\nimport { NewKpiCategory, KpiCategoryPatch } from './kpi-category-type'\n\n@Resolver(KpiCategory)\nexport class KpiCategoryMutation {\n @Directive('@transaction')\n @Mutation(returns => KpiCategory, { description: 'Create a new KPI category with the provided details.' })\n async createKpiCategory(\n @Arg('kpiCategory', { description: 'Input object containing details for the new KPI category.' })\n kpiCategory: NewKpiCategory,\n @Ctx() context: ResolverContext\n ): Promise<KpiCategory> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(KpiCategory, tx).save({\n ...kpiCategory,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiCategory, { description: 'To modify KpiCategory information' })\n async updateKpiCategory(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiCategoryPatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiCategory> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(KpiCategory, tx)\n const kpiCategory = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...kpiCategory,\n ...patch,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => [KpiCategory], { description: \"To modify multiple KpiCategories' information\" })\n async updateMultipleKpiCategory(\n @Arg('patches', type => [KpiCategoryPatch]) patches: KpiCategoryPatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiCategory[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const kpiCategoryRepo = getRepository(KpiCategory, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await kpiCategoryRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n })\n\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 kpiCategory = await kpiCategoryRepo.findOneBy({ id: updateRecord.id })\n\n const result = await kpiCategoryRepo.save({\n ...kpiCategory,\n ...updateRecord,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete KpiCategory' })\n async deleteKpiCategory(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiCategory, tx).delete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete multiple KpiCategories' })\n async deleteKpiCategories(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiCategory, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To import multiple KpiCategories' })\n async importKpiCategories(\n @Arg('kpiCategories', type => [KpiCategoryPatch]) kpiCategories: KpiCategoryPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await Promise.all(\n kpiCategories.map(async (kpiCategory: KpiCategoryPatch) => {\n const createdKpiCategory: KpiCategory = await getRepository(KpiCategory, tx).save({ domain, ...kpiCategory })\n })\n )\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-category-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-category/kpi-category-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { getRepository } from '@things-factory/shell'\nimport { KpiCategory } from './kpi-category'\nimport { NewKpiCategory, KpiCategoryPatch } from './kpi-category-type'\nimport { KpiCategoryValueResult } from './kpi-category-query'\nimport { parseFormula } from '../../calculator/parser'\nimport { evaluateFormula } from '../../calculator/evaluator'\nimport { builtinFunctions } from '../../calculator/functions'\nimport { KpiValueProvider } from '../../controllers/kpi-value-provider'\nimport { getDefaultValueDate } from '../utils/value-date-util'\nimport { KpiPeriodType } from '../kpi/kpi'\nimport { KpiValueScoreService } from '../kpi-value/kpi-value-score.service'\nimport { KpiCategoryValue } from '../kpi-category-value/kpi-category-value'\n\n@Resolver(KpiCategory)\nexport class KpiCategoryMutation {\n @Directive('@transaction')\n @Mutation(returns => KpiCategory, { description: 'Create a new KPI category.' })\n async createKpiCategory(\n @Arg('kpiCategory') kpiCategory: NewKpiCategory,\n @Ctx() context: ResolverContext\n ): Promise<KpiCategory> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(KpiCategory, tx).save({\n ...kpiCategory,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiCategory, { description: 'Update an existing KPI category.' })\n async updateKpiCategory(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiCategoryPatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiCategory> {\n const { domain, user, tx } = context.state\n\n const kpiCategory = await getRepository(KpiCategory, tx).findOne({\n where: { id, domain: { id: domain.id } }\n })\n if (!kpiCategory) {\n throw new Error(`KPI category with id ${id} not found`)\n }\n\n Object.assign(kpiCategory, {\n ...patch,\n updater: user\n })\n\n return await getRepository(KpiCategory, tx).save(kpiCategory)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'Delete a KPI category.' })\n async deleteKpiCategory(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n const kpiCategory = await getRepository(KpiCategory, tx).findOne({\n where: { id, domain: { id: domain.id } }\n })\n if (!kpiCategory) {\n throw new Error(`KPI category with id ${id} not found`)\n }\n\n await getRepository(KpiCategory, tx).remove(kpiCategory)\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => KpiCategoryValueResult, { description: 'Calculate KPI category value and score.' })\n async calculateKpiValue(\n @Arg('categoryId') categoryId: string,\n @Arg('valueDate', { nullable: true }) valueDate: string,\n @Arg('group', { nullable: true }) group: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiCategoryValueResult> {\n const { domain, user, tx } = context.state\n\n // 1. 카테고리 정보 조회\n const category = await getRepository(KpiCategory, tx).findOne({\n where: { id: categoryId, domain: { id: domain.id } }\n })\n if (!category) return { score: null }\n\n // 기본 계산 기준일 설정 (카테고리 periodType 사용)\n const defaultDate = valueDate || getDefaultValueDate(category.periodType || KpiPeriodType.DAY, 'last')\n\n // 2. 카테고리 formula가 있으면 formula로 계산\n if (category.formula) {\n const ast = parseFormula(category.formula)\n const provider = new KpiValueProvider({\n valueDate: defaultDate,\n group,\n domainId: domain.id,\n tx\n })\n const evalContext = { functions: builtinFunctions, provider }\n const value = await evaluateFormula(ast, evalContext)\n // 카테고리 formula 결과를 score로 변환 (0-1 범위)\n const score = value !== null && value !== undefined && !isNaN(value) ? Math.max(0, Math.min(1, value)) : null\n\n // KpiCategoryValue에 저장 (for formula case)\n const kpiCategoryValue = getRepository(KpiCategoryValue, tx).create({\n domainId: domain.id,\n categoryId: categoryId,\n valueDate: defaultDate,\n group,\n score,\n creator: user,\n updater: user\n })\n await getRepository(KpiCategoryValue, tx).save(kpiCategoryValue)\n\n return {\n score,\n valueDate: defaultDate,\n group\n }\n }\n\n // 3. formula가 없으면 KPI score들의 가중 평균으로 category score 계산\n const { Kpi } = require('../kpi/kpi')\n const kpis = await getRepository(Kpi, tx).find({\n where: { domain: { id: domain.id }, category: { id: categoryId } }\n })\n if (!kpis.length) return { score: null }\n\n // 가중치 정규화를 위한 전체 가중치 합 계산\n let totalWeightSum = 0\n for (const kpi of kpis as any[]) {\n const weight = kpi.weight ?? 1\n totalWeightSum += weight\n }\n\n // 가중치가 0이면 기본값 1로 설정\n if (totalWeightSum === 0) {\n totalWeightSum = kpis.length\n }\n\n let weightedScoreSum = 0\n\n for (const kpi of kpis as any[]) {\n // KPI value 계산\n let value = null\n if (kpi.formula) {\n const ast = parseFormula(kpi.formula)\n const provider = new KpiValueProvider({\n valueDate: defaultDate,\n group,\n domainId: domain.id,\n tx\n })\n const evalContext = { functions: builtinFunctions, provider }\n value = await evaluateFormula(ast, evalContext)\n } else {\n const { KpiValue } = require('../kpi-value/kpi-value')\n const kpiValue = await getRepository(KpiValue, tx).findOne({\n where: {\n kpi: { id: kpi.id },\n valueDate: defaultDate,\n group: group ?? '',\n domain: { id: domain.id }\n }\n })\n value = (kpiValue as any)?.value ?? 0\n }\n\n // KPI score 계산\n const scoreService = new KpiValueScoreService()\n let kpiScore = null\n if (value !== null && value !== undefined) {\n let scoreResult = await scoreService.calculateScoreFromFormula(kpi as any, value)\n if (!scoreResult) {\n scoreResult = scoreService.calculateScoreFromLookup(kpi as any, value)\n }\n kpiScore = scoreResult?.score ?? null\n }\n\n // 정규화된 가중치 계산 (전체 가중치 합으로 나누어 비율로 변환)\n const normalizedWeight = (kpi.weight ?? 1) / totalWeightSum\n if (kpiScore !== null) {\n weightedScoreSum += kpiScore * normalizedWeight\n }\n }\n\n // category score 계산 (정규화된 가중치로 계산된 결과)\n const categoryScore = weightedScoreSum\n\n // KpiCategoryValue에 저장\n const kpiCategoryValue = getRepository(KpiCategoryValue, tx).create({\n domainId: domain.id,\n categoryId: categoryId,\n valueDate: defaultDate,\n group,\n score: categoryScore,\n creator: user,\n updater: user\n })\n await getRepository(KpiCategoryValue, tx).save(kpiCategoryValue)\n\n return {\n score: categoryScore,\n valueDate: defaultDate,\n group\n }\n }\n}\n"]}
@@ -3,24 +3,16 @@ import { User } from '@things-factory/auth-base';
3
3
  import { KpiCategory } from './kpi-category';
4
4
  import { KpiCategoryList } from './kpi-category-type';
5
5
  import { Kpi } from '../kpi/kpi';
6
- declare class KpiValueItem {
7
- kpiId: string;
8
- value: number;
9
- }
10
- declare class KpiCategoryValueResult {
11
- value?: number;
6
+ export declare class KpiCategoryValueResult {
12
7
  score?: number;
13
8
  valueDate?: string;
14
9
  group?: string;
15
- kpiValues: KpiValueItem[];
16
10
  }
17
11
  export declare class KpiCategoryQuery {
18
12
  kpiCategory(id: string, context: ResolverContext): Promise<KpiCategory>;
19
13
  kpiCategories(params: ListParam, context: ResolverContext): Promise<KpiCategoryList>;
20
- calculateKpiValue(categoryId: string, valueDate: string, group: string, context: ResolverContext): Promise<KpiCategoryValueResult>;
21
14
  kpis(kpiCategory: KpiCategory): Promise<Kpi[]>;
22
15
  domain(kpiCategory: KpiCategory): Promise<Domain>;
23
16
  updater(kpiCategory: KpiCategory): Promise<User>;
24
17
  creator(kpiCategory: KpiCategory): Promise<User>;
25
18
  }
26
- export {};