@dssp/dkpi 1.0.0-alpha.80 → 1.0.0-alpha.81

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 (63) hide show
  1. package/dist-client/bootstrap.d.ts +1 -0
  2. package/dist-client/bootstrap.js +11 -0
  3. package/dist-client/bootstrap.js.map +1 -1
  4. package/dist-client/components/kpi-single-boxplot-chart.d.ts +3 -2
  5. package/dist-client/components/kpi-single-boxplot-chart.js +30 -23
  6. package/dist-client/components/kpi-single-boxplot-chart.js.map +1 -1
  7. package/dist-client/pages/component/project-update-header.d.ts +1 -0
  8. package/dist-client/pages/component/project-update-header.js +127 -0
  9. package/dist-client/pages/component/project-update-header.js.map +1 -0
  10. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +1 -1
  11. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +1 -1
  12. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  13. package/dist-client/pages/kpi-value/kpi-value-list-page.js +1 -1
  14. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  15. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.d.ts +16 -2
  16. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +138 -128
  17. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
  18. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.d.ts +4 -2
  19. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +109 -44
  20. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
  21. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.d.ts +3 -0
  22. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js +32 -4
  23. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js.map +1 -1
  24. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.d.ts +24 -0
  25. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +365 -157
  26. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -1
  27. package/dist-client/pages/sv-project-complete.d.ts +4 -1
  28. package/dist-client/pages/sv-project-complete.js +43 -12
  29. package/dist-client/pages/sv-project-complete.js.map +1 -1
  30. package/dist-client/pages/sv-project-detail.d.ts +11 -0
  31. package/dist-client/pages/sv-project-detail.js +184 -48
  32. package/dist-client/pages/sv-project-detail.js.map +1 -1
  33. package/dist-client/pages/sv-project-list.d.ts +9 -0
  34. package/dist-client/pages/sv-project-list.js +93 -3
  35. package/dist-client/pages/sv-project-list.js.map +1 -1
  36. package/dist-client/pages/sv-project-update.d.ts +86 -0
  37. package/dist-client/pages/sv-project-update.js +1331 -0
  38. package/dist-client/pages/sv-project-update.js.map +1 -0
  39. package/dist-client/route.d.ts +1 -1
  40. package/dist-client/route.js +3 -0
  41. package/dist-client/route.js.map +1 -1
  42. package/dist-client/shared/complete-api.d.ts +10 -9
  43. package/dist-client/shared/complete-api.js +44 -18
  44. package/dist-client/shared/complete-api.js.map +1 -1
  45. package/dist-client/tsconfig.tsbuildinfo +1 -1
  46. package/dist-client/viewparts/menu-tools.js +9 -18
  47. package/dist-client/viewparts/menu-tools.js.map +1 -1
  48. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +23 -0
  49. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +72 -28
  50. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  51. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +9 -2
  52. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -1
  53. package/dist-server/service/kpi-stat/kpi-stat-query.js +19 -18
  54. package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -1
  55. package/dist-server/service/kpi-value/kpi-value-query.js +2 -2
  56. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  57. package/dist-server/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +3 -3
  59. package/schema.graphql +13 -1
  60. package/things-factory.config.js +1 -0
  61. package/dist-client/shared/domain-context.d.ts +0 -7
  62. package/dist-client/shared/domain-context.js +0 -13
  63. package/dist-client/shared/domain-context.js.map +0 -1
