@things-factory/kpi 9.0.32 → 9.0.34

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 (61) hide show
  1. package/client/pages/kpi-dashboard/kpi-dashboard-map.ts +291 -49
  2. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.d.ts +3 -1
  3. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js +268 -47
  4. package/dist-client/pages/kpi-dashboard/kpi-dashboard-map.js.map +1 -1
  5. package/dist-client/tsconfig.tsbuildinfo +1 -1
  6. package/dist-server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  7. package/dist-server/migrations/seed-data/scope-definitions-seed.json +90 -0
  8. package/dist-server/service/index.d.ts +4 -3
  9. package/dist-server/service/index.js +7 -3
  10. package/dist-server/service/index.js.map +1 -1
  11. package/dist-server/service/kpi/kpi-query.js.map +1 -1
  12. package/dist-server/service/kpi-org-scope/index.d.ts +0 -4
  13. package/dist-server/service/kpi-org-scope/index.js +0 -5
  14. package/dist-server/service/kpi-org-scope/index.js.map +1 -1
  15. package/dist-server/service/kpi-scope/index.d.ts +9 -0
  16. package/dist-server/service/kpi-scope/index.js +14 -0
  17. package/dist-server/service/kpi-scope/index.js.map +1 -0
  18. package/dist-server/service/kpi-scope/kpi-scope-mutation.d.ts +9 -0
  19. package/dist-server/service/kpi-scope/kpi-scope-mutation.js +135 -0
  20. package/dist-server/service/kpi-scope/kpi-scope-mutation.js.map +1 -0
  21. package/dist-server/service/kpi-scope/kpi-scope-query.d.ts +11 -0
  22. package/dist-server/service/kpi-scope/kpi-scope-query.js +89 -0
  23. package/dist-server/service/kpi-scope/kpi-scope-query.js.map +1 -0
  24. package/dist-server/service/kpi-scope/kpi-scope-type.d.ts +35 -0
  25. package/dist-server/service/kpi-scope/kpi-scope-type.js +138 -0
  26. package/dist-server/service/kpi-scope/kpi-scope-type.js.map +1 -0
  27. package/dist-server/service/kpi-scope/kpi-scope.d.ts +38 -0
  28. package/dist-server/service/kpi-scope/kpi-scope.js +144 -0
  29. package/dist-server/service/kpi-scope/kpi-scope.js.map +1 -0
  30. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.d.ts +43 -0
  31. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js +181 -0
  32. package/dist-server/service/kpi-statistic/kpi-statistic-batch.service.js.map +1 -0
  33. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.d.ts +50 -0
  34. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js +324 -0
  35. package/dist-server/service/kpi-statistic/kpi-statistic-calculation.service.js.map +1 -0
  36. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.d.ts +4 -0
  37. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js +76 -0
  38. package/dist-server/service/kpi-statistic/kpi-statistic-mutation.js.map +1 -1
  39. package/dist-server/service/kpi-statistic/kpi-statistic-query.d.ts +5 -1
  40. package/dist-server/service/kpi-statistic/kpi-statistic-query.js +92 -1
  41. package/dist-server/service/kpi-statistic/kpi-statistic-query.js.map +1 -1
  42. package/dist-server/service/kpi-statistic/kpi-statistic.d.ts +3 -0
  43. package/dist-server/service/kpi-statistic/kpi-statistic.js +23 -1
  44. package/dist-server/service/kpi-statistic/kpi-statistic.js.map +1 -1
  45. package/dist-server/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +5 -5
  47. package/server/migrations/seed-data/kpi-scopes-seed.json +121 -0
  48. package/server/migrations/seed-data/scope-definitions-seed.json +90 -0
  49. package/server/service/index.ts +7 -3
  50. package/server/service/kpi/kpi-query.ts +1 -0
  51. package/server/service/kpi-org-scope/index.ts +1 -6
  52. package/server/service/kpi-scope/index.ts +11 -0
  53. package/server/service/kpi-scope/kpi-scope-mutation.ts +129 -0
  54. package/server/service/kpi-scope/kpi-scope-query.ts +63 -0
  55. package/server/service/kpi-scope/kpi-scope-type.ts +96 -0
  56. package/server/service/kpi-scope/kpi-scope.ts +143 -0
  57. package/server/service/kpi-statistic/kpi-statistic-batch.service.ts +231 -0
  58. package/server/service/kpi-statistic/kpi-statistic-calculation.service.ts +410 -0
  59. package/server/service/kpi-statistic/kpi-statistic-mutation.ts +97 -0
  60. package/server/service/kpi-statistic/kpi-statistic-query.ts +89 -2
  61. package/server/service/kpi-statistic/kpi-statistic.ts +23 -1
@@ -7,6 +7,8 @@ const typeorm_1 = require("typeorm");
7
7
  const shell_1 = require("@things-factory/shell");
8
8
  const kpi_statistic_js_1 = require("./kpi-statistic.js");
9
9
  const kpi_statistic_type_js_1 = require("./kpi-statistic-type.js");
