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

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 (68) 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-admin/kpi-system-guide.d.ts +1 -1
  11. package/dist-client/pages/kpi-admin/kpi-system-guide.js +29 -21
  12. package/dist-client/pages/kpi-admin/kpi-system-guide.js.map +1 -1
  13. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.d.ts +1 -1
  14. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js +1 -1
  15. package/dist-client/pages/kpi-metric-value/kpi-metric-value-list-page.js.map +1 -1
  16. package/dist-client/pages/kpi-value/kpi-value-list-page.js +1 -1
  17. package/dist-client/pages/kpi-value/kpi-value-list-page.js.map +1 -1
  18. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.d.ts +21 -2
  19. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js +166 -134
  20. package/dist-client/pages/project-complete-tabs/pc-tab1-plan.js.map +1 -1
  21. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.d.ts +4 -2
  22. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js +109 -44
  23. package/dist-client/pages/project-complete-tabs/pc-tab2-rating.js.map +1 -1
  24. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.d.ts +3 -0
  25. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js +32 -4
  26. package/dist-client/pages/project-complete-tabs/pc-tab3-upload.js.map +1 -1
  27. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.d.ts +24 -0
  28. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js +365 -157
  29. package/dist-client/pages/project-complete-tabs/pc-tab4-monthly.js.map +1 -1
  30. package/dist-client/pages/sv-project-complete.d.ts +4 -1
  31. package/dist-client/pages/sv-project-complete.js +43 -12
  32. package/dist-client/pages/sv-project-complete.js.map +1 -1
  33. package/dist-client/pages/sv-project-completed-list.js +3 -3
  34. package/dist-client/pages/sv-project-completed-list.js.map +1 -1
  35. package/dist-client/pages/sv-project-detail.d.ts +11 -0
  36. package/dist-client/pages/sv-project-detail.js +188 -46
  37. package/dist-client/pages/sv-project-detail.js.map +1 -1
  38. package/dist-client/pages/sv-project-list.d.ts +10 -0
  39. package/dist-client/pages/sv-project-list.js +96 -6
  40. package/dist-client/pages/sv-project-list.js.map +1 -1
  41. package/dist-client/pages/sv-project-update.d.ts +86 -0
  42. package/dist-client/pages/sv-project-update.js +1121 -0
  43. package/dist-client/pages/sv-project-update.js.map +1 -0
  44. package/dist-client/route.d.ts +1 -1
  45. package/dist-client/route.js +3 -0
  46. package/dist-client/route.js.map +1 -1
  47. package/dist-client/shared/complete-api.d.ts +10 -9
  48. package/dist-client/shared/complete-api.js +47 -19
  49. package/dist-client/shared/complete-api.js.map +1 -1
  50. package/dist-client/tsconfig.tsbuildinfo +1 -1
  51. package/dist-client/viewparts/menu-tools.js +47 -54
  52. package/dist-client/viewparts/menu-tools.js.map +1 -1
  53. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.d.ts +23 -0
  54. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js +72 -28
  55. package/dist-server/service/kpi-metric-value/kpi-metric-value-mutation.js.map +1 -1
  56. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +9 -2
  57. package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -1
  58. package/dist-server/service/kpi-stat/kpi-stat-query.js +19 -18
  59. package/dist-server/service/kpi-stat/kpi-stat-query.js.map +1 -1
  60. package/dist-server/service/kpi-value/kpi-value-query.js +2 -2
  61. package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
  62. package/dist-server/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +3 -3
  64. package/schema.graphql +13 -1
  65. package/things-factory.config.js +1 -0
  66. package/dist-client/shared/domain-context.d.ts +0 -7
  67. package/dist-client/shared/domain-context.js +0 -13
  68. package/dist-client/shared/domain-context.js.map +0 -1
@@ -5,7 +5,7 @@ import { css, html, LitElement } from 'lit';
5
5
  import { customElement, property, query, state } from 'lit/decorators.js';
6
6
  import { store, connect } from '@operato/shell';
7
7
  import { client } from '@operato/graphql';
8
- import { isProjectTypeDomain } from '../shared/domain-context';
8
+ import { isProjectTypeDomain } from '@dssp/project/dist-client/shared/domain-context';
9
9
  // import { ICONS_HOME, ICONS_KPIS, ICONS_INTEGRATION, ICONS_SETTING } from '../icons/menu-icons'