@@ -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, ObjectType, Field } from 'type-graphql'\nimport { getRepository, ScalarObject, EnvVar, Domain } from '@things-factory/shell'\nimport { runScenario } from '@things-factory/integration-base'\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'\nimport FormData from 'form-data'\nimport fetch from 'node-fetch'\nimport https from 'https'\nimport http from 'http'\n\n/**\n * 외부 시스템 데이터 수집 결과 — 시스템별 한 row.\n * UI \"자동 수집\" 버튼이 시나리오 호출 후 시스템별 성공·오류 표시에 사용.\n */\n@ObjectType({ description: '외부 시스템(세움터/올바로/키스콘) 데이터 수집 시나리오 호출 결과' })\nclass ExternalDataCollectionResult {\n @Field({ description: '소스 키: saeumteo | allbaro | kiscon' })\n source!: string\n\n @Field({ description: '표시 라벨 (세움터/올바로/키스콘)' })\n label!: string\n\n @Field({ description: '시나리오 실행 성공 여부' })\n ok!: boolean\n\n @Field({ description: '성공 시 \"완료\", 실패 시 에러 메시지' })\n message!: string\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n '시나리오 result 객체 — projectKey: value 맵. ' +\n '세움터={area, floorAreaRatio, upperFloorCount, lowerFloorCount, structureType, siteType}, ' +\n '올바로={totalConstructionWasteAmount}, ' +\n '키스콘={constructionPeriod, constructionCost}. ' +\n 'siteType (건축물 용도, 예 APARTMENT_COMPLEX) / structureType (구조형태) 는 ' +\n 'BuildingComplex 의 시설유형/구조유형 속성 후보. KISCON 의 \"공사유형(신설/증축)\" 은 ' +\n 'DSSP SiteType (용도분류) 와 다른 도메인이라 매핑 대상 아님.'\n })\n data?: any\n}\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 uploadedFile = await attachment.file\n const { filename } = uploadedFile\n const fileBuffer = await this.readFileToBuffer(uploadedFile)\n\n console.log(`Processing PDF file: ${filename}, size: ${fileBuffer.length} bytes`)\n\n // 4. 새 파일 저장 (버퍼를 사용하여 attachment 생성)\n const recreatedFile = this.createFileUploadFromBuffer(fileBuffer, filename, 'application/pdf')\n const { id: resultId } = await createAttachment(null, { attachment: { ...attachment, file: recreatedFile } }, context)\n const result = await attachmentRepo.findOne({ where: { id: resultId } })\n projectRepo.update(projectId, { completeReport: result })\n\n // 5. pdf 파일을 operator-runner 서비스에 업로드하여 분석\n let safetyScore = 0\n let qualityScore = 0\n\n try {\n const operatorRunnerUrl = process.env.OPERATOR_RUNNER_URL || 'https://hatiolab-korea-uni.ettisoft.com'\n\n // sl-pa-safety 서비스 호출\n safetyScore = await this.callOperatorRunnerServiceWithBuffer(operatorRunnerUrl, 'sl-pa-safety', fileBuffer, filename)\n\n // sl-pa-quality 서비스 호출\n qualityScore = await this.callOperatorRunnerServiceWithBuffer(operatorRunnerUrl, 'sl-pa-quality', fileBuffer, filename)\n } catch (error) {\n console.error('Failed to analyze PDF with operator-runner:', error)\n }\n\n // 5. 메트릭 점수 저장\n await this.saveMetricValue(metricValueRepo, metricRepo, projectId, 'SL-PA 안전 평가', safetyScore, domain, user)\n await this.saveMetricValue(metricValueRepo, metricRepo, projectId, 'SL-PA 품질 평가', qualityScore, domain, user)\n\n return result\n }\n\n /**\n * FileUpload 스트림을 버퍼로 읽기\n */\n private async readFileToBuffer(fileUpload: any): Promise<Buffer> {\n const { createReadStream } = fileUpload\n const chunks: Buffer[] = []\n\n return new Promise((resolve, reject) => {\n const stream = createReadStream()\n stream.on('data', (chunk: Buffer) => chunks.push(chunk))\n stream.on('end', () => resolve(Buffer.concat(chunks)))\n stream.on('error', (error: Error) => reject(error))\n })\n }\n\n /**\n * Buffer로부터 FileUpload 객체 생성\n */\n private createFileUploadFromBuffer(buffer: Buffer, filename: string, mimetype: string): any {\n const { Readable } = require('stream')\n return {\n filename,\n mimetype,\n encoding: '7bit',\n createReadStream: () => {\n const readable = new Readable()\n readable.push(buffer)\n readable.push(null)\n return readable\n }\n }\n }\n\n /**\n * operator-runner 서비스 호출 (Buffer 사용)\n */\n private async callOperatorRunnerServiceWithBuffer(\n baseUrl: string,\n serviceName: string,\n fileBuffer: Buffer,\n filename: string\n ): Promise<number> {\n console.log(`Calling operator-runner service: ${serviceName}`)\n console.log(`Base URL: ${baseUrl}`)\n console.log(`Filename: ${filename}`)\n console.log(`Buffer size: ${fileBuffer.length} bytes`)\n\n const formData = new FormData()\n\n // Buffer를 스트림으로 변환하여 추가\n const { Readable } = require('stream')\n const bufferStream = Readable.from(fileBuffer)\n\n formData.append('files', bufferStream, {\n filename,\n contentType: 'application/pdf'\n })\n\n const url = `${baseUrl}/api/run/${serviceName}`\n console.log(`Request URL: ${url}`)\n\n // HTTP/HTTPS agent 설정\n const isHttps = url.startsWith('https')\n const agent = isHttps\n ? new https.Agent({\n keepAlive: false,\n timeout: 120000,\n rejectUnauthorized: false\n })\n : new http.Agent({\n keepAlive: false,\n timeout: 120000\n })\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: formData as any,\n headers: {\n ...formData.getHeaders(),\n Authorization: `Basic ${Buffer.from('admin:admin1234').toString('base64')}`\n },\n agent,\n timeout: 120000\n })\n\n console.log(`Response status: ${response.status}`)\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error(`Service ${serviceName} error response:`, errorText)\n throw new Error(`Service ${serviceName} failed (${response.status}): ${errorText}`)\n }\n\n const data = await response.json()\n console.log(`Service ${serviceName} response:`, JSON.stringify(data))\n\n const score = data?.result?.score || data?.score || 0\n console.log(`Extracted score: ${score}`)\n\n return score\n } catch (error) {\n console.error(`Error calling ${serviceName}:`, error)\n throw error\n }\n }\n\n /**\n * 메트릭 값 저장\n */\n private async saveMetricValue(\n metricValueRepo: any,\n metricRepo: any,\n projectId: string,\n metricName: string,\n value: number,\n domain: any,\n user: any\n ): Promise<void> {\n const metricValue = await metricValueRepo.findOne({\n where: { org: projectId, metric: { name: metricName } }\n })\n\n if (metricValue) {\n await metricValueRepo.save({\n ...metricValue,\n value,\n updater: user\n })\n } else {\n const originMetric = await metricRepo.findOne({ where: { name: metricName } })\n if (originMetric) {\n await metricValueRepo.save({\n metric: { id: originMetric.id },\n unit: originMetric.unit || '',\n org: projectId,\n periodType: originMetric.periodType,\n valueDate: moment().tz('Asia/Seoul').format('YYYY-MM-DD'),\n value,\n domain,\n updater: user\n })\n }\n }\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 // 시나리오·EnvVar·KPI value 모두 프로젝트(테넌트) 도메인 기준이라 컨텍스트 스위치\n // 한 번 만든 뒤 이후 작업 모두 그 컨텍스트로 일관 진행.\n const projectContext = await this.switchToProjectDomain(projectId, context)\n\n // 외부 시스템 데이터 수집은 별도 mutation (collectProjectExternalData) 로 분리.\n // 사용자가 UI \"자동 수집\" 으로 먼저 명시 수집 후 결과 검토하고 완공 처리하는 흐름.\n // 안전 차원에서 finalize 시점에도 한 번 더 수집을 시도 — 실패는 warning 만.\n await this.runExternalDataScenarios(projectContext)\n\n // 프로젝트 KPI Value 계산을 다시 할 것이다 — 테넌트 도메인 컨텍스트에서.\n await this.recalculateProjectKpiValues(projectId, projectContext)\n\n projectRepo.save({\n ...project,\n state: ProjectState.COMPLETED\n })\n\n return true\n }\n\n /**\n * UI \"자동 수집\" 버튼 전용 mutation. 외부 시스템 3종 시나리오를 순차 호출하고\n * 시스템별 성공/실패 + 메시지를 반환. UI 는 결과를 보고 카드별 상태 (성공·오류) 를 표시.\n *\n * 시나리오는 도메인 EnvVar (주소·자격증명·서비스키 등) 만으로 동작하므로 파라미터 X.\n * 한 시스템 실패가 다른 시스템 수집을 막지 않도록 try/catch 로 격리.\n *\n * 운영 현실: 키스콘·올바로는 시공사 ID/PW 가 자주 미확보 → 오류 흔함. 세움터는 공공\n * 데이터 서비스키만으로 동작 가능. UI 는 시스템별로 명확한 오류 메시지 노출.\n */\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [ExternalDataCollectionResult], {\n description: 'Run external data collection scenarios per system, returning per-system result.'\n })\n async collectProjectExternalData(\n @Arg('projectId') projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<ExternalDataCollectionResult[]> {\n const projectContext = await this.switchToProjectDomain(projectId, context)\n return await this.runExternalDataScenariosWithResults(projectContext)\n }\n\n /**\n * 프로젝트 정보 수정 화면의 \"정보 연동\" 버튼 전용 — 세움터 단일 시나리오만 호출.\n * BuildingComplex 기본 속성 (area / floorAreaRatio / siteType / structureType /\n * coverageRatio / householdCount 등) 자동 채움 목적.\n *\n * address 인자가 있으면 시나리오 실행 전에 EnvVar `Step::건축물관리대장조회::address::query`\n * 를 그 값으로 upsert — 운영자가 폼에서 방금 입력한 주소를 시나리오가 곧바로 사용.\n * (도메인의 기존 EnvVar 와 다를 수 있어 명시적 갱신.)\n *\n * **도메인 스위치**: mutation 호출은 system / 운영자 도메인에서 일어나지만 시나리오·\n * EnvVar 는 **프로젝트가 속한 도메인** 에 있어야 자연. project.domain 으로 컨텍스트\n * 스위치 후 그 도메인에서 EnvVar upsert + 시나리오 실행.\n */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"mutation\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ExternalDataCollectionResult, {\n description: 'Run only 건축물관리대장조회 scenario for project basic info collection.'\n })\n async collectProjectBasicInfo(\n @Arg('projectId') projectId: string,\n @Arg('address', { nullable: true }) address: string,\n @Ctx() context: ResolverContext\n ): Promise<ExternalDataCollectionResult> {\n const projectContext = await this.switchToProjectDomain(projectId, context)\n if (address && address.trim()) {\n await this.upsertEnvVar('Step::건축물관리대장조회::address::query', address.trim(), projectContext)\n }\n return await this.runSingleScenario(\n { source: 'saeumteo', label: '세움터', name: '건축물관리대장조회' },\n projectContext\n )\n }\n\n /**\n * mutation 호출이 system / 운영자 도메인에서 일어나도 시나리오·EnvVar 는 **프로젝트\n * 테넌트 도메인** 에서 동작해야 자연. project.code 로 자식 (테넌트) 도메인을 찾아\n * 컨텍스트 사본 만들어 반환.\n *\n * 테넌트 도메인 매핑: Domain.subdomain = project.code AND Domain.extType = 'project'\n * (promoteProjectToTenant mutation 이 그렇게 생성). project.domain 자체는 부모\n * 도메인이라 외부 연동 EnvVar 가 거기 있을 일이 없어 사용 부적합.\n *\n * 테넌트 도메인이 없거나 (= 아직 승격 안 됨) project.code 가 비어있으면 원본\n * 컨텍스트 그대로 반환 (방어). project 자체가 없으면 throw.\n */\n private async switchToProjectDomain(\n projectId: string,\n context: ResolverContext\n ): Promise<ResolverContext> {\n const { tx } = context.state\n const project = await getRepository(Project, tx).findOne({ where: { id: projectId } })\n if (!project) {\n throw new Error(`Project not found: ${projectId}`)\n }\n if (!project.code) {\n console.warn(`[collect] project ${projectId} 는 아직 테넌트 승격되지 않음 (no code) — caller domain 그대로 사용`)\n return context\n }\n const tenantDomain = await getRepository(Domain, tx).findOne({\n where: { subdomain: project.code, extType: 'project' } as any\n })\n if (!tenantDomain) {\n console.warn(\n `[collect] project ${projectId} (code=${project.code}) 의 테넌트 도메인을 찾지 못함 — caller domain 그대로 사용`\n )\n return context\n }\n return {\n ...context,\n state: { ...context.state, domain: tenantDomain }\n } as ResolverContext\n }\n\n /**\n * 컨텍스트의 도메인에 EnvVar 1개 upsert. 시나리오가 도메인 EnvVar 를 우선 참조하는\n * 정책이라, 폼에서 입력한 주소를 시나리오 입력으로 흘리는 다리 역할.\n */\n private async upsertEnvVar(name: string, value: string, context: ResolverContext): Promise<void> {\n const { domain, user, tx } = context.state\n const repo = getRepository(EnvVar, tx)\n const existing = await repo.findOne({ where: { domain: { id: domain.id }, name } as any })\n if (existing) {\n existing.value = value\n existing.active = true\n ;(existing as any).updater = user\n await repo.save(existing)\n } else {\n await repo.save(\n repo.create({\n name,\n value,\n active: true,\n domain,\n description: 'Project basic info 자동 연동용 (project-update 정보연동 버튼)',\n creator: user,\n updater: user\n } as any)\n )\n }\n }\n\n /**\n * 단일 시나리오 호출 + result unwrap + 실패 판정 — collectProjectExternalData 의\n * loop 본체와 같은 로직을 1건짜리로 분리.\n */\n private async runSingleScenario(\n s: { source: string; label: string; name: string },\n context: ResolverContext\n ): Promise<ExternalDataCollectionResult> {\n const { domain } = context.state\n const instanceName = `collect-${s.name}-${Date.now()}`\n try {\n const runResult: any = await runScenario(instanceName, s.name, {}, context)\n if (!runResult) {\n console.warn(`[collect] '${s.name}' no result on domain '${domain.subdomain}'`)\n throw new Error('업데이트할 정보가 없습니다')\n }\n if (runResult.state === 'HALTED') {\n console.warn(\n `[collect] '${s.name}' HALTED on domain '${domain.subdomain}': ${runResult.message || '(no message)'}`\n )\n throw new Error('업데이트할 정보가 없습니다')\n }\n\n let data = runResult.result ?? runResult.data ?? {}\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n const wrapKeys = Object.keys(data)\n if (\n wrapKeys.length === 1 &&\n data[wrapKeys[0]] &&\n typeof data[wrapKeys[0]] === 'object' &&\n !Array.isArray(data[wrapKeys[0]])\n ) {\n data = data[wrapKeys[0]]\n }\n }\n console.log(`[collect] '${s.name}' OK on '${domain.subdomain}' keys=${Object.keys(data || {}).join(',')}`)\n return { source: s.source, label: s.label, ok: true, message: '완료', data }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.warn(`[collect] '${s.name}' failed on '${domain.subdomain}': ${msg}`)\n return { source: s.source, label: s.label, ok: false, message: msg }\n }\n }\n\n /**\n * 외부 시스템 3종 시나리오 순차 실행 + 시스템별 결과 수집.\n */\n private async runExternalDataScenariosWithResults(context: ResolverContext): Promise<ExternalDataCollectionResult[]> {\n const { domain } = context.state\n const SCENARIOS: Array<{ source: string; label: string; name: string }> = [\n { source: 'saeumteo', label: '세움터', name: '건축물관리대장조회' },\n { source: 'allbaro', label: '올바로', name: '건설폐기물정보조회' },\n { source: 'kiscon', label: '키스콘', name: '건설공사정보조회' }\n ]\n\n const results: ExternalDataCollectionResult[] = []\n for (const s of SCENARIOS) {\n results.push(await this.runSingleScenario(s, context))\n }\n return results\n }\n\n /**\n * finalize 흐름용 시나리오 호출. 결과 형태 없이 진행만 — finalize 의 KPI 재계산이 곧\n * 이어지므로 시스템별 결과를 클라이언트에 돌려줄 필요 없음. 실패는 warning 만.\n */\n private async runExternalDataScenarios(context: ResolverContext): Promise<void> {\n await this.runExternalDataScenariosWithResults(context)\n }\n\n /**\n * 프로젝트의 모든 KPI Value들을 계층적으로 재계산합니다.\n * 1. 기존 KPI Value 삭제 (중복 방지)\n * 2. Leaf KPIs (자식이 없는 KPI): formula 기반 계산\n * 3. 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 Value 삭제 (재계산으로 인한 중복 방지)\n const existingKpiValues = await kpiValueRepo.find({\n where: {\n group: projectId,\n domain: { id: domain.id }\n }\n })\n\n if (existingKpiValues.length > 0) {\n await kpiValueRepo.remove(existingKpiValues)\n console.log(`Deleted ${existingKpiValues.length} existing KPI values for project ${projectId}`)\n }\n\n // 2. 모든 KPI들을 조회 (계층 구조 포함)\n const allKpis = await kpiRepo.find({\n relations: ['parent', 'children']\n })\n\n console.log(`Found ${allKpis.length} KPIs total for domain`)\n\n // 3. 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 // 4. 먼저 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 // 5. Parent KPIs를 계층 레벨순으로 정렬 (깊은 레벨부터)\n const sortedParentKpis = this.sortKpisByLevel(parentKpis, allKpis)\n\n // 6. 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 } catch (error) {\n console.error(`Error recalculating KPI values for project ${projectId}:`, error)\n throw error\n }\n }\n\n /**\n * 개별 KPI Value를 재계산합니다.\n * 항상 최신 버전의 KPI를 사용하여 계산합니다.\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 // 항상 최신 버전의 KPI를 조회하여 사용\n // kpiValue.kpi가 이미 로드되어 있으면 사용하고, 없으면 DB에서 최신 버전 조회\n const kpi =\n kpiValue.kpi ||\n (await kpiRepo.findOne({\n where: { id: kpiValue.kpiId },\n order: { version: 'DESC' }\n }))\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.version = kpi.version || 1\n kpiValue.updater = user\n\n // 성과 점수 자동 계산 및 저장\n try {\n // 2D lookup KPI (X13 등)인 경우 project의 totalProgress 조회\n let scoreContext: { progressRate?: number } | undefined\n const gradesData = kpi.grades as any\n if (gradesData && !Array.isArray(gradesData) && gradesData.type === 'PROGRESS_DEVIATION_LOOKUP') {\n const projectId = kpiValue.group || org\n const projectRepo = getRepository(Project, tx)\n const project = await projectRepo.findOne({ where: { id: projectId } })\n scoreContext = { progressRate: project?.totalProgress ?? 50 }\n console.log(`2D lookup KPI ${kpi.name}: progressRate=${scoreContext.progressRate}%`)\n }\n\n await this.calculateAndSaveScore(kpiValue, kpi, scoreContext)\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 return {\n score: performanceScore,\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 * 1D (기존 배열) 및 2D (X13 공정률×편차) lookup 모두 지원\n */\n private calculateScoreFromLookup(\n kpi: Kpi,\n value: number,\n context?: { progressRate?: number }\n ): { score: number; calculationMethod: string } | null {\n if (!kpi.grades) {\n return null\n }\n\n // 2D lookup table 처리 (X13: 공정률 × 편차 → 점수)\n const grades = kpi.grades as any\n if (!Array.isArray(grades) && grades.type === 'PROGRESS_DEVIATION_LOOKUP') {\n return this.calculateScoreFrom2DLookup(value, grades, context?.progressRate)\n }\n\n // 1D lookup table 처리 (기존)\n if (!Array.isArray(grades) || grades.length === 0) {\n return null\n }\n\n const grade = grades.find((g: any) => value >= g.minValue && value <= g.maxValue)\n if (!grade) {\n return null\n }\n\n return {\n score: grade.score,\n calculationMethod: 'lookup'\n }\n }\n\n /**\n * 2D lookup table에서 점수 계산 (X13: 공정률 × 편차 → 점수 1~5)\n */\n private calculateScoreFrom2DLookup(\n deviationValue: number,\n grades: any,\n progressRate?: number\n ): { score: number; calculationMethod: string } | null {\n if (!grades.rows || !Array.isArray(grades.rows)) return null\n\n const progress = progressRate ?? 50\n const progressIndex = Math.min(99, Math.max(0, Math.floor(progress)))\n const row = grades.rows.find((r: any) => r.progressRate === progressIndex)\n if (!row) return null\n\n let score: number\n if (deviationValue < row.boundary5to4) {\n score = 5\n } else if (deviationValue < row.boundary4to3) {\n score = 4\n } else if (deviationValue < row.boundary3to2) {\n score = 3\n } else if (deviationValue < row.boundary2to1) {\n score = 2\n } else {\n score = 1\n }\n\n return { score, calculationMethod: 'PROGRESS_DEVIATION_LOOKUP' }\n }\n\n /**\n * KpiValue의 성과 점수 계산 및 저장\n * @param context.progressRate X13 등 2D lookup KPI에 필요한 공정률 (0~100)\n */\n private async calculateAndSaveScore(\n kpiValue: KpiValue,\n kpi: Kpi,\n context?: { progressRate?: number }\n ): 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, context)\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 * 참고: recalculateProjectKpiValues에서 호출 시 기존 값이 이미 삭제되었으므로 항상 새로 생성됩니다.\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 version: kpi.version || 1,\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를 계산합니다.\n * 1. formula가 있으면 자식 KPI 값들을 변수로 사용하여 formula 계산\n * 2. formula가 없으면 자식 KPI scores의 weighted average로 계산\n * 참고: recalculateProjectKpiValues에서 호출 시 기존 값이 이미 삭제되었으므로 항상 새로 생성됩니다.\n */\n private async recalculateParentKpiValue(\n parentKpi: Kpi,\n projectId: string,\n allKpis: Kpi[],\n context: ResolverContext\n ): 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 let calculatedValue: number\n let calculatedScore: number\n\n // 1. formula가 있으면 formula로 계산\n if (parentKpi.formula) {\n try {\n const ast = parseFormula(parentKpi.formula)\n\n // 자식 KPI 이름 -> score 값 매핑을 위한 provider\n const childKpiScoreMap: Record<string, number> = {}\n childKpiValues.forEach(kpiValue => {\n const childKpi = childKpis.find(k => k.id === kpiValue.kpi.id)\n if (childKpi) {\n childKpiScoreMap[childKpi.name] = kpiValue.score ?? 0\n }\n })\n\n const provider = {\n get: async (name: string) => {\n const value = childKpiScoreMap[name]\n if (value === undefined) {\n throw new Error(`Child KPI '${name}' not found in parent KPI formula`)\n }\n return value\n }\n }\n\n const evalContext = { functions: builtinFunctions, provider }\n const result = await evaluateFormula(ast, evalContext)\n\n calculatedValue = result\n calculatedScore = result\n\n console.log(`Calculated parent KPI ${parentKpi.name} using formula: value=${calculatedValue.toFixed(4)}`)\n } catch (error) {\n console.error(`Failed to evaluate formula for parent KPI ${parentKpi.name}:`, error)\n // formula 계산 실패 시 가중치 평균으로 대체\n const { weightedValue, weightedScore } = this.calculateWeightedAverage(childKpiValues, childKpis)\n calculatedValue = weightedValue\n calculatedScore = weightedScore\n console.log(`Fallback to weighted average for parent KPI ${parentKpi.name}`)\n }\n } else {\n // 2. formula가 없으면 가중치 평균 계산\n const { weightedValue, weightedScore } = this.calculateWeightedAverage(childKpiValues, childKpis)\n calculatedValue = weightedValue\n calculatedScore = weightedScore\n console.log(`Calculated parent KPI ${parentKpi.name} using weighted average`)\n }\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 = calculatedValue\n parentKpiValue.score = calculatedScore\n parentKpiValue.version = parentKpi.version || 1\n parentKpiValue.updater = user\n } else {\n // 새 값 생성\n parentKpiValue = kpiValueRepo.create({\n kpi: parentKpi,\n group: projectId,\n version: parentKpi.version || 1,\n domain,\n valueDate: new Date().toISOString().slice(0, 10),\n value: calculatedValue,\n score: calculatedScore,\n updater: user\n })\n }\n\n await kpiValueRepo.save(parentKpiValue)\n console.log(`Updated parent KPI ${parentKpi.name}: value=${calculatedValue.toFixed(4)}, score=${calculatedScore.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 /* value.score 가 value 역할을 value.value 가 아니라 value.score 가 맞다. */\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"]}
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, ObjectType, Field } from 'type-graphql'\nimport { getRepository, ScalarObject, EnvVar, Domain } from '@things-factory/shell'\nimport { runScenario } from '@things-factory/integration-base'\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'\nimport FormData from 'form-data'\nimport fetch from 'node-fetch'\nimport https from 'https'\nimport http from 'http'\n\n/**\n * 외부 시스템 데이터 수집 결과 — 시스템별 한 row.\n * UI \"자동 수집\" 버튼이 시나리오 호출 후 시스템별 성공·오류 표시에 사용.\n */\n@ObjectType({ description: '외부 시스템(세움터/올바로/키스콘) 데이터 수집 시나리오 호출 결과' })\nclass ExternalDataCollectionResult {\n @Field({ description: '소스 키: saeumteo | allbaro | kiscon' })\n source!: string\n\n @Field({ description: '표시 라벨 (세움터/올바로/키스콘)' })\n label!: string\n\n @Field({ description: '시나리오 실행 성공 여부' })\n ok!: boolean\n\n @Field({ description: '성공 시 \"완료\", 실패 시 에러 메시지' })\n message!: string\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n '시나리오 result 객체 — projectKey: value 맵. ' +\n '세움터={area, floorAreaRatio, upperFloorCount, lowerFloorCount, structureType, siteType}, ' +\n '올바로={totalConstructionWasteAmount}, ' +\n '키스콘={constructionPeriod, constructionCost}. ' +\n 'siteType (건축물 용도, 예 APARTMENT_COMPLEX) / structureType (구조형태) 는 ' +\n 'BuildingComplex 의 시설유형/구조유형 속성 후보. KISCON 의 \"공사유형(신설/증축)\" 은 ' +\n 'DSSP SiteType (용도분류) 와 다른 도메인이라 매핑 대상 아님.'\n })\n data?: any\n}\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueMutation {\n /* 프로젝트 수행과정 중에 (시간, 비용, 발생 건수 등) 누적된 값을 반영하여 KPI Metric Value 값을 수정 - 예를 들면, 총 설계 변경 건수, 총 건설 폐기물 발생량, 공사비, 공사기간, 재해 건수 등 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"input\", 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 return await this.upsertKpiMetricValues(patches, context)\n }\n\n /* 전문 감리사에 의해서 평가된 별점을 반영하여 KPI Metric Value 값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"assessment\", 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 return await this.upsertKpiMetricValues(patches, context)\n }\n\n /**\n * KpiMetricValue 의 unique 조합 (domain, metric, valueDate, org) 기준 진짜 upsert.\n *\n * 기존 mutation 의 `repo.save({...patch})` 는 patch.id 만 보고 update/insert 결정해\n * 같은 metric × 같은 valueDate × 같은 org 인데 patch.id 가 새 UUID 인 경우 unique\n * 인덱스 (ix_kpi_metric_value_latest) 위반 에러 또는 row 누적 위험. 정확한 upsert\n * 동작을 보장하기 위해 조합 lookup → 기존 id 사용 → save.\n *\n * 월별 metric (periodType=MONTH, valueDate=YYYY-MM-01) 의 단일 row 정책을 자연 충족.\n *\n * **도메인 컨텍스트 스위치**: caller (운영자) 가 system 도메인일 수 있어 patch.org\n * (= projectId) 로 프로젝트 테넌트 도메인을 lookup 해 그 컨텍스트로 저장. 모든\n * patch 가 같은 projectId 라 가정 (한 번의 mutation = 한 프로젝트의 값들).\n */\n private async upsertKpiMetricValues(\n patches: KpiMetricValuePatch[],\n context: ResolverContext\n ): Promise<KpiMetricValue[]> {\n if (patches.length === 0) return []\n // 첫 patch.org 의 projectId 로 도메인 스위치. patch.org 가 없으면 caller context 그대로.\n const projectId = (patches[0] as any).org\n const ctx = projectId ? await this.switchToProjectDomain(projectId, context) : context\n const { domain, user, tx } = ctx.state\n const metricValueRepo = getRepository(KpiMetricValue, tx)\n const metricRepo = getRepository(KpiMetric, tx)\n\n const results: KpiMetricValue[] = []\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 // unique 조합 기준 기존 row lookup. 있으면 그 id 로 save → update.\n const existing = await metricValueRepo.findOne({\n where: {\n domain: { id: domain.id },\n metric: { id: patch.metricId },\n valueDate: patch.valueDate,\n org: patch.org\n } as any\n })\n const result = await metricValueRepo.save({\n domain,\n ...patch,\n id: existing?.id ?? patch.id,\n metric,\n updater: user\n } as any)\n results.push(result)\n }\n return results\n }\n\n /* 전문 감리사에 의 감리 최종 평가서의 긍부정을 텍스트 분석하는 감정 분석 기반 평가값을 수정 */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"sentiment\", 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 uploadedFile = await attachment.file\n const { filename } = uploadedFile\n const fileBuffer = await this.readFileToBuffer(uploadedFile)\n\n console.log(`Processing PDF file: ${filename}, size: ${fileBuffer.length} bytes`)\n\n // 4. 새 파일 저장 (버퍼를 사용하여 attachment 생성)\n const recreatedFile = this.createFileUploadFromBuffer(fileBuffer, filename, 'application/pdf')\n const { id: resultId } = await createAttachment(null, { attachment: { ...attachment, file: recreatedFile } }, context)\n const result = await attachmentRepo.findOne({ where: { id: resultId } })\n projectRepo.update(projectId, { completeReport: result })\n\n // 5. pdf 파일을 operator-runner 서비스에 업로드하여 분석\n let safetyScore = 0\n let qualityScore = 0\n\n try {\n const operatorRunnerUrl = process.env.OPERATOR_RUNNER_URL || 'https://hatiolab-korea-uni.ettisoft.com'\n\n // sl-pa-safety 서비스 호출\n safetyScore = await this.callOperatorRunnerServiceWithBuffer(operatorRunnerUrl, 'sl-pa-safety', fileBuffer, filename)\n\n // sl-pa-quality 서비스 호출\n qualityScore = await this.callOperatorRunnerServiceWithBuffer(operatorRunnerUrl, 'sl-pa-quality', fileBuffer, filename)\n } catch (error) {\n console.error('Failed to analyze PDF with operator-runner:', error)\n }\n\n // 5. 메트릭 점수 저장\n await this.saveMetricValue(metricValueRepo, metricRepo, projectId, 'SL-PA 안전 평가', safetyScore, domain, user)\n await this.saveMetricValue(metricValueRepo, metricRepo, projectId, 'SL-PA 품질 평가', qualityScore, domain, user)\n\n return result\n }\n\n /**\n * FileUpload 스트림을 버퍼로 읽기\n */\n private async readFileToBuffer(fileUpload: any): Promise<Buffer> {\n const { createReadStream } = fileUpload\n const chunks: Buffer[] = []\n\n return new Promise((resolve, reject) => {\n const stream = createReadStream()\n stream.on('data', (chunk: Buffer) => chunks.push(chunk))\n stream.on('end', () => resolve(Buffer.concat(chunks)))\n stream.on('error', (error: Error) => reject(error))\n })\n }\n\n /**\n * Buffer로부터 FileUpload 객체 생성\n */\n private createFileUploadFromBuffer(buffer: Buffer, filename: string, mimetype: string): any {\n const { Readable } = require('stream')\n return {\n filename,\n mimetype,\n encoding: '7bit',\n createReadStream: () => {\n const readable = new Readable()\n readable.push(buffer)\n readable.push(null)\n return readable\n }\n }\n }\n\n /**\n * operator-runner 서비스 호출 (Buffer 사용)\n */\n private async callOperatorRunnerServiceWithBuffer(\n baseUrl: string,\n serviceName: string,\n fileBuffer: Buffer,\n filename: string\n ): Promise<number> {\n console.log(`Calling operator-runner service: ${serviceName}`)\n console.log(`Base URL: ${baseUrl}`)\n console.log(`Filename: ${filename}`)\n console.log(`Buffer size: ${fileBuffer.length} bytes`)\n\n const formData = new FormData()\n\n // Buffer를 스트림으로 변환하여 추가\n const { Readable } = require('stream')\n const bufferStream = Readable.from(fileBuffer)\n\n formData.append('files', bufferStream, {\n filename,\n contentType: 'application/pdf'\n })\n\n const url = `${baseUrl}/api/run/${serviceName}`\n console.log(`Request URL: ${url}`)\n\n // HTTP/HTTPS agent 설정\n const isHttps = url.startsWith('https')\n const agent = isHttps\n ? new https.Agent({\n keepAlive: false,\n timeout: 120000,\n rejectUnauthorized: false\n })\n : new http.Agent({\n keepAlive: false,\n timeout: 120000\n })\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n body: formData as any,\n headers: {\n ...formData.getHeaders(),\n Authorization: `Basic ${Buffer.from('admin:admin1234').toString('base64')}`\n },\n agent,\n timeout: 120000\n })\n\n console.log(`Response status: ${response.status}`)\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error(`Service ${serviceName} error response:`, errorText)\n throw new Error(`Service ${serviceName} failed (${response.status}): ${errorText}`)\n }\n\n const data = await response.json()\n console.log(`Service ${serviceName} response:`, JSON.stringify(data))\n\n const score = data?.result?.score || data?.score || 0\n console.log(`Extracted score: ${score}`)\n\n return score\n } catch (error) {\n console.error(`Error calling ${serviceName}:`, error)\n throw error\n }\n }\n\n /**\n * 메트릭 값 저장\n */\n private async saveMetricValue(\n metricValueRepo: any,\n metricRepo: any,\n projectId: string,\n metricName: string,\n value: number,\n domain: any,\n user: any\n ): Promise<void> {\n const metricValue = await metricValueRepo.findOne({\n where: { org: projectId, metric: { name: metricName } }\n })\n\n if (metricValue) {\n await metricValueRepo.save({\n ...metricValue,\n value,\n updater: user\n })\n } else {\n const originMetric = await metricRepo.findOne({ where: { name: metricName } })\n if (originMetric) {\n await metricValueRepo.save({\n metric: { id: originMetric.id },\n unit: originMetric.unit || '',\n org: projectId,\n periodType: originMetric.periodType,\n valueDate: moment().tz('Asia/Seoul').format('YYYY-MM-DD'),\n value,\n domain,\n updater: user\n })\n }\n }\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"finalize\", 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 // 외부 시스템 데이터 수집은 별도 mutation (collectProjectExternalData) 로 분리 —\n // 사용자가 UI \"자동 수집\" 버튼으로 명시 실행. finalize/recalculate 흐름에서는\n // 외부 연동을 끌어들이지 않음 (DB 에 이미 저장된 KpiMetricValue 만 가지고 계산).\n const projectContext = await this.switchToProjectDomain(projectId, context)\n\n await this.recalculateProjectKpiValues(projectId, projectContext)\n\n projectRepo.save({\n ...project,\n state: ProjectState.COMPLETED\n })\n\n return true\n }\n\n /**\n * 완공 처리 없이 KPI 만 재계산 — 진행 중 프로젝트의 중간 결과 산정 용도.\n * DB 에 이미 저장된 KpiMetricValue 만 가지고 formula 평가. 외부 시나리오 (juso/\n * allbaro/kiscon) 자동 수집은 의도적으로 호출하지 않음 — 외부 수집은 사용자가\n * \"자동 수집\" 버튼 (`collectProjectExternalData`) 으로 명시적으로 실행하는 흐름.\n * 권한은 `kpi:recalculate` 로 분리해 finalize 보다 가볍게 부여 가능.\n */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"recalculate\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => Boolean, { description: 'Recalculate project KPI without finalizing (interim).' })\n async recalculateProjectKpi(\n @Arg('projectId') projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { tx } = context.state\n const project = await getRepository(Project, tx).findOne({ where: { id: projectId } })\n if (!project) {\n throw new Error(`Project not found: ${projectId}`)\n }\n\n const projectContext = await this.switchToProjectDomain(projectId, context)\n await this.recalculateProjectKpiValues(projectId, projectContext)\n\n return true\n }\n\n /**\n * UI \"자동 수집\" 버튼 전용 mutation. 외부 시스템 3종 시나리오를 순차 호출하고\n * 시스템별 성공/실패 + 메시지를 반환. UI 는 결과를 보고 카드별 상태 (성공·오류) 를 표시.\n *\n * 시나리오는 도메인 EnvVar (주소·자격증명·서비스키 등) 만으로 동작하므로 파라미터 X.\n * 한 시스템 실패가 다른 시스템 수집을 막지 않도록 try/catch 로 격리.\n *\n * 운영 현실: 키스콘·올바로는 시공사 ID/PW 가 자주 미확보 → 오류 흔함. 세움터는 공공\n * 데이터 서비스키만으로 동작 가능. UI 는 시스템별로 명확한 오류 메시지 노출.\n */\n @Directive('@privilege(category: \"kpi\", privilege: \"auto-collect\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => [ExternalDataCollectionResult], {\n description: 'Run external data collection scenarios per system, returning per-system result.'\n })\n async collectProjectExternalData(\n @Arg('projectId') projectId: string,\n @Ctx() context: ResolverContext\n ): Promise<ExternalDataCollectionResult[]> {\n const projectContext = await this.switchToProjectDomain(projectId, context)\n return await this.runExternalDataScenariosWithResults(projectContext)\n }\n\n /**\n * 프로젝트 정보 수정 화면의 \"정보 연동\" 버튼 전용 — 세움터 단일 시나리오만 호출.\n * BuildingComplex 기본 속성 (area / floorAreaRatio / siteType / structureType /\n * coverageRatio / householdCount 등) 자동 채움 목적.\n *\n * address 인자가 있으면 시나리오 실행 전에 EnvVar `Step::건축물관리대장조회::address::query`\n * 를 그 값으로 upsert — 운영자가 폼에서 방금 입력한 주소를 시나리오가 곧바로 사용.\n * (도메인의 기존 EnvVar 와 다를 수 있어 명시적 갱신.)\n *\n * **도메인 스위치**: mutation 호출은 system / 운영자 도메인에서 일어나지만 시나리오·\n * EnvVar 는 **프로젝트가 속한 도메인** 에 있어야 자연. project.domain 으로 컨텍스트\n * 스위치 후 그 도메인에서 EnvVar upsert + 시나리오 실행.\n */\n @Directive('@transaction')\n @Directive('@privilege(category: \"kpi\", privilege: \"basic-info\", domainOwnerGranted: true, superUserGranted: true)')\n @Mutation(returns => ExternalDataCollectionResult, {\n description: 'Run only 건축물관리대장조회 scenario for project basic info collection.'\n })\n async collectProjectBasicInfo(\n @Arg('projectId') projectId: string,\n @Arg('address', { nullable: true }) address: string,\n @Ctx() context: ResolverContext\n ): Promise<ExternalDataCollectionResult> {\n const projectContext = await this.switchToProjectDomain(projectId, context)\n if (address && address.trim()) {\n await this.upsertEnvVar('Step::건축물관리대장조회::address::query', address.trim(), projectContext)\n }\n return await this.runSingleScenario(\n { source: 'saeumteo', label: '세움터', name: '건축물관리대장조회' },\n projectContext\n )\n }\n\n /**\n * mutation 호출이 system / 운영자 도메인에서 일어나도 시나리오·EnvVar 는 **프로젝트\n * 테넌트 도메인** 에서 동작해야 자연. project.code 로 자식 (테넌트) 도메인을 찾아\n * 컨텍스트 사본 만들어 반환.\n *\n * 테넌트 도메인 매핑: Domain.subdomain = project.code AND Domain.extType = 'project'\n * (promoteProjectToTenant mutation 이 그렇게 생성). project.domain 자체는 부모\n * 도메인이라 외부 연동 EnvVar 가 거기 있을 일이 없어 사용 부적합.\n *\n * 테넌트 도메인이 없거나 (= 아직 승격 안 됨) project.code 가 비어있으면 원본\n * 컨텍스트 그대로 반환 (방어). project 자체가 없으면 throw.\n */\n private async switchToProjectDomain(\n projectId: string,\n context: ResolverContext\n ): Promise<ResolverContext> {\n const { tx } = context.state\n const project = await getRepository(Project, tx).findOne({ where: { id: projectId } })\n if (!project) {\n throw new Error(`Project not found: ${projectId}`)\n }\n if (!project.code) {\n console.warn(`[collect] project ${projectId} 는 아직 테넌트 승격되지 않음 (no code) — caller domain 그대로 사용`)\n return context\n }\n const tenantDomain = await getRepository(Domain, tx).findOne({\n where: { subdomain: project.code, extType: 'project' } as any\n })\n if (!tenantDomain) {\n console.warn(\n `[collect] project ${projectId} (code=${project.code}) 의 테넌트 도메인을 찾지 못함 — caller domain 그대로 사용`\n )\n return context\n }\n return {\n ...context,\n state: { ...context.state, domain: tenantDomain }\n } as ResolverContext\n }\n\n /**\n * 컨텍스트의 도메인에 EnvVar 1개 upsert. 시나리오가 도메인 EnvVar 를 우선 참조하는\n * 정책이라, 폼에서 입력한 주소를 시나리오 입력으로 흘리는 다리 역할.\n */\n private async upsertEnvVar(name: string, value: string, context: ResolverContext): Promise<void> {\n const { domain, user, tx } = context.state\n const repo = getRepository(EnvVar, tx)\n const existing = await repo.findOne({ where: { domain: { id: domain.id }, name } as any })\n if (existing) {\n existing.value = value\n existing.active = true\n ;(existing as any).updater = user\n await repo.save(existing)\n } else {\n await repo.save(\n repo.create({\n name,\n value,\n active: true,\n domain,\n description: 'Project basic info 자동 연동용 (project-update 정보연동 버튼)',\n creator: user,\n updater: user\n } as any)\n )\n }\n }\n\n /**\n * 단일 시나리오 호출 + result unwrap + 실패 판정 — collectProjectExternalData 의\n * loop 본체와 같은 로직을 1건짜리로 분리.\n */\n private async runSingleScenario(\n s: { source: string; label: string; name: string },\n context: ResolverContext\n ): Promise<ExternalDataCollectionResult> {\n const { domain } = context.state\n const instanceName = `collect-${s.name}-${Date.now()}`\n try {\n const runResult: any = await runScenario(instanceName, s.name, {}, context)\n if (!runResult) {\n console.warn(`[collect] '${s.name}' no result on domain '${domain.subdomain}'`)\n throw new Error('업데이트할 정보가 없습니다')\n }\n if (runResult.state === 'HALTED') {\n console.warn(\n `[collect] '${s.name}' HALTED on domain '${domain.subdomain}': ${runResult.message || '(no message)'}`\n )\n throw new Error('업데이트할 정보가 없습니다')\n }\n\n let data = runResult.result ?? runResult.data ?? {}\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n const wrapKeys = Object.keys(data)\n if (\n wrapKeys.length === 1 &&\n data[wrapKeys[0]] &&\n typeof data[wrapKeys[0]] === 'object' &&\n !Array.isArray(data[wrapKeys[0]])\n ) {\n data = data[wrapKeys[0]]\n }\n }\n console.log(`[collect] '${s.name}' OK on '${domain.subdomain}' keys=${Object.keys(data || {}).join(',')}`)\n return { source: s.source, label: s.label, ok: true, message: '완료', data }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.warn(`[collect] '${s.name}' failed on '${domain.subdomain}': ${msg}`)\n return { source: s.source, label: s.label, ok: false, message: msg }\n }\n }\n\n /**\n * 외부 시스템 3종 시나리오 순차 실행 + 시스템별 결과 수집.\n */\n private async runExternalDataScenariosWithResults(context: ResolverContext): Promise<ExternalDataCollectionResult[]> {\n const { domain } = context.state\n const SCENARIOS: Array<{ source: string; label: string; name: string }> = [\n { source: 'saeumteo', label: '세움터', name: '건축물관리대장조회' },\n { source: 'allbaro', label: '올바로', name: '건설폐기물정보조회' },\n { source: 'kiscon', label: '키스콘', name: '건설공사정보조회' }\n ]\n\n const results: ExternalDataCollectionResult[] = []\n for (const s of SCENARIOS) {\n results.push(await this.runSingleScenario(s, context))\n }\n return results\n }\n\n /**\n * finalize 흐름용 시나리오 호출. 결과 형태 없이 진행만 — finalize 의 KPI 재계산이 곧\n * 이어지므로 시스템별 결과를 클라이언트에 돌려줄 필요 없음. 실패는 warning 만.\n */\n private async runExternalDataScenarios(context: ResolverContext): Promise<void> {\n await this.runExternalDataScenariosWithResults(context)\n }\n\n /**\n * 프로젝트의 모든 KPI Value들을 계층적으로 재계산합니다.\n * 1. 기존 KPI Value 삭제 (중복 방지)\n * 2. Leaf KPIs (자식이 없는 KPI): formula 기반 계산\n * 3. 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 Value 삭제 (재계산으로 인한 중복 방지)\n const existingKpiValues = await kpiValueRepo.find({\n where: {\n group: projectId,\n domain: { id: domain.id }\n }\n })\n\n if (existingKpiValues.length > 0) {\n await kpiValueRepo.remove(existingKpiValues)\n console.log(`Deleted ${existingKpiValues.length} existing KPI values for project ${projectId}`)\n }\n\n // 2. 모든 KPI들을 조회 (계층 구조 포함)\n const allKpis = await kpiRepo.find({\n relations: ['parent', 'children']\n })\n\n console.log(`Found ${allKpis.length} KPIs total for domain`)\n\n // 3. 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 // 4. 먼저 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 // 5. Parent KPIs를 계층 레벨순으로 정렬 (깊은 레벨부터)\n const sortedParentKpis = this.sortKpisByLevel(parentKpis, allKpis)\n\n // 6. 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 } catch (error) {\n console.error(`Error recalculating KPI values for project ${projectId}:`, error)\n throw error\n }\n }\n\n /**\n * 개별 KPI Value를 재계산합니다.\n * 항상 최신 버전의 KPI를 사용하여 계산합니다.\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 // 항상 최신 버전의 KPI를 조회하여 사용\n // kpiValue.kpi가 이미 로드되어 있으면 사용하고, 없으면 DB에서 최신 버전 조회\n const kpi =\n kpiValue.kpi ||\n (await kpiRepo.findOne({\n where: { id: kpiValue.kpiId },\n order: { version: 'DESC' }\n }))\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.version = kpi.version || 1\n kpiValue.updater = user\n\n // 성과 점수 자동 계산 및 저장\n try {\n // 2D lookup KPI (X13 등)인 경우 project의 totalProgress 조회\n let scoreContext: { progressRate?: number } | undefined\n const gradesData = kpi.grades as any\n if (gradesData && !Array.isArray(gradesData) && gradesData.type === 'PROGRESS_DEVIATION_LOOKUP') {\n const projectId = kpiValue.group || org\n const projectRepo = getRepository(Project, tx)\n const project = await projectRepo.findOne({ where: { id: projectId } })\n scoreContext = { progressRate: project?.totalProgress ?? 50 }\n console.log(`2D lookup KPI ${kpi.name}: progressRate=${scoreContext.progressRate}%`)\n }\n\n await this.calculateAndSaveScore(kpiValue, kpi, scoreContext)\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 return {\n score: performanceScore,\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 * 1D (기존 배열) 및 2D (X13 공정률×편차) lookup 모두 지원\n */\n private calculateScoreFromLookup(\n kpi: Kpi,\n value: number,\n context?: { progressRate?: number }\n ): { score: number; calculationMethod: string } | null {\n if (!kpi.grades) {\n return null\n }\n\n // 2D lookup table 처리 (X13: 공정률 × 편차 → 점수)\n const grades = kpi.grades as any\n if (!Array.isArray(grades) && grades.type === 'PROGRESS_DEVIATION_LOOKUP') {\n return this.calculateScoreFrom2DLookup(value, grades, context?.progressRate)\n }\n\n // 1D lookup table 처리 (기존)\n if (!Array.isArray(grades) || grades.length === 0) {\n return null\n }\n\n const grade = grades.find((g: any) => value >= g.minValue && value <= g.maxValue)\n if (!grade) {\n return null\n }\n\n return {\n score: grade.score,\n calculationMethod: 'lookup'\n }\n }\n\n /**\n * 2D lookup table에서 점수 계산 (X13: 공정률 × 편차 → 점수 1~5)\n */\n private calculateScoreFrom2DLookup(\n deviationValue: number,\n grades: any,\n progressRate?: number\n ): { score: number; calculationMethod: string } | null {\n if (!grades.rows || !Array.isArray(grades.rows)) return null\n\n const progress = progressRate ?? 50\n const progressIndex = Math.min(99, Math.max(0, Math.floor(progress)))\n const row = grades.rows.find((r: any) => r.progressRate === progressIndex)\n if (!row) return null\n\n let score: number\n if (deviationValue < row.boundary5to4) {\n score = 5\n } else if (deviationValue < row.boundary4to3) {\n score = 4\n } else if (deviationValue < row.boundary3to2) {\n score = 3\n } else if (deviationValue < row.boundary2to1) {\n score = 2\n } else {\n score = 1\n }\n\n return { score, calculationMethod: 'PROGRESS_DEVIATION_LOOKUP' }\n }\n\n /**\n * KpiValue의 성과 점수 계산 및 저장\n * @param context.progressRate X13 등 2D lookup KPI에 필요한 공정률 (0~100)\n */\n private async calculateAndSaveScore(\n kpiValue: KpiValue,\n kpi: Kpi,\n context?: { progressRate?: number }\n ): 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, context)\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 * 참고: recalculateProjectKpiValues에서 호출 시 기존 값이 이미 삭제되었으므로 항상 새로 생성됩니다.\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 version: kpi.version || 1,\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를 계산합니다.\n * 1. formula가 있으면 자식 KPI 값들을 변수로 사용하여 formula 계산\n * 2. formula가 없으면 자식 KPI scores의 weighted average로 계산\n * 참고: recalculateProjectKpiValues에서 호출 시 기존 값이 이미 삭제되었으므로 항상 새로 생성됩니다.\n */\n private async recalculateParentKpiValue(\n parentKpi: Kpi,\n projectId: string,\n allKpis: Kpi[],\n context: ResolverContext\n ): 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 let calculatedValue: number\n let calculatedScore: number\n\n // 1. formula가 있으면 formula로 계산\n if (parentKpi.formula) {\n try {\n const ast = parseFormula(parentKpi.formula)\n\n // 자식 KPI 이름 -> score 값 매핑을 위한 provider\n const childKpiScoreMap: Record<string, number> = {}\n childKpiValues.forEach(kpiValue => {\n const childKpi = childKpis.find(k => k.id === kpiValue.kpi.id)\n if (childKpi) {\n childKpiScoreMap[childKpi.name] = kpiValue.score ?? 0\n }\n })\n\n const provider = {\n get: async (name: string) => {\n const value = childKpiScoreMap[name]\n if (value === undefined) {\n throw new Error(`Child KPI '${name}' not found in parent KPI formula`)\n }\n return value\n }\n }\n\n const evalContext = { functions: builtinFunctions, provider }\n const result = await evaluateFormula(ast, evalContext)\n\n calculatedValue = result\n calculatedScore = result\n\n console.log(`Calculated parent KPI ${parentKpi.name} using formula: value=${calculatedValue.toFixed(4)}`)\n } catch (error) {\n console.error(`Failed to evaluate formula for parent KPI ${parentKpi.name}:`, error)\n // formula 계산 실패 시 가중치 평균으로 대체\n const { weightedValue, weightedScore } = this.calculateWeightedAverage(childKpiValues, childKpis)\n calculatedValue = weightedValue\n calculatedScore = weightedScore\n console.log(`Fallback to weighted average for parent KPI ${parentKpi.name}`)\n }\n } else {\n // 2. formula가 없으면 가중치 평균 계산\n const { weightedValue, weightedScore } = this.calculateWeightedAverage(childKpiValues, childKpis)\n calculatedValue = weightedValue\n calculatedScore = weightedScore\n console.log(`Calculated parent KPI ${parentKpi.name} using weighted average`)\n }\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 = calculatedValue\n parentKpiValue.score = calculatedScore\n parentKpiValue.version = parentKpi.version || 1\n parentKpiValue.updater = user\n } else {\n // 새 값 생성\n parentKpiValue = kpiValueRepo.create({\n kpi: parentKpi,\n group: projectId,\n version: parentKpi.version || 1,\n domain,\n valueDate: new Date().toISOString().slice(0, 10),\n value: calculatedValue,\n score: calculatedScore,\n updater: user\n })\n }\n\n await kpiValueRepo.save(parentKpiValue)\n console.log(`Updated parent KPI ${parentKpi.name}: value=${calculatedValue.toFixed(4)}, score=${calculatedScore.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 /* value.score 가 value 역할을 value.value 가 아니라 value.score 가 맞다. */\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"]}
@@ -5,16 +5,23 @@ const tslib_1 = require("tslib");
5
5
  const type_graphql_1 = require("type-graphql");