10
+ const kpi_statistic_calculation_service_js_1 = require("./kpi-statistic-calculation.service.js");
11
+ const kpi_js_1 = require("../kpi/kpi.js");
10
12
  let KpiStatisticMutation = class KpiStatisticMutation {
11
13
  async createKpiStatistic(kpiStatistic, context) {
12
14
  const { domain, user, tx } = context.state;
@@ -129,6 +131,40 @@ let KpiStatisticMutation = class KpiStatisticMutation {
129
131
  }
130
132
  return true;
131
133
  }
134
+ async calculateKpiStatistics(kpiId, periodType, valueDate, context) {
135
+ const overallStats = await kpi_statistic_calculation_service_js_1.KpiStatisticCalculationService.calculateKpiStatistics(kpiId, periodType, valueDate, null, // 전체 통계
136
+ context);
137
+ const scopedStats = await kpi_statistic_calculation_service_js_1.KpiStatisticCalculationService.calculateScopedStatistics(kpiId, periodType, valueDate, context);
138
+ return [overallStats, ...scopedStats].filter(Boolean);
139
+ }
140
+ async calculateAllKpiStatistics(periodType, valueDate, context) {
141
+ return await kpi_statistic_calculation_service_js_1.KpiStatisticCalculationService.calculateAllStatistics(periodType, valueDate, context);
142
+ }
143
+ async calculateRegionalStatistics(periodType, valueDate, context) {
144
+ const { domain, user, tx } = context.state;
145
+ // 지역별(scope02) 통계만 계산
146
+ const kpiStatistics = await (0, shell_1.getRepository)(kpi_statistic_js_1.KpiStatistic, tx)
147
+ .createQueryBuilder('stat')
148
+ .leftJoinAndSelect('stat.kpiOrgScope', 'orgScope')
149
+ .leftJoinAndSelect('stat.kpi', 'kpi')
150
+ .where('stat.domain = :domainId', { domainId: domain.id })
151
+ .andWhere('stat.periodType = :periodType', { periodType })
152
+ .andWhere('stat.valueDate = :valueDate', { valueDate })
153
+ .andWhere('orgScope.scope02 IS NOT NULL') // 지역 정보가 있는 것만
154
+ .getMany();
155
+ // 계산 결과가 없으면 새로 계산
156
+ if (kpiStatistics.length === 0) {
157
+ return await kpi_statistic_calculation_service_js_1.KpiStatisticCalculationService.calculateAllStatistics(periodType, valueDate, context);
158
+ }
159
+ // 기존 통계 재계산
160
+ const results = [];
161
+ for (const stat of kpiStatistics) {
162
+ const recalculated = await kpi_statistic_calculation_service_js_1.KpiStatisticCalculationService.calculateKpiStatistics(stat.kpiId, periodType, valueDate, stat.kpiOrgScope, context);
163
+ if (recalculated)
164
+ results.push(recalculated);
165
+ }
166
+ return results;
167
+ }
132
168
  };
133
169
  exports.KpiStatisticMutation = KpiStatisticMutation;