10
10
  export async function queryDataSets() {
11
11
  const response = await client.query({
@@ -59,6 +59,7 @@ let MenuTools = class MenuTools extends connect(store)(LitElement) {
59
59
  icon: 'location_city',
60
60
  active: ({ path }) => /^project/.test(path),
61
61
  submenus: [
62
+ { name: 'KPI 대시보드', path: 'kpi-dashboard-map', icon: 'dashboard' },
62
63
  { name: '프로젝트 목록', path: 'project-list', icon: 'autoplay' },
63
64
  { name: '완료 프로젝트 목록', path: 'project-completed-list', icon: 'stop_circle' }
64
65
  ]
@@ -72,7 +73,7 @@ let MenuTools = class MenuTools extends connect(store)(LitElement) {
72
73
  submenus: [
73
74
  { name: '프로젝트 대시보드', path: 'project-detail', icon: 'dashboard' },
74
75
  { name: '프로젝트 수정', path: 'project-update', icon: 'edit_note' },
75
- { name: '완공처리', path: 'project-complete', icon: 'assignment_turned_in' }
76
+ { name: 'KPI 데이타입력', path: 'project-complete', icon: 'edit_note' }
76
77
  ]
77
78
  };
78
79
  return [
@@ -83,61 +84,53 @@ let MenuTools = class MenuTools extends connect(store)(LitElement) {
83
84
  icon: 'bar_chart',
84
85
  submenus: [
85
86
  { name: 'KPI 개요', path: 'kpi-overview', icon: 'widget_small' },
86
- // { name: 'KPI 성과판', path: 'kpi-dashboard', icon: 'dashboard' },
87
- // {
88
- // name: i18next.t('title.kpi statistic list'),
89
- // icon: 'candlestick_chart',
90
- // path: 'kpi-statistic-list'
91
- // },
92
- // {
93
- // name: i18next.t('title.kpi statistic editor'),
94
- // icon: 'edit_square',
95
- // path: 'kpi-statistic-editor'
96
- // },
97
- { name: 'KPI 목록', path: 'kpi-list', icon: 'readiness_score' },
98
- { name: 'KPI 값 목록', path: 'kpi-value-list', icon: 'heap_snapshot_multiple' },
99
- { name: 'KPI 메트릭 목록', path: 'kpi-metric-list', icon: 'data_exploration' },
100
- { name: 'KPI 메트릭 값 목록', path: 'kpi-metric-value-list', icon: 'heap_snapshot_multiple' },
87
+ (!isProjectDomain && { name: 'KPI 목록', path: 'kpi-list', icon: 'readiness_score' }) || null,
88
+ (!isProjectDomain && { name: 'KPI 값 목록', path: 'kpi-value-list', icon: 'heap_snapshot_multiple' }) || null,
89
+ (!isProjectDomain && { name: 'KPI 메트릭 목록', path: 'kpi-metric-list', icon: 'data_exploration' }) || null,
90
+ (!isProjectDomain && { name: 'KPI 메트릭 값 목록', path: 'kpi-metric-value-list', icon: 'heap_snapshot_multiple' }) ||
91
+ null,
101
92
  { name: 'KPI 매트릭 값 수동 입력', path: 'kpi-metric-value-manual-entry', icon: 'edit' },
102
93
  { name: 'KPI 시스템 가이드', path: 'kpi-system-guide', icon: 'menu_book' }
103
- ]
104
- },
105
- {
106
- name: 'Data Set',
107
- path: 'data-set-list',
108
- icon: 'dataset',
109
- submenus: [
110
- { name: 'Data Set 목록', path: 'data-set-list', icon: 'dataset' },
111
- { name: 'Data Key 목록', path: 'data-key-set-list', icon: 'key' },
112
- { name: 'Data Sample 값 수동 입력', path: 'data-entry-list', icon: 'edit' },
113
- {
114
- name: 'Data Sample 목록',
115
- path: 'data-sample-list',
116
- icon: 'rule',
117
- subsubmenus: dataSets.map(item => {
118
- return {
119
- name: item.name,
120
- icon: 'checklist_rtl',
121
- path: `data-sample-search/${item.id}`
122
- };
123
- }) || []
124
- },
125
- {
126
- name: 'Data Summary 목록',
127
- path: 'data-summary-list',
128
- icon: 'functions',
129
- subsubmenus: dataSets
130
- .filter(item => item.active && item.summaryPeriod)
131
- .map(item => {
132
- return {
133
- name: item.name,
134
- icon: 'checklist',
135
- path: `data-summary-period/${item.id}`
136
- };
137
- }) || []
138
- }
139
- ]
94
+ ].filter(Boolean)
140
95
  },
96
+ // {
97
+ // name: 'Data Set',
98
+ // path: 'data-set-list',
99
+ // icon: 'dataset',
100
+ // submenus: [
101
+ // { name: 'Data Set 목록', path: 'data-set-list', icon: 'dataset' },
102
+ // { name: 'Data Key 목록', path: 'data-key-set-list', icon: 'key' },
103
+ // { name: 'Data Sample 값 수동 입력', path: 'data-entry-list', icon: 'edit' },
104
+ // {
105
+ // name: 'Data Sample 목록',
106
+ // path: 'data-sample-list',
107
+ // icon: 'rule',
108
+ // subsubmenus:
109
+ // dataSets.map(item => {
110
+ // return {
111
+ // name: item.name,
112
+ // icon: 'checklist_rtl',
113
+ // path: `data-sample-search/${item.id}`
114
+ // }
115
+ // }) || []
116
+ // },
117
+ // {
118
+ // name: 'Data Summary 목록',
119
+ // path: 'data-summary-list',
120
+ // icon: 'functions',
121
+ // subsubmenus:
122
+ // dataSets
123
+ // .filter(item => item.active && item.summaryPeriod)
124
+ // .map(item => {
125
+ // return {
126
+ // name: item.name,
127
+ // icon: 'checklist',
128
+ // path: `data-summary-period/${item.id}`
129
+ // }
130
+ // }) || []
131
+ // }
132
+ // ]
133
+ // },
141
134
  {
142
135
  name: '시스템연계',
143
136
  path: 'project-task-list',
@@ -1 +1 @@
1
- {"version":3,"file":"menu-tools.js","sourceRoot":"","sources":["../../client/viewparts/menu-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { store, connect } from '@operato/shell'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\n\nimport { isProjectTypeDomain } from '../shared/domain-context'\n\n// import { ICONS_HOME, ICONS_KPIS, ICONS_INTEGRATION, ICONS_SETTING } from '../icons/menu-icons'\nexport async function queryDataSets(): Promise<{ id: string; name: string; description: string; active: boolean }[]> {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: dataSets(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n active\n summaryPeriod\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n {\n name: 'active',\n operator: 'eq',\n value: true\n }\n ],\n pagination: {},\n sortings: []\n }\n })\n\n return response.data.responses.items\n}\n\n@customElement('menu-tools')\nexport class MenuTools extends connect(store)(LitElement) {\n static styles = [\n css`\n :host {\n position: relative;\n display: flex;\n background-color: var(--secondary-color);\n\n /* for narrow mode */\n flex-direction: column;\n width: 100%;\n --menu-tools-color: rgba(255, 255, 255, 0.9);\n --menu-tools-active-color: rgba(107, 178, 249, 1);\n }\n\n :host([width='WIDE']) {\n /* for wide mode */\n flex-direction: row;\n width: initial;\n height: 100%;\n }\n\n ul {\n display: flex;\n flex-direction: row;\n\n margin: auto;\n padding: 0;\n list-style: none;\n height: 100%;\n overflow: none;\n }\n\n :host([width='NARROW']) ul {\n width: 100%;\n justify-content: space-around;\n }\n\n :host([width='WIDE']) ul {\n flex-direction: column;\n }\n :host([width='NARROW']) li {\n flex: 1;\n }\n\n :host([width='WIDE']) li {\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n }\n\n a {\n display: flex;\n flex-direction: column;\n padding: 8px 8px 4px 8px;\n opacity: 0.7;\n align-items: center;\n text-align: center;\n text-decoration: none;\n text-transform: capitalize;\n color: var(--menu-tools-color);\n border-left: 2px solid transparent;\n\n --md-icon-size: 36px;\n }\n\n a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.15);\n border-left: 2px solid var(--menu-tools-active-color);\n }\n\n :host([width='NARROW']) a {\n padding: 0px 0px 5px 0px;\n opacity: 0.8;\n color: var(--menu-tools-color);\n border-left: none;\n border-top: 2px solid transparent;\n }\n\n :host([width='NARROW']) a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.15);\n border-left: none;\n border-top: 2px solid var(--menu-tools-active-color);\n }\n\n img {\n display: block;\n width: 35px;\n padding: 5px 10px 0px 10px;\n }\n\n :host([width='NARROW']) img {\n padding: 0;\n }\n\n div {\n font-size: 0.6em;\n }\n\n .submenu-popup {\n position: absolute;\n left: 60px; /* 탑메뉴 width */\n top: 0;\n width: 220px;\n height: 100%;\n background: linear-gradient(135deg, #1e293b 0%, #334155 100%);\n color: #fff;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n border-radius: 0 10px 10px 0;\n }\n\n .submenu-popup ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .submenu-popup li {\n font-size: 1.1em;\n }\n\n .submenu-popup li a {\n color: #fff;\n text-decoration: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n transition: background 0.2s;\n padding: 12px 16px;\n }\n\n .submenu-popup li a:hover {\n background: #333;\n }\n\n .submenu-popup li a md-icon {\n --md-icon-size: 20px;\n color: rgba(255, 255, 255, 0.8);\n }\n\n .submenu-popup li a[active] md-icon {\n color: var(--menu-tools-active-color);\n }\n .submenu-popup li {\n position: relative;\n }\n .subsubmenu {\n margin-left: 20px;\n margin-top: 8px;\n border-left: 2px solid rgba(255, 255, 255, 0.2);\n padding-left: 12px;\n }\n .subsubmenu li {\n padding: 8px 16px;\n font-size: 0.9em;\n }\n .subsubmenu li a {\n padding: 8px 12px;\n font-size: 0.85em;\n opacity: 0.8;\n }\n .subsubmenu li a:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .subsubmenu li a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n background: rgba(107, 178, 249, 0.2);\n }\n .subsubmenu li a md-icon {\n --md-icon-size: 16px;\n }\n .expand-button {\n margin-left: auto;\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.6);\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n transition: all 0.2s;\n }\n .expand-button:hover {\n color: rgba(255, 255, 255, 0.9);\n background: rgba(255, 255, 255, 0.1);\n }\n .expand-button md-icon {\n --md-icon-size: 16px;\n transition: transform 0.2s;\n }\n .expand-button.expanded md-icon {\n transform: rotate(90deg);\n }\n `\n ]\n\n @property({ type: String }) page?: string\n @property({ type: String, reflect: true }) width?: string\n\n @state() dataSets: any[] = []\n @state() menus: {\n name: string\n path: string\n icon: string\n active?: ({ path }: { path: string }) => boolean\n submenus?: {\n name: string\n path: string\n icon?: string\n active?: ({ path }: { path: string }) => boolean\n subsubmenus?: { name: string; path: string; icon?: string; active?: ({ path }: { path: string }) => boolean }[]\n }[]\n }[] = this.getMenus()\n\n private getMenus(): {\n name: string\n path: string\n icon: string\n active?: ({ path }: { path: string }) => boolean\n submenus?: {\n name: string\n path: string\n icon?: string\n active?: ({ path }: { path: string }) => boolean\n subsubmenus?: { name: string; path: string; icon?: string; active?: ({ path }: { path: string }) => boolean }[]\n }[]\n }[] {\n const dataSets = this.dataSets\n const isProjectDomain = isProjectTypeDomain()\n\n // 일반(=비-project) 도메인의 home: 프로젝트 목록 중심\n const generalHomeMenu = {\n name: '홈',\n path: 'project-list',\n icon: 'location_city',\n active: ({ path }: { path: string }) => /^project/.test(path),\n submenus: [\n { name: '프로젝트 목록', path: 'project-list', icon: 'autoplay' },\n { name: '완료 프로젝트 목록', path: 'project-completed-list', icon: 'stop_circle' }\n ]\n }\n\n // PROJECT 도메인의 home: 단일 프로젝트의 KPI 대시보드 + 프로젝트 수정 + 완공처리\n const projectHomeMenu = {\n name: '프로젝트',\n path: 'project-overview',\n icon: 'apartment',\n active: ({ path }: { path: string }) => /^(kpi-overview|project-detail|project-complete)/.test(path),\n submenus: [\n { name: '프로젝트 대시보드', path: 'project-detail', icon: 'dashboard' },\n { name: '프로젝트 수정', path: 'project-update', icon: 'edit_note' },\n { name: '완공처리', path: 'project-complete', icon: 'assignment_turned_in' }\n ]\n }\n\n return [\n isProjectDomain ? projectHomeMenu : generalHomeMenu,\n {\n name: 'KPI',\n path: 'kpi-overview',\n icon: 'bar_chart',\n submenus: [\n { name: 'KPI 개요', path: 'kpi-overview', icon: 'widget_small' },\n // { name: 'KPI 성과판', path: 'kpi-dashboard', icon: 'dashboard' },\n // {\n // name: i18next.t('title.kpi statistic list'),\n // icon: 'candlestick_chart',\n // path: 'kpi-statistic-list'\n // },\n // {\n // name: i18next.t('title.kpi statistic editor'),\n // icon: 'edit_square',\n // path: 'kpi-statistic-editor'\n // },\n { name: 'KPI 목록', path: 'kpi-list', icon: 'readiness_score' },\n { name: 'KPI 값 목록', path: 'kpi-value-list', icon: 'heap_snapshot_multiple' },\n { name: 'KPI 메트릭 목록', path: 'kpi-metric-list', icon: 'data_exploration' },\n { name: 'KPI 메트릭 값 목록', path: 'kpi-metric-value-list', icon: 'heap_snapshot_multiple' },\n { name: 'KPI 매트릭 값 수동 입력', path: 'kpi-metric-value-manual-entry', icon: 'edit' },\n { name: 'KPI 시스템 가이드', path: 'kpi-system-guide', icon: 'menu_book' }\n ]\n },\n {\n name: 'Data Set',\n path: 'data-set-list',\n icon: 'dataset',\n submenus: [\n { name: 'Data Set 목록', path: 'data-set-list', icon: 'dataset' },\n { name: 'Data Key 목록', path: 'data-key-set-list', icon: 'key' },\n { name: 'Data Sample 값 수동 입력', path: 'data-entry-list', icon: 'edit' },\n {\n name: 'Data Sample 목록',\n path: 'data-sample-list',\n icon: 'rule',\n subsubmenus:\n dataSets.map(item => {\n return {\n name: item.name,\n icon: 'checklist_rtl',\n path: `data-sample-search/${item.id}`\n }\n }) || []\n },\n {\n name: 'Data Summary 목록',\n path: 'data-summary-list',\n icon: 'functions',\n subsubmenus:\n dataSets\n .filter(item => item.active && item.summaryPeriod)\n .map(item => {\n return {\n name: item.name,\n icon: 'checklist',\n path: `data-summary-period/${item.id}`\n }\n }) || []\n }\n ]\n },\n {\n name: '시스템연계',\n path: 'project-task-list',\n icon: 'hub',\n submenus: [\n { name: '연계 현황', path: 'integration-monitor', icon: 'hub' },\n { name: '연계 설정', path: 'connection', icon: 'settings' },\n { name: '연계 시나리오', path: 'scenario', icon: 'hub' }\n ]\n },\n {\n name: '셋팅',\n path: 'users',\n icon: 'settings',\n submenus: [\n { name: '사용자 관리', path: 'users', icon: 'people' },\n { name: '환경 설정', path: 'setting', icon: 'settings' }\n ]\n }\n ]\n }\n\n @property({ type: Number }) openedMenuIndex: number | null = null\n @property({ type: Number }) openedSubmenuIndex: number | null = null\n @query('ul') menuUl!: HTMLUListElement\n @property({ type: Number }) submenuHeight: number | null = null\n\n render() {\n var page = this.page || ''\n return html`\n <ul>\n ${this.menus.map(\n (menu, i) => html`\n <li\n @click=${(e: Event) => {\n e.stopPropagation()\n this.openedMenuIndex = i\n this._setSubmenuHeight()\n }}\n >\n <a href=\"javascript:void(0)\" ?active=${this._isActiveMenu(page, menu)}>\n <md-icon>${menu.icon}</md-icon>\n <div>${menu.name}</div>\n </a>\n </li>\n `\n )}\n </ul>\n ${this.openedMenuIndex !== null\n ? html`\n <div class=\"submenu-popup\">\n <ul>\n ${this.menus[this.openedMenuIndex].submenus?.map(\n (sub, subIndex) => html`\n <li>\n <a\n href=${sub.subsubmenus ? 'javascript:void(0)' : sub.path}\n ?active=${this._isActiveSubmenu(page, sub)}\n @click=${sub.subsubmenus ? (e: Event) => e.preventDefault() : undefined}\n >\n ${sub.icon ? html`<md-icon>${sub.icon}</md-icon>` : ''} ${sub.name}\n ${sub.subsubmenus\n ? html`\n <button\n class=\"expand-button ${this.openedSubmenuIndex === subIndex ? 'expanded' : ''}\"\n @click=${(e: Event) => this._toggleSubsubmenu(e, subIndex)}\n >\n <md-icon>chevron_right</md-icon>\n </button>\n `\n : ''}\n </a>\n ${sub.subsubmenus && this.openedSubmenuIndex === subIndex\n ? html`\n <ul class=\"subsubmenu\">\n ${sub.subsubmenus.map(\n subsub => html`\n <li>\n <a href=${subsub.path} ?active=${this._isActiveSubsubmenu(page, subsub.path)}>\n ${subsub.icon ? html`<md-icon>${subsub.icon}</md-icon>` : ''} ${subsub.name}\n </a>\n </li>\n `\n )}\n </ul>\n `\n : ''}\n </li>\n `\n )}\n </ul>\n </div>\n `\n : ''}\n `\n }\n\n private _isActiveMenu(currentPage: string, menu: any): boolean {\n // 메인 메뉴의 기본 path 매칭 확인\n if (currentPage === menu.path) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (menu.active && typeof menu.active === 'function') {\n if (menu.active({ path: currentPage })) return true\n }\n\n // 서브메뉴 중 하나라도 active인지 확인\n if (menu.submenus) {\n return menu.submenus.some((sub: any) => {\n // 서브메뉴 기본 path 매칭\n if (currentPage === sub.path || currentPage.startsWith(sub.path + '/')) return true\n\n // 서브메뉴에 커스텀 active 함수가 있으면 추가로 확인\n if (sub.active && typeof sub.active === 'function') {\n return sub.active({ path: currentPage })\n }\n\n return false\n })\n }\n\n return false\n }\n\n private _isActiveSubmenu(currentPage: string, submenu: any): boolean {\n // 기본 path 매칭 확인\n if (currentPage === submenu.path || currentPage.startsWith(submenu.path + '/')) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (submenu.active && typeof submenu.active === 'function') {\n return submenu.active({ path: currentPage })\n }\n\n return false\n }\n\n async firstUpdated() {\n this._setSubmenuHeight()\n\n this.dataSets = await queryDataSets()\n this.menus = this.getMenus()\n }\n\n updated(changedProps: Map<string, any>) {\n if (changedProps.has('openedMenuIndex')) {\n this._setSubmenuHeight()\n }\n }\n\n _setSubmenuHeight() {\n if (this.menuUl) {\n this.submenuHeight = this.menuUl.clientHeight\n }\n }\n\n connectedCallback() {\n super.connectedCallback()\n window.addEventListener('click', this._closeSubmenu)\n }\n\n disconnectedCallback() {\n window.removeEventListener('click', this._closeSubmenu)\n super.disconnectedCallback()\n }\n\n private _closeSubmenu = () => {\n this.openedMenuIndex = null\n }\n\n private _toggleSubsubmenu(e: Event, subIndex: number) {\n e.stopPropagation()\n if (this.openedSubmenuIndex === subIndex) {\n this.openedSubmenuIndex = null\n } else {\n this.openedSubmenuIndex = subIndex\n }\n }\n\n private _isActiveSubsubmenu(currentPage: string, subsubmenu: any): boolean {\n // 기본 path 매칭 확인\n if (currentPage === subsubmenu.path || currentPage.startsWith(subsubmenu.path + '/')) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (subsubmenu.active && typeof subsubmenu.active === 'function') {\n return subsubmenu.active({ path: currentPage })\n }\n\n return false\n }\n\n stateChanged(state: any) {\n this.page = state.route.page\n this.width = state.layout.width\n }\n}\n"]}
1
+ {"version":3,"file":"menu-tools.js","sourceRoot":"","sources":["../../client/viewparts/menu-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { store, connect } from '@operato/shell'\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\n\nimport { isProjectTypeDomain } from '@dssp/project/dist-client/shared/domain-context'\n\n// import { ICONS_HOME, ICONS_KPIS, ICONS_INTEGRATION, ICONS_SETTING } from '../icons/menu-icons'\nexport async function queryDataSets(): Promise<{ id: string; name: string; description: string; active: boolean }[]> {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: dataSets(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n active\n summaryPeriod\n }\n total\n }\n }\n `,\n variables: {\n filters: [\n {\n name: 'active',\n operator: 'eq',\n value: true\n }\n ],\n pagination: {},\n sortings: []\n }\n })\n\n return response.data.responses.items\n}\n\n@customElement('menu-tools')\nexport class MenuTools extends connect(store)(LitElement) {\n static styles = [\n css`\n :host {\n position: relative;\n display: flex;\n background-color: var(--secondary-color);\n\n /* for narrow mode */\n flex-direction: column;\n width: 100%;\n --menu-tools-color: rgba(255, 255, 255, 0.9);\n --menu-tools-active-color: rgba(107, 178, 249, 1);\n }\n\n :host([width='WIDE']) {\n /* for wide mode */\n flex-direction: row;\n width: initial;\n height: 100%;\n }\n\n ul {\n display: flex;\n flex-direction: row;\n\n margin: auto;\n padding: 0;\n list-style: none;\n height: 100%;\n overflow: none;\n }\n\n :host([width='NARROW']) ul {\n width: 100%;\n justify-content: space-around;\n }\n\n :host([width='WIDE']) ul {\n flex-direction: column;\n }\n :host([width='NARROW']) li {\n flex: 1;\n }\n\n :host([width='WIDE']) li {\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n }\n\n a {\n display: flex;\n flex-direction: column;\n padding: 8px 8px 4px 8px;\n opacity: 0.7;\n align-items: center;\n text-align: center;\n text-decoration: none;\n text-transform: capitalize;\n color: var(--menu-tools-color);\n border-left: 2px solid transparent;\n\n --md-icon-size: 36px;\n }\n\n a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.15);\n border-left: 2px solid var(--menu-tools-active-color);\n }\n\n :host([width='NARROW']) a {\n padding: 0px 0px 5px 0px;\n opacity: 0.8;\n color: var(--menu-tools-color);\n border-left: none;\n border-top: 2px solid transparent;\n }\n\n :host([width='NARROW']) a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n font-weight: bold;\n background-color: rgba(0, 0, 0, 0.15);\n border-left: none;\n border-top: 2px solid var(--menu-tools-active-color);\n }\n\n img {\n display: block;\n width: 35px;\n padding: 5px 10px 0px 10px;\n }\n\n :host([width='NARROW']) img {\n padding: 0;\n }\n\n div {\n font-size: 0.6em;\n }\n\n .submenu-popup {\n position: absolute;\n left: 60px; /* 탑메뉴 width */\n top: 0;\n width: 220px;\n height: 100%;\n background: linear-gradient(135deg, #1e293b 0%, #334155 100%);\n color: #fff;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n border-radius: 0 10px 10px 0;\n }\n\n .submenu-popup ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .submenu-popup li {\n font-size: 1.1em;\n }\n\n .submenu-popup li a {\n color: #fff;\n text-decoration: none;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n transition: background 0.2s;\n padding: 12px 16px;\n }\n\n .submenu-popup li a:hover {\n background: #333;\n }\n\n .submenu-popup li a md-icon {\n --md-icon-size: 20px;\n color: rgba(255, 255, 255, 0.8);\n }\n\n .submenu-popup li a[active] md-icon {\n color: var(--menu-tools-active-color);\n }\n .submenu-popup li {\n position: relative;\n }\n .subsubmenu {\n margin-left: 20px;\n margin-top: 8px;\n border-left: 2px solid rgba(255, 255, 255, 0.2);\n padding-left: 12px;\n }\n .subsubmenu li {\n padding: 8px 16px;\n font-size: 0.9em;\n }\n .subsubmenu li a {\n padding: 8px 12px;\n font-size: 0.85em;\n opacity: 0.8;\n }\n .subsubmenu li a:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .subsubmenu li a[active] {\n opacity: 1;\n color: var(--menu-tools-active-color);\n background: rgba(107, 178, 249, 0.2);\n }\n .subsubmenu li a md-icon {\n --md-icon-size: 16px;\n }\n .expand-button {\n margin-left: auto;\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.6);\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n transition: all 0.2s;\n }\n .expand-button:hover {\n color: rgba(255, 255, 255, 0.9);\n background: rgba(255, 255, 255, 0.1);\n }\n .expand-button md-icon {\n --md-icon-size: 16px;\n transition: transform 0.2s;\n }\n .expand-button.expanded md-icon {\n transform: rotate(90deg);\n }\n `\n ]\n\n @property({ type: String }) page?: string\n @property({ type: String, reflect: true }) width?: string\n\n @state() dataSets: any[] = []\n @state() menus: {\n name: string\n path: string\n icon: string\n active?: ({ path }: { path: string }) => boolean\n submenus?: {\n name: string\n path: string\n icon?: string\n active?: ({ path }: { path: string }) => boolean\n subsubmenus?: { name: string; path: string; icon?: string; active?: ({ path }: { path: string }) => boolean }[]\n }[]\n }[] = this.getMenus()\n\n private getMenus(): {\n name: string\n path: string\n icon: string\n active?: ({ path }: { path: string }) => boolean\n submenus?: {\n name: string\n path: string\n icon?: string\n active?: ({ path }: { path: string }) => boolean\n subsubmenus?: { name: string; path: string; icon?: string; active?: ({ path }: { path: string }) => boolean }[]\n }[]\n }[] {\n const dataSets = this.dataSets\n const isProjectDomain = isProjectTypeDomain()\n\n // 일반(=비-project) 도메인의 home: 프로젝트 목록 중심\n const generalHomeMenu = {\n name: '홈',\n path: 'project-list',\n icon: 'location_city',\n active: ({ path }: { path: string }) => /^project/.test(path),\n submenus: [\n { name: 'KPI 대시보드', path: 'kpi-dashboard-map', icon: 'dashboard' },\n { name: '프로젝트 목록', path: 'project-list', icon: 'autoplay' },\n { name: '완료 프로젝트 목록', path: 'project-completed-list', icon: 'stop_circle' }\n ]\n }\n\n // PROJECT 도메인의 home: 단일 프로젝트의 KPI 대시보드 + 프로젝트 수정 + 완공처리\n const projectHomeMenu = {\n name: '프로젝트',\n path: 'project-overview',\n icon: 'apartment',\n active: ({ path }: { path: string }) => /^(kpi-overview|project-detail|project-complete)/.test(path),\n submenus: [\n { name: '프로젝트 대시보드', path: 'project-detail', icon: 'dashboard' },\n { name: '프로젝트 수정', path: 'project-update', icon: 'edit_note' },\n { name: 'KPI 데이타입력', path: 'project-complete', icon: 'edit_note' }\n ]\n }\n\n return [\n isProjectDomain ? projectHomeMenu : generalHomeMenu,\n {\n name: 'KPI',\n path: 'kpi-overview',\n icon: 'bar_chart',\n submenus: [\n { name: 'KPI 개요', path: 'kpi-overview', icon: 'widget_small' },\n (!isProjectDomain && { name: 'KPI 목록', path: 'kpi-list', icon: 'readiness_score' }) || null,\n (!isProjectDomain && { name: 'KPI 값 목록', path: 'kpi-value-list', icon: 'heap_snapshot_multiple' }) || null,\n (!isProjectDomain && { name: 'KPI 메트릭 목록', path: 'kpi-metric-list', icon: 'data_exploration' }) || null,\n (!isProjectDomain && { name: 'KPI 메트릭 값 목록', path: 'kpi-metric-value-list', icon: 'heap_snapshot_multiple' }) ||\n null,\n { name: 'KPI 매트릭 값 수동 입력', path: 'kpi-metric-value-manual-entry', icon: 'edit' },\n { name: 'KPI 시스템 가이드', path: 'kpi-system-guide', icon: 'menu_book' }\n ].filter(Boolean) as { name: string; path: string; icon: string }[]\n },\n // {\n // name: 'Data Set',\n // path: 'data-set-list',\n // icon: 'dataset',\n // submenus: [\n // { name: 'Data Set 목록', path: 'data-set-list', icon: 'dataset' },\n // { name: 'Data Key 목록', path: 'data-key-set-list', icon: 'key' },\n // { name: 'Data Sample 값 수동 입력', path: 'data-entry-list', icon: 'edit' },\n // {\n // name: 'Data Sample 목록',\n // path: 'data-sample-list',\n // icon: 'rule',\n // subsubmenus:\n // dataSets.map(item => {\n // return {\n // name: item.name,\n // icon: 'checklist_rtl',\n // path: `data-sample-search/${item.id}`\n // }\n // }) || []\n // },\n // {\n // name: 'Data Summary 목록',\n // path: 'data-summary-list',\n // icon: 'functions',\n // subsubmenus:\n // dataSets\n // .filter(item => item.active && item.summaryPeriod)\n // .map(item => {\n // return {\n // name: item.name,\n // icon: 'checklist',\n // path: `data-summary-period/${item.id}`\n // }\n // }) || []\n // }\n // ]\n // },\n {\n name: '시스템연계',\n path: 'project-task-list',\n icon: 'hub',\n submenus: [\n { name: '연계 현황', path: 'integration-monitor', icon: 'hub' },\n { name: '연계 설정', path: 'connection', icon: 'settings' },\n { name: '연계 시나리오', path: 'scenario', icon: 'hub' }\n ]\n },\n {\n name: '셋팅',\n path: 'users',\n icon: 'settings',\n submenus: [\n { name: '사용자 관리', path: 'users', icon: 'people' },\n { name: '환경 설정', path: 'setting', icon: 'settings' }\n ]\n }\n ]\n }\n\n @property({ type: Number }) openedMenuIndex: number | null = null\n @property({ type: Number }) openedSubmenuIndex: number | null = null\n @query('ul') menuUl!: HTMLUListElement\n @property({ type: Number }) submenuHeight: number | null = null\n\n render() {\n var page = this.page || ''\n return html`\n <ul>\n ${this.menus.map(\n (menu, i) => html`\n <li\n @click=${(e: Event) => {\n e.stopPropagation()\n this.openedMenuIndex = i\n this._setSubmenuHeight()\n }}\n >\n <a href=\"javascript:void(0)\" ?active=${this._isActiveMenu(page, menu)}>\n <md-icon>${menu.icon}</md-icon>\n <div>${menu.name}</div>\n </a>\n </li>\n `\n )}\n </ul>\n ${this.openedMenuIndex !== null\n ? html`\n <div class=\"submenu-popup\">\n <ul>\n ${this.menus[this.openedMenuIndex].submenus?.map(\n (sub, subIndex) => html`\n <li>\n <a\n href=${sub.subsubmenus ? 'javascript:void(0)' : sub.path}\n ?active=${this._isActiveSubmenu(page, sub)}\n @click=${sub.subsubmenus ? (e: Event) => e.preventDefault() : undefined}\n >\n ${sub.icon ? html`<md-icon>${sub.icon}</md-icon>` : ''} ${sub.name}\n ${sub.subsubmenus\n ? html`\n <button\n class=\"expand-button ${this.openedSubmenuIndex === subIndex ? 'expanded' : ''}\"\n @click=${(e: Event) => this._toggleSubsubmenu(e, subIndex)}\n >\n <md-icon>chevron_right</md-icon>\n </button>\n `\n : ''}\n </a>\n ${sub.subsubmenus && this.openedSubmenuIndex === subIndex\n ? html`\n <ul class=\"subsubmenu\">\n ${sub.subsubmenus.map(\n subsub => html`\n <li>\n <a href=${subsub.path} ?active=${this._isActiveSubsubmenu(page, subsub.path)}>\n ${subsub.icon ? html`<md-icon>${subsub.icon}</md-icon>` : ''} ${subsub.name}\n </a>\n </li>\n `\n )}\n </ul>\n `\n : ''}\n </li>\n `\n )}\n </ul>\n </div>\n `\n : ''}\n `\n }\n\n private _isActiveMenu(currentPage: string, menu: any): boolean {\n // 메인 메뉴의 기본 path 매칭 확인\n if (currentPage === menu.path) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (menu.active && typeof menu.active === 'function') {\n if (menu.active({ path: currentPage })) return true\n }\n\n // 서브메뉴 중 하나라도 active인지 확인\n if (menu.submenus) {\n return menu.submenus.some((sub: any) => {\n // 서브메뉴 기본 path 매칭\n if (currentPage === sub.path || currentPage.startsWith(sub.path + '/')) return true\n\n // 서브메뉴에 커스텀 active 함수가 있으면 추가로 확인\n if (sub.active && typeof sub.active === 'function') {\n return sub.active({ path: currentPage })\n }\n\n return false\n })\n }\n\n return false\n }\n\n private _isActiveSubmenu(currentPage: string, submenu: any): boolean {\n // 기본 path 매칭 확인\n if (currentPage === submenu.path || currentPage.startsWith(submenu.path + '/')) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (submenu.active && typeof submenu.active === 'function') {\n return submenu.active({ path: currentPage })\n }\n\n return false\n }\n\n async firstUpdated() {\n this._setSubmenuHeight()\n\n this.dataSets = await queryDataSets()\n this.menus = this.getMenus()\n }\n\n updated(changedProps: Map<string, any>) {\n if (changedProps.has('openedMenuIndex')) {\n this._setSubmenuHeight()\n }\n }\n\n _setSubmenuHeight() {\n if (this.menuUl) {\n this.submenuHeight = this.menuUl.clientHeight\n }\n }\n\n connectedCallback() {\n super.connectedCallback()\n window.addEventListener('click', this._closeSubmenu)\n }\n\n disconnectedCallback() {\n window.removeEventListener('click', this._closeSubmenu)\n super.disconnectedCallback()\n }\n\n private _closeSubmenu = () => {\n this.openedMenuIndex = null\n }\n\n private _toggleSubsubmenu(e: Event, subIndex: number) {\n e.stopPropagation()\n if (this.openedSubmenuIndex === subIndex) {\n this.openedSubmenuIndex = null\n } else {\n this.openedSubmenuIndex = subIndex\n }\n }\n\n private _isActiveSubsubmenu(currentPage: string, subsubmenu: any): boolean {\n // 기본 path 매칭 확인\n if (currentPage === subsubmenu.path || currentPage.startsWith(subsubmenu.path + '/')) return true\n\n // 커스텀 active 함수가 있으면 추가로 확인\n if (subsubmenu.active && typeof subsubmenu.active === 'function') {\n return subsubmenu.active({ path: currentPage })\n }\n\n return false\n }\n\n stateChanged(state: any) {\n this.page = state.route.page\n this.width = state.layout.width\n }\n}\n"]}
@@ -14,6 +14,21 @@ declare class ExternalDataCollectionResult {
14
14
  export declare class KpiMetricValueMutation {
15
15
  updateKpiMetricValuesCumulative(patches: KpiMetricValuePatch[], context: ResolverContext): Promise<KpiMetricValue[]>;
16
16
  updateKpiMetricValuesAssessment(patches: KpiMetricValuePatch[], context: ResolverContext): Promise<KpiMetricValue[]>;
17
+ /**
18
+ * KpiMetricValue 의 unique 조합 (domain, metric, valueDate, org) 기준 진짜 upsert.
19
+ *
20
+ * 기존 mutation 의 `repo.save({...patch})` 는 patch.id 만 보고 update/insert 결정해
21
+ * 같은 metric × 같은 valueDate × 같은 org 인데 patch.id 가 새 UUID 인 경우 unique
22
+ * 인덱스 (ix_kpi_metric_value_latest) 위반 에러 또는 row 누적 위험. 정확한 upsert
23
+ * 동작을 보장하기 위해 조합 lookup → 기존 id 사용 → save.
24
+ *
25
+ * 월별 metric (periodType=MONTH, valueDate=YYYY-MM-01) 의 단일 row 정책을 자연 충족.
26
+ *
27
+ * **도메인 컨텍스트 스위치**: caller (운영자) 가 system 도메인일 수 있어 patch.org
28
+ * (= projectId) 로 프로젝트 테넌트 도메인을 lookup 해 그 컨텍스트로 저장. 모든
29
+ * patch 가 같은 projectId 라 가정 (한 번의 mutation = 한 프로젝트의 값들).
30
+ */
31
+ private upsertKpiMetricValues;
17
32
  updateKpiMetricValuesSentiment(attachment: NewAttachment, context: ResolverContext): Promise<Attachment | null>;
18
33
  /**
19
34
  * FileUpload 스트림을 버퍼로 읽기
@@ -32,6 +47,14 @@ export declare class KpiMetricValueMutation {
32
47
  */
33
48
  private saveMetricValue;
34
49
  finalizeProjectWithKpiRecalculation(projectId: string, context: ResolverContext): Promise<boolean>;
50
+ /**
51
+ * 완공 처리 없이 KPI 만 재계산 — 진행 중 프로젝트의 중간 결과 산정 용도.
52
+ * DB 에 이미 저장된 KpiMetricValue 만 가지고 formula 평가. 외부 시나리오 (juso/
53
+ * allbaro/kiscon) 자동 수집은 의도적으로 호출하지 않음 — 외부 수집은 사용자가
54
+ * "자동 수집" 버튼 (`collectProjectExternalData`) 으로 명시적으로 실행하는 흐름.
55
+ * 권한은 `kpi:recalculate` 로 분리해 finalize 보다 가볍게 부여 가능.
56
+ */
57
+ recalculateProjectKpi(projectId: string, context: ResolverContext): Promise<boolean>;
35
58
  /**
36
59
  * UI "자동 수집" 버튼 전용 mutation. 외부 시스템 3종 시나리오를 순차 호출하고
37
60
  * 시스템별 성공/실패 + 메시지를 반환. UI 는 결과를 보고 카드별 상태 (성공·오류) 를 표시.
@@ -55,23 +55,34 @@ ExternalDataCollectionResult = tslib_1.__decorate([
55
55
  let KpiMetricValueMutation = class KpiMetricValueMutation {
56
56
  /* 프로젝트 수행과정 중에 (시간, 비용, 발생 건수 등) 누적된 값을 반영하여 KPI Metric Value 값을 수정 - 예를 들면, 총 설계 변경 건수, 총 건설 폐기물 발생량, 공사비, 공사기간, 재해 건수 등 */
57
57
  async updateKpiMetricValuesCumulative(patches, context) {
58
- const { domain, user, tx } = context.state;
59
- const metricValueRepo = (0, shell_1.getRepository)(kpi_1.KpiMetricValue, tx);
60
- const metricRepo = (0, shell_1.getRepository)(kpi_1.KpiMetric, tx);
61
- const results = [];
62
- for (const patch of patches) {
63
- const metric = await metricRepo.findOne({ where: { id: patch.metricId } });
64
- if (!metric) {
65
- throw new Error(`Metric not found: ${patch.metricId}`);
66
- }
67
- const result = await metricValueRepo.save(Object.assign(Object.assign({ domain }, patch), { metric, updater: user }));
68
- results.push(result);
69
- }
70
- return results;
58
+ return await this.upsertKpiMetricValues(patches, context);
71
59
  }
72
60
  /* 전문 감리사에 의해서 평가된 별점을 반영하여 KPI Metric Value 값을 수정 */
73
61
  async updateKpiMetricValuesAssessment(patches, context) {
74
- const { domain, user, tx } = context.state;
62
+ return await this.upsertKpiMetricValues(patches, context);
63
+ }
64
+ /**
65
+ * KpiMetricValue 의 unique 조합 (domain, metric, valueDate, org) 기준 진짜 upsert.
66
+ *
67
+ * 기존 mutation 의 `repo.save({...patch})` 는 patch.id 만 보고 update/insert 결정해
68
+ * 같은 metric × 같은 valueDate × 같은 org 인데 patch.id 가 새 UUID 인 경우 unique
69
+ * 인덱스 (ix_kpi_metric_value_latest) 위반 에러 또는 row 누적 위험. 정확한 upsert
70
+ * 동작을 보장하기 위해 조합 lookup → 기존 id 사용 → save.
71
+ *
72
+ * 월별 metric (periodType=MONTH, valueDate=YYYY-MM-01) 의 단일 row 정책을 자연 충족.
73
+ *
74
+ * **도메인 컨텍스트 스위치**: caller (운영자) 가 system 도메인일 수 있어 patch.org
75
+ * (= projectId) 로 프로젝트 테넌트 도메인을 lookup 해 그 컨텍스트로 저장. 모든
76
+ * patch 가 같은 projectId 라 가정 (한 번의 mutation = 한 프로젝트의 값들).
77
+ */
78
+ async upsertKpiMetricValues(patches, context) {
79
+ var _a;
80
+ if (patches.length === 0)
81
+ return [];
82
+ // 첫 patch.org 의 projectId 로 도메인 스위치. patch.org 가 없으면 caller context 그대로.
83
+ const projectId = patches[0].org;
84
+ const ctx = projectId ? await this.switchToProjectDomain(projectId, context) : context;
85
+ const { domain, user, tx } = ctx.state;
75
86
  const metricValueRepo = (0, shell_1.getRepository)(kpi_1.KpiMetricValue, tx);
76
87
  const metricRepo = (0, shell_1.getRepository)(kpi_1.KpiMetric, tx);
77
88
  const results = [];
@@ -80,7 +91,16 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
80
91
  if (!metric) {
81
92
  throw new Error(`Metric not found: ${patch.metricId}`);
82
93
  }
83
- const result = await metricValueRepo.save(Object.assign(Object.assign({ domain }, patch), { metric, updater: user }));
94
+ // unique 조합 기준 기존 row lookup. 있으면 id save update.
95
+ const existing = await metricValueRepo.findOne({
96
+ where: {
97
+ domain: { id: domain.id },
98
+ metric: { id: patch.metricId },
99
+ valueDate: patch.valueDate,
100
+ org: patch.org
101
+ }
102
+ });
103
+ const result = await metricValueRepo.save(Object.assign(Object.assign({ domain }, patch), { id: (_a = existing === null || existing === void 0 ? void 0 : existing.id) !== null && _a !== void 0 ? _a : patch.id, metric, updater: user }));
84
104
  results.push(result);
85
105
  }
86
106
  return results;
@@ -248,18 +268,32 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
248
268
  if (!project) {
249
269
  throw new Error(`Project not found: ${projectId}`);
250
270
  }
251
- // 시나리오·EnvVar·KPI value 모두 프로젝트(테넌트) 도메인 기준이라 컨텍스트 스위치
252
- // 만든 이후 작업 모두 컨텍스트로 일관 진행.
271
+ // KPI value 계산은 프로젝트(테넌트) 도메인 기준이라 컨텍스트 스위치.
272
+ // 외부 시스템 데이터 수집은 별도 mutation (collectProjectExternalData) 분리
273
+ // 사용자가 UI "자동 수집" 버튼으로 명시 실행. finalize/recalculate 흐름에서는
274
+ // 외부 연동을 끌어들이지 않음 (DB 에 이미 저장된 KpiMetricValue 만 가지고 계산).
253
275
  const projectContext = await this.switchToProjectDomain(projectId, context);
254
- // 외부 시스템 데이터 수집은 별도 mutation (collectProjectExternalData) 로 분리.
255
- // 사용자가 UI "자동 수집" 으로 먼저 명시 수집 후 결과 검토하고 완공 처리하는 흐름.
256
- // 안전 차원에서 finalize 시점에도 한 번 더 수집을 시도 — 실패는 warning 만.
257
- await this.runExternalDataScenarios(projectContext);
258
- // 프로젝트 KPI Value 계산을 다시 할 것이다 — 테넌트 도메인 컨텍스트에서.
259
276
  await this.recalculateProjectKpiValues(projectId, projectContext);
260
277
  projectRepo.save(Object.assign(Object.assign({}, project), { state: project_1.ProjectState.COMPLETED }));
261
278
  return true;
262
279
  }
280
+ /**
281
+ * 완공 처리 없이 KPI 만 재계산 — 진행 중 프로젝트의 중간 결과 산정 용도.
282
+ * DB 에 이미 저장된 KpiMetricValue 만 가지고 formula 평가. 외부 시나리오 (juso/
283
+ * allbaro/kiscon) 자동 수집은 의도적으로 호출하지 않음 — 외부 수집은 사용자가
284
+ * "자동 수집" 버튼 (`collectProjectExternalData`) 으로 명시적으로 실행하는 흐름.
285
+ * 권한은 `kpi:recalculate` 로 분리해 finalize 보다 가볍게 부여 가능.
286
+ */
287
+ async recalculateProjectKpi(projectId, context) {
288
+ const { tx } = context.state;
289
+ const project = await (0, shell_1.getRepository)(project_1.Project, tx).findOne({ where: { id: projectId } });
290
+ if (!project) {
291
+ throw new Error(`Project not found: ${projectId}`);
292
+ }
293
+ const projectContext = await this.switchToProjectDomain(projectId, context);
294
+ await this.recalculateProjectKpiValues(projectId, projectContext);
295
+ return true;
296
+ }
263
297
  /**
264
298
  * UI "자동 수집" 버튼 전용 mutation. 외부 시스템 3종 시나리오를 순차 호출하고
265
299
  * 시스템별 성공/실패 + 메시지를 반환. UI 는 결과를 보고 카드별 상태 (성공·오류) 를 표시.
@@ -839,7 +873,7 @@ let KpiMetricValueMutation = class KpiMetricValueMutation {
839
873
  exports.KpiMetricValueMutation = KpiMetricValueMutation;
840
874
  tslib_1.__decorate([
841
875
  (0, type_graphql_1.Directive)('@transaction'),
842
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
876
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "input", domainOwnerGranted: true, superUserGranted: true)'),
843
877
  (0, type_graphql_1.Mutation)(returns => [kpi_1.KpiMetricValue], { description: "To modify multiple cumulative KpiMetricValues' value" }),
844
878
  tslib_1.__param(0, (0, type_graphql_1.Arg)('patches', type => [kpi_1.KpiMetricValuePatch])),
845
879
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -849,7 +883,7 @@ tslib_1.__decorate([
849
883
  ], KpiMetricValueMutation.prototype, "updateKpiMetricValuesCumulative", null);
850
884
  tslib_1.__decorate([
851
885
  (0, type_graphql_1.Directive)('@transaction'),
852
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
886
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "assessment", domainOwnerGranted: true, superUserGranted: true)'),
853
887
  (0, type_graphql_1.Mutation)(returns => [kpi_1.KpiMetricValue], { description: "To modify multiple assessment KpiMetricValues' value" }),
854
888
  tslib_1.__param(0, (0, type_graphql_1.Arg)('patches', type => [kpi_1.KpiMetricValuePatch])),
855
889
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -859,7 +893,7 @@ tslib_1.__decorate([
859
893
  ], KpiMetricValueMutation.prototype, "updateKpiMetricValuesAssessment", null);
860
894
  tslib_1.__decorate([
861
895
  (0, type_graphql_1.Directive)('@transaction'),
862
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
896
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "sentiment", domainOwnerGranted: true, superUserGranted: true)'),
863
897
  (0, type_graphql_1.Mutation)(returns => attachment_base_1.Attachment, { nullable: true, description: "To modify multiple sentiment KpiMetricValues' value" }),
864
898
  tslib_1.__param(0, (0, type_graphql_1.Arg)('attachment', type => attachment_base_1.NewAttachment)),
865
899
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -869,7 +903,7 @@ tslib_1.__decorate([
869
903
  ], KpiMetricValueMutation.prototype, "updateKpiMetricValuesSentiment", null);
870
904
  tslib_1.__decorate([
871
905
  (0, type_graphql_1.Directive)('@transaction'),
872
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
906
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "finalize", domainOwnerGranted: true, superUserGranted: true)'),
873
907
  (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'To finalize project with KPI recalculation' }),
874
908
  tslib_1.__param(0, (0, type_graphql_1.Arg)('projectId')),
875
909
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
@@ -878,7 +912,17 @@ tslib_1.__decorate([
878
912
  tslib_1.__metadata("design:returntype", Promise)
879
913
  ], KpiMetricValueMutation.prototype, "finalizeProjectWithKpiRecalculation", null);
880
914
  tslib_1.__decorate([
881
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
915
+ (0, type_graphql_1.Directive)('@transaction'),
916
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "recalculate", domainOwnerGranted: true, superUserGranted: true)'),
917
+ (0, type_graphql_1.Mutation)(returns => Boolean, { description: 'Recalculate project KPI without finalizing (interim).' }),
918
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('projectId')),
919
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
920
+ tslib_1.__metadata("design:type", Function),
921
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
922
+ tslib_1.__metadata("design:returntype", Promise)
923
+ ], KpiMetricValueMutation.prototype, "recalculateProjectKpi", null);
924
+ tslib_1.__decorate([
925
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "auto-collect", domainOwnerGranted: true, superUserGranted: true)'),
882
926
  (0, type_graphql_1.Mutation)(returns => [ExternalDataCollectionResult], {
883
927
  description: 'Run external data collection scenarios per system, returning per-system result.'
884
928
  }),
@@ -890,7 +934,7 @@ tslib_1.__decorate([
890
934
  ], KpiMetricValueMutation.prototype, "collectProjectExternalData", null);
891
935
  tslib_1.__decorate([
892
936
  (0, type_graphql_1.Directive)('@transaction'),
893
- (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)'),
937
+ (0, type_graphql_1.Directive)('@privilege(category: "kpi", privilege: "basic-info", domainOwnerGranted: true, superUserGranted: true)'),
894
938
  (0, type_graphql_1.Mutation)(returns => ExternalDataCollectionResult, {
895
939
  description: 'Run only 건축물관리대장조회 scenario for project basic info collection.'
896
940
  }),