6
6
  const shell_1 = require("@things-factory/shell");
7
7
  const kpi_1 = require("@things-factory/kpi");
8
+ const domain_inheritance_js_1 = require("@things-factory/kpi/dist-server/service/utils/domain-inheritance.js");
8
9
  const project_1 = require("@dssp/project");
9
10
  let KpiMetricValueQuery = class KpiMetricValueQuery {
10
11
  async kpiMetricValues(params, context) {
11
12
  const { domain } = context.state;
13
+ // multi-level 부모 도메인까지 포함. things-factory 의 KpiMetricValueQuery 와 동일 패턴.
14
+ // SYSTEM → 프로젝트 테넌트 계층에서 정의가 부모에 있고 값이 자식에 있어도 합쳐 보임.
15
+ const domainIds = await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain);
12
16
  const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
13
- domain,
17
+ domain: undefined, // 도메인 필터는 아래에서 IN 절로 직접 추가
14
18
  params,
15
19
  repository: await (0, shell_1.getRepository)(kpi_1.KpiMetricValue),
16
20
  searchables: ['metricId', 'group', 'valueDate', 'org']
17
21
  });
22
+ queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {
23
+ ancestorDomainIds: domainIds
24
+ });
18
25
  const [items, total] = await queryBuilder.getManyAndCount();