134
170
  tslib_1.__decorate([
@@ -192,6 +228,46 @@ tslib_1.__decorate([
192
228
  tslib_1.__metadata("design:paramtypes", [Array, Object]),
193
229
  tslib_1.__metadata("design:returntype", Promise)
194
230
  ], KpiStatisticMutation.prototype, "importKpiStatistics", null);
231
+ tslib_1.__decorate([
232
+ (0, type_graphql_1.Directive)('@transaction'),
233
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
234
+ (0, type_graphql_1.Mutation)(returns => [kpi_statistic_js_1.KpiStatistic], {
235
+ description: 'Calculate statistics for a specific KPI and period from KpiValue data'
236
+ }),
237
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('kpiId')),
238
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('periodType', type => kpi_js_1.KpiPeriodType)),
239
+ tslib_1.__param(2, (0, type_graphql_1.Arg)('valueDate')),
240
+ tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
241
+ tslib_1.__metadata("design:type", Function),
242
+ tslib_1.__metadata("design:paramtypes", [String, String, String, Object]),
243
+ tslib_1.__metadata("design:returntype", Promise)
244
+ ], KpiStatisticMutation.prototype, "calculateKpiStatistics", null);
245
+ tslib_1.__decorate([
246
+ (0, type_graphql_1.Directive)('@transaction'),
247
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
248
+ (0, type_graphql_1.Mutation)(returns => [kpi_statistic_js_1.KpiStatistic], {
249
+ description: 'Calculate statistics for all KPIs in a specific period from KpiValue data'
250
+ }),
251
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('periodType', type => kpi_js_1.KpiPeriodType)),
252
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('valueDate')),
253
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
254
+ tslib_1.__metadata("design:type", Function),
255
+ tslib_1.__metadata("design:paramtypes", [String, String, Object]),
256
+ tslib_1.__metadata("design:returntype", Promise)
257
+ ], KpiStatisticMutation.prototype, "calculateAllKpiStatistics", null);
258
+ tslib_1.__decorate([
259
+ (0, type_graphql_1.Directive)('@transaction'),
260
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
261
+ (0, type_graphql_1.Mutation)(returns => [kpi_statistic_js_1.KpiStatistic], {
262
+ description: 'Recalculate statistics for dashboard regions (scope02-based statistics)'
263
+ }),
264
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('periodType', type => kpi_js_1.KpiPeriodType, { defaultValue: kpi_js_1.KpiPeriodType.MONTH })),
265
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('valueDate')),
266
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
267
+ tslib_1.__metadata("design:type", Function),
268
+ tslib_1.__metadata("design:paramtypes", [String, String, Object]),
269
+ tslib_1.__metadata("design:returntype", Promise)
270
+ ], KpiStatisticMutation.prototype, "calculateRegionalStatistics", null);
195
271
  exports.KpiStatisticMutation = KpiStatisticMutation = tslib_1.__decorate([
196
272
  (0, type_graphql_1.Resolver)(kpi_statistic_js_1.KpiStatistic)
197
273
  ], KpiStatisticMutation);
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-statistic-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic-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 { KpiStatistic } from './kpi-statistic.js'\nimport { NewKpiStatistic, KpiStatisticPatch } from './kpi-statistic-type.js'\n\n@Resolver(KpiStatistic)\nexport class KpiStatisticMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => KpiStatistic, { description: 'To create new KpiStatistic' })\n async createKpiStatistic(\n @Arg('kpiStatistic') kpiStatistic: NewKpiStatistic,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic> {\n const { domain, user, tx } = context.state\n\n // 메타데이터 자동 설정\n const enrichedKpiStatistic = {\n ...kpiStatistic,\n metadata: {\n calculationMethod: kpiStatistic.metadata?.calculationMethod || 'manual',\n lastCalculated: new Date(),\n dataCount: kpiStatistic.count || 0\n }\n }\n\n const result = await getRepository(KpiStatistic, tx).save({\n ...enrichedKpiStatistic,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => KpiStatistic, { description: 'To modify KpiStatistic information' })\n async updateKpiStatistic(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiStatisticPatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(KpiStatistic, tx)\n const kpiStatistic = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n // 메타데이터 업데이트\n const updatedMetadata = {\n ...kpiStatistic.metadata,\n ...patch.metadata,\n lastCalculated: new Date()\n }\n\n const result = await repository.save({\n ...kpiStatistic,\n ...patch,\n metadata: updatedMetadata,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiStatistic], { description: \"To modify multiple KpiStatistics' information\" })\n async updateMultipleKpiStatistic(\n @Arg('patches', type => [KpiStatisticPatch]) patches: KpiStatisticPatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\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 kpiStatisticRepo = getRepository(KpiStatistic, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n // 메타데이터 자동 설정\n const enrichedRecord = {\n ...newRecord,\n metadata: {\n calculationMethod: newRecord.metadata?.calculationMethod || 'manual',\n lastCalculated: new Date(),\n dataCount: newRecord.count || 0\n }\n }\n\n const result = await kpiStatisticRepo.save({\n ...enrichedRecord,\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 kpiStatistic = await kpiStatisticRepo.findOneBy({ id: updateRecord.id })\n\n // 메타데이터 업데이트\n const updatedMetadata = {\n ...kpiStatistic.metadata,\n ...updateRecord.metadata,\n lastCalculated: new Date()\n }\n\n const result = await kpiStatisticRepo.save({\n ...kpiStatistic,\n ...updateRecord,\n metadata: updatedMetadata,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete KpiStatistic' })\n async deleteKpiStatistic(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiStatistic, tx).delete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple KpiStatistics' })\n async deleteKpiStatistics(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiStatistic, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import KpiStatistics' })\n async importKpiStatistics(\n @Arg('kpiStatistics', type => [KpiStatisticPatch]) kpiStatistics: KpiStatisticPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n for (const kpiStatistic of kpiStatistics) {\n // 메타데이터 자동 설정\n const enrichedKpiStatistic = {\n ...kpiStatistic,\n metadata: {\n calculationMethod: kpiStatistic.metadata?.calculationMethod || 'import',\n lastCalculated: new Date(),\n dataCount: kpiStatistic.count || 0\n }\n }\n\n await getRepository(KpiStatistic, tx).save({\n ...enrichedKpiStatistic,\n domain,\n creator: user,\n updater: user\n })\n }\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-statistic-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic-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 type ResolverContext from '@things-factory/auth-base'\n\nimport { KpiStatistic } from './kpi-statistic.js'\nimport { NewKpiStatistic, KpiStatisticPatch } from './kpi-statistic-type.js'\nimport { KpiStatisticCalculationService } from './kpi-statistic-calculation.service.js'\nimport { KpiPeriodType } from '../kpi/kpi.js'\n\n@Resolver(KpiStatistic)\nexport class KpiStatisticMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => KpiStatistic, { description: 'To create new KpiStatistic' })\n async createKpiStatistic(\n @Arg('kpiStatistic') kpiStatistic: NewKpiStatistic,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic> {\n const { domain, user, tx } = context.state\n\n // 메타데이터 자동 설정\n const enrichedKpiStatistic = {\n ...kpiStatistic,\n metadata: {\n calculationMethod: kpiStatistic.metadata?.calculationMethod || 'manual',\n lastCalculated: new Date(),\n dataCount: kpiStatistic.count || 0\n }\n }\n\n const result = await getRepository(KpiStatistic, tx).save({\n ...enrichedKpiStatistic,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => KpiStatistic, { description: 'To modify KpiStatistic information' })\n async updateKpiStatistic(\n @Arg('id') id: string,\n @Arg('patch') patch: KpiStatisticPatch,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(KpiStatistic, tx)\n const kpiStatistic = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n // 메타데이터 업데이트\n const updatedMetadata = {\n ...kpiStatistic.metadata,\n ...patch.metadata,\n lastCalculated: new Date()\n }\n\n const result = await repository.save({\n ...kpiStatistic,\n ...patch,\n metadata: updatedMetadata,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiStatistic], { description: \"To modify multiple KpiStatistics' information\" })\n async updateMultipleKpiStatistic(\n @Arg('patches', type => [KpiStatisticPatch]) patches: KpiStatisticPatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\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 kpiStatisticRepo = getRepository(KpiStatistic, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n // 메타데이터 자동 설정\n const enrichedRecord = {\n ...newRecord,\n metadata: {\n calculationMethod: newRecord.metadata?.calculationMethod || 'manual',\n lastCalculated: new Date(),\n dataCount: newRecord.count || 0\n }\n }\n\n const result = await kpiStatisticRepo.save({\n ...enrichedRecord,\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 kpiStatistic = await kpiStatisticRepo.findOneBy({ id: updateRecord.id })\n\n // 메타데이터 업데이트\n const updatedMetadata = {\n ...kpiStatistic.metadata,\n ...updateRecord.metadata,\n lastCalculated: new Date()\n }\n\n const result = await kpiStatisticRepo.save({\n ...kpiStatistic,\n ...updateRecord,\n metadata: updatedMetadata,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete KpiStatistic' })\n async deleteKpiStatistic(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiStatistic, tx).delete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple KpiStatistics' })\n async deleteKpiStatistics(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(KpiStatistic, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import KpiStatistics' })\n async importKpiStatistics(\n @Arg('kpiStatistics', type => [KpiStatisticPatch]) kpiStatistics: KpiStatisticPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n for (const kpiStatistic of kpiStatistics) {\n // 메타데이터 자동 설정\n const enrichedKpiStatistic = {\n ...kpiStatistic,\n metadata: {\n calculationMethod: kpiStatistic.metadata?.calculationMethod || 'import',\n lastCalculated: new Date(),\n dataCount: kpiStatistic.count || 0\n }\n }\n\n await getRepository(KpiStatistic, tx).save({\n ...enrichedKpiStatistic,\n domain,\n creator: user,\n updater: user\n })\n }\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiStatistic], { \n description: 'Calculate statistics for a specific KPI and period from KpiValue data' \n })\n async calculateKpiStatistics(\n @Arg('kpiId') kpiId: string,\n @Arg('periodType', type => KpiPeriodType) periodType: KpiPeriodType,\n @Arg('valueDate') valueDate: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\n const overallStats = await KpiStatisticCalculationService.calculateKpiStatistics(\n kpiId,\n periodType,\n valueDate,\n null, // 전체 통계\n context\n )\n\n const scopedStats = await KpiStatisticCalculationService.calculateScopedStatistics(\n kpiId,\n periodType,\n valueDate,\n context\n )\n\n return [overallStats, ...scopedStats].filter(Boolean)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiStatistic], { \n description: 'Calculate statistics for all KPIs in a specific period from KpiValue data' \n })\n async calculateAllKpiStatistics(\n @Arg('periodType', type => KpiPeriodType) periodType: KpiPeriodType,\n @Arg('valueDate') valueDate: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\n return await KpiStatisticCalculationService.calculateAllStatistics(\n periodType,\n valueDate,\n context\n )\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiStatistic], { \n description: 'Recalculate statistics for dashboard regions (scope02-based statistics)' \n })\n async calculateRegionalStatistics(\n @Arg('periodType', type => KpiPeriodType, { defaultValue: KpiPeriodType.MONTH }) periodType: KpiPeriodType,\n @Arg('valueDate') valueDate: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\n const { domain, user, tx } = context.state\n \n // 지역별(scope02) 통계만 계산\n const kpiStatistics = await getRepository(KpiStatistic, tx)\n .createQueryBuilder('stat')\n .leftJoinAndSelect('stat.kpiOrgScope', 'orgScope')\n .leftJoinAndSelect('stat.kpi', 'kpi')\n .where('stat.domain = :domainId', { domainId: domain.id })\n .andWhere('stat.periodType = :periodType', { periodType })\n .andWhere('stat.valueDate = :valueDate', { valueDate })\n .andWhere('orgScope.scope02 IS NOT NULL') // 지역 정보가 있는 것만\n .getMany()\n\n // 계산 결과가 없으면 새로 계산\n if (kpiStatistics.length === 0) {\n return await KpiStatisticCalculationService.calculateAllStatistics(\n periodType,\n valueDate,\n context\n )\n }\n\n // 기존 통계 재계산\n const results: KpiStatistic[] = []\n for (const stat of kpiStatistics) {\n const recalculated = await KpiStatisticCalculationService.calculateKpiStatistics(\n stat.kpiId,\n periodType,\n valueDate,\n stat.kpiOrgScope,\n context\n )\n if (recalculated) results.push(recalculated)\n }\n\n return results\n }\n}\n"]}
@@ -2,7 +2,8 @@ import { Domain, ListParam } from '@things-factory/shell';
2
2
  import { User } from '@things-factory/auth-base';
3
3
  import { KpiStatistic } from './kpi-statistic.js';
4
4
  import { KpiStatisticList } from './kpi-statistic-type.js';
5
- import { Kpi } from '../kpi/kpi.js';
5
+ import { Kpi, KpiPeriodType } from '../kpi/kpi.js';
6
+ import { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope.js';
6
7
  export declare class KpiStatisticQuery {
7
8
  kpiStatistic(id: string, context: ResolverContext): Promise<KpiStatistic>;
8
9
  kpiStatistics(params: ListParam, context: ResolverContext): Promise<KpiStatisticList>;
@@ -10,4 +11,7 @@ export declare class KpiStatisticQuery {
10
11
  domain(kpiStatistic: KpiStatistic): Promise<Domain>;
11
12
  updater(kpiStatistic: KpiStatistic): Promise<User>;
12
13
  creator(kpiStatistic: KpiStatistic): Promise<User>;
14
+ kpiOrgScope(kpiStatistic: KpiStatistic): Promise<KpiOrgScope>;
15
+ regionalKpiStatistics(valueDate: string, periodType: KpiPeriodType, regions: string[] | undefined, context: ResolverContext): Promise<KpiStatistic[]>;
16
+ dashboardRegionalStatistics(valueDate: string, periodType: KpiPeriodType, context: ResolverContext): Promise<KpiStatistic[]>;
13
17
  }
@@ -8,6 +8,7 @@ const auth_base_1 = require("@things-factory/auth-base");
8
8
  const kpi_statistic_js_1 = require("./kpi-statistic.js");
9
9
  const kpi_statistic_type_js_1 = require("./kpi-statistic-type.js");
10
10
  const kpi_js_1 = require("../kpi/kpi.js");
11
+ const kpi_org_scope_js_1 = require("../kpi-org-scope/kpi-org-scope.js");
11
12
  let KpiStatisticQuery = class KpiStatisticQuery {
12
13
  async kpiStatistic(id, context) {
13
14
  const { domain } = context.state;
@@ -21,7 +22,17 @@ let KpiStatisticQuery = class KpiStatisticQuery {
21
22
  domain,
22
23
  params,
23
24
  repository: await (0, shell_1.getRepository)(kpi_statistic_js_1.KpiStatistic),
24
- searchables: ['kpi', 'period']
25
+ searchables: ['kpi', 'valueDate'],
26
+ filtersMap: {
27
+ kpi: { columnName: 'id', relationColumn: 'kpi' },
28
+ kpiOrgScope: { columnName: 'id', relationColumn: 'kpiOrgScope' },
29
+ periodType: { columnName: 'periodType' },
30
+ valueDate: { columnName: 'valueDate' },
31
+ scope02: {
32
+ columnName: 'scope02',
33
+ relationColumn: 'kpiOrgScope'
34
+ }
35
+ }
25
36
  });
26
37
  const [items, total] = await queryBuilder.getManyAndCount();
27
38
  return { items, total };
@@ -38,6 +49,54 @@ let KpiStatisticQuery = class KpiStatisticQuery {
38
49
  async creator(kpiStatistic) {
39
50
  return kpiStatistic.creatorId && (await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: kpiStatistic.creatorId }));
40
51
  }
52
+ async kpiOrgScope(kpiStatistic) {
53
+ return kpiStatistic.kpiOrgScopeId && (await (0, shell_1.getRepository)(kpi_org_scope_js_1.KpiOrgScope).findOneBy({ id: kpiStatistic.kpiOrgScopeId }));
54
+ }
55
+ async regionalKpiStatistics(valueDate, periodType, regions, context) {
56
+ const { domain } = context.state;
57
+ const queryBuilder = (0, shell_1.getRepository)(kpi_statistic_js_1.KpiStatistic)
58
+ .createQueryBuilder('stat')
59
+ .leftJoinAndSelect('stat.kpi', 'kpi')
60
+ .leftJoinAndSelect('stat.kpiOrgScope', 'orgScope')
61
+ .where('stat.domain = :domainId', { domainId: domain.id })
62
+ .andWhere('stat.periodType = :periodType', { periodType })
63
+ .andWhere('stat.valueDate = :valueDate', { valueDate })
64
+ .andWhere('orgScope.scope02 IS NOT NULL'); // 지역 정보가 있는 것만
65
+ if (regions && regions.length > 0) {
66
+ queryBuilder.andWhere('orgScope.scope02 IN (:...regions)', { regions });
67
+ }
68
+ queryBuilder.orderBy('orgScope.scope02', 'ASC')
69
+ .addOrderBy('kpi.name', 'ASC');
70
+ return await queryBuilder.getMany();
71
+ }
72
+ async dashboardRegionalStatistics(valueDate, periodType, context) {
73
+ const { domain } = context.state;
74
+ // 지역별로 평균을 내서 하나의 통계로 합침
75
+ const query = `
76
+ SELECT
77
+ 'regional-aggregate-' || orgScope.scope02 as id,
78
+ kpi.id as kpiId,
79
+ kpi.name as kpiName,
80
+ orgScope.scope02 as region,
81
+ AVG(stat.mean) as avgMean,
82
+ AVG(stat.median) as avgMedian,
83
+ MIN(stat.minimum) as overallMin,
84
+ MAX(stat.maximum) as overallMax,
85
+ AVG(stat.standardDeviation) as avgStdDev,
86
+ SUM(stat.count) as totalCount,
87
+ COUNT(*) as orgCount
88
+ FROM kpi_statistic stat
89
+ LEFT JOIN kpi ON stat.kpiId = kpi.id
90
+ LEFT JOIN kpi_org_scope orgScope ON stat.kpiOrgScopeId = orgScope.id
91
+ WHERE stat.domainId = ?
92
+ AND stat.periodType = ?
93
+ AND stat.valueDate = ?
94
+ AND orgScope.scope02 IS NOT NULL
95
+ GROUP BY kpi.id, orgScope.scope02
96
+ ORDER BY orgScope.scope02, kpi.name
97
+ `;
98
+ return await (0, shell_1.getRepository)(kpi_statistic_js_1.KpiStatistic).query(query, [domain.id, periodType, valueDate]);
99
+ }
41
100
  };
42
101
  exports.KpiStatisticQuery = KpiStatisticQuery;
43
102
  tslib_1.__decorate([
@@ -86,6 +145,38 @@ tslib_1.__decorate([
86
145
  tslib_1.__metadata("design:paramtypes", [kpi_statistic_js_1.KpiStatistic]),
87
146
  tslib_1.__metadata("design:returntype", Promise)
88
147
  ], KpiStatisticQuery.prototype, "creator", null);
148
+ tslib_1.__decorate([
149
+ (0, type_graphql_1.FieldResolver)(type => kpi_org_scope_js_1.KpiOrgScope),
150
+ tslib_1.__param(0, (0, type_graphql_1.Root)()),
151
+ tslib_1.__metadata("design:type", Function),
152
+ tslib_1.__metadata("design:paramtypes", [kpi_statistic_js_1.KpiStatistic]),
153
+ tslib_1.__metadata("design:returntype", Promise)
154
+ ], KpiStatisticQuery.prototype, "kpiOrgScope", null);
155
+ tslib_1.__decorate([
156
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
157
+ (0, type_graphql_1.Query)(returns => [kpi_statistic_js_1.KpiStatistic], {
158
+ description: 'Get regional statistics for dashboard map visualization'
159
+ }),
160
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('valueDate')),
161
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('periodType', type => kpi_js_1.KpiPeriodType, { defaultValue: kpi_js_1.KpiPeriodType.MONTH })),
162
+ tslib_1.__param(2, (0, type_graphql_1.Arg)('regions', type => [String], { nullable: true })),
163
+ tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
164
+ tslib_1.__metadata("design:type", Function),
165
+ tslib_1.__metadata("design:paramtypes", [String, String, Array, Object]),
166
+ tslib_1.__metadata("design:returntype", Promise)
167
+ ], KpiStatisticQuery.prototype, "regionalKpiStatistics", null);
168
+ tslib_1.__decorate([
169
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
170
+ (0, type_graphql_1.Query)(returns => [kpi_statistic_js_1.KpiStatistic], {
171
+ description: 'Get aggregated statistics by scope02 (regional level) for dashboard'
172
+ }),
173
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('valueDate')),
174
+ tslib_1.__param(1, (0, type_graphql_1.Arg)('periodType', type => kpi_js_1.KpiPeriodType, { defaultValue: kpi_js_1.KpiPeriodType.MONTH })),
175
+ tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
176
+ tslib_1.__metadata("design:type", Function),
177
+ tslib_1.__metadata("design:paramtypes", [String, String, Object]),
178
+ tslib_1.__metadata("design:returntype", Promise)
179
+ ], KpiStatisticQuery.prototype, "dashboardRegionalStatistics", null);
89
180
  exports.KpiStatisticQuery = KpiStatisticQuery = tslib_1.__decorate([
90
181
  (0, type_graphql_1.Resolver)(kpi_statistic_js_1.KpiStatistic)
91
182
  ], KpiStatisticQuery);
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-statistic-query.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { KpiStatistic } from './kpi-statistic.js'\nimport { KpiStatisticList } from './kpi-statistic-type.js'\nimport { Kpi } from '../kpi/kpi.js'\n\n@Resolver(KpiStatistic)\nexport class KpiStatisticQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiStatistic!, { nullable: true, description: 'To fetch a KpiStatistic' })\n async kpiStatistic(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<KpiStatistic> {\n const { domain } = context.state\n\n return await getRepository(KpiStatistic).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Query(returns => KpiStatisticList, { description: 'To fetch multiple KpiStatistics' })\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n async kpiStatistics(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatisticList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(KpiStatistic),\n searchables: ['kpi', 'period']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => Kpi)\n async kpi(@Root() kpiStatistic: KpiStatistic): Promise<Kpi> {\n return kpiStatistic.kpiId && (await getRepository(Kpi).findOneBy({ id: kpiStatistic.kpiId }))\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpiStatistic: KpiStatistic): Promise<Domain> {\n return kpiStatistic.domainId && (await getRepository(Domain).findOneBy({ id: kpiStatistic.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpiStatistic: KpiStatistic): Promise<User> {\n return kpiStatistic.updaterId && (await getRepository(User).findOneBy({ id: kpiStatistic.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpiStatistic: KpiStatistic): Promise<User> {\n return kpiStatistic.creatorId && (await getRepository(User).findOneBy({ id: kpiStatistic.creatorId }))\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-statistic-query.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport type ResolverContext from '@things-factory/auth-base'\nimport { KpiStatistic } from './kpi-statistic.js'\nimport { KpiStatisticList } from './kpi-statistic-type.js'\nimport { Kpi, KpiPeriodType } from '../kpi/kpi.js'\nimport { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope.js'\n\n@Resolver(KpiStatistic)\nexport class KpiStatisticQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiStatistic!, { nullable: true, description: 'To fetch a KpiStatistic' })\n async kpiStatistic(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<KpiStatistic> {\n const { domain } = context.state\n\n return await getRepository(KpiStatistic).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Query(returns => KpiStatisticList, { description: 'To fetch multiple KpiStatistics' })\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n async kpiStatistics(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatisticList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(KpiStatistic),\n searchables: ['kpi', 'valueDate'],\n filtersMap: {\n kpi: { columnName: 'id', relationColumn: 'kpi' },\n kpiOrgScope: { columnName: 'id', relationColumn: 'kpiOrgScope' },\n periodType: { columnName: 'periodType' },\n valueDate: { columnName: 'valueDate' },\n scope02: { \n columnName: 'scope02', \n relationColumn: 'kpiOrgScope'\n }\n }\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => Kpi)\n async kpi(@Root() kpiStatistic: KpiStatistic): Promise<Kpi> {\n return kpiStatistic.kpiId && (await getRepository(Kpi).findOneBy({ id: kpiStatistic.kpiId }))\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpiStatistic: KpiStatistic): Promise<Domain> {\n return kpiStatistic.domainId && (await getRepository(Domain).findOneBy({ id: kpiStatistic.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpiStatistic: KpiStatistic): Promise<User> {\n return kpiStatistic.updaterId && (await getRepository(User).findOneBy({ id: kpiStatistic.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpiStatistic: KpiStatistic): Promise<User> {\n return kpiStatistic.creatorId && (await getRepository(User).findOneBy({ id: kpiStatistic.creatorId }))\n }\n\n @FieldResolver(type => KpiOrgScope)\n async kpiOrgScope(@Root() kpiStatistic: KpiStatistic): Promise<KpiOrgScope> {\n return kpiStatistic.kpiOrgScopeId && (await getRepository(KpiOrgScope).findOneBy({ id: kpiStatistic.kpiOrgScopeId }))\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [KpiStatistic], { \n description: 'Get regional statistics for dashboard map visualization' \n })\n async regionalKpiStatistics(\n @Arg('valueDate') valueDate: string,\n @Arg('periodType', type => KpiPeriodType, { defaultValue: KpiPeriodType.MONTH }) periodType: KpiPeriodType,\n @Arg('regions', type => [String], { nullable: true }) regions: string[] | undefined,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\n const { domain } = context.state\n \n const queryBuilder = getRepository(KpiStatistic)\n .createQueryBuilder('stat')\n .leftJoinAndSelect('stat.kpi', 'kpi')\n .leftJoinAndSelect('stat.kpiOrgScope', 'orgScope')\n .where('stat.domain = :domainId', { domainId: domain.id })\n .andWhere('stat.periodType = :periodType', { periodType })\n .andWhere('stat.valueDate = :valueDate', { valueDate })\n .andWhere('orgScope.scope02 IS NOT NULL') // 지역 정보가 있는 것만\n \n if (regions && regions.length > 0) {\n queryBuilder.andWhere('orgScope.scope02 IN (:...regions)', { regions })\n }\n \n queryBuilder.orderBy('orgScope.scope02', 'ASC')\n .addOrderBy('kpi.name', 'ASC')\n \n return await queryBuilder.getMany()\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [KpiStatistic], { \n description: 'Get aggregated statistics by scope02 (regional level) for dashboard' \n })\n async dashboardRegionalStatistics(\n @Arg('valueDate') valueDate: string,\n @Arg('periodType', type => KpiPeriodType, { defaultValue: KpiPeriodType.MONTH }) periodType: KpiPeriodType,\n @Ctx() context: ResolverContext\n ): Promise<KpiStatistic[]> {\n const { domain } = context.state\n \n // 지역별로 평균을 내서 하나의 통계로 합침\n const query = `\n SELECT \n 'regional-aggregate-' || orgScope.scope02 as id,\n kpi.id as kpiId,\n kpi.name as kpiName,\n orgScope.scope02 as region,\n AVG(stat.mean) as avgMean,\n AVG(stat.median) as avgMedian,\n MIN(stat.minimum) as overallMin,\n MAX(stat.maximum) as overallMax,\n AVG(stat.standardDeviation) as avgStdDev,\n SUM(stat.count) as totalCount,\n COUNT(*) as orgCount\n FROM kpi_statistic stat\n LEFT JOIN kpi ON stat.kpiId = kpi.id\n LEFT JOIN kpi_org_scope orgScope ON stat.kpiOrgScopeId = orgScope.id\n WHERE stat.domainId = ?\n AND stat.periodType = ?\n AND stat.valueDate = ?\n AND orgScope.scope02 IS NOT NULL\n GROUP BY kpi.id, orgScope.scope02\n ORDER BY orgScope.scope02, kpi.name\n `\n \n return await getRepository(KpiStatistic).query(query, [domain.id, periodType, valueDate])\n }\n}\n"]}
@@ -1,12 +1,15 @@
1
1
  import { Domain } from '@things-factory/shell';
2
2
  import { User } from '@things-factory/auth-base';
3
3
  import { Kpi, KpiPeriodType } from '../kpi/kpi';
4
+ import { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope';
4
5
  export declare class KpiStatistic {
5
6
  readonly id: string;
6
7
  kpi: Kpi;
7
8
  kpiId: string;
8
9
  valueDate: string;
9
10
  periodType: KpiPeriodType;
11
+ kpiOrgScope?: KpiOrgScope;
12
+ kpiOrgScopeId?: string;
10
13
  scope?: string;
11
14
  count?: number;
12
15
  sum?: number;
@@ -7,6 +7,7 @@ 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 kpi_1 = require("../kpi/kpi");
10
+ const kpi_org_scope_1 = require("../kpi-org-scope/kpi-org-scope");
10
11
  let KpiStatistic = class KpiStatistic {
11
12
  };
12
13
  exports.KpiStatistic = KpiStatistic;
@@ -39,9 +40,24 @@ tslib_1.__decorate([
39
40
  (0, type_graphql_1.Field)(type => kpi_1.KpiPeriodType, { description: 'Aggregation period type for this statistic.' }),
40
41
  tslib_1.__metadata("design:type", String)
41
42
  ], KpiStatistic.prototype, "periodType", void 0);
43
+ tslib_1.__decorate([
44
+ (0, typeorm_1.ManyToOne)(() => kpi_org_scope_1.KpiOrgScope, { nullable: true }),
45
+ (0, type_graphql_1.Field)(type => kpi_org_scope_1.KpiOrgScope, {
46
+ nullable: true,
47
+ description: 'Organization scope for scoped statistics. Null for overall statistics.'
48
+ }),
49
+ tslib_1.__metadata("design:type", kpi_org_scope_1.KpiOrgScope)
50
+ ], KpiStatistic.prototype, "kpiOrgScope", void 0);
51
+ tslib_1.__decorate([
52
+ (0, typeorm_1.RelationId)((kpiStatistic) => kpiStatistic.kpiOrgScope),
53
+ tslib_1.__metadata("design:type", String)
54
+ ], KpiStatistic.prototype, "kpiOrgScopeId", void 0);
42
55
  tslib_1.__decorate([
43
56
  (0, typeorm_1.Column)({ nullable: true }),
44
- (0, type_graphql_1.Field)({ nullable: true, description: 'Statistical scope - null for overall statistics, category value for scoped statistics (e.g., "서울", "부장", "대규모")' }),
57
+ (0, type_graphql_1.Field)({
58
+ nullable: true,
59
+ description: 'Legacy scope field - use kpiOrgScope instead. Statistical scope - null for overall statistics, category value for scoped statistics (e.g., "서울", "부장", "대규모")'
60
+ }),
45
61
  tslib_1.__metadata("design:type", String)
46
62
  ], KpiStatistic.prototype, "scope", void 0);
47
63
  tslib_1.__decorate([
@@ -176,6 +192,12 @@ exports.KpiStatistic = KpiStatistic = tslib_1.__decorate([
176
192
  kpiStatistic.periodType
177
193
  ]),
178
194
  (0, typeorm_1.Index)('ix_kpi_statistic_scope', (kpiStatistic) => [
195
+ kpiStatistic.domain,
196
+ kpiStatistic.kpi,
197
+ kpiStatistic.kpiOrgScope,
198
+ kpiStatistic.valueDate
199
+ ]),
200
+ (0, typeorm_1.Index)('ix_kpi_statistic_legacy_scope', (kpiStatistic) => [
179
201
  kpiStatistic.domain,
180
202
  kpiStatistic.kpi,
181
203
  kpiStatistic.scope,
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-statistic.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Kpi, KpiPeriodType } from '../kpi/kpi'\n\n@Entity()\n@Index('ix_kpi_statistic_target', (kpiStatistic: KpiStatistic) => [kpiStatistic.domain, kpiStatistic.kpi])\n@Index('ix_kpi_statistic_period', (kpiStatistic: KpiStatistic) => [\n kpiStatistic.domain,\n kpiStatistic.valueDate,\n kpiStatistic.periodType\n])\n@Index('ix_kpi_statistic_scope', (kpiStatistic: KpiStatistic) => [\n kpiStatistic.domain,\n kpiStatistic.kpi,\n kpiStatistic.scope,\n kpiStatistic.valueDate\n])\n@ObjectType({\n description:\n 'KPI Statistics Entity - Stores comprehensive statistical information for KPIs and Categories including central tendency measures (mean, median), dispersion metrics (standard deviation, variance), range indicators (min, max), and percentile distributions (25th, 75th percentiles, IQR). Supports both KPI and Category targets with flexible period-based aggregation (daily, weekly, monthly, yearly). Includes extensible JSON fields for additional metrics and metadata for calculation tracking.'\n})\nexport class KpiStatistic {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n // === 대상 정보 ===\n\n @ManyToOne(() => Kpi)\n @Field(type => Kpi, {\n nullable: true,\n description: 'Reference to the KPI definition for which this value is calculated.'\n })\n kpi: Kpi\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.kpi)\n kpiId: string\n\n // === 통계 기간 ===\n @Column()\n @Field({\n description:\n 'Date or period for which this statistic is calculated (e.g., day: YYYY-MM-DD, month: YYYY-MM, quarter: YYYY-Qn, range: YYYY-MM-DD~YYYY-MM-DD).'\n })\n valueDate: string\n\n @Column({ default: 'DAY' })\n @Field(type => KpiPeriodType, { description: 'Aggregation period type for this statistic.' })\n periodType: KpiPeriodType\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Statistical scope - null for overall statistics, category value for scoped statistics (e.g., \"서울\", \"부장\", \"대규모\")' })\n scope?: string\n\n // === 핵심 통계 필드 (14개) ===\n\n // 1. 기본 정보 (3개)\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Number of data points used in calculation' })\n count?: number // 데이터 개수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Sum of all values in the dataset' })\n sum?: number // 합계\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Range of values (maximum - minimum)' })\n range?: number // 범위\n\n // 2. 중심 경향 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Arithmetic mean of all values' })\n mean?: number // 평균\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Middle value when data is sorted (50th percentile)' })\n median?: number // 중앙값\n\n // 3. 범위 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Minimum value in the dataset' })\n minimum?: number // 최소값\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Maximum value in the dataset' })\n maximum?: number // 최대값\n\n // 4. 분산 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Standard deviation - measure of data dispersion' })\n standardDeviation?: number // 표준편차\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Variance - square of standard deviation' })\n variance?: number // 분산\n\n // 5. 분위수 (5개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: '25th percentile - 25% of data is below this value' })\n percentile25?: number // 25분위수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: '75th percentile - 75% of data is below this value' })\n percentile75?: number // 75분위수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Interquartile range (75th percentile - 25th percentile)' })\n iqr?: number // 사분위수 범위\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Lower fence for outlier detection (Q1 - 1.5 * IQR)' })\n lowerFence?: number // 하위 울타리\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Upper fence for outlier detection (Q3 + 1.5 * IQR)' })\n upperFence?: number // 상위 울타리\n\n // === 확장 가능한 필드 (JSON) ===\n @Column('simple-json', { nullable: true })\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Additional statistical metrics stored as key-value pairs'\n })\n additionalStatistics: {\n [metricName: string]: number\n }\n\n // === 메타데이터 (JSON) ===\n @Column('simple-json', { nullable: true })\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Calculation metadata including method, timestamp, and data quality information'\n })\n metadata: { [key: string]: any }\n\n // === 표준 필드들 ===\n @ManyToOne(type => Domain)\n @Field({ nullable: true, description: 'Domain this statistic belongs to' })\n domain?: Domain\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.domain)\n domainId?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this statistic was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this statistic was last updated' })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who created this statistic' })\n creator?: User\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who last updated this statistic' })\n updater?: User\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.updater)\n updaterId?: string\n}\n"]}
1
+ {"version":3,"file":"kpi-statistic.js","sourceRoot":"","sources":["../../../server/service/kpi-statistic/kpi-statistic.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Kpi, KpiPeriodType } from '../kpi/kpi'\nimport { KpiOrgScope } from '../kpi-org-scope/kpi-org-scope'\n\n@Entity()\n@Index('ix_kpi_statistic_target', (kpiStatistic: KpiStatistic) => [kpiStatistic.domain, kpiStatistic.kpi])\n@Index('ix_kpi_statistic_period', (kpiStatistic: KpiStatistic) => [\n kpiStatistic.domain,\n kpiStatistic.valueDate,\n kpiStatistic.periodType\n])\n@Index('ix_kpi_statistic_scope', (kpiStatistic: KpiStatistic) => [\n kpiStatistic.domain,\n kpiStatistic.kpi,\n kpiStatistic.kpiOrgScope,\n kpiStatistic.valueDate\n])\n@Index('ix_kpi_statistic_legacy_scope', (kpiStatistic: KpiStatistic) => [\n kpiStatistic.domain,\n kpiStatistic.kpi,\n kpiStatistic.scope,\n kpiStatistic.valueDate\n])\n@ObjectType({\n description:\n 'KPI Statistics Entity - Stores comprehensive statistical information for KPIs and Categories including central tendency measures (mean, median), dispersion metrics (standard deviation, variance), range indicators (min, max), and percentile distributions (25th, 75th percentiles, IQR). Supports both KPI and Category targets with flexible period-based aggregation (daily, weekly, monthly, yearly). Includes extensible JSON fields for additional metrics and metadata for calculation tracking.'\n})\nexport class KpiStatistic {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n // === 대상 정보 ===\n\n @ManyToOne(() => Kpi)\n @Field(type => Kpi, {\n nullable: true,\n description: 'Reference to the KPI definition for which this value is calculated.'\n })\n kpi: Kpi\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.kpi)\n kpiId: string\n\n // === 통계 기간 ===\n @Column()\n @Field({\n description:\n 'Date or period for which this statistic is calculated (e.g., day: YYYY-MM-DD, month: YYYY-MM, quarter: YYYY-Qn, range: YYYY-MM-DD~YYYY-MM-DD).'\n })\n valueDate: string\n\n @Column({ default: 'DAY' })\n @Field(type => KpiPeriodType, { description: 'Aggregation period type for this statistic.' })\n periodType: KpiPeriodType\n\n // === 스코프 정보 ===\n \n @ManyToOne(() => KpiOrgScope, { nullable: true })\n @Field(type => KpiOrgScope, {\n nullable: true,\n description: 'Organization scope for scoped statistics. Null for overall statistics.'\n })\n kpiOrgScope?: KpiOrgScope\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.kpiOrgScope)\n kpiOrgScopeId?: string\n\n @Column({ nullable: true })\n @Field({ \n nullable: true, \n description: 'Legacy scope field - use kpiOrgScope instead. Statistical scope - null for overall statistics, category value for scoped statistics (e.g., \"서울\", \"부장\", \"대규모\")'\n })\n scope?: string\n\n // === 핵심 통계 필드 (14개) ===\n\n // 1. 기본 정보 (3개)\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Number of data points used in calculation' })\n count?: number // 데이터 개수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Sum of all values in the dataset' })\n sum?: number // 합계\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Range of values (maximum - minimum)' })\n range?: number // 범위\n\n // 2. 중심 경향 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Arithmetic mean of all values' })\n mean?: number // 평균\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Middle value when data is sorted (50th percentile)' })\n median?: number // 중앙값\n\n // 3. 범위 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Minimum value in the dataset' })\n minimum?: number // 최소값\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Maximum value in the dataset' })\n maximum?: number // 최대값\n\n // 4. 분산 (2개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Standard deviation - measure of data dispersion' })\n standardDeviation?: number // 표준편차\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Variance - square of standard deviation' })\n variance?: number // 분산\n\n // 5. 분위수 (5개)\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: '25th percentile - 25% of data is below this value' })\n percentile25?: number // 25분위수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: '75th percentile - 75% of data is below this value' })\n percentile75?: number // 75분위수\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Interquartile range (75th percentile - 25th percentile)' })\n iqr?: number // 사분위수 범위\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Lower fence for outlier detection (Q1 - 1.5 * IQR)' })\n lowerFence?: number // 하위 울타리\n\n @Column({ type: 'float', nullable: true })\n @Field({ nullable: true, description: 'Upper fence for outlier detection (Q3 + 1.5 * IQR)' })\n upperFence?: number // 상위 울타리\n\n // === 확장 가능한 필드 (JSON) ===\n @Column('simple-json', { nullable: true })\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Additional statistical metrics stored as key-value pairs'\n })\n additionalStatistics: {\n [metricName: string]: number\n }\n\n // === 메타데이터 (JSON) ===\n @Column('simple-json', { nullable: true })\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Calculation metadata including method, timestamp, and data quality information'\n })\n metadata: { [key: string]: any }\n\n // === 표준 필드들 ===\n @ManyToOne(type => Domain)\n @Field({ nullable: true, description: 'Domain this statistic belongs to' })\n domain?: Domain\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.domain)\n domainId?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this statistic was created' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Timestamp when this statistic was last updated' })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who created this statistic' })\n creator?: User\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'User who last updated this statistic' })\n updater?: User\n\n @RelationId((kpiStatistic: KpiStatistic) => kpiStatistic.updater)\n updaterId?: string\n}\n"]}