@things-factory/kpi 10.1.244 → 10.1.245

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.
@@ -61,7 +61,8 @@ let KpiValueQuery = class KpiValueQuery {
61
61
  `${queryBuilder.alias}.valueDate`,
62
62
  `${queryBuilder.alias}.kpiOrgScope`
63
63
  ])
64
- .addOrderBy(`${queryBuilder.alias}.domainId`, 'ASC')
64
+ /* DISTINCT ON reads its columns first in the order - in place of the list's own order. */
65
+ .orderBy(`${queryBuilder.alias}.domainId`, 'ASC')
65
66
  .addOrderBy(`${queryBuilder.alias}.kpiId`, 'ASC')
66
67
  .addOrderBy(`${queryBuilder.alias}.valueDate`, 'ASC')
67
68
  .addOrderBy(`${queryBuilder.alias}.kpiOrgScope`, 'ASC')
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-value/kpi-value-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { In } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive, Float } from 'type-graphql'\nimport {\n Domain,\n getQueryBuilderFromListParams,\n getRepository,\n ListParam,\n getDomainIdsWithAncestors\n} from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { KpiValue } from './kpi-value'\nimport { KpiValueList } from './kpi-value-type'\nimport { Kpi } from '../kpi/kpi'\nimport { KpiValueScoreService } from './kpi-value-score.service'\n\n@Resolver(KpiValue)\nexport class KpiValueQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiValue!, { nullable: true, description: 'Fetch a single KPI value by its unique identifier.' })\n async kpiValue(\n @Arg('id', { description: 'Unique identifier of the KPI value to fetch.' }) id: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiValue> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(KpiValue).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 => KpiValueList, { description: 'To fetch multiple KpiValues' })\n async kpiValues(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<KpiValueList> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain: undefined,\n params,\n repository: getRepository(KpiValue),\n searchables: ['kpi', 'group', 'valueDate']\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /**\n * 같은 (domain, kpi, valueDate, kpiOrgScope) 좌표에서 version 이 가장 큰 row 만 반환.\n * 차트·최종 KPI 계산 등 \"최신 상태\" 만 필요한 사용처용.\n *\n * 구현: subquery 로 (domain, kpi, valueDate, kpiOrgScope) 그룹별 MAX(version) 를 구한 뒤\n * 본 테이블과 매칭. 기존 kpiValues 와 동일하게 ListParam (filters/sortings/pagination)\n * 지원, 도메인 inheritance 적용.\n */\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiValueList, {\n description: 'Fetch latest-version KpiValues only — one row per (domain, kpi, valueDate, kpiOrgScope).'\n })\n async latestKpiValues(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiValueList> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain: undefined,\n params,\n repository: getRepository(KpiValue),\n searchables: ['kpi', 'group', 'valueDate']\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n // 같은 (domain, kpi, valueDate, kpiOrgScope) 좌표에서 가장 높은 version 만 통과.\n // 운영 DB 가 PostgreSQL 이라 DISTINCT ON 활용 — TypeORM QueryBuilder 의 정식 메서드.\n queryBuilder\n .distinctOn([\n `${queryBuilder.alias}.domainId`,\n `${queryBuilder.alias}.kpiId`,\n `${queryBuilder.alias}.valueDate`,\n `${queryBuilder.alias}.kpiOrgScope`\n ])\n .addOrderBy(`${queryBuilder.alias}.domainId`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.kpiId`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.valueDate`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.kpiOrgScope`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.version`, 'DESC')\n\n const items = await queryBuilder.getMany()\n\n return { items, total: items.length }\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpiValue: KpiValue): Promise<Domain> {\n return kpiValue.domainId && (await getRepository(Domain).findOneBy({ id: kpiValue.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpiValue: KpiValue): Promise<User> {\n return kpiValue.updaterId && (await getRepository(User).findOneBy({ id: kpiValue.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpiValue: KpiValue): Promise<User> {\n return kpiValue.creatorId && (await getRepository(User).findOneBy({ id: kpiValue.creatorId }))\n }\n\n @FieldResolver(type => Kpi)\n async kpi(@Root() kpiValue: KpiValue): Promise<Kpi | null> {\n if (!kpiValue.kpiId) return null\n return await getRepository(Kpi).findOneBy({ id: kpiValue.kpiId })\n }\n}\n"]}
1
+ {"version":3,"file":"kpi-value-query.js","sourceRoot":"","sources":["../../../server/service/kpi-value/kpi-value-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { In } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive, Float } from 'type-graphql'\nimport {\n Domain,\n getQueryBuilderFromListParams,\n getRepository,\n ListParam,\n getDomainIdsWithAncestors\n} from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { KpiValue } from './kpi-value'\nimport { KpiValueList } from './kpi-value-type'\nimport { Kpi } from '../kpi/kpi'\nimport { KpiValueScoreService } from './kpi-value-score.service'\n\n@Resolver(KpiValue)\nexport class KpiValueQuery {\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiValue!, { nullable: true, description: 'Fetch a single KPI value by its unique identifier.' })\n async kpiValue(\n @Arg('id', { description: 'Unique identifier of the KPI value to fetch.' }) id: string,\n @Ctx() context: ResolverContext\n ): Promise<KpiValue> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n return await getRepository(KpiValue).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 => KpiValueList, { description: 'To fetch multiple KpiValues' })\n async kpiValues(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<KpiValueList> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain: undefined,\n params,\n repository: getRepository(KpiValue),\n searchables: ['kpi', 'group', 'valueDate']\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /**\n * 같은 (domain, kpi, valueDate, kpiOrgScope) 좌표에서 version 이 가장 큰 row 만 반환.\n * 차트·최종 KPI 계산 등 \"최신 상태\" 만 필요한 사용처용.\n *\n * 구현: subquery 로 (domain, kpi, valueDate, kpiOrgScope) 그룹별 MAX(version) 를 구한 뒤\n * 본 테이블과 매칭. 기존 kpiValues 와 동일하게 ListParam (filters/sortings/pagination)\n * 지원, 도메인 inheritance 적용.\n */\n @Directive('@privilege(category: \"kpi\", privilege: \"query\", domainOwnerGranted: true, superUserGranted: true)')\n @Query(returns => KpiValueList, {\n description: 'Fetch latest-version KpiValues only — one row per (domain, kpi, valueDate, kpiOrgScope).'\n })\n async latestKpiValues(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<KpiValueList> {\n const { domain } = context.state\n const domainIds = await getDomainIdsWithAncestors(domain)\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain: undefined,\n params,\n repository: getRepository(KpiValue),\n searchables: ['kpi', 'group', 'valueDate']\n })\n\n queryBuilder.andWhere(`${queryBuilder.alias}.domain IN (:...ancestorDomainIds)`, {\n ancestorDomainIds: domainIds\n })\n\n // 같은 (domain, kpi, valueDate, kpiOrgScope) 좌표에서 가장 높은 version 만 통과.\n // 운영 DB 가 PostgreSQL 이라 DISTINCT ON 활용 — TypeORM QueryBuilder 의 정식 메서드.\n queryBuilder\n .distinctOn([\n `${queryBuilder.alias}.domainId`,\n `${queryBuilder.alias}.kpiId`,\n `${queryBuilder.alias}.valueDate`,\n `${queryBuilder.alias}.kpiOrgScope`\n ])\n /* DISTINCT ON reads its columns first in the order - in place of the list's own order. */\n .orderBy(`${queryBuilder.alias}.domainId`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.kpiId`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.valueDate`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.kpiOrgScope`, 'ASC')\n .addOrderBy(`${queryBuilder.alias}.version`, 'DESC')\n\n const items = await queryBuilder.getMany()\n\n return { items, total: items.length }\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() kpiValue: KpiValue): Promise<Domain> {\n return kpiValue.domainId && (await getRepository(Domain).findOneBy({ id: kpiValue.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() kpiValue: KpiValue): Promise<User> {\n return kpiValue.updaterId && (await getRepository(User).findOneBy({ id: kpiValue.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() kpiValue: KpiValue): Promise<User> {\n return kpiValue.creatorId && (await getRepository(User).findOneBy({ id: kpiValue.creatorId }))\n }\n\n @FieldResolver(type => Kpi)\n async kpi(@Root() kpiValue: KpiValue): Promise<Kpi | null> {\n if (!kpiValue.kpiId) return null\n return await getRepository(Kpi).findOneBy({ id: kpiValue.kpiId })\n }\n}\n"]}