@things-factory/kpi 10.0.0-beta.9 → 10.0.0-beta.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/index.ts +1 -0
- package/client/pages/kpi/kpi-list-page.ts +150 -17
- package/client/pages/kpi-dashboard/components/kpi-map-panel.ts +2 -2
- package/client/pages/kpi-metric/kpi-metric-list-page.ts +17 -3
- package/dist-client/index.d.ts +1 -0
- package/dist-client/index.js +1 -1
- package/dist-client/index.js.map +1 -1
- package/dist-client/pages/kpi/kpi-list-page.d.ts +48 -3
- package/dist-client/pages/kpi/kpi-list-page.js +140 -18
- package/dist-client/pages/kpi/kpi-list-page.js.map +1 -1
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js +2 -2
- package/dist-client/pages/kpi-dashboard/components/kpi-map-panel.js.map +1 -1
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js +17 -3
- package/dist-client/pages/kpi-metric/kpi-metric-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/kpi/kpi-query.d.ts +1 -1
- package/dist-server/service/kpi/kpi-query.js +38 -16
- package/dist-server/service/kpi/kpi-query.js.map +1 -1
- package/dist-server/service/kpi/kpi-type.d.ts +5 -1
- package/dist-server/service/kpi/kpi-type.js +28 -0
- package/dist-server/service/kpi/kpi-type.js.map +1 -1
- package/dist-server/service/kpi/kpi.d.ts +64 -0
- package/dist-server/service/kpi/kpi.js +89 -1
- package/dist-server/service/kpi/kpi.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-mutation.js +15 -7
- package/dist-server/service/kpi-metric/kpi-metric-mutation.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-query.d.ts +2 -0
- package/dist-server/service/kpi-metric/kpi-metric-query.js +30 -5
- package/dist-server/service/kpi-metric/kpi-metric-query.js.map +1 -1
- package/dist-server/service/kpi-metric/kpi-metric-type.d.ts +3 -2
- package/dist-server/service/kpi-metric/kpi-metric-type.js +7 -6
- package/dist-server/service/kpi-metric/kpi-metric-type.js.map +1 -1
- package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js +10 -3
- package/dist-server/service/kpi-metric-value/kpi-metric-value-query.js.map +1 -1
- package/dist-server/service/kpi-value/kpi-value-query.js +10 -3
- package/dist-server/service/kpi-value/kpi-value-query.js.map +1 -1
- package/dist-server/service/utils/domain-inheritance.d.ts +17 -0
- package/dist-server/service/utils/domain-inheritance.js +69 -0
- package/dist-server/service/utils/domain-inheritance.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -9,7 +9,7 @@ export declare class KpiQuery {
|
|
|
9
9
|
kpisLevel1(rootId: string, context: ResolverContext): Promise<Kpi[]>;
|
|
10
10
|
kpi(id: string, context: ResolverContext): Promise<Kpi>;
|
|
11
11
|
kpis(params: ListParam, context: ResolverContext): Promise<KpiList>;
|
|
12
|
-
children(kpi: Kpi): Promise<Kpi[]>;
|
|
12
|
+
children(kpi: Kpi, context: ResolverContext): Promise<Kpi[]>;
|
|
13
13
|
thumbnail(kpi: Kpi): Promise<string | undefined>;
|
|
14
14
|
domain(kpi: Kpi): Promise<Domain>;
|
|
15
15
|
updater(kpi: Kpi): Promise<User>;
|
|
@@ -12,17 +12,20 @@ const kpi_type_1 = require("./kpi-type");
|
|
|
12
12
|
const kpi_value_1 = require("../kpi-value/kpi-value");
|
|
13
13
|
const kpi_history_1 = require("./kpi-history");
|
|
14
14
|
const type_graphql_2 = require("type-graphql");
|
|
15
|
+
const domain_inheritance_1 = require("../utils/domain-inheritance");
|
|
15
16
|
let KpiQuery = class KpiQuery {
|
|
16
17
|
async kpisLevel0(context) {
|
|
17
18
|
const { domain } = context.state;
|
|
19
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
18
20
|
return await (0, shell_1.getRepository)(kpi_1.Kpi).find({
|
|
19
|
-
where: { domain: { id:
|
|
21
|
+
where: { domain: { id: (0, typeorm_1.In)(domainIds) }, parent: (0, typeorm_1.IsNull)() },
|
|
20
22
|
order: { name: 'ASC' }
|
|
21
23
|
});
|
|
22
24
|
}
|
|
23
25
|
async kpisLevel1(rootId, context) {
|
|
24
26
|
const { domain } = context.state;
|
|
25
|
-
|
|
27
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
28
|
+
let whereCondition = { domain: { id: (0, typeorm_1.In)(domainIds) } };
|
|
26
29
|
if (rootId) {
|
|
27
30
|
// 특정 부모의 자식들
|
|
28
31
|
whereCondition.parent = { id: rootId };
|
|
@@ -35,7 +38,7 @@ let KpiQuery = class KpiQuery {
|
|
|
35
38
|
.leftJoinAndSelect('kpi.parent', 'parent')
|
|
36
39
|
.leftJoinAndSelect('kpi.children', 'children')
|
|
37
40
|
.leftJoinAndSelect('children.children', 'grandchildren')
|
|
38
|
-
.where('kpi.domain
|
|
41
|
+
.where('kpi.domain IN (:...domainIds)', { domainIds })
|
|
39
42
|
.andWhere('parent.id IS NOT NULL')
|
|
40
43
|
.andWhere('parent.parent IS NULL')
|
|
41
44
|
.orderBy('kpi.name', 'ASC')
|
|
@@ -52,27 +55,41 @@ let KpiQuery = class KpiQuery {
|
|
|
52
55
|
}
|
|
53
56
|
async kpi(id, context) {
|
|
54
57
|
const { domain } = context.state;
|
|
58
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
55
59
|
return await (0, shell_1.getRepository)(kpi_1.Kpi).findOne({
|
|
56
|
-
where: { domain: { id:
|
|
60
|
+
where: { domain: { id: (0, typeorm_1.In)(domainIds) }, id }
|
|
57
61
|
});
|
|
58
62
|
}
|
|
59
63
|
async kpis(params, context) {
|
|
60
64
|
const { domain } = context.state;
|
|
65
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
66
|
+
// closest-wins dedup 을 위해 pagination 은 dedup 이후 직접 적용한다.
|
|
67
|
+
const { pagination, ...rest } = params || {};
|
|
61
68
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
62
|
-
domain
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
// domain 필터링은 ancestor 기반으로 직접 적용 (shell helper 는 single-parent 만 지원)
|
|
70
|
+
domain: undefined,
|
|
71
|
+
params: rest,
|
|
72
|
+
repository: (0, shell_1.getRepository)(kpi_1.Kpi),
|
|
65
73
|
searchables: ['name', 'description'],
|
|
66
74
|
filtersMap: {
|
|
67
75
|
parent: { columnName: 'id', relationColumn: 'parent' }
|
|
68
76
|
}
|
|
69
77
|
});
|
|
70
|
-
|
|
78
|
+
queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {
|
|
79
|
+
ancestorDomainIds: domainIds
|
|
80
|
+
});
|
|
81
|
+
const allItems = await queryBuilder.getMany();
|
|
82
|
+
const deduped = (0, domain_inheritance_1.dedupByClosestDomain)(allItems, domainIds, k => k.name);
|
|
83
|
+
const { page = 1, limit } = pagination || {};
|
|
84
|
+
const total = deduped.length;
|
|
85
|
+
const items = limit && limit > 0 ? deduped.slice(Math.max(0, (page - 1) * limit), Math.max(0, (page - 1) * limit) + limit) : deduped;
|
|
71
86
|
return { items, total };
|
|
72
87
|
}
|
|
73
|
-
children(kpi) {
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
async children(kpi, context) {
|
|
89
|
+
const { domain } = context.state;
|
|
90
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
91
|
+
return await (0, shell_1.getRepository)(kpi_1.Kpi).find({
|
|
92
|
+
where: { domain: { id: (0, typeorm_1.In)(domainIds) }, parent: { id: kpi.id } }
|
|
76
93
|
});
|
|
77
94
|
}
|
|
78
95
|
async thumbnail(kpi) {
|
|
@@ -96,8 +113,9 @@ let KpiQuery = class KpiQuery {
|
|
|
96
113
|
}
|
|
97
114
|
async value(kpi, context, orgScope) {
|
|
98
115
|
const { domain } = context.state;
|
|
116
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
99
117
|
let whereCondition = {
|
|
100
|
-
domain: { id:
|
|
118
|
+
domain: { id: (0, typeorm_1.In)(domainIds) },
|
|
101
119
|
kpi: { id: kpi.id }
|
|
102
120
|
};
|
|
103
121
|
// orgScope 필터가 있으면 KpiOrgScope로 필터링
|
|
@@ -123,9 +141,10 @@ let KpiQuery = class KpiQuery {
|
|
|
123
141
|
}
|
|
124
142
|
async histories(kpi, context, limit) {
|
|
125
143
|
const { domain } = context.state;
|
|
144
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
126
145
|
const qb = (0, shell_1.getRepository)(kpi_history_1.KpiHistory)
|
|
127
146
|
.createQueryBuilder('history')
|
|
128
|
-
.where('history.domain
|
|
147
|
+
.where('history.domain IN (:...domainIds)', { domainIds })
|
|
129
148
|
.andWhere('history.originalId = :kpiId', { kpiId: kpi.id })
|
|
130
149
|
.orderBy('history.updatedAt', 'DESC');
|
|
131
150
|
if (limit)
|
|
@@ -136,16 +155,18 @@ let KpiQuery = class KpiQuery {
|
|
|
136
155
|
}
|
|
137
156
|
async kpiTree(context) {
|
|
138
157
|
const { domain } = context.state;
|
|
158
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
139
159
|
return await (0, shell_1.getRepository)(kpi_1.Kpi).find({
|
|
140
|
-
where: { domain: { id:
|
|
160
|
+
where: { domain: { id: (0, typeorm_1.In)(domainIds) }, parent: (0, typeorm_1.IsNull)() },
|
|
141
161
|
relations: ['children', 'children.children', 'children.children.children'],
|
|
142
162
|
order: { name: 'ASC' }
|
|
143
163
|
});
|
|
144
164
|
}
|
|
145
165
|
async kpiChildren(parentId, context) {
|
|
146
166
|
const { domain } = context.state;
|
|
167
|
+
const domainIds = await (0, domain_inheritance_1.getDomainIdsWithAncestors)(domain);
|
|
147
168
|
return await (0, shell_1.getRepository)(kpi_1.Kpi).find({
|
|
148
|
-
where: { domain: { id:
|
|
169
|
+
where: { domain: { id: (0, typeorm_1.In)(domainIds) }, parent: { id: parentId } },
|
|
149
170
|
order: { name: 'ASC' }
|
|
150
171
|
});
|
|
151
172
|
}
|
|
@@ -194,8 +215,9 @@ tslib_1.__decorate([
|
|
|
194
215
|
tslib_1.__decorate([
|
|
195
216
|
(0, type_graphql_1.FieldResolver)(type => [kpi_1.Kpi]),
|
|
196
217
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
218
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
197
219
|
tslib_1.__metadata("design:type", Function),
|
|
198
|
-
tslib_1.__metadata("design:paramtypes", [kpi_1.Kpi]),
|
|
220
|
+
tslib_1.__metadata("design:paramtypes", [kpi_1.Kpi, Object]),
|
|
199
221
|
tslib_1.__metadata("design:returntype", Promise)
|
|
200
222
|
], KpiQuery.prototype, "children", null);
|
|
201
223
|
tslib_1.__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-query.js","sourceRoot":"","sources":["../../../server/service/kpi/kpi-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { IsNull } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Attachment } from '@things-factory/attachment-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport type ResolverContext from '@things-factory/auth-base'\nimport { Kpi } from './kpi'\nimport { KpiList } from './kpi-type'\nimport { KpiValue } from '../kpi-value/kpi-value'\nimport { KpiHistory } from './kpi-history'\nimport { Int } from 'type-graphql'\n\n@Resolver(Kpi)\nexport class KpiQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch root KPIs (KPIs without parent)' })\n async kpisLevel0(@Ctx() context: ResolverContext): Promise<Kpi[]> {\n const { domain } = context.state\n\n return await getRepository(Kpi).find({\n where: { domain: { id: domain.id }, parent: null },\n order: { name: 'ASC' }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], {\n description:\n 'Fetch first level child KPIs. If rootId is provided, get children of that parent. If not, get all level 1 KPIs (children of root KPIs)'\n })\n async kpisLevel1(\n @Arg('rootId', {\n nullable: true,\n description: 'ID of the parent KPI to get level 1 children. If not provided, returns all level 1 KPIs'\n })\n rootId: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi[]> {\n const { domain } = context.state\n\n let whereCondition: any = { domain: { id: domain.id } }\n\n if (rootId) {\n // 특정 부모의 자식들\n whereCondition.parent = { id: rootId }\n } else {\n // 모든 level 1 KPI들 (root KPI들의 직계 자식들)\n // 부모가 있으면서 부모의 부모가 null인 KPI들\n const kpis = await getRepository(Kpi)\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.parent', 'parent')\n .leftJoinAndSelect('kpi.children', 'children')\n .leftJoinAndSelect('children.children', 'grandchildren')\n .where('kpi.domain = :domainId', { domainId: domain.id })\n .andWhere('parent.id IS NOT NULL')\n .andWhere('parent.parent IS NULL')\n .orderBy('kpi.name', 'ASC')\n .getMany()\n\n return kpis\n }\n\n // rootId 제공된 경우\n const kpis = await getRepository(Kpi).find({\n where: whereCondition,\n relations: ['children', 'children.children'],\n order: { name: 'ASC' }\n })\n\n return kpis\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => Kpi!, { nullable: true, description: 'Fetch a single KPI by its unique identifier.' })\n async kpi(\n @Arg('id', { description: 'Unique identifier of the KPI to fetch.' }) id: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi> {\n const { domain } = context.state\n\n return await getRepository(Kpi).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiList, { description: 'To fetch multiple Kpis' })\n async kpis(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<KpiList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(Kpi),\n searchables: ['name', 'description'],\n filtersMap: {\n parent: { columnName: 'id', relationColumn: 'parent' }\n }\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => [Kpi])\n children(@Root() kpi: Kpi): Promise<Kpi[]> {\n return getRepository(Kpi).find({\n where: { parent: { id: kpi.id } }\n })\n }\n\n @FieldResolver(type => String)\n async thumbnail(@Root() kpi: Kpi): Promise<string | undefined> {\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: kpi.domainId },\n refType: Kpi.name,\n refBy: kpi.id\n }\n })\n\n return attachment?.fullpath\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpi: Kpi): Promise<Domain> {\n return kpi.domainId && (await getRepository(Domain).findOneBy({ id: kpi.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpi: Kpi): Promise<User> {\n return kpi.updaterId && (await getRepository(User).findOneBy({ id: kpi.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpi: Kpi): Promise<User> {\n return kpi.creatorId && (await getRepository(User).findOneBy({ id: kpi.creatorId }))\n }\n\n @FieldResolver(type => KpiValue, { nullable: true })\n async value(\n @Root() kpi: Kpi,\n @Ctx() context,\n @Arg('orgScope', { nullable: true, description: 'Organization scope filter for value' }) orgScope?: string\n ): Promise<KpiValue | null> {\n const { domain } = context.state\n\n let whereCondition: any = {\n domain: { id: domain.id },\n kpi: { id: kpi.id }\n }\n\n // orgScope 필터가 있으면 KpiOrgScope로 필터링\n if (orgScope) {\n whereCondition.kpiOrgScope = { org: orgScope }\n }\n\n return await getRepository(KpiValue).findOne({\n where: whereCondition,\n relations: ['kpiOrgScope'],\n order: { valueDate: 'DESC' }\n })\n }\n\n @FieldResolver(type => Number, { nullable: true })\n targetValue(@Root() kpi: Kpi): number | undefined {\n return kpi.vizMeta?.targetValue\n }\n\n @FieldResolver(type => String, { nullable: true })\n unit(@Root() kpi: Kpi): string | undefined {\n return kpi.vizMeta?.unit\n }\n\n @FieldResolver(type => Kpi, { nullable: true })\n async parent(@Root() kpi: Kpi): Promise<Kpi | null> {\n if (!kpi.parentId) return null\n return await getRepository(Kpi).findOneBy({ id: kpi.parentId })\n }\n\n @FieldResolver(type => [KpiHistory], { nullable: true })\n async histories(\n @Root() kpi: Kpi,\n @Ctx() context,\n @Arg('limit', type => Int, { nullable: true }) limit?: number\n ): Promise<KpiHistory[]> {\n const { domain } = context.state\n const qb = getRepository(KpiHistory)\n .createQueryBuilder('history')\n .where('history.domain = :domainId', { domainId: domain.id })\n .andWhere('history.originalId = :kpiId', { kpiId: kpi.id })\n .orderBy('history.updatedAt', 'DESC')\n if (limit) qb.limit(limit)\n else qb.limit(1)\n return await qb.getMany()\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch KPIs in hierarchical tree structure' })\n async kpiTree(@Ctx() context: ResolverContext): Promise<Kpi[]> {\n const { domain } = context.state\n\n return await getRepository(Kpi).find({\n where: { domain: { id: domain.id }, parent: IsNull() },\n relations: ['children', 'children.children', 'children.children.children'],\n order: { name: 'ASC' }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch child KPIs of a given parent KPI' })\n async kpiChildren(\n @Arg('parentId', { description: 'ID of the parent KPI' }) parentId: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi[]> {\n const { domain } = context.state\n\n return await getRepository(Kpi).find({\n where: { domain: { id: domain.id }, parent: { id: parentId } },\n order: { name: 'ASC' }\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"kpi-query.js","sourceRoot":"","sources":["../../../server/service/kpi/kpi-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { In, IsNull } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Attachment } from '@things-factory/attachment-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport type ResolverContext from '@things-factory/auth-base'\nimport { Kpi } from './kpi'\nimport { KpiList } from './kpi-type'\nimport { KpiValue } from '../kpi-value/kpi-value'\nimport { KpiHistory } from './kpi-history'\nimport { Int } from 'type-graphql'\nimport { dedupByClosestDomain, getDomainIdsWithAncestors } from '../utils/domain-inheritance'\n\n@Resolver(Kpi)\nexport class KpiQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch root KPIs (KPIs without parent)' })\n async kpisLevel0(@Ctx() context: ResolverContext): Promise<Kpi[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(Kpi).find({\n where: { domain: { id: In(domainIds) }, parent: IsNull() },\n order: { name: 'ASC' }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], {\n description:\n 'Fetch first level child KPIs. If rootId is provided, get children of that parent. If not, get all level 1 KPIs (children of root KPIs)'\n })\n async kpisLevel1(\n @Arg('rootId', {\n nullable: true,\n description: 'ID of the parent KPI to get level 1 children. If not provided, returns all level 1 KPIs'\n })\n rootId: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n let whereCondition: any = { domain: { id: In(domainIds) } }\n\n if (rootId) {\n // 특정 부모의 자식들\n whereCondition.parent = { id: rootId }\n } else {\n // 모든 level 1 KPI들 (root KPI들의 직계 자식들)\n // 부모가 있으면서 부모의 부모가 null인 KPI들\n const kpis = await getRepository(Kpi)\n .createQueryBuilder('kpi')\n .leftJoinAndSelect('kpi.parent', 'parent')\n .leftJoinAndSelect('kpi.children', 'children')\n .leftJoinAndSelect('children.children', 'grandchildren')\n .where('kpi.domain IN (:...domainIds)', { domainIds })\n .andWhere('parent.id IS NOT NULL')\n .andWhere('parent.parent IS NULL')\n .orderBy('kpi.name', 'ASC')\n .getMany()\n\n return kpis\n }\n\n // rootId 제공된 경우\n const kpis = await getRepository(Kpi).find({\n where: whereCondition,\n relations: ['children', 'children.children'],\n order: { name: 'ASC' }\n })\n\n return kpis\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => Kpi!, { nullable: true, description: 'Fetch a single KPI by its unique identifier.' })\n async kpi(\n @Arg('id', { description: 'Unique identifier of the KPI to fetch.' }) id: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(Kpi).findOne({\n where: { domain: { id: In(domainIds) }, id }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiList, { description: 'To fetch multiple Kpis' })\n async kpis(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<KpiList> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n // closest-wins dedup 을 위해 pagination 은 dedup 이후 직접 적용한다.\n const { pagination, ...rest } = params || ({} as ListParam)\n\n const queryBuilder = getQueryBuilderFromListParams({\n // domain 필터링은 ancestor 기반으로 직접 적용 (shell helper 는 single-parent 만 지원)\n domain: undefined,\n params: rest as ListParam,\n repository: getRepository(Kpi),\n searchables: ['name', 'description'],\n filtersMap: {\n parent: { columnName: 'id', relationColumn: 'parent' }\n }\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n const allItems = await queryBuilder.getMany()\n const deduped = dedupByClosestDomain(allItems, domainIds, k => k.name)\n\n const { page = 1, limit } = pagination || {}\n const total = deduped.length\n const items =\n limit && limit > 0 ? deduped.slice(Math.max(0, (page - 1) * limit), Math.max(0, (page - 1) * limit) + limit) : deduped\n\n return { items, total }\n }\n\n @FieldResolver(type => [Kpi])\n async children(@Root() kpi: Kpi, @Ctx() context: ResolverContext): Promise<Kpi[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(Kpi).find({\n where: { domain: { id: In(domainIds) }, parent: { id: kpi.id } }\n })\n }\n\n @FieldResolver(type => String)\n async thumbnail(@Root() kpi: Kpi): Promise<string | undefined> {\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: kpi.domainId },\n refType: Kpi.name,\n refBy: kpi.id\n }\n })\n\n return attachment?.fullpath\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpi: Kpi): Promise<Domain> {\n return kpi.domainId && (await getRepository(Domain).findOneBy({ id: kpi.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpi: Kpi): Promise<User> {\n return kpi.updaterId && (await getRepository(User).findOneBy({ id: kpi.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpi: Kpi): Promise<User> {\n return kpi.creatorId && (await getRepository(User).findOneBy({ id: kpi.creatorId }))\n }\n\n @FieldResolver(type => KpiValue, { nullable: true })\n async value(\n @Root() kpi: Kpi,\n @Ctx() context,\n @Arg('orgScope', { nullable: true, description: 'Organization scope filter for value' }) orgScope?: string\n ): Promise<KpiValue | null> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n let whereCondition: any = {\n domain: { id: In(domainIds) },\n kpi: { id: kpi.id }\n }\n\n // orgScope 필터가 있으면 KpiOrgScope로 필터링\n if (orgScope) {\n whereCondition.kpiOrgScope = { org: orgScope }\n }\n\n return await getRepository(KpiValue).findOne({\n where: whereCondition,\n relations: ['kpiOrgScope'],\n order: { valueDate: 'DESC' }\n })\n }\n\n @FieldResolver(type => Number, { nullable: true })\n targetValue(@Root() kpi: Kpi): number | undefined {\n return kpi.vizMeta?.targetValue\n }\n\n @FieldResolver(type => String, { nullable: true })\n unit(@Root() kpi: Kpi): string | undefined {\n return kpi.vizMeta?.unit\n }\n\n @FieldResolver(type => Kpi, { nullable: true })\n async parent(@Root() kpi: Kpi): Promise<Kpi | null> {\n if (!kpi.parentId) return null\n return await getRepository(Kpi).findOneBy({ id: kpi.parentId })\n }\n\n @FieldResolver(type => [KpiHistory], { nullable: true })\n async histories(\n @Root() kpi: Kpi,\n @Ctx() context,\n @Arg('limit', type => Int, { nullable: true }) limit?: number\n ): Promise<KpiHistory[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n const qb = getRepository(KpiHistory)\n .createQueryBuilder('history')\n .where('history.domain IN (:...domainIds)', { domainIds })\n .andWhere('history.originalId = :kpiId', { kpiId: kpi.id })\n .orderBy('history.updatedAt', 'DESC')\n if (limit) qb.limit(limit)\n else qb.limit(1)\n return await qb.getMany()\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch KPIs in hierarchical tree structure' })\n async kpiTree(@Ctx() context: ResolverContext): Promise<Kpi[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(Kpi).find({\n where: { domain: { id: In(domainIds) }, parent: IsNull() },\n relations: ['children', 'children.children', 'children.children.children'],\n order: { name: 'ASC' }\n })\n }\n\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => [Kpi], { description: 'Fetch child KPIs of a given parent KPI' })\n async kpiChildren(\n @Arg('parentId', { description: 'ID of the parent KPI' }) parentId: string,\n @Ctx() context: ResolverContext\n ): Promise<Kpi[]> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(Kpi).find({\n where: { domain: { id: In(domainIds) }, parent: { id: parentId } },\n order: { name: 'ASC' }\n })\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FileUpload } from 'graphql-upload/GraphQLUpload.js';
|
|
2
2
|
import { ObjectRef } from '@things-factory/shell';
|
|
3
|
-
import { Kpi, KpiStatus, KpiVizType } from './kpi';
|
|
3
|
+
import { Kpi, KpiStatus, KpiVizType, KpiScoreType, KpiValueType } from './kpi';
|
|
4
4
|
import { KpiScores } from './kpi-grade.types';
|
|
5
5
|
export declare class NewKpi {
|
|
6
6
|
name: string;
|
|
@@ -16,6 +16,8 @@ export declare class NewKpi {
|
|
|
16
16
|
schedule?: string;
|
|
17
17
|
timezone?: string;
|
|
18
18
|
weight?: number;
|
|
19
|
+
scoreType?: KpiScoreType;
|
|
20
|
+
valueType?: KpiValueType;
|
|
19
21
|
grades?: KpiScores;
|
|
20
22
|
scoreFormula?: string;
|
|
21
23
|
}
|
|
@@ -35,6 +37,8 @@ export declare class KpiPatch {
|
|
|
35
37
|
schedule?: string;
|
|
36
38
|
timezone?: string;
|
|
37
39
|
weight?: number;
|
|
40
|
+
scoreType?: KpiScoreType;
|
|
41
|
+
valueType?: KpiValueType;
|
|
38
42
|
grades?: KpiScores;
|
|
39
43
|
scoreFormula?: string;
|
|
40
44
|
}
|
|
@@ -70,6 +70,20 @@ tslib_1.__decorate([
|
|
|
70
70
|
(0, type_graphql_1.Field)({ nullable: true, description: 'Weight for aggregation in parent category.' }),
|
|
71
71
|
tslib_1.__metadata("design:type", Number)
|
|
72
72
|
], NewKpi.prototype, "weight", void 0);
|
|
73
|
+
tslib_1.__decorate([
|
|
74
|
+
(0, type_graphql_1.Field)(type => kpi_1.KpiScoreType, {
|
|
75
|
+
nullable: true,
|
|
76
|
+
description: 'value → score 변환 방식.'
|
|
77
|
+
}),
|
|
78
|
+
tslib_1.__metadata("design:type", String)
|
|
79
|
+
], NewKpi.prototype, "scoreType", void 0);
|
|
80
|
+
tslib_1.__decorate([
|
|
81
|
+
(0, type_graphql_1.Field)(type => kpi_1.KpiValueType, {
|
|
82
|
+
nullable: true,
|
|
83
|
+
description: 'value 획득 방식.'
|
|
84
|
+
}),
|
|
85
|
+
tslib_1.__metadata("design:type", String)
|
|
86
|
+
], NewKpi.prototype, "valueType", void 0);
|
|
73
87
|
tslib_1.__decorate([
|
|
74
88
|
(0, type_graphql_1.Field)(type => shell_1.ScalarObject, {
|
|
75
89
|
nullable: true,
|
|
@@ -159,6 +173,20 @@ tslib_1.__decorate([
|
|
|
159
173
|
(0, type_graphql_1.Field)({ nullable: true, description: 'Weight for aggregation in parent category.' }),
|
|
160
174
|
tslib_1.__metadata("design:type", Number)
|
|
161
175
|
], KpiPatch.prototype, "weight", void 0);
|
|
176
|
+
tslib_1.__decorate([
|
|
177
|
+
(0, type_graphql_1.Field)(type => kpi_1.KpiScoreType, {
|
|
178
|
+
nullable: true,
|
|
179
|
+
description: 'value → score 변환 방식.'
|
|
180
|
+
}),
|
|
181
|
+
tslib_1.__metadata("design:type", String)
|
|
182
|
+
], KpiPatch.prototype, "scoreType", void 0);
|
|
183
|
+
tslib_1.__decorate([
|
|
184
|
+
(0, type_graphql_1.Field)(type => kpi_1.KpiValueType, {
|
|
185
|
+
nullable: true,
|
|
186
|
+
description: 'value 획득 방식.'
|
|
187
|
+
}),
|
|
188
|
+
tslib_1.__metadata("design:type", String)
|
|
189
|
+
], KpiPatch.prototype, "valueType", void 0);
|
|
162
190
|
tslib_1.__decorate([
|
|
163
191
|
(0, type_graphql_1.Field)(type => shell_1.ScalarObject, {
|
|
164
192
|
nullable: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-type.js","sourceRoot":"","sources":["../../../server/service/kpi/kpi-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { ObjectRef, ScalarObject } from '@things-factory/shell'\n\nimport { Kpi, KpiStatus, KpiVizType } from './kpi'\nimport { KpiScores } from './kpi-grade.types'\n\n@InputType({ description: 'Input type for creating a new KPI. Used in mutations to provide KPI details.' })\nexport class NewKpi {\n @Field({ description: 'Name of the KPI.' })\n name: string\n\n @Field({ nullable: true, description: 'Detailed description of the KPI.' })\n description?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Reference to the parent KPI in hierarchical structure.' })\n parent?: ObjectRef\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is a leaf node (has actual measured values).' })\n isLeaf?: boolean\n\n @Field({ nullable: true, description: 'Calculation formula for the KPI, using metric codes and operators.' })\n formula?: string\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is active and usable.' })\n active?: boolean\n\n @Field(type => KpiStatus, { nullable: true, description: 'Current state of the KPI (DRAFT, RELEASED, ARCHIVED).' })\n state?: KpiStatus\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this KPI.' })\n thumbnail?: FileUpload\n\n @Field(type => KpiVizType, {\n nullable: true,\n description: 'Visualization type for this KPI (e.g., CARD, GAUGE, PROGRESS, BAR, LINE, etc.).'\n })\n vizType?: KpiVizType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n 'Visualization options and metadata for this KPI, such as color, icon, thresholds, unit, decimal places, etc.'\n })\n vizMeta?: any\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field({ nullable: true, description: 'Timezone for the KPI schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Weight for aggregation in parent category.' })\n weight?: number\n\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Score lookup table for this KPI version'\n })\n grades?: KpiScores\n\n @Field({\n nullable: true,\n description: 'Score calculation formula for this KPI. Converts KPI value to performance score (0-1).'\n })\n scoreFormula?: string\n}\n\n@InputType({ description: 'Input type for updating an existing KPI. Used in mutations to patch KPI details.' })\nexport class KpiPatch {\n @Field(type => ID, { nullable: true, description: 'ID of the KPI to update.' })\n id?: string\n\n @Field({ nullable: true, description: 'Name of the KPI.' })\n name?: string\n\n @Field({ nullable: true, description: 'Detailed description of the KPI.' })\n description?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Reference to the parent KPI in hierarchical structure.' })\n parent?: ObjectRef\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is a leaf node (has actual measured values).' })\n isLeaf?: boolean\n\n @Field({ nullable: true, description: 'Calculation formula for the KPI, using metric codes and operators.' })\n formula?: string\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is active and usable.' })\n active?: boolean\n\n @Field(type => KpiStatus, { nullable: true, description: 'Current state of the KPI (DRAFT, RELEASED, ARCHIVED).' })\n state?: KpiStatus\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this KPI.' })\n thumbnail?: FileUpload\n\n @Field(type => KpiVizType, {\n nullable: true,\n description: 'Visualization type for this KPI (e.g., CARD, GAUGE, PROGRESS, BAR, LINE, etc.).'\n })\n vizType?: KpiVizType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n 'Visualization options and metadata for this KPI, such as color, icon, thresholds, unit, decimal places, etc.'\n })\n vizMeta?: any\n\n @Field({ nullable: true, description: 'Custom flag for update operations (internal use).' })\n cuFlag?: string\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field({ nullable: true, description: 'Timezone for the KPI schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Weight for aggregation in parent category.' })\n weight?: number\n\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Score lookup table for this KPI version'\n })\n grades?: KpiScores\n\n @Field({\n nullable: true,\n description: 'Score calculation formula for this KPI. Converts KPI value to performance score (0-1).'\n })\n scoreFormula?: string\n}\n\n@ObjectType()\nexport class KpiList {\n @Field(type => [Kpi])\n items: Kpi[]\n\n @Field(type => Int)\n total: number\n}\n"]}
|
|
1
|
+
{"version":3,"file":"kpi-type.js","sourceRoot":"","sources":["../../../server/service/kpi/kpi-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport { ObjectType, Field, InputType, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { ObjectRef, ScalarObject } from '@things-factory/shell'\n\nimport { Kpi, KpiStatus, KpiVizType, KpiScoreType, KpiValueType } from './kpi'\nimport { KpiScores } from './kpi-grade.types'\n\n@InputType({ description: 'Input type for creating a new KPI. Used in mutations to provide KPI details.' })\nexport class NewKpi {\n @Field({ description: 'Name of the KPI.' })\n name: string\n\n @Field({ nullable: true, description: 'Detailed description of the KPI.' })\n description?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Reference to the parent KPI in hierarchical structure.' })\n parent?: ObjectRef\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is a leaf node (has actual measured values).' })\n isLeaf?: boolean\n\n @Field({ nullable: true, description: 'Calculation formula for the KPI, using metric codes and operators.' })\n formula?: string\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is active and usable.' })\n active?: boolean\n\n @Field(type => KpiStatus, { nullable: true, description: 'Current state of the KPI (DRAFT, RELEASED, ARCHIVED).' })\n state?: KpiStatus\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this KPI.' })\n thumbnail?: FileUpload\n\n @Field(type => KpiVizType, {\n nullable: true,\n description: 'Visualization type for this KPI (e.g., CARD, GAUGE, PROGRESS, BAR, LINE, etc.).'\n })\n vizType?: KpiVizType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n 'Visualization options and metadata for this KPI, such as color, icon, thresholds, unit, decimal places, etc.'\n })\n vizMeta?: any\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field({ nullable: true, description: 'Timezone for the KPI schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Weight for aggregation in parent category.' })\n weight?: number\n\n @Field(type => KpiScoreType, {\n nullable: true,\n description: 'value → score 변환 방식.'\n })\n scoreType?: KpiScoreType\n\n @Field(type => KpiValueType, {\n nullable: true,\n description: 'value 획득 방식.'\n })\n valueType?: KpiValueType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Score lookup table for this KPI version'\n })\n grades?: KpiScores\n\n @Field({\n nullable: true,\n description: 'Score calculation formula for this KPI. Converts KPI value to performance score (0-1).'\n })\n scoreFormula?: string\n}\n\n@InputType({ description: 'Input type for updating an existing KPI. Used in mutations to patch KPI details.' })\nexport class KpiPatch {\n @Field(type => ID, { nullable: true, description: 'ID of the KPI to update.' })\n id?: string\n\n @Field({ nullable: true, description: 'Name of the KPI.' })\n name?: string\n\n @Field({ nullable: true, description: 'Detailed description of the KPI.' })\n description?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Reference to the parent KPI in hierarchical structure.' })\n parent?: ObjectRef\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is a leaf node (has actual measured values).' })\n isLeaf?: boolean\n\n @Field({ nullable: true, description: 'Calculation formula for the KPI, using metric codes and operators.' })\n formula?: string\n\n @Field({ nullable: true, description: 'Indicates whether this KPI is active and usable.' })\n active?: boolean\n\n @Field(type => KpiStatus, { nullable: true, description: 'Current state of the KPI (DRAFT, RELEASED, ARCHIVED).' })\n state?: KpiStatus\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Thumbnail image or file for this KPI.' })\n thumbnail?: FileUpload\n\n @Field(type => KpiVizType, {\n nullable: true,\n description: 'Visualization type for this KPI (e.g., CARD, GAUGE, PROGRESS, BAR, LINE, etc.).'\n })\n vizType?: KpiVizType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description:\n 'Visualization options and metadata for this KPI, such as color, icon, thresholds, unit, decimal places, etc.'\n })\n vizMeta?: any\n\n @Field({ nullable: true, description: 'Custom flag for update operations (internal use).' })\n cuFlag?: string\n\n @Field({\n nullable: true,\n description: 'Cron schedule string for periodic KPI value aggregation (e.g., \"0 0 * * *\" for daily).'\n })\n schedule?: string\n\n @Field({ nullable: true, description: 'Timezone for the KPI schedule.' })\n timezone?: string\n\n @Field({ nullable: true, description: 'Weight for aggregation in parent category.' })\n weight?: number\n\n @Field(type => KpiScoreType, {\n nullable: true,\n description: 'value → score 변환 방식.'\n })\n scoreType?: KpiScoreType\n\n @Field(type => KpiValueType, {\n nullable: true,\n description: 'value 획득 방식.'\n })\n valueType?: KpiValueType\n\n @Field(type => ScalarObject, {\n nullable: true,\n description: 'Score lookup table for this KPI version'\n })\n grades?: KpiScores\n\n @Field({\n nullable: true,\n description: 'Score calculation formula for this KPI. Converts KPI value to performance score (0-1).'\n })\n scoreFormula?: string\n}\n\n@ObjectType()\nexport class KpiList {\n @Field(type => [Kpi])\n items: Kpi[]\n\n @Field(type => Int)\n total: number\n}\n"]}
|
|
@@ -32,6 +32,68 @@ export declare enum KpiPeriodType {
|
|
|
32
32
|
RANGE = "RANGE",
|
|
33
33
|
ALLTIME = "ALLTIME"
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* KPI scoreType — value → score 변환 방식
|
|
37
|
+
*
|
|
38
|
+
* 미설정(null)이면 score 변환이 정의되지 않은 상태.
|
|
39
|
+
*
|
|
40
|
+
* DIRECT — value = score, 별도 변환 없음.
|
|
41
|
+
* value 자체가 최종 성과 점수로 사용됨.
|
|
42
|
+
* 예: Y1~Y6(영역별 성과), Z(전체스코어) — formula로 계산된 value가 곧 score.
|
|
43
|
+
* 예: X14(일정성과 수준 평가) — 감리자가 입력한 1~5점이 곧 score.
|
|
44
|
+
*
|
|
45
|
+
* FORMULA — scoreFormula 수식으로 value → score 변환.
|
|
46
|
+
* KPI 엔티티의 scoreFormula 필드에 정의된 수식을 적용.
|
|
47
|
+
* 예: "1 - value / 0.82", "if(value >= 90, 100, 70)"
|
|
48
|
+
*
|
|
49
|
+
* LOOKUP — grade table(1D 배열)로 raw value → 0~1 score 변환.
|
|
50
|
+
* KPI 엔티티의 grades 필드에 {minValue, maxValue, score} 배열로 정의.
|
|
51
|
+
* value가 속하는 구간의 score를 반환.
|
|
52
|
+
* 예: X11(연면적 대비 공사기간), X33(검측 불합격률), X34(품질 SL-PA)
|
|
53
|
+
*
|
|
54
|
+
* CUSTOM — 2D 룩업 등 애플리케이션에서 정의하는 특수 변환.
|
|
55
|
+
* grades에 다차원 lookup 구조가 저장됨.
|
|
56
|
+
* 예: X13(일정 이탈 수준) — 공정률(%) × 편차율(%) → 1~5점
|
|
57
|
+
*/
|
|
58
|
+
export declare enum KpiScoreType {
|
|
59
|
+
DIRECT = "DIRECT",
|
|
60
|
+
FORMULA = "FORMULA",
|
|
61
|
+
LOOKUP = "LOOKUP",
|
|
62
|
+
CUSTOM = "CUSTOM"
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* KPI valueType — value 획득 방식
|
|
66
|
+
*
|
|
67
|
+
* KPI의 value(측정값/입력값)를 어떤 방식으로 얻는지를 정의한다.
|
|
68
|
+
* scoreType(value→score 변환)과는 독립적인 개념.
|
|
69
|
+
*
|
|
70
|
+
* MEASURED — 외부 시스템(API, DB 연계)에서 자동 수집한 정량 측정값.
|
|
71
|
+
* 연속 실수값이며, 단위와 범위가 KPI마다 다름.
|
|
72
|
+
* 예: X11(연면적 대비 공사기간), X33(검측 불합격률), X41(재해율), X61(투입인력 생산성)
|
|
73
|
+
* 보통 scoreType=LOOKUP과 함께 사용하여 grade table로 score 변환.
|
|
74
|
+
*
|
|
75
|
+
* ASSESSED — 감리자/평가자가 직접 입력한 정성 평가.
|
|
76
|
+
* 배점 기준(1~5점 척도)에 따라 수동 입력됨.
|
|
77
|
+
* 예: X14(일정성과 수준 평가), X23(비용성과), X35(품질성과), X44(안전성과)
|
|
78
|
+
* 보통 scoreType=DIRECT와 함께 사용 (value가 곧 score).
|
|
79
|
+
*
|
|
80
|
+
* CALCULATED — 산식(formula 필드)으로 하위 KPI들의 가중합 등을 자동 계산.
|
|
81
|
+
* KPI 엔티티의 formula 필드에 정의된 수식을 기반으로 서버에서 연산.
|
|
82
|
+
* 예: Y1(일정성과) = X11*0.3 + X12*0.4 + X13/5*0.15 + X14/5*0.15
|
|
83
|
+
* 예: Z(전체스코어) = Y1~Y6의 가중 평균
|
|
84
|
+
* 보통 scoreType=DIRECT와 함께 사용 (계산 결과가 곧 score).
|
|
85
|
+
*
|
|
86
|
+
* COMPOSITE — 다차원 입력의 복합 결과.
|
|
87
|
+
* 단일 raw value가 아닌 복수의 입력(공정률, 편차율 등)을 조합하여 산출.
|
|
88
|
+
* 예: X13(일정 이탈 수준) — 공정률(%) × 공기편차(%) 2D 룩업 → 1~5점
|
|
89
|
+
* 보통 scoreType=CUSTOM과 함께 사용.
|
|
90
|
+
*/
|
|
91
|
+
export declare enum KpiValueType {
|
|
92
|
+
MEASURED = "MEASURED",
|
|
93
|
+
ASSESSED = "ASSESSED",
|
|
94
|
+
CALCULATED = "CALCULATED",
|
|
95
|
+
COMPOSITE = "COMPOSITE"
|
|
96
|
+
}
|
|
35
97
|
export declare class Kpi {
|
|
36
98
|
readonly id: string;
|
|
37
99
|
version?: number;
|
|
@@ -53,6 +115,8 @@ export declare class Kpi {
|
|
|
53
115
|
timezone?: string;
|
|
54
116
|
periodType: KpiPeriodType;
|
|
55
117
|
weight?: number;
|
|
118
|
+
scoreType?: KpiScoreType;
|
|
119
|
+
valueType?: KpiValueType;
|
|
56
120
|
grades?: KpiScores;
|
|
57
121
|
scoreFormula?: string;
|
|
58
122
|
createdAt?: Date;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Kpi = exports.KpiPeriodType = exports.KpiVizType = exports.KpiStatus = void 0;
|
|
3
|
+
exports.Kpi = exports.KpiValueType = exports.KpiScoreType = exports.KpiPeriodType = exports.KpiVizType = exports.KpiStatus = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const typeorm_1 = require("typeorm");
|
|
6
6
|
const type_graphql_1 = require("type-graphql");
|
|
@@ -44,6 +44,70 @@ var KpiPeriodType;
|
|
|
44
44
|
KpiPeriodType["RANGE"] = "RANGE";
|
|
45
45
|
KpiPeriodType["ALLTIME"] = "ALLTIME";
|
|
46
46
|
})(KpiPeriodType || (exports.KpiPeriodType = KpiPeriodType = {}));
|
|
47
|
+
/**
|
|
48
|
+
* KPI scoreType — value → score 변환 방식
|
|
49
|
+
*
|
|
50
|
+
* 미설정(null)이면 score 변환이 정의되지 않은 상태.
|
|
51
|
+
*
|
|
52
|
+
* DIRECT — value = score, 별도 변환 없음.
|
|
53
|
+
* value 자체가 최종 성과 점수로 사용됨.
|
|
54
|
+
* 예: Y1~Y6(영역별 성과), Z(전체스코어) — formula로 계산된 value가 곧 score.
|
|
55
|
+
* 예: X14(일정성과 수준 평가) — 감리자가 입력한 1~5점이 곧 score.
|
|
56
|
+
*
|
|
57
|
+
* FORMULA — scoreFormula 수식으로 value → score 변환.
|
|
58
|
+
* KPI 엔티티의 scoreFormula 필드에 정의된 수식을 적용.
|
|
59
|
+
* 예: "1 - value / 0.82", "if(value >= 90, 100, 70)"
|
|
60
|
+
*
|
|
61
|
+
* LOOKUP — grade table(1D 배열)로 raw value → 0~1 score 변환.
|
|
62
|
+
* KPI 엔티티의 grades 필드에 {minValue, maxValue, score} 배열로 정의.
|
|
63
|
+
* value가 속하는 구간의 score를 반환.
|
|
64
|
+
* 예: X11(연면적 대비 공사기간), X33(검측 불합격률), X34(품질 SL-PA)
|
|
65
|
+
*
|
|
66
|
+
* CUSTOM — 2D 룩업 등 애플리케이션에서 정의하는 특수 변환.
|
|
67
|
+
* grades에 다차원 lookup 구조가 저장됨.
|
|
68
|
+
* 예: X13(일정 이탈 수준) — 공정률(%) × 편차율(%) → 1~5점
|
|
69
|
+
*/
|
|
70
|
+
var KpiScoreType;
|
|
71
|
+
(function (KpiScoreType) {
|
|
72
|
+
KpiScoreType["DIRECT"] = "DIRECT";
|
|
73
|
+
KpiScoreType["FORMULA"] = "FORMULA";
|
|
74
|
+
KpiScoreType["LOOKUP"] = "LOOKUP";
|
|
75
|
+
KpiScoreType["CUSTOM"] = "CUSTOM";
|
|
76
|
+
})(KpiScoreType || (exports.KpiScoreType = KpiScoreType = {}));
|
|
77
|
+
/**
|
|
78
|
+
* KPI valueType — value 획득 방식
|
|
79
|
+
*
|
|
80
|
+
* KPI의 value(측정값/입력값)를 어떤 방식으로 얻는지를 정의한다.
|
|
81
|
+
* scoreType(value→score 변환)과는 독립적인 개념.
|
|
82
|
+
*
|
|
83
|
+
* MEASURED — 외부 시스템(API, DB 연계)에서 자동 수집한 정량 측정값.
|
|
84
|
+
* 연속 실수값이며, 단위와 범위가 KPI마다 다름.
|
|
85
|
+
* 예: X11(연면적 대비 공사기간), X33(검측 불합격률), X41(재해율), X61(투입인력 생산성)
|
|
86
|
+
* 보통 scoreType=LOOKUP과 함께 사용하여 grade table로 score 변환.
|
|
87
|
+
*
|
|
88
|
+
* ASSESSED — 감리자/평가자가 직접 입력한 정성 평가.
|
|
89
|
+
* 배점 기준(1~5점 척도)에 따라 수동 입력됨.
|
|
90
|
+
* 예: X14(일정성과 수준 평가), X23(비용성과), X35(품질성과), X44(안전성과)
|
|
91
|
+
* 보통 scoreType=DIRECT와 함께 사용 (value가 곧 score).
|
|
92
|
+
*
|
|
93
|
+
* CALCULATED — 산식(formula 필드)으로 하위 KPI들의 가중합 등을 자동 계산.
|
|
94
|
+
* KPI 엔티티의 formula 필드에 정의된 수식을 기반으로 서버에서 연산.
|
|
95
|
+
* 예: Y1(일정성과) = X11*0.3 + X12*0.4 + X13/5*0.15 + X14/5*0.15
|
|
96
|
+
* 예: Z(전체스코어) = Y1~Y6의 가중 평균
|
|
97
|
+
* 보통 scoreType=DIRECT와 함께 사용 (계산 결과가 곧 score).
|
|
98
|
+
*
|
|
99
|
+
* COMPOSITE — 다차원 입력의 복합 결과.
|
|
100
|
+
* 단일 raw value가 아닌 복수의 입력(공정률, 편차율 등)을 조합하여 산출.
|
|
101
|
+
* 예: X13(일정 이탈 수준) — 공정률(%) × 공기편차(%) 2D 룩업 → 1~5점
|
|
102
|
+
* 보통 scoreType=CUSTOM과 함께 사용.
|
|
103
|
+
*/
|
|
104
|
+
var KpiValueType;
|
|
105
|
+
(function (KpiValueType) {
|
|
106
|
+
KpiValueType["MEASURED"] = "MEASURED";
|
|
107
|
+
KpiValueType["ASSESSED"] = "ASSESSED";
|
|
108
|
+
KpiValueType["CALCULATED"] = "CALCULATED";
|
|
109
|
+
KpiValueType["COMPOSITE"] = "COMPOSITE";
|
|
110
|
+
})(KpiValueType || (exports.KpiValueType = KpiValueType = {}));
|
|
47
111
|
(0, type_graphql_1.registerEnumType)(KpiStatus, {
|
|
48
112
|
name: 'KpiStatus',
|
|
49
113
|
description: 'State enumeration of a KPI (DRAFT, RELEASED, ARCHIVED)'
|
|
@@ -56,6 +120,14 @@ var KpiPeriodType;
|
|
|
56
120
|
name: 'KpiPeriodType',
|
|
57
121
|
description: 'Aggregation period type for KPI (DAY, WEEK, MONTH, QUARTER, RANGE, ALLTIME)'
|
|
58
122
|
});
|
|
123
|
+
(0, type_graphql_1.registerEnumType)(KpiScoreType, {
|
|
124
|
+
name: 'KpiScoreType',
|
|
125
|
+
description: 'value → score 변환 방식. DIRECT: value=score(변환 없음), FORMULA: scoreFormula 수식 적용, LOOKUP: grade table(1D) 매핑, CUSTOM: 2D 룩업 등 특수 변환.'
|
|
126
|
+
});
|
|
127
|
+
(0, type_graphql_1.registerEnumType)(KpiValueType, {
|
|
128
|
+
name: 'KpiValueType',
|
|
129
|
+
description: 'value 획득 방식. MEASURED: 외부 시스템 수집 측정값, ASSESSED: 감리자 직접 평가(1~5), CALCULATED: formula 자동 계산, COMPOSITE: 다차원 복합 입력 결과.'
|
|
130
|
+
});
|
|
59
131
|
let Kpi = class Kpi {
|
|
60
132
|
constructor() {
|
|
61
133
|
this.version = 1;
|
|
@@ -187,6 +259,22 @@ tslib_1.__decorate([
|
|
|
187
259
|
(0, type_graphql_1.Field)({ nullable: true, description: 'Weight for aggregation in parent category.' }),
|
|
188
260
|
tslib_1.__metadata("design:type", Number)
|
|
189
261
|
], Kpi.prototype, "weight", void 0);
|
|
262
|
+
tslib_1.__decorate([
|
|
263
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
264
|
+
(0, type_graphql_1.Field)(type => KpiScoreType, {
|
|
265
|
+
nullable: true,
|
|
266
|
+
description: 'value → score 변환 방식. NONE: 미설정, DIRECT: value=score(변환 없음), FORMULA: scoreFormula 수식, LOOKUP: grade table(1D), CUSTOM: 2D 룩업 등 특수 변환.'
|
|
267
|
+
}),
|
|
268
|
+
tslib_1.__metadata("design:type", String)
|
|
269
|
+
], Kpi.prototype, "scoreType", void 0);
|
|
270
|
+
tslib_1.__decorate([
|
|
271
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
272
|
+
(0, type_graphql_1.Field)(type => KpiValueType, {
|
|
273
|
+
nullable: true,
|
|
274
|
+
description: 'value 획득 방식. MEASURED: 외부 시스템 수집 측정값, ASSESSED: 감리자 직접 평가(1~5), CALCULATED: formula 자동 계산, COMPOSITE: 다차원 룩업 결과.'
|
|
275
|
+
}),
|
|
276
|
+
tslib_1.__metadata("design:type", String)
|
|
277
|
+
], Kpi.prototype, "valueType", void 0);
|
|
190
278
|
tslib_1.__decorate([
|
|
191
279
|
(0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
|
|
192
280
|
(0, type_graphql_1.Field)(type => shell_2.ScalarObject, {
|