@dssp/dkpi 1.0.0-alpha.56 → 1.0.0-alpha.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/images/project-image.png +0 -0
- package/dist-client/components/kpi-boxplot-chart.js +12 -48
- package/dist-client/components/kpi-boxplot-chart.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +6 -6
- package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
- package/dist-client/pages/sv-project-detail.d.ts +4 -0
- package/dist-client/pages/sv-project-detail.js +218 -0
- package/dist-client/pages/sv-project-detail.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/menu-tools.d.ts +10 -1
- package/dist-client/viewparts/menu-tools.js +36 -7
- package/dist-client/viewparts/menu-tools.js.map +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +38 -0
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +311 -2
- package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-query.d.ts +1 -0
- package/dist-server/service/kpi-value/kpi-value-query.js +22 -0
- package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/schema.graphql +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-metric-value-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { In } from 'typeorm'\nimport { getRepository } from '@things-factory/shell'\nimport { Float } from 'type-graphql'\nimport { KpiPeriodType, KpiMetric, KpiMetricValue, KpiMetricValuePatch } from '@things-factory/kpi'\nimport { Attachment, NewAttachment, createAttachment } from '@things-factory/attachment-base'\nimport { Project, ProjectState } from '@dssp/project'\nimport moment from 'moment-timezone'\n\n// import { ScalarObject } from '@things-factory/shell'\n// import { getDefaultValueDate } from '@things-factory/kpi/utils/value-date-util'\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueMutation {\n /* 프로젝트 수행과정 중에 (시간, 비용, 발생 건수 등) 누적된 값을 반영하여 KPI Metric Value 값을 수정 - 예를 들면, 총 설계 변경 건수, 총 건설 폐기물 발생량, 공사비, 공사기간, 재해 건수 등 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple cumulative KpiMetricValues' value\" })\n async updateKpiMetricValuesCumulative(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n const results = []\n for (const patch of patches) {\n const metric = await metricRepo.findOne({ where: { id: patch.metricId } })\n if (!metric) {\n throw new Error(`Metric not found: ${patch.metricId}`)\n }\n const result = await metricValueRepo.save({\n domain,\n ...patch,\n metric,\n updater: user\n } as any)\n\n results.push(result)\n }\n\n return results\n }\n\n /* 전문 감리사에 의해서 평가된 별점을 반영하여 KPI Metric Value 값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple assessment KpiMetricValues' value\" })\n async updateKpiMetricValuesAssessment(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n const results = []\n for (const patch of patches) {\n const metric = await metricRepo.findOne({ where: { id: patch.metricId } })\n if (!metric) {\n throw new Error(`Metric not found: ${patch.metricId}`)\n }\n const result = await metricValueRepo.save({\n domain,\n ...patch,\n metric,\n updater: user\n } as any)\n\n results.push(result)\n }\n\n return results\n }\n\n /* 전문 감리사에 의 감리 최종 평가서의 긍부정을 텍스트 분석하는 감정 분석 기반 평가값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Attachment, { nullable: true, description: \"To modify multiple sentiment KpiMetricValues' value\" })\n async updateKpiMetricValuesSentiment(\n @Arg('attachment', type => NewAttachment) attachment: NewAttachment,\n @Ctx() context: ResolverContext\n ): Promise<Attachment | null> {\n const { domain, user, tx } = context.state\n const projectRepo = getRepository(Project, tx)\n const projectId = attachment.refBy\n const attachmentRepo = getRepository(Attachment, tx)\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n // 1. 기존 파일 삭제\n projectRepo.update(projectId, { completeReport: null })\n await attachmentRepo.delete({ refBy: projectId, refType: attachment.refType })\n\n // 2. 새 파일 없으면 끝\n if (!attachment.file) {\n return null\n }\n\n // 3. 새 파일 저장\n const result = await createAttachment(null, { attachment }, context)\n projectRepo.update(projectId, { completeReport: result })\n\n // 4. pdf 파일 업로드를 처리\n\n // 5. 임시로 메트릭 점수 생성\n for (const metric of ['SL-PA 안전 평가', 'SL-PA 품질 평가']) {\n const metricValue = await metricValueRepo.findOne({\n where: { org: projectId, metric: { name: metric } }\n })\n\n if (metricValue) {\n await metricValueRepo.save({\n ...metricValue,\n value: Number((Math.random() * 2).toFixed(1)),\n updater: user\n })\n } else {\n const originMetric = await metricRepo.findOne({ where: { name: metric } })\n await metricValueRepo.save({\n metric: { id: originMetric.id },\n unit: originMetric?.unit || '',\n org: projectId, // 프로젝트 ID 추가\n periodType: originMetric?.periodType,\n valueDate: moment().tz('Asia/Seoul').format('YYYY-MM-DD'),\n value: Number((Math.random() * 2).toFixed(1)),\n domain,\n updater: user\n })\n }\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To finalize project with KPI recalculation' })\n async finalizeProjectWithKpiRecalculation(\n @Arg('projectId') projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n const projectRepo = getRepository(Project, tx)\n\n const project = await projectRepo.findOne({ where: { id: projectId } })\n\n console.log('project :', project)\n\n if (!project) {\n throw new Error(`Project not found: ${projectId}`)\n }\n\n projectRepo.save({\n ...project,\n state: ProjectState.COMPLETED\n })\n\n return true\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"kpi-metric-value-mutation.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { getRepository } from '@things-factory/shell'\nimport { In } from 'typeorm'\nimport {\n KpiPeriodType,\n KpiMetric,\n KpiMetricValue,\n KpiMetricValuePatch,\n Kpi,\n KpiValue,\n parseFormula,\n evaluateFormula,\n builtinFunctions,\n KpiMetricValueProvider\n} from '@things-factory/kpi'\nimport { Attachment, NewAttachment, createAttachment } from '@things-factory/attachment-base'\nimport { Project, ProjectState } from '@dssp/project'\nimport moment from 'moment-timezone'\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueMutation {\n /* 프로젝트 수행과정 중에 (시간, 비용, 발생 건수 등) 누적된 값을 반영하여 KPI Metric Value 값을 수정 - 예를 들면, 총 설계 변경 건수, 총 건설 폐기물 발생량, 공사비, 공사기간, 재해 건수 등 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple cumulative KpiMetricValues' value\" })\n async updateKpiMetricValuesCumulative(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n const results = []\n for (const patch of patches) {\n const metric = await metricRepo.findOne({ where: { id: patch.metricId } })\n if (!metric) {\n throw new Error(`Metric not found: ${patch.metricId}`)\n }\n const result = await metricValueRepo.save({\n domain,\n ...patch,\n metric,\n updater: user\n } as any)\n\n results.push(result)\n }\n\n return results\n }\n\n /* 전문 감리사에 의해서 평가된 별점을 반영하여 KPI Metric Value 값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [KpiMetricValue], { description: \"To modify multiple assessment KpiMetricValues' value\" })\n async updateKpiMetricValuesAssessment(\n @Arg('patches', type => [KpiMetricValuePatch]) patches: KpiMetricValuePatch[],\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n const { domain, user, tx } = context.state\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n const results = []\n for (const patch of patches) {\n const metric = await metricRepo.findOne({ where: { id: patch.metricId } })\n if (!metric) {\n throw new Error(`Metric not found: ${patch.metricId}`)\n }\n const result = await metricValueRepo.save({\n domain,\n ...patch,\n metric,\n updater: user\n } as any)\n\n results.push(result)\n }\n\n return results\n }\n\n /* 전문 감리사에 의 감리 최종 평가서의 긍부정을 텍스트 분석하는 감정 분석 기반 평가값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Attachment, { nullable: true, description: \"To modify multiple sentiment KpiMetricValues' value\" })\n async updateKpiMetricValuesSentiment(\n @Arg('attachment', type => NewAttachment) attachment: NewAttachment,\n @Ctx() context: ResolverContext\n ): Promise<Attachment | null> {\n const { domain, user, tx } = context.state\n const projectRepo = getRepository(Project, tx)\n const projectId = attachment.refBy\n const attachmentRepo = getRepository(Attachment, tx)\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n // 1. 기존 파일 삭제\n projectRepo.update(projectId, { completeReport: null })\n await attachmentRepo.delete({ refBy: projectId, refType: attachment.refType })\n\n // 2. 새 파일 없으면 끝\n if (!attachment.file) {\n return null\n }\n\n // 3. 새 파일 저장\n const result = await createAttachment(null, { attachment }, context)\n projectRepo.update(projectId, { completeReport: result })\n\n // 4. pdf 파일 업로드를 처리\n\n // 5. 임시로 메트릭 점수 생성\n for (const metric of ['SL-PA 안전 평가', 'SL-PA 품질 평가']) {\n const metricValue = await metricValueRepo.findOne({\n where: { org: projectId, metric: { name: metric } }\n })\n\n if (metricValue) {\n await metricValueRepo.save({\n ...metricValue,\n value: Number((Math.random() * 2).toFixed(1)),\n updater: user\n })\n } else {\n const originMetric = await metricRepo.findOne({ where: { name: metric } })\n await metricValueRepo.save({\n metric: { id: originMetric.id },\n unit: originMetric?.unit || '',\n org: projectId, // 프로젝트 ID 추가\n periodType: originMetric?.periodType,\n valueDate: moment().tz('Asia/Seoul').format('YYYY-MM-DD'),\n value: Number((Math.random() * 2).toFixed(1)),\n domain,\n updater: user\n })\n }\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'To finalize project with KPI recalculation' })\n async finalizeProjectWithKpiRecalculation(\n @Arg('projectId') projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n const projectRepo = getRepository(Project, tx)\n\n const project = await projectRepo.findOne({ where: { id: projectId } })\n\n console.log('project :', project)\n\n if (!project) {\n throw new Error(`Project not found: ${projectId}`)\n }\n\n // 이지점에서 프로젝트 KPI Value 계산을 다시 할 것이다.\n await this.recalculateProjectKpiValues(projectId, context)\n\n projectRepo.save({\n ...project,\n state: ProjectState.COMPLETED\n })\n\n return true\n }\n\n /**\n * 프로젝트의 모든 KPI Value들을 계층적으로 재계산합니다.\n * 1. Leaf KPIs (자식이 없는 KPI): formula 기반 계산\n * 2. Parent KPIs (자식이 있는 KPI): 자식 KPI scores의 weighted average 계산\n */\n private async recalculateProjectKpiValues(projectId: string, context: ResolverContext): Promise<void> {\n const { domain, user, tx } = context.state\n const kpiValueRepo = getRepository(KpiValue, tx)\n const kpiRepo = getRepository(Kpi, tx)\n\n try {\n // 1. 모든 KPI들을 조회 (계층 구조 포함)\n const allKpis = await kpiRepo.find({\n where: { domain: { id: domain.id } },\n relations: ['parent', 'children']\n })\n\n console.log(`Found ${allKpis.length} KPIs total for domain`)\n\n // 2. Leaf KPIs (자식이 없는 KPI)와 Parent KPIs 구분\n const leafKpis = allKpis.filter(kpi => kpi.isLeaf || !kpi.children || kpi.children.length === 0)\n const parentKpis = allKpis.filter(kpi => !kpi.isLeaf && kpi.children && kpi.children.length > 0)\n\n console.log(`Processing ${leafKpis.length} leaf KPIs and ${parentKpis.length} parent KPIs`)\n\n // 3. 먼저 Leaf KPIs를 formula로 계산\n for (const leafKpi of leafKpis) {\n try {\n await this.recalculateLeafKpiValue(leafKpi, projectId, context)\n console.log(`Successfully calculated leaf KPI: ${leafKpi.name}`)\n } catch (error) {\n console.error(`Failed to calculate leaf KPI ${leafKpi.name}:`, error.message)\n // 개별 KPI 계산 실패는 전체 프로세스를 중단하지 않음\n }\n }\n\n // 4. Parent KPIs를 계층 레벨순으로 정렬 (깊은 레벨부터)\n const sortedParentKpis = this.sortKpisByLevel(parentKpis, allKpis)\n\n // 5. Parent KPIs를 weighted average로 계산\n for (const parentKpi of sortedParentKpis) {\n try {\n await this.recalculateParentKpiValue(parentKpi, projectId, allKpis, context)\n console.log(`Successfully calculated parent KPI: ${parentKpi.name}`)\n } catch (error) {\n console.error(`Failed to calculate parent KPI ${parentKpi.name}:`, error.message)\n }\n }\n\n } catch (error) {\n console.error(`Error recalculating KPI values for project ${projectId}:`, error)\n throw error\n }\n }\n\n /**\n * 개별 KPI Value를 재계산합니다.\n */\n private async recalculateKpiValue(kpiValue: KpiValue, context: ResolverContext): Promise<KpiValue> {\n const { domain, user, tx } = context.state\n const kpiValueRepo = getRepository(KpiValue, tx)\n const kpiRepo = getRepository(Kpi, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n\n const kpi = kpiValue.kpi || (await kpiRepo.findOne({ where: { id: kpiValue.kpiId, domain: { id: domain.id } } }))\n if (!kpi) throw new Error('KPI 정보 없음')\n if (!kpi.formula) {\n console.log(`KPI ${kpi.name} has no formula, skipping recalculation`)\n return kpiValue\n }\n\n const periodType = kpi.periodType || KpiPeriodType.DAY\n const valueDate = null // kpiValue.valueDate\n const org = kpiValue.group || 'unknown' // project ID를 org로 사용\n\n // things-factory calculator 기반 formula 계산\n let kpiValueResult: number\n try {\n const ast = parseFormula(kpi.formula)\n const provider = new KpiMetricValueProvider({\n valueDate,\n org,\n domainId: domain.id,\n tx\n })\n const evalContext = { functions: builtinFunctions, provider }\n kpiValueResult = await evaluateFormula(ast, evalContext)\n\n if (kpiValueResult == null || isNaN(kpiValueResult)) {\n throw new Error('KPI formula 결과값 없음')\n }\n } catch (error) {\n console.error(`Formula evaluation failed for KPI ${kpi.name}: ${kpi.formula}`, error)\n return kpiValue // 계산 실패시 기존 값 유지\n }\n\n // KPI Value 업데이트\n kpiValue.value = kpiValueResult\n kpiValue.updater = user\n\n // 성과 점수 자동 계산 및 저장\n try {\n await this.calculateAndSaveScore(kpiValue, kpi)\n console.log(`Successfully calculated score for KPI value ${kpiValue.id}`)\n } catch (scoreError) {\n console.error(`Failed to calculate score for KPI value ${kpiValue.id}:`, scoreError.message)\n // 성과 점수 계산 실패는 KPI Value 저장을 막지 않음\n }\n\n return await kpiValueRepo.save(kpiValue)\n }\n\n /**\n * scoreFormula를 사용한 성과 점수 계산\n */\n private async calculateScoreFromFormula(kpi: Kpi, value: number): Promise<{ score: number; calculationMethod: string } | null> {\n if (!kpi.scoreFormula) {\n return null\n }\n\n try {\n const ast = parseFormula(kpi.scoreFormula)\n const provider = {\n get: async (name: string) => {\n if (name === 'value') return value\n return null\n }\n }\n const evalContext = { functions: builtinFunctions, provider }\n const result = await evaluateFormula(ast, evalContext)\n\n if (result !== null && result !== undefined && !isNaN(result)) {\n const performanceScore = Number(result)\n\n // score를 0~1 범위로 제한\n const clampedScore = Math.max(0, Math.min(1, performanceScore))\n\n return {\n score: clampedScore,\n calculationMethod: 'formula'\n }\n }\n } catch (error) {\n console.error(`Score formula evaluation for '${kpi.name}: ${kpi.scoreFormula}' error:`, error)\n }\n\n return null\n }\n\n /**\n * KPI의 grades lookup table을 이용한 성과 점수 변환\n */\n private calculateScoreFromLookup(kpi: Kpi, value: number): { score: number; calculationMethod: string } | null {\n if (!kpi.grades || kpi.grades.length === 0) {\n return null\n }\n\n // grades lookup table에서 해당 값의 범위에 맞는 성과 점수 찾기\n const grade = kpi.grades.find((g: any) => value >= g.minValue && value <= g.maxValue)\n\n if (!grade) {\n return null\n }\n\n // score를 0~1 범위로 제한\n const clampedScore = Math.max(0, Math.min(1, grade.score))\n\n return {\n score: clampedScore,\n calculationMethod: 'lookup'\n }\n }\n\n /**\n * KpiValue의 성과 점수 계산 및 저장\n */\n private async calculateAndSaveScore(kpiValue: KpiValue, kpi: Kpi): Promise<void> {\n // 1. scoreFormula 우선 시도\n let scoreResult = await this.calculateScoreFromFormula(kpi, kpiValue.value)\n\n // 2. scoreFormula가 없거나 실패하면 grades lookup table 사용\n if (!scoreResult) {\n scoreResult = this.calculateScoreFromLookup(kpi, kpiValue.value)\n }\n\n if (scoreResult) {\n // KpiValue의 score 필드에 성과 점수 저장\n kpiValue.score = scoreResult.score\n console.log(`Calculated score ${scoreResult.score} for KPI ${kpi.name} with method ${scoreResult.calculationMethod}`)\n } else {\n console.log(`No score calculation method available for KPI ${kpi.name}`)\n }\n }\n\n /**\n * Leaf KPI Value를 formula로 계산합니다.\n */\n private async recalculateLeafKpiValue(kpi: Kpi, projectId: string, context: ResolverContext): Promise<void> {\n const { domain, user, tx } = context.state\n const kpiValueRepo = getRepository(KpiValue, tx)\n\n // 기존 KPI Value 조회 또는 생성\n let kpiValue = await kpiValueRepo.findOne({\n where: {\n kpi: { id: kpi.id },\n group: projectId,\n domain: { id: domain.id }\n }\n })\n\n if (!kpiValue) {\n // 새 KPI Value 생성\n kpiValue = kpiValueRepo.create({\n kpi,\n group: projectId,\n domain,\n valueDate: new Date().toISOString().slice(0, 10),\n value: 0,\n score: 0,\n updater: user\n })\n }\n\n // formula 기반 계산\n await this.recalculateKpiValue(kpiValue, context)\n }\n\n /**\n * Parent KPI Value를 자식 KPI scores의 weighted average로 계산합니다.\n */\n private async recalculateParentKpiValue(parentKpi: Kpi, projectId: string, allKpis: Kpi[], context: ResolverContext): Promise<void> {\n const { domain, user, tx } = context.state\n const kpiValueRepo = getRepository(KpiValue, tx)\n\n // 자식 KPIs 조회\n const childKpis = allKpis.filter(kpi => kpi.parent?.id === parentKpi.id)\n\n if (childKpis.length === 0) {\n console.log(`No child KPIs found for parent KPI: ${parentKpi.name}`)\n return\n }\n\n // 자식 KPI Values 조회\n const childKpiIds = childKpis.map(kpi => kpi.id)\n const childKpiValues = await kpiValueRepo.find({\n where: {\n kpi: { id: In(childKpiIds) },\n group: projectId,\n domain: { id: domain.id }\n },\n relations: ['kpi']\n })\n\n if (childKpiValues.length === 0) {\n console.log(`No child KPI values found for parent KPI: ${parentKpi.name}`)\n return\n }\n\n // Weighted average 계산\n const { weightedValue, weightedScore } = this.calculateWeightedAverage(childKpiValues, childKpis)\n\n // 기존 Parent KPI Value 조회 또는 생성\n let parentKpiValue = await kpiValueRepo.findOne({\n where: {\n kpi: { id: parentKpi.id },\n group: projectId,\n domain: { id: domain.id }\n }\n })\n\n if (parentKpiValue) {\n // 기존 값 업데이트\n parentKpiValue.value = weightedValue\n parentKpiValue.score = weightedScore\n parentKpiValue.updater = user\n } else {\n // 새 값 생성\n parentKpiValue = kpiValueRepo.create({\n kpi: parentKpi,\n group: projectId,\n domain,\n valueDate: new Date().toISOString().slice(0, 10),\n value: weightedValue,\n score: weightedScore,\n updater: user\n })\n }\n\n await kpiValueRepo.save(parentKpiValue)\n console.log(`Updated parent KPI ${parentKpi.name}: value=${weightedValue.toFixed(4)}, score=${weightedScore.toFixed(4)}`)\n }\n\n /**\n * KPIs를 계층 레벨순으로 정렬합니다 (깊은 레벨부터)\n */\n private sortKpisByLevel(parentKpis: Kpi[], allKpis: Kpi[]): Kpi[] {\n const kpiLevels = new Map<string, number>()\n\n const calculateLevel = (kpi: Kpi): number => {\n if (kpiLevels.has(kpi.id)) {\n return kpiLevels.get(kpi.id)!\n }\n\n if (!kpi.parent) {\n kpiLevels.set(kpi.id, 0)\n return 0\n }\n\n const parentKpi = allKpis.find(k => k.id === kpi.parent?.id)\n if (!parentKpi) {\n kpiLevels.set(kpi.id, 1)\n return 1\n }\n\n const level = calculateLevel(parentKpi) + 1\n kpiLevels.set(kpi.id, level)\n return level\n }\n\n // 각 parent KPI의 레벨 계산\n parentKpis.forEach(kpi => calculateLevel(kpi))\n\n // 레벨 순으로 정렬 (깊은 레벨부터)\n return parentKpis.sort((a, b) => (kpiLevels.get(b.id) || 0) - (kpiLevels.get(a.id) || 0))\n }\n\n /**\n * 자식 KPI values의 weighted average를 계산합니다.\n */\n private calculateWeightedAverage(childValues: any[], childKpis: Kpi[]): { weightedValue: number; weightedScore: number } {\n let totalWeightedValue = 0\n let totalWeightedScore = 0\n let totalWeight = 0\n\n for (const value of childValues) {\n const childKpi = childKpis.find(kpi => kpi.id === value.kpi.id)\n const weight = childKpi?.weight || 1\n\n totalWeightedValue += value.score * weight\n totalWeightedScore += value.score * weight\n totalWeight += weight\n }\n\n if (totalWeight === 0) {\n return { weightedValue: 0, weightedScore: 0 }\n }\n\n return {\n weightedValue: totalWeightedValue / totalWeight,\n weightedScore: totalWeightedScore / totalWeight\n }\n }\n}\n"]}
|
|
@@ -3,5 +3,6 @@ import { KpiValue, KpiValueList } from '@things-factory/kpi';
|
|
|
3
3
|
import { Project } from '@dssp/project/dist-server/service/project/project';
|
|
4
4
|
export declare class KpiValueQueryForProject {
|
|
5
5
|
kpiValues(params: ListParam, context: ResolverContext): Promise<KpiValueList>;
|
|
6
|
+
projectXKpiValues(projectId: string, context: ResolverContext): Promise<KpiValue[]>;
|
|
6
7
|
project(kpiValue: KpiValue): Promise<Project | null>;
|
|
7
8
|
}
|
|
@@ -18,6 +18,19 @@ let KpiValueQueryForProject = class KpiValueQueryForProject {
|
|
|
18
18
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
19
19
|
return { items, total };
|
|
20
20
|
}
|
|
21
|
+
async projectXKpiValues(projectId, context) {
|
|
22
|
+
const { domain } = context.state;
|
|
23
|
+
const repository = await (0, shell_1.getRepository)(kpi_1.KpiValue);
|
|
24
|
+
const kpiValues = await repository
|
|
25
|
+
.createQueryBuilder('kpiValue')
|
|
26
|
+
.leftJoinAndSelect('kpiValue.kpi', 'kpi')
|
|
27
|
+
.where('kpiValue.domain = :domain', { domain: domain.id })
|
|
28
|
+
.andWhere('kpiValue.group = :projectId', { projectId })
|
|
29
|
+
.andWhere('kpi.name LIKE :namePrefix', { namePrefix: 'X%' })
|
|
30
|
+
.orderBy('kpi.name', 'ASC')
|
|
31
|
+
.getMany();
|
|
32
|
+
return kpiValues;
|
|
33
|
+
}
|
|
21
34
|
async project(kpiValue) {
|
|
22
35
|
if (!kpiValue.group)
|
|
23
36
|
return null;
|
|
@@ -34,6 +47,15 @@ tslib_1.__decorate([
|
|
|
34
47
|
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
35
48
|
tslib_1.__metadata("design:returntype", Promise)
|
|
36
49
|
], KpiValueQueryForProject.prototype, "kpiValues", null);
|
|
50
|
+
tslib_1.__decorate([
|
|
51
|
+
(0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
|
|
52
|
+
(0, type_graphql_1.Query)(returns => [kpi_1.KpiValue], { description: 'To fetch KpiValues by project group with X prefix kpi names' }),
|
|
53
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('projectId', type => String)),
|
|
54
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
55
|
+
tslib_1.__metadata("design:type", Function),
|
|
56
|
+
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
57
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
58
|
+
], KpiValueQueryForProject.prototype, "projectXKpiValues", null);
|
|
37
59
|
tslib_1.__decorate([
|
|
38
60
|
(0, type_graphql_1.FieldResolver)(type => project_1.Project),
|
|
39
61
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-value/kpi-value-query.ts"],"names":[],"mappings":";;;;AAAA,+CAAqG;AACrG,iDAAuG;AAEvG,6CAAiE;AACjE,+EAA2E;AAGpE,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAG5B,AAAN,KAAK,CAAC,SAAS,CAA0B,MAAiB,EAAS,OAAwB;QACzF,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM;YACN,MAAM;YACN,UAAU,EAAE,MAAM,IAAA,qBAAa,EAAC,cAAQ,CAAC;YACzC,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC;SAC3C,CAAC,CAAA;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAS,QAAkB;QACtC,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAChC,OAAO,MAAM,IAAA,qBAAa,EAAC,iBAAO,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACvE,CAAC;CACF,CAAA;
|
|
1
|
+
{"version":3,"file":"kpi-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-value/kpi-value-query.ts"],"names":[],"mappings":";;;;AAAA,+CAAqG;AACrG,iDAAuG;AAEvG,6CAAiE;AACjE,+EAA2E;AAGpE,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAG5B,AAAN,KAAK,CAAC,SAAS,CAA0B,MAAiB,EAAS,OAAwB;QACzF,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM;YACN,MAAM;YACN,UAAU,EAAE,MAAM,IAAA,qBAAa,EAAC,cAAQ,CAAC;YACzC,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC;SAC3C,CAAC,CAAA;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAIK,AAAN,KAAK,CAAC,iBAAiB,CACa,SAAiB,EAC5C,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAa,EAAC,cAAQ,CAAC,CAAA;QAEhD,MAAM,SAAS,GAAG,MAAM,UAAU;aAC/B,kBAAkB,CAAC,UAAU,CAAC;aAC9B,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC;aACxC,KAAK,CAAC,2BAA2B,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;aACzD,QAAQ,CAAC,6BAA6B,EAAE,EAAE,SAAS,EAAE,CAAC;aACtD,QAAQ,CAAC,2BAA2B,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;aAC3D,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;aAC1B,OAAO,EAAE,CAAA;QAEZ,OAAO,SAAS,CAAA;IAClB,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAS,QAAkB;QACtC,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAChC,OAAO,MAAM,IAAA,qBAAa,EAAC,iBAAO,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACvE,CAAC;CACF,CAAA;AA7CY,0DAAuB;AAG5B;IAFL,IAAA,wBAAS,EAAC,mGAAmG,CAAC;IAC9G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,kBAAY,EAAE,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;IAC9D,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IAAqB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAAjB,iBAAS;;wDAazD;AAIK;IAFL,IAAA,wBAAS,EAAC,mGAAmG,CAAC;IAC9G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,cAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC;IAE1G,mBAAA,IAAA,kBAAG,EAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;IAChC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;gEAgBP;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAO,CAAC;IAChB,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAW,cAAQ;;sDAGvC;kCA5CU,uBAAuB;IADnC,IAAA,uBAAQ,EAAC,cAAQ,CAAC;GACN,uBAAuB,CA6CnC","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive, Float } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Kpi, KpiValue, KpiValueList } from '@things-factory/kpi'\nimport { Project } from '@dssp/project/dist-server/service/project/project'\n\n@Resolver(KpiValue)\nexport class KpiValueQueryForProject {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiValueList, { description: 'To fetch multiple KpiValues' })\n async kpiValues(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<KpiValueList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(KpiValue),\n searchables: ['kpi', 'group', 'valueDate']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [KpiValue], { description: 'To fetch KpiValues by project group with X prefix kpi names' })\n async projectXKpiValues(\n @Arg('projectId', type => String) projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiValue[]> {\n const { domain } = context.state\n\n const repository = await getRepository(KpiValue)\n\n const kpiValues = await repository\n .createQueryBuilder('kpiValue')\n .leftJoinAndSelect('kpiValue.kpi', 'kpi')\n .where('kpiValue.domain = :domain', { domain: domain.id })\n .andWhere('kpiValue.group = :projectId', { projectId })\n .andWhere('kpi.name LIKE :namePrefix', { namePrefix: 'X%' })\n .orderBy('kpi.name', 'ASC')\n .getMany()\n\n return kpiValues\n }\n\n @FieldResolver(type => Project)\n async project(@Root() kpiValue: KpiValue): Promise<Project | null> {\n if (!kpiValue.group) return null\n return await getRepository(Project).findOneBy({ id: kpiValue.group })\n }\n}\n"]}
|