19
26
  return { items, total };
20
27
  }
@@ -31,7 +38,7 @@ let KpiMetricValueQuery = class KpiMetricValueQuery {
31
38
  };
32
39
  exports.KpiMetricValueQuery = KpiMetricValueQuery;
33
40
  tslib_1.__decorate([
34
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
41
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
35
42
  (0, type_graphql_1.Query)(returns => kpi_1.KpiMetricValueList, { description: 'To fetch multiple KpiMetricValues' }),
36
43
  tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
37
44
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-metric-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAC9F,iDAAuG;AAEvG,6CAAwE;AACxE,2CAAuC;AAGhC,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAGxB,AAAN,KAAK,CAAC,eAAe,CACM,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM;YACN,MAAM;YACN,UAAU,EAAE,MAAM,IAAA,qBAAa,EAAC,oBAAc,CAAC;YAC/C,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC;SACvD,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,cAA8B;QAClD,IAAI,CAAC,cAAc,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,IAAA,qBAAa,EAAC,iBAAO,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC,GAAG,EAAE,CAAC,CAAA;QAC3E,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA;AA7BY,kDAAmB;AAGxB;IAFL,IAAA,wBAAS,EAAC,mGAAmG,CAAC;IAC9G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,wBAAkB,EAAE,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IAExF,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;0DAc3C;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpC,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAiB,oBAAc;;kDAOnD;8BA5BU,mBAAmB;IAD/B,IAAA,uBAAQ,EAAC,oBAAc,CAAC;GACZ,mBAAmB,CA6B/B","sourcesContent":["import { Directive, Resolver, Query, Args, Arg, Ctx, FieldResolver, Root } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { KpiMetricValue, KpiMetricValueList } from '@things-factory/kpi'\nimport { Project } from '@dssp/project'\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiMetricValueList, { description: 'To fetch multiple KpiMetricValues' })\n async kpiMetricValues(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValueList> {\n const { domain } = context.state\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(KpiMetricValue),\n searchables: ['metricId', 'group', 'valueDate', 'org']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => Project, { nullable: true })\n async project(@Root() kpiMetricValue: KpiMetricValue): Promise<Project | null> {\n if (!kpiMetricValue.org) return null\n try {\n return await getRepository(Project).findOneBy({ id: kpiMetricValue.org })\n } catch {\n return null\n }\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-metric-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-metric-value/kpi-metric-value-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8F;AAC9F,iDAAuG;AAEvG,6CAAwE;AACxE,+GAA+G;AAC/G,2CAAuC;AAGhC,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAGxB,AAAN,KAAK,CAAC,eAAe,CACM,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAChC,yEAAyE;QACzE,sDAAsD;QACtD,MAAM,SAAS,GAAG,MAAM,IAAA,iDAAyB,EAAC,MAAM,CAAC,CAAA;QAEzD,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM,EAAE,SAAS,EAAE,2BAA2B;YAC9C,MAAM;YACN,UAAU,EAAE,MAAM,IAAA,qBAAa,EAAC,oBAAc,CAAC;YAC/C,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC;SACvD,CAAC,CAAA;QAEF,YAAY,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,KAAK,oCAAoC,EAAE;YAC/E,iBAAiB,EAAE,SAAS;SAC7B,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,cAA8B;QAClD,IAAI,CAAC,cAAc,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,IAAA,qBAAa,EAAC,iBAAO,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC,GAAG,EAAE,CAAC,CAAA;QAC3E,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF,CAAA;AArCY,kDAAmB;AAGxB;IAFL,IAAA,wBAAS,EAAC,kGAAkG,CAAC;IAC7G,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,wBAAkB,EAAE,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IAExF,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;0DAsB3C;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpC,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAiB,oBAAc;;kDAOnD;8BApCU,mBAAmB;IAD/B,IAAA,uBAAQ,EAAC,oBAAc,CAAC;GACZ,mBAAmB,CAqC/B","sourcesContent":["import { Directive, Resolver, Query, Args, Arg, Ctx, FieldResolver, Root } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { KpiMetricValue, KpiMetricValueList } from '@things-factory/kpi'\nimport { getDomainIdsWithAncestors } from '@things-factory/kpi/dist-server/service/utils/domain-inheritance.js'\nimport { Project } from '@dssp/project'\n\n@Resolver(KpiMetricValue)\nexport class KpiMetricValueQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"read\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiMetricValueList, { description: 'To fetch multiple KpiMetricValues' })\n async kpiMetricValues(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiMetricValueList> {\n const { domain } = context.state\n // multi-level 부모 도메인까지 포함. things-factory 의 KpiMetricValueQuery 와 동일 패턴.\n // SYSTEM → 프로젝트 테넌트 계층에서 정의가 부모에 있고 값이 자식에 있어도 합쳐 보임.\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain: undefined, // 도메인 필터는 아래에서 IN 절로 직접 추가\n params,\n repository: await getRepository(KpiMetricValue),\n searchables: ['metricId', 'group', 'valueDate', 'org']\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => Project, { nullable: true })\n async project(@Root() kpiMetricValue: KpiMetricValue): Promise<Project | null> {\n if (!kpiMetricValue.org) return null\n try {\n return await getRepository(Project).findOneBy({ id: kpiMetricValue.org })\n } catch {\n return null\n }\n }\n}\n"]}
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const type_graphql_1 = require("type-graphql");
6
6
  const shell_1 = require("@things-factory/shell");
7
7
  const kpi_1 = require("@things-factory/kpi");
8
+ const domain_inheritance_js_1 = require("@things-factory/kpi/dist-server/service/utils/domain-inheritance.js");
8
9
  const kpi_stat_types_1 = require("./kpi-stat-types");
9
10
  let KpiStatQuery = class KpiStatQuery {
10
11
  async totalKpiZValueComprehensiveStats(startYearMonth, endYearMonth, sectorType, buildingUsage, context) {
@@ -25,7 +26,7 @@ let KpiStatQuery = class KpiStatQuery {
25
26
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
26
27
  .where('k.name LIKE :pattern', { pattern: 'Z%' })
27
28
  .andWhere('p.end_date IS NOT NULL')
28
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
29
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
29
30
  // 기간 필터
30
31
  if (startYearMonth && startYearMonth.trim() !== '') {
31
32
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
@@ -80,7 +81,7 @@ let KpiStatQuery = class KpiStatQuery {
80
81
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
81
82
  .where('k.name LIKE :pattern', { pattern: 'Y%' })
82
83
  .andWhere('p.end_date IS NOT NULL')
83
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
84
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
84
85
  // 기간 필터
85
86
  if (startYearMonth && startYearMonth.trim() !== '') {
86
87
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
@@ -153,7 +154,7 @@ let KpiStatQuery = class KpiStatQuery {
153
154
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
154
155
  .where('p.end_date IS NOT NULL')
155
156
  .andWhere('p.geo_group IS NOT NULL')
156
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
157
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
157
158
  // 기간 필터
158
159
  if (startYearMonth && startYearMonth.trim() !== '') {
159
160
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
@@ -223,7 +224,7 @@ let KpiStatQuery = class KpiStatQuery {
223
224
  .where('k.name LIKE :pattern', { pattern: 'Y%' })
224
225
  .andWhere('p.end_date IS NOT NULL')
225
226
  .andWhere('p.geo_group IS NOT NULL')
226
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id })
227
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) })
227
228
  .groupBy('p.geo_group, k.name');
228
229
  if (geoGroup && geoGroup.trim() !== '') {
229
230
  queryBuilder.andWhere('p.geo_group LIKE :geoGroup', { geoGroup: `%${geoGroup}%` });
@@ -285,7 +286,7 @@ let KpiStatQuery = class KpiStatQuery {
285
286
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
286
287
  .where('p.end_date IS NOT NULL')
287
288
  .andWhere('p.geo_group IS NOT NULL')
288
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
289
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
289
290
  // 기간 필터
290
291
  if (startYearMonth && startYearMonth.trim() !== '') {
291
292
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
@@ -341,7 +342,7 @@ let KpiStatQuery = class KpiStatQuery {
341
342
  .leftJoin('kpis', 'pk', 'k.parent_id = pk.id')
342
343
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
343
344
  .where('p.end_date IS NOT NULL')
344
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
345
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
345
346
  if (sectorType === null || sectorType === void 0 ? void 0 : sectorType.trim()) {
346
347
  qb.andWhere('p.sector_type = :sectorType', { sectorType });
347
348
  }
@@ -391,7 +392,7 @@ let KpiStatQuery = class KpiStatQuery {
391
392
  .innerJoin('projects', 'p', 'kv.kpi_org_scope_id = p.id')
392
393
  .where('p.end_date IS NOT NULL')
393
394
  .andWhere('p.geo_group IS NOT NULL')
394
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
395
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
395
396
  if (startYearMonth === null || startYearMonth === void 0 ? void 0 : startYearMonth.trim()) {
396
397
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
397
398
  }
@@ -446,7 +447,7 @@ let KpiStatQuery = class KpiStatQuery {
446
447
  .where('k.name LIKE :pattern', { pattern: 'Y%' })
447
448
  .andWhere('p.end_date IS NOT NULL')
448
449
  .andWhere('p.geo_group = :geoGroup', { geoGroup })
449
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
450
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
450
451
  if (startYearMonth === null || startYearMonth === void 0 ? void 0 : startYearMonth.trim()) {
451
452
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
452
453
  }
@@ -490,7 +491,7 @@ let KpiStatQuery = class KpiStatQuery {
490
491
  .where('k.name LIKE :pattern', { pattern: 'Y%' })
491
492
  .andWhere('p.end_date IS NOT NULL')
492
493
  .andWhere('p.geo_group IS NOT NULL')
493
- .andWhere('kv.domain_id = :domainId', { domainId: domain.id });
494
+ .andWhere('kv.domain_id IN (:...domainIds)', { domainIds: await (0, domain_inheritance_js_1.getDomainIdsWithAncestors)(domain) });
494
495
  // 기간 필터
495
496
  if (startYearMonth && startYearMonth.trim() !== '') {
496
497
  queryBuilder.andWhere(`TO_CHAR(p.end_date, 'YYYY-MM') >= :startYearMonth`, { startYearMonth });
@@ -545,7 +546,7 @@ let KpiStatQuery = class KpiStatQuery {
545
546
  };
546
547
  exports.KpiStatQuery = KpiStatQuery;
547
548
  tslib_1.__decorate([
548
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
549
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
549
550
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStats], { description: 'Get KPI box plot statistics for Z-category KPIs for all projects' }),
550
551
  tslib_1.__param(0, (0, type_graphql_1.Arg)('startYearMonth', { nullable: true })),
551
552
  tslib_1.__param(1, (0, type_graphql_1.Arg)('endYearMonth', { nullable: true })),
@@ -557,7 +558,7 @@ tslib_1.__decorate([
557
558
  tslib_1.__metadata("design:returntype", Promise)
558
559
  ], KpiStatQuery.prototype, "totalKpiZValueComprehensiveStats", null);
559
560
  tslib_1.__decorate([
560
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
561
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
561
562
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStats], { description: 'Get KPI box plot statistics for Y-category KPIs for all projects' }),
562
563
  tslib_1.__param(0, (0, type_graphql_1.Arg)('startYearMonth', { nullable: true })),
563
564
  tslib_1.__param(1, (0, type_graphql_1.Arg)('endYearMonth', { nullable: true })),
@@ -569,7 +570,7 @@ tslib_1.__decorate([
569
570
  tslib_1.__metadata("design:returntype", Promise)
570
571
  ], KpiStatQuery.prototype, "totalKpiYValueComprehensiveStats", null);
571
572
  tslib_1.__decorate([
572
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
573
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
573
574
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStatsByGeoGroup], {
574
575
  description: 'Get KPI box plot statistics for Z-category KPIs by metro area'
575
576
  }),
@@ -585,7 +586,7 @@ tslib_1.__decorate([
585
586
  tslib_1.__metadata("design:returntype", Promise)
586
587
  ], KpiStatQuery.prototype, "kpiZValueComprehensiveStatsByGeoGroup", null);
587
588
  tslib_1.__decorate([
588
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
589
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
589
590
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStatsByGeoGroup], { description: 'Get KPI box plot statistics for Y-category KPIs by geo group' }),
590
591
  tslib_1.__param(0, (0, type_graphql_1.Arg)('geoGroup', { nullable: true })),
591
592
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -594,7 +595,7 @@ tslib_1.__decorate([
594
595
  tslib_1.__metadata("design:returntype", Promise)
595
596
  ], KpiStatQuery.prototype, "kpiYValueComprehensiveStatsByGeoGroup", null);
596
597
  tslib_1.__decorate([
597
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
598
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
598
599
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiMonthlyTrend], { description: 'Get monthly KPI trend for Z-category KPIs by metro area' }),
599
600
  tslib_1.__param(0, (0, type_graphql_1.Arg)('kpiName', { nullable: true })),
600
601
  tslib_1.__param(1, (0, type_graphql_1.Arg)('startYearMonth', { nullable: true })),
@@ -607,7 +608,7 @@ tslib_1.__decorate([
607
608
  tslib_1.__metadata("design:returntype", Promise)
608
609
  ], KpiStatQuery.prototype, "kpiZValueMonthlyTrendByGeoGroup", null);
609
610
  tslib_1.__decorate([
610
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
611
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
611
612
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiProjectStat], { description: 'Get KPI stats aggregated from project data with optional sectorType/buildingUsage filters' }),
612
613
  tslib_1.__param(0, (0, type_graphql_1.Arg)('sectorType', { nullable: true })),
613
614
  tslib_1.__param(1, (0, type_graphql_1.Arg)('buildingUsage', { nullable: true })),
@@ -620,7 +621,7 @@ tslib_1.__decorate([
620
621
  tslib_1.__metadata("design:returntype", Promise)
621
622
  ], KpiStatQuery.prototype, "kpiProjectStats", null);
622
623
  tslib_1.__decorate([
623
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
624
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
624
625
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStatsByGeoGroup], {
625
626
  description: 'Get KPI statistics by sigungu (geo_group code) level'
626
627
  }),
@@ -635,7 +636,7 @@ tslib_1.__decorate([
635
636
  tslib_1.__metadata("design:returntype", Promise)
636
637
  ], KpiStatQuery.prototype, "kpiZValueStatsBySigungu", null);
637
638
  tslib_1.__decorate([
638
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
639
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
639
640
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStats], { description: 'Get Y-level KPI statistics by geo_group code (sigungu)' }),
640
641
  tslib_1.__param(0, (0, type_graphql_1.Arg)('geoGroup')),
641
642
  tslib_1.__param(1, (0, type_graphql_1.Arg)('startYearMonth', { nullable: true })),
@@ -646,7 +647,7 @@ tslib_1.__decorate([
646
647
  tslib_1.__metadata("design:returntype", Promise)
647
648
  ], KpiStatQuery.prototype, "kpiYValueStatsByGeoGroup", null);
648
649
  tslib_1.__decorate([
649
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "query", domainOwnerGranted: true, superUserGranted: true)'),
650
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "read", domainOwnerGranted: true, superUserGranted: true)'),
650
651
  (0, type_graphql_1.Query)(() => [kpi_stat_types_1.KpiComprehensiveStats], { description: 'Get KPI statistics for Y-category KPIs by specific metro area' }),
651
652
  tslib_1.__param(0, (0, type_graphql_1.Arg)('metroArea')),
652
653
  tslib_1.__param(1, (0, type_graphql_1.Arg)('startYearMonth', { nullable: true })),