@things-factory/board-service 10.1.244 → 10.1.246
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/dist-server/service/board/board-counts.d.ts +8 -0
- package/dist-server/service/board/board-counts.js +34 -0
- package/dist-server/service/board/board-counts.js.map +1 -0
- package/dist-server/service/board/board-query.d.ts +2 -1
- package/dist-server/service/board/board-query.js +19 -1
- package/dist-server/service/board/board-query.js.map +1 -1
- package/dist-server/service/board-favorite/board-favorite-query.d.ts +2 -0
- package/dist-server/service/board-favorite/board-favorite-query.js +4 -11
- package/dist-server/service/board-favorite/board-favorite-query.js.map +1 -1
- package/dist-server/service/board-template/board-template-query.d.ts +2 -1
- package/dist-server/service/board-template/board-template-query.js +39 -11
- package/dist-server/service/board-template/board-template-query.js.map +1 -1
- package/dist-server/service/index.d.ts +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/tests/board-counts.test.ts +53 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ListParam, ListValueCount } from '@things-factory/shell';
|
|
2
|
+
/**
|
|
3
|
+
* How many boards each type or state chip of the board list would show, in the list's scope - every board, the
|
|
4
|
+
* caller's favorites (`favor`) or the caller's own (`mywork`) - under the list's other conditions.
|
|
5
|
+
*/
|
|
6
|
+
export declare function boardCounts(domain: any, user: {
|
|
7
|
+
id: string;
|
|
8
|
+
}, field: string, scope: string | null | undefined, params: ListParam): Promise<ListValueCount[]>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.boardCounts = boardCounts;
|
|
4
|
+
const fav_base_1 = require("@things-factory/fav-base");
|
|
5
|
+
const shell_1 = require("@things-factory/shell");
|
|
6
|
+
const board_favorite_query_js_1 = require("../board-favorite/board-favorite-query.js");
|
|
7
|
+
const board_js_1 = require("./board.js");
|
|
8
|
+
/** The values a board list narrows by chips - its types and its states. */
|
|
9
|
+
const BOARD_CHIP_VALUES = { type: ['main', 'sub', 'popup'], state: ['draft', 'released'] };
|
|
10
|
+
/**
|
|
11
|
+
* How many boards each type or state chip of the board list would show, in the list's scope - every board, the
|
|
12
|
+
* caller's favorites (`favor`) or the caller's own (`mywork`) - under the list's other conditions.
|
|
13
|
+
*/
|
|
14
|
+
async function boardCounts(domain, user, field, scope, params) {
|
|
15
|
+
const values = BOARD_CHIP_VALUES[field];
|
|
16
|
+
if (!values)
|
|
17
|
+
throw new Error(`Boards are not counted by ${field}`);
|
|
18
|
+
const counted = await (0, shell_1.countListByField)({
|
|
19
|
+
repository: (0, shell_1.getRepository)(board_js_1.Board),
|
|
20
|
+
params,
|
|
21
|
+
domain,
|
|
22
|
+
alias: 'Board',
|
|
23
|
+
searchables: ['name', 'description'],
|
|
24
|
+
field,
|
|
25
|
+
narrow: builder => {
|
|
26
|
+
if (scope === 'favor')
|
|
27
|
+
builder.innerJoin(fav_base_1.Favorite, 'Favorite', board_favorite_query_js_1.FAVORITE_JOIN).andWhere('Favorite.user = :userId', { userId: user.id });
|
|
28
|
+
else if (scope === 'mywork')
|
|
29
|
+
builder.andWhere('Board.creator = :user', { user: user.id });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return values.map(value => ({ value, count: counted.get(value) ?? 0 }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=board-counts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-counts.js","sourceRoot":"","sources":["../../../server/service/board/board-counts.ts"],"names":[],"mappings":";;AAaA,kCAgBC;AA7BD,uDAAmD;AACnD,iDAAkG;AAElG,uFAAyE;AACzE,yCAAkC;AAElC,2EAA2E;AAC3E,MAAM,iBAAiB,GAA6B,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAA;AAEpH;;;GAGG;AACI,KAAK,UAAU,WAAW,CAAC,MAAW,EAAE,IAAoB,EAAE,KAAa,EAAE,KAAgC,EAAE,MAAiB;IACrI,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IACvC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAA;IAClE,MAAM,OAAO,GAAG,MAAM,IAAA,wBAAgB,EAAC;QACrC,UAAU,EAAE,IAAA,qBAAa,EAAC,gBAAK,CAAC;QAChC,MAAM;QACN,MAAM;QACN,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;QACpC,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,EAAE;YAChB,IAAI,KAAK,KAAK,OAAO;gBAAE,OAAO,CAAC,SAAS,CAAC,mBAAQ,EAAE,UAAU,EAAE,uCAAa,CAAC,CAAC,QAAQ,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;iBACjI,IAAI,KAAK,KAAK,QAAQ;gBAAE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QAC3F,CAAC;KACF,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;AACzE,CAAC","sourcesContent":["import { Favorite } from '@things-factory/fav-base'\nimport { countListByField, getRepository, ListParam, ListValueCount } from '@things-factory/shell'\n\nimport { FAVORITE_JOIN } from '../board-favorite/board-favorite-query.js'\nimport { Board } from './board.js'\n\n/** The values a board list narrows by chips - its types and its states. */\nconst BOARD_CHIP_VALUES: Record<string, string[]> = { type: ['main', 'sub', 'popup'], state: ['draft', 'released'] }\n\n/**\n * How many boards each type or state chip of the board list would show, in the list's scope - every board, the\n * caller's favorites (`favor`) or the caller's own (`mywork`) - under the list's other conditions.\n */\nexport async function boardCounts(domain: any, user: { id: string }, field: string, scope: string | null | undefined, params: ListParam): Promise<ListValueCount[]> {\n const values = BOARD_CHIP_VALUES[field]\n if (!values) throw new Error(`Boards are not counted by ${field}`)\n const counted = await countListByField({\n repository: getRepository(Board),\n params,\n domain,\n alias: 'Board',\n searchables: ['name', 'description'],\n field,\n narrow: builder => {\n if (scope === 'favor') builder.innerJoin(Favorite, 'Favorite', FAVORITE_JOIN).andWhere('Favorite.user = :userId', { userId: user.id })\n else if (scope === 'mywork') builder.andWhere('Board.creator = :user', { user: user.id })\n }\n })\n return values.map(value => ({ value, count: counted.get(value) ?? 0 }))\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { User } from '@things-factory/auth-base';
|
|
2
|
-
import { Domain, ListParam } from '@things-factory/shell';
|
|
2
|
+
import { Domain, ListParam, ListValueCount } from '@things-factory/shell';
|
|
3
3
|
import { Group } from '../group/group.js';
|
|
4
4
|
import { PlayGroup } from '../play-group/play-group.js';
|
|
5
5
|
import { Board } from './board.js';
|
|
@@ -14,6 +14,7 @@ export declare class BoardQuery {
|
|
|
14
14
|
boardPublished(id: string, context: ResolverContext): Promise<BoardHistory | null>;
|
|
15
15
|
boardVersionDiff(id: string, version: number, context: ResolverContext, toVersion?: number): Promise<BoardVersionDiff>;
|
|
16
16
|
boards(params: ListParam, context: ResolverContext): Promise<BoardList>;
|
|
17
|
+
boardCounts(field: string, scope: string, params: ListParam, context: ResolverContext): Promise<ListValueCount[]>;
|
|
17
18
|
boardsUpdatedSince(since: Date, context: ResolverContext): Promise<Board[]>;
|
|
18
19
|
group(board: Board): Promise<Group>;
|
|
19
20
|
playGroups(board: Board): Promise<PlayGroup[]>;
|
|
@@ -10,6 +10,7 @@ const operato_license_checker_1 = require("@things-factory/operato-license-check
|
|
|
10
10
|
const group_js_1 = require("../group/group.js");
|
|
11
11
|
const play_group_js_1 = require("../play-group/play-group.js");
|
|
12
12
|
const board_js_1 = require("./board.js");
|
|
13
|
+
const board_counts_js_1 = require("./board-counts.js");
|
|
13
14
|
const board_type_js_1 = require("./board-type.js");
|
|
14
15
|
const board_history_js_1 = require("./board-history.js");
|
|
15
16
|
const board_version_type_js_1 = require("./board-version-type.js");
|
|
@@ -152,12 +153,16 @@ let BoardQuery = class BoardQuery {
|
|
|
152
153
|
});
|
|
153
154
|
// 클라이언트 정렬 지정이 없으면 sortOrder 기본 정렬
|
|
154
155
|
if (!params.sortings?.length) {
|
|
155
|
-
queryBuilder.
|
|
156
|
+
queryBuilder.orderBy(`"${queryBuilder.alias}"."sort_order"`, 'ASC', 'NULLS LAST');
|
|
156
157
|
queryBuilder.addOrderBy(`"${queryBuilder.alias}"."created_at"`, 'ASC');
|
|
157
158
|
}
|
|
158
159
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
159
160
|
return { items, total };
|
|
160
161
|
}
|
|
162
|
+
async boardCounts(field, scope, params, context) {
|
|
163
|
+
const { domain, user } = context.state;
|
|
164
|
+
return (0, board_counts_js_1.boardCounts)(domain, user, field, scope, params);
|
|
165
|
+
}
|
|
161
166
|
async boardsUpdatedSince(since, context) {
|
|
162
167
|
const { domain } = context.state;
|
|
163
168
|
return await (0, shell_1.getRepository)(board_js_1.Board)
|
|
@@ -270,6 +275,19 @@ tslib_1.__decorate([
|
|
|
270
275
|
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
271
276
|
tslib_1.__metadata("design:returntype", Promise)
|
|
272
277
|
], BoardQuery.prototype, "boards", null);
|
|
278
|
+
tslib_1.__decorate([
|
|
279
|
+
(0, type_graphql_1.Query)(returns => [shell_1.ListValueCount], {
|
|
280
|
+
description: "How many boards hold each type or state (field: type or state) in the list's scope (all, favor - the caller's favorites, mywork - the caller's own), under the list conditions other than that field."
|
|
281
|
+
}),
|
|
282
|
+
(0, type_graphql_1.Directive)('@privilege(category: "board", privilege: "query", domainOwnerGranted: true)'),
|
|
283
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('field')),
|
|
284
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('scope', { nullable: true })),
|
|
285
|
+
tslib_1.__param(2, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
|
|
286
|
+
tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
|
|
287
|
+
tslib_1.__metadata("design:type", Function),
|
|
288
|
+
tslib_1.__metadata("design:paramtypes", [String, String, shell_1.ListParam, Object]),
|
|
289
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
290
|
+
], BoardQuery.prototype, "boardCounts", null);
|
|
273
291
|
tslib_1.__decorate([
|
|
274
292
|
(0, type_graphql_1.Query)(returns => [board_js_1.Board], {
|
|
275
293
|
description: 'Retrieves boards that have been updated or soft-deleted since the given timestamp.'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-query.js","sourceRoot":"","sources":["../../../server/service/board/board-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { In, MoreThan } from 'typeorm'\nimport { Arg, Args, Ctx, FieldResolver, Int, Query, Resolver, Root, Directive } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { checkTarget, checkDomain, getPermission } from '@things-factory/operato-license-checker'\n\nimport { Group } from '../group/group.js'\nimport { PlayGroup } from '../play-group/play-group.js'\nimport { Board } from './board.js'\nimport { BoardList } from './board-type.js'\nimport { BoardHistory } from './board-history.js'\nimport { BoardVersionDiff } from './board-version-type.js'\nimport { diffBoardModels } from './board-version-diff.js'\n\nimport { LicenseError } from '../../errors/license-error.js'\n@Resolver(Board)\nexport class BoardQuery {\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => Board, { description: 'Finds a single board by its ID. If cachedUpdatedAt matches, model is omitted.' })\n async board(\n @Arg('id') id: string,\n @Arg('cachedUpdatedAt', { nullable: true, description: 'Client cache timestamp — if matches, model field is omitted' }) cachedUpdatedAt: string,\n @Ctx() context: ResolverContext\n ): Promise<Board> {\n const { domain } = context.state\n\n var board = await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id }\n })\n\n // 캐시 유효성 체크: updatedAt이 동일하면 model을 생략하여 전송량 절감\n if (board && cachedUpdatedAt && board.updatedAt?.toISOString() === cachedUpdatedAt) {\n board.model = null\n }\n\n if (domain) {\n // 1. check domainSecret is over limit quantity or not\n var count = await getRepository(Domain)\n .manager.createQueryBuilder()\n .select('id')\n .from(Domain, 'domain')\n .getCount()\n\n if (!checkDomain(count)) {\n throw new LicenseError({\n errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)\n })\n }\n }\n\n if (board) {\n // 1. check boardSecret is over limit quantity or not\n var count = await getRepository(Board)\n .manager.createQueryBuilder()\n .select('id')\n .from(Board, 'board')\n .where('\"domain_id\" = :domainId', { domainId: domain.id })\n .getCount()\n\n if (!checkTarget(count)) {\n throw new LicenseError({\n errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)\n })\n }\n }\n\n return board\n }\n\n @Query(returns => Board, { nullable: true, description: 'Finds a single board by its name.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardByName(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Board> {\n const { domain } = context.state\n\n return await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, name }\n })\n }\n\n @Query(returns => BoardList, { description: 'Retrieves a paginated list of boards created by the current user.' })\n async boardsCreatedByMe(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardList> {\n const { domain, user } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(Board),\n params,\n domain,\n alias: 'board',\n searchables: ['name', 'description']\n }).andWhere('board.creator = :user', { user: user.id })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => [BoardHistory], { description: 'Retrieves up to 10 historical versions of a specific board.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardVersions(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardHistory[]> {\n const { domain } = context.state\n\n return await getRepository(BoardHistory).find({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, originalId: id },\n relations: ['updater'],\n order: { version: 'DESC' },\n take: 10\n })\n }\n\n /*\n * Nullable, because \"nobody has published this board yet\" is an ordinary state (2026-09-11).\n *\n * This was declared non-null while the implementation returns whatever findOne finds, so a board\n * that exists but has never been published answered with\n * `Cannot return null for non-nullable field Query.boardPublished` and code INTERNAL_SERVER_ERROR.\n * Two callers reported it independently: operato-plant's station board page, which has to catch\n * that error and ask a second question to tell \"not published yet\" apart from \"no such board\",\n * and its station scenario tool, which asserts a draft cannot reach the shop floor.\n *\n * A caller cannot tell an unpublished board from a broken server, and the server logs an error\n * for a normal request. Answering null says the true thing.\n */\n @Query(returns => BoardHistory, {\n nullable: true,\n description: 'Retrieves the most recently published version of a board, or null if none was published.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardPublished(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardHistory | null> {\n const { domain } = context.state\n\n return await getRepository(BoardHistory).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, originalId: id },\n order: { version: 'DESC' }\n })\n }\n\n @Query(returns => BoardVersionDiff, {\n description:\n 'Computes the component-level difference between a board version and another version or the current draft. ' +\n 'Omit toVersion to diff the base version against the current draft.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardVersionDiff(\n @Arg('id') id: string,\n @Arg('version', type => Int) version: number,\n @Ctx() context: ResolverContext,\n @Arg('toVersion', type => Int, { nullable: true }) toVersion?: number\n ): Promise<BoardVersionDiff> {\n const { domain } = context.state\n const domainIds = [domain.id, domain.parentId].filter(Boolean)\n const historyRepo = getRepository(BoardHistory)\n\n const base = await historyRepo.findOne({\n where: { domain: { id: In(domainIds) }, originalId: id, version }\n })\n if (!base) {\n throw new Error(`Board version (${id}:${version}) is not found`)\n }\n\n let targetModel: any\n let targetVersion: number | null = null\n if (toVersion !== undefined && toVersion !== null) {\n const target = await historyRepo.findOne({\n where: { domain: { id: In(domainIds) }, originalId: id, version: toVersion }\n })\n if (!target) {\n throw new Error(`Board version (${id}:${toVersion}) is not found`)\n }\n targetModel = target.model\n targetVersion = toVersion\n } else {\n const board = await getRepository(Board).findOne({\n where: { domain: { id: In(domainIds) }, id }\n })\n if (!board) {\n throw new Error(`Board (${id}) is not found`)\n }\n targetModel = board.model\n }\n\n const componentDiffs = diffBoardModels(base.model, targetModel)\n return {\n fromVersion: version,\n toVersion: targetVersion,\n addedCount: componentDiffs.filter(d => d.changeType === 'added').length,\n removedCount: componentDiffs.filter(d => d.changeType === 'removed').length,\n modifiedCount: componentDiffs.filter(d => d.changeType === 'modified').length,\n componentDiffs\n }\n }\n\n @Query(returns => BoardList, { description: 'Retrieves a paginated list of all boards.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boards(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<BoardList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(Board),\n params,\n domain,\n searchables: ['name', 'description']\n })\n\n // 클라이언트 정렬 지정이 없으면 sortOrder 기본 정렬\n if (!params.sortings?.length) {\n queryBuilder.addOrderBy(`\"${queryBuilder.alias}\".\"sort_order\"`, 'ASC', 'NULLS LAST')\n queryBuilder.addOrderBy(`\"${queryBuilder.alias}\".\"created_at\"`, 'ASC')\n }\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => [Board], {\n description: 'Retrieves boards that have been updated or soft-deleted since the given timestamp.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardsUpdatedSince(\n @Arg('since') since: Date,\n @Ctx() context: ResolverContext\n ): Promise<Board[]> {\n const { domain } = context.state\n\n return await getRepository(Board)\n .createQueryBuilder('board')\n .withDeleted()\n .where('board.domain_id = :domainId', { domainId: domain.id })\n .andWhere('board.updated_at > :since', { since })\n .getMany()\n }\n\n @FieldResolver(type => Group, { description: 'Resolves the group that the board belongs to.' })\n async group(@Root() board: Board) {\n return (\n board.groupId &&\n (await getRepository(Group).findOneBy({\n id: board.groupId\n }))\n )\n }\n\n @FieldResolver(type => [PlayGroup], {\n description: 'Resolves the list of play groups that this board is a member of.'\n })\n async playGroups(@Root() board: Board) {\n return (\n await getRepository(Board).findOne({\n where: { id: board.id },\n relations: ['playGroups']\n })\n )?.playGroups\n }\n\n @FieldResolver(type => Domain, { description: 'Resolves the domain associated with the board.' })\n async domain(@Root() board: Board) {\n return (\n board.domainId &&\n (await getRepository(Domain).findOneBy({\n id: board.domainId\n }))\n )\n }\n\n @FieldResolver(type => User, { description: 'Resolves the user who last updated the board.' })\n async updater(@Root() board: Board): Promise<User> {\n return (\n board.updaterId &&\n (await getRepository(User).findOneBy({\n id: board.updaterId\n }))\n )\n }\n\n @FieldResolver(type => User, { description: 'Resolves the user who created the board.' })\n async creator(@Root() board: Board): Promise<User> {\n return (\n board.creatorId &&\n (await getRepository(User).findOneBy({\n id: board.creatorId\n }))\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"board-query.js","sourceRoot":"","sources":["../../../server/service/board/board-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { In, MoreThan } from 'typeorm'\nimport { Arg, Args, Ctx, FieldResolver, Int, Query, Resolver, Root, Directive } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam, ListValueCount } from '@things-factory/shell'\nimport { checkTarget, checkDomain, getPermission } from '@things-factory/operato-license-checker'\n\nimport { Group } from '../group/group.js'\nimport { PlayGroup } from '../play-group/play-group.js'\nimport { Board } from './board.js'\nimport { boardCounts } from './board-counts.js'\nimport { BoardList } from './board-type.js'\nimport { BoardHistory } from './board-history.js'\nimport { BoardVersionDiff } from './board-version-type.js'\nimport { diffBoardModels } from './board-version-diff.js'\n\nimport { LicenseError } from '../../errors/license-error.js'\n@Resolver(Board)\nexport class BoardQuery {\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => Board, { description: 'Finds a single board by its ID. If cachedUpdatedAt matches, model is omitted.' })\n async board(\n @Arg('id') id: string,\n @Arg('cachedUpdatedAt', { nullable: true, description: 'Client cache timestamp — if matches, model field is omitted' }) cachedUpdatedAt: string,\n @Ctx() context: ResolverContext\n ): Promise<Board> {\n const { domain } = context.state\n\n var board = await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id }\n })\n\n // 캐시 유효성 체크: updatedAt이 동일하면 model을 생략하여 전송량 절감\n if (board && cachedUpdatedAt && board.updatedAt?.toISOString() === cachedUpdatedAt) {\n board.model = null\n }\n\n if (domain) {\n // 1. check domainSecret is over limit quantity or not\n var count = await getRepository(Domain)\n .manager.createQueryBuilder()\n .select('id')\n .from(Domain, 'domain')\n .getCount()\n\n if (!checkDomain(count)) {\n throw new LicenseError({\n errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)\n })\n }\n }\n\n if (board) {\n // 1. check boardSecret is over limit quantity or not\n var count = await getRepository(Board)\n .manager.createQueryBuilder()\n .select('id')\n .from(Board, 'board')\n .where('\"domain_id\" = :domainId', { domainId: domain.id })\n .getCount()\n\n if (!checkTarget(count)) {\n throw new LicenseError({\n errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)\n })\n }\n }\n\n return board\n }\n\n @Query(returns => Board, { nullable: true, description: 'Finds a single board by its name.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardByName(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Board> {\n const { domain } = context.state\n\n return await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, name }\n })\n }\n\n @Query(returns => BoardList, { description: 'Retrieves a paginated list of boards created by the current user.' })\n async boardsCreatedByMe(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardList> {\n const { domain, user } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(Board),\n params,\n domain,\n alias: 'board',\n searchables: ['name', 'description']\n }).andWhere('board.creator = :user', { user: user.id })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => [BoardHistory], { description: 'Retrieves up to 10 historical versions of a specific board.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardVersions(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardHistory[]> {\n const { domain } = context.state\n\n return await getRepository(BoardHistory).find({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, originalId: id },\n relations: ['updater'],\n order: { version: 'DESC' },\n take: 10\n })\n }\n\n /*\n * Nullable, because \"nobody has published this board yet\" is an ordinary state (2026-09-11).\n *\n * This was declared non-null while the implementation returns whatever findOne finds, so a board\n * that exists but has never been published answered with\n * `Cannot return null for non-nullable field Query.boardPublished` and code INTERNAL_SERVER_ERROR.\n * Two callers reported it independently: operato-plant's station board page, which has to catch\n * that error and ask a second question to tell \"not published yet\" apart from \"no such board\",\n * and its station scenario tool, which asserts a draft cannot reach the shop floor.\n *\n * A caller cannot tell an unpublished board from a broken server, and the server logs an error\n * for a normal request. Answering null says the true thing.\n */\n @Query(returns => BoardHistory, {\n nullable: true,\n description: 'Retrieves the most recently published version of a board, or null if none was published.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardPublished(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardHistory | null> {\n const { domain } = context.state\n\n return await getRepository(BoardHistory).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, originalId: id },\n order: { version: 'DESC' }\n })\n }\n\n @Query(returns => BoardVersionDiff, {\n description:\n 'Computes the component-level difference between a board version and another version or the current draft. ' +\n 'Omit toVersion to diff the base version against the current draft.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardVersionDiff(\n @Arg('id') id: string,\n @Arg('version', type => Int) version: number,\n @Ctx() context: ResolverContext,\n @Arg('toVersion', type => Int, { nullable: true }) toVersion?: number\n ): Promise<BoardVersionDiff> {\n const { domain } = context.state\n const domainIds = [domain.id, domain.parentId].filter(Boolean)\n const historyRepo = getRepository(BoardHistory)\n\n const base = await historyRepo.findOne({\n where: { domain: { id: In(domainIds) }, originalId: id, version }\n })\n if (!base) {\n throw new Error(`Board version (${id}:${version}) is not found`)\n }\n\n let targetModel: any\n let targetVersion: number | null = null\n if (toVersion !== undefined && toVersion !== null) {\n const target = await historyRepo.findOne({\n where: { domain: { id: In(domainIds) }, originalId: id, version: toVersion }\n })\n if (!target) {\n throw new Error(`Board version (${id}:${toVersion}) is not found`)\n }\n targetModel = target.model\n targetVersion = toVersion\n } else {\n const board = await getRepository(Board).findOne({\n where: { domain: { id: In(domainIds) }, id }\n })\n if (!board) {\n throw new Error(`Board (${id}) is not found`)\n }\n targetModel = board.model\n }\n\n const componentDiffs = diffBoardModels(base.model, targetModel)\n return {\n fromVersion: version,\n toVersion: targetVersion,\n addedCount: componentDiffs.filter(d => d.changeType === 'added').length,\n removedCount: componentDiffs.filter(d => d.changeType === 'removed').length,\n modifiedCount: componentDiffs.filter(d => d.changeType === 'modified').length,\n componentDiffs\n }\n }\n\n @Query(returns => BoardList, { description: 'Retrieves a paginated list of all boards.' })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boards(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<BoardList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(Board),\n params,\n domain,\n searchables: ['name', 'description']\n })\n\n // 클라이언트 정렬 지정이 없으면 sortOrder 기본 정렬\n if (!params.sortings?.length) {\n queryBuilder.orderBy(`\"${queryBuilder.alias}\".\"sort_order\"`, 'ASC', 'NULLS LAST')\n queryBuilder.addOrderBy(`\"${queryBuilder.alias}\".\"created_at\"`, 'ASC')\n }\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => [ListValueCount], {\n description:\n \"How many boards hold each type or state (field: type or state) in the list's scope (all, favor - the caller's favorites, mywork - the caller's own), under the list conditions other than that field.\"\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardCounts(\n @Arg('field') field: string,\n @Arg('scope', { nullable: true }) scope: string,\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<ListValueCount[]> {\n const { domain, user } = context.state\n return boardCounts(domain, user, field, scope, params)\n }\n\n @Query(returns => [Board], {\n description: 'Retrieves boards that have been updated or soft-deleted since the given timestamp.'\n })\n @Directive('@privilege(category: \"board\", privilege: \"query\", domainOwnerGranted: true)')\n async boardsUpdatedSince(\n @Arg('since') since: Date,\n @Ctx() context: ResolverContext\n ): Promise<Board[]> {\n const { domain } = context.state\n\n return await getRepository(Board)\n .createQueryBuilder('board')\n .withDeleted()\n .where('board.domain_id = :domainId', { domainId: domain.id })\n .andWhere('board.updated_at > :since', { since })\n .getMany()\n }\n\n @FieldResolver(type => Group, { description: 'Resolves the group that the board belongs to.' })\n async group(@Root() board: Board) {\n return (\n board.groupId &&\n (await getRepository(Group).findOneBy({\n id: board.groupId\n }))\n )\n }\n\n @FieldResolver(type => [PlayGroup], {\n description: 'Resolves the list of play groups that this board is a member of.'\n })\n async playGroups(@Root() board: Board) {\n return (\n await getRepository(Board).findOne({\n where: { id: board.id },\n relations: ['playGroups']\n })\n )?.playGroups\n }\n\n @FieldResolver(type => Domain, { description: 'Resolves the domain associated with the board.' })\n async domain(@Root() board: Board) {\n return (\n board.domainId &&\n (await getRepository(Domain).findOneBy({\n id: board.domainId\n }))\n )\n }\n\n @FieldResolver(type => User, { description: 'Resolves the user who last updated the board.' })\n async updater(@Root() board: Board): Promise<User> {\n return (\n board.updaterId &&\n (await getRepository(User).findOneBy({\n id: board.updaterId\n }))\n )\n }\n\n @FieldResolver(type => User, { description: 'Resolves the user who created the board.' })\n async creator(@Root() board: Board): Promise<User> {\n return (\n board.creatorId &&\n (await getRepository(User).findOneBy({\n id: board.creatorId\n }))\n )\n }\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ListParam } from '@things-factory/shell';
|
|
2
2
|
import { BoardFavoriteList } from './board-favorite-type.js';
|
|
3
|
+
/** How a board (aliased `Board`) meets its favorites: by the board's id in the favorite's routing. */
|
|
4
|
+
export declare const FAVORITE_JOIN: string;
|
|
3
5
|
export declare class BoardFavoriteQuery {
|
|
4
6
|
favoriteBoards(params: ListParam, context: ResolverContext): Promise<BoardFavoriteList>;
|
|
5
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BoardFavoriteQuery = void 0;
|
|
3
|
+
exports.BoardFavoriteQuery = exports.FAVORITE_JOIN = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
6
|
const env_1 = require("@things-factory/env");
|
|
@@ -10,6 +10,8 @@ const board_js_1 = require("../board/board.js");
|
|
|
10
10
|
const board_favorite_type_js_1 = require("./board-favorite-type.js");
|
|
11
11
|
const ORMCONFIG = env_1.config.get('ormconfig', {});
|
|
12
12
|
const DATABASE_TYPE = ORMCONFIG.type;
|
|
13
|
+
/** How a board (aliased `Board`) meets its favorites: by the board's id in the favorite's routing. */
|
|
14
|
+
exports.FAVORITE_JOIN = DATABASE_TYPE === 'postgres' ? 'CAST(Board.id as VARCHAR) = Favorite.routing' : 'Board.id = Favorite.routing';
|
|
13
15
|
let BoardFavoriteQuery = class BoardFavoriteQuery {
|
|
14
16
|
async favoriteBoards(params, context) {
|
|
15
17
|
const { user } = context.state;
|
|
@@ -20,17 +22,8 @@ let BoardFavoriteQuery = class BoardFavoriteQuery {
|
|
|
20
22
|
alias: 'Board',
|
|
21
23
|
searchables: ['name', 'description']
|
|
22
24
|
});
|
|
23
|
-
var joinStatement = '';
|
|
24
|
-
switch (DATABASE_TYPE) {
|
|
25
|
-
case 'postgres':
|
|
26
|
-
joinStatement = 'CAST(Board.id as VARCHAR) = Favorite.routing';
|
|
27
|
-
break;
|
|
28
|
-
case 'sqlite':
|
|
29
|
-
default:
|
|
30
|
-
joinStatement = 'Board.id = Favorite.routing';
|
|
31
|
-
}
|
|
32
25
|
var qb = queryBuilder
|
|
33
|
-
.innerJoin(fav_base_1.Favorite, 'Favorite',
|
|
26
|
+
.innerJoin(fav_base_1.Favorite, 'Favorite', exports.FAVORITE_JOIN)
|
|
34
27
|
.select([
|
|
35
28
|
'Board.id as id',
|
|
36
29
|
'Board.name as name',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-favorite-query.js","sourceRoot":"","sources":["../../../server/service/board-favorite/board-favorite-query.ts"],"names":[],"mappings":";;;;AAAA,+CAAyD;AAEzD,6CAA4C;AAC5C,uDAAmD;AACnD,iDAA+F;AAE/F,gDAAyC;AACzC,qEAA2E;AAE3E,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;AAC7C,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"board-favorite-query.js","sourceRoot":"","sources":["../../../server/service/board-favorite/board-favorite-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Args, Ctx, Query, Resolver } from 'type-graphql'\n\nimport { config } from '@things-factory/env'\nimport { Favorite } from '@things-factory/fav-base'\nimport { getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\n\nimport { Board } from '../board/board.js'\nimport { BoardFavorite, BoardFavoriteList } from './board-favorite-type.js'\n\nconst ORMCONFIG = config.get('ormconfig', {})\nconst DATABASE_TYPE = ORMCONFIG.type\n\n/** How a board (aliased `Board`) meets its favorites: by the board's id in the favorite's routing. */\nexport const FAVORITE_JOIN = DATABASE_TYPE === 'postgres' ? 'CAST(Board.id as VARCHAR) = Favorite.routing' : 'Board.id = Favorite.routing'\n\n@Resolver(BoardFavorite)\nexport class BoardFavoriteQuery {\n @Query(returns => BoardFavoriteList, { description: 'To fetch multiple BoardFavorites' })\n async favoriteBoards(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardFavoriteList> {\n const { user } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(Board),\n params,\n domain: context.state.domain,\n alias: 'Board',\n searchables: ['name', 'description']\n })\n\n var qb = queryBuilder\n .innerJoin(Favorite, 'Favorite', FAVORITE_JOIN)\n .select([\n 'Board.id as id',\n 'Board.name as name',\n 'Board.description as description',\n 'Board.thumbnail as thumbnail',\n /* What a board card says about itself - the draft badge and the \"v3 · 2 days ago\" line\n * read these, and the Favorite view drew every board as a dateless draft without them. */\n 'Board.type as type',\n 'Board.state as state',\n 'Board.version as version',\n 'Board.createdAt as \"createdAt\"',\n 'Board.updatedAt as \"updatedAt\"',\n 'Favorite.id as \"favoriteId\"'\n ])\n .andWhere('Favorite.user = :userId', {\n userId: user.id\n })\n\n /* Raw rows skip the entity transformers, so dates arrive as the driver's strings and the\n * DateTime scalar refuses them. Hydrate them the way the entity would (UTC when untagged). */\n const items = (await qb.getRawMany()).map(item => ({\n ...item,\n createdAt: toDate(item.createdAt),\n updatedAt: toDate(item.updatedAt)\n }))\n const total = await qb.getCount()\n\n return { items, total }\n }\n}\n\nfunction toDate(value: unknown): Date | null {\n if (!value) return null\n if (value instanceof Date) return value\n\n const text = String(value)\n const tagged = /(Z|[+-]\\d{2}:?\\d{2})$/.test(text)\n const date = new Date(tagged ? text : text.replace(' ', 'T') + 'Z')\n\n return Number.isNaN(date.getTime()) ? null : date\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Domain, ListParam } from '@things-factory/shell';
|
|
1
|
+
import { Domain, ListParam, ListValueCount } from '@things-factory/shell';
|
|
2
2
|
import { User } from '@things-factory/auth-base';
|
|
3
3
|
import { BoardTemplate } from './board-template.js';
|
|
4
4
|
import { BoardTemplateList } from './board-template-type.js';
|
|
@@ -6,6 +6,7 @@ export declare class BoardTemplateQuery {
|
|
|
6
6
|
boardTemplate(id: string, context: ResolverContext): Promise<BoardTemplate>;
|
|
7
7
|
boardTemplatesCreatedByMe(params: ListParam, context: ResolverContext): Promise<BoardTemplateList>;
|
|
8
8
|
boardTemplates(params: ListParam, context: ResolverContext): Promise<BoardTemplateList>;
|
|
9
|
+
boardTemplateVisibilityCounts(params: ListParam, context: ResolverContext): Promise<ListValueCount[]>;
|
|
9
10
|
mine(boardTemplate: BoardTemplate, context: ResolverContext): Promise<boolean>;
|
|
10
11
|
domain(boardTemplate: BoardTemplate): Promise<Domain>;
|
|
11
12
|
updater(boardTemplate: BoardTemplate): Promise<User>;
|
|
@@ -8,6 +8,23 @@ const shell_1 = require("@things-factory/shell");
|
|
|
8
8
|
const auth_base_1 = require("@things-factory/auth-base");
|
|
9
9
|
const board_template_js_1 = require("./board-template.js");
|
|
10
10
|
const board_template_type_js_1 = require("./board-template-type.js");
|
|
11
|
+
/**
|
|
12
|
+
* The templates a person sees in the list: the public ones, the domain's (or its parent's) and their own private ones.
|
|
13
|
+
* The list and its visibility counts narrow alike.
|
|
14
|
+
*/
|
|
15
|
+
function visibleTemplates(builder, domain, user) {
|
|
16
|
+
return builder.andWhere(new typeorm_1.Brackets(qb => {
|
|
17
|
+
qb.where({ visibility: 'public' })
|
|
18
|
+
.orWhere({
|
|
19
|
+
visibility: 'domain',
|
|
20
|
+
domain: { id: (0, typeorm_1.In)([domain.id, domain.parentId]) }
|
|
21
|
+
})
|
|
22
|
+
.orWhere({
|
|
23
|
+
visibility: 'private',
|
|
24
|
+
creator: { id: user.id }
|
|
25
|
+
});
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
11
28
|
let BoardTemplateQuery = class BoardTemplateQuery {
|
|
12
29
|
async boardTemplate(id, context) {
|
|
13
30
|
const { domain, user } = context.state;
|
|
@@ -56,20 +73,22 @@ let BoardTemplateQuery = class BoardTemplateQuery {
|
|
|
56
73
|
params,
|
|
57
74
|
repository: await (0, shell_1.getRepository)(board_template_js_1.BoardTemplate),
|
|
58
75
|
searchables: ['name', 'description']
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
.orWhere({
|
|
62
|
-
visibility: 'domain',
|
|
63
|
-
domain: { id: (0, typeorm_1.In)([domain.id, domain.parentId]) }
|
|
64
|
-
})
|
|
65
|
-
.orWhere({
|
|
66
|
-
visibility: 'private',
|
|
67
|
-
creator: { id: user.id }
|
|
68
|
-
});
|
|
69
|
-
}));
|
|
76
|
+
});
|
|
77
|
+
visibleTemplates(queryBuilder, domain, user);
|
|
70
78
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
71
79
|
return { items, total };
|
|
72
80
|
}
|
|
81
|
+
async boardTemplateVisibilityCounts(params, context) {
|
|
82
|
+
const { domain, user } = context.state;
|
|
83
|
+
const counted = await (0, shell_1.countListByField)({
|
|
84
|
+
params,
|
|
85
|
+
repository: (0, shell_1.getRepository)(board_template_js_1.BoardTemplate),
|
|
86
|
+
searchables: ['name', 'description'],
|
|
87
|
+
field: 'visibility',
|
|
88
|
+
narrow: builder => visibleTemplates(builder, domain, user)
|
|
89
|
+
});
|
|
90
|
+
return ['private', 'domain', 'public'].map(value => ({ value, count: counted.get(value) ?? 0 }));
|
|
91
|
+
}
|
|
73
92
|
async mine(boardTemplate, context) {
|
|
74
93
|
const { creatorId } = boardTemplate;
|
|
75
94
|
const { user } = context.state;
|
|
@@ -112,6 +131,15 @@ tslib_1.__decorate([
|
|
|
112
131
|
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
113
132
|
tslib_1.__metadata("design:returntype", Promise)
|
|
114
133
|
], BoardTemplateQuery.prototype, "boardTemplates", null);
|
|
134
|
+
tslib_1.__decorate([
|
|
135
|
+
(0, type_graphql_1.Query)(returns => [shell_1.ListValueCount], { description: 'How many of the templates the list shows hold each visibility (private, domain, public), under the list conditions other than the visibility' }),
|
|
136
|
+
(0, type_graphql_1.Directive)('@privilege(category: "board-template", privilege: "query", domainOwnerGranted: true)'),
|
|
137
|
+
tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
|
|
138
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
139
|
+
tslib_1.__metadata("design:type", Function),
|
|
140
|
+
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
141
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
142
|
+
], BoardTemplateQuery.prototype, "boardTemplateVisibilityCounts", null);
|
|
115
143
|
tslib_1.__decorate([
|
|
116
144
|
(0, type_graphql_1.FieldResolver)(type => Boolean),
|
|
117
145
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-template-query.js","sourceRoot":"","sources":["../../../server/service/board-template/board-template-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets, In } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { BoardTemplate } from './board-template.js'\nimport { BoardTemplateList } from './board-template-type.js'\n\n@Resolver(BoardTemplate)\nexport class BoardTemplateQuery {\n @Query(returns => BoardTemplate!, { nullable: true, description: 'To fetch a BoardTemplate' })\n @Directive('@privilege(category: \"board-template\", privilege: \"query\", domainOwnerGranted: true)')\n async boardTemplate(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardTemplate> {\n const { domain, user } = context.state\n\n const qb = await getRepository(BoardTemplate)\n .createQueryBuilder('BoardTemplate')\n .where('id=:id', { id })\n .andWhere(\n new Brackets(qb => {\n qb.where({ visibility: 'public' })\n .orWhere({\n visibility: 'domain',\n domain: { id: In([domain.id, domain.parentId]) }\n })\n .orWhere({\n visibility: 'private',\n creator: { id: user.id }\n })\n })\n )\n\n return qb.getOne()\n\n // return await getRepository(BoardTemplate).findOne({\n // where: {\n // domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },\n // id\n // }\n // })\n }\n\n @Query(returns => BoardTemplateList, { description: 'To fetch BoardTemplates created by me' })\n async boardTemplatesCreatedByMe(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardTemplateList> {\n const { user } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(BoardTemplate),\n params,\n alias: 'template',\n searchables: ['name', 'description']\n }).andWhere('template.creator = :user', { user: user.id })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => BoardTemplateList, { description: 'To fetch multiple BoardTemplates' })\n @Directive('@privilege(category: \"board-template\", privilege: \"query\", domainOwnerGranted: true)')\n async boardTemplates(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardTemplateList> {\n const { domain, user } = context.state\n /* \n 리스트에 포함되는 보드템플릿들 \n - visibility가 public 인 경우\n - visibility가 domain이며 컨텍스트의 도메인과 같은 경우\n - visibility가 private 이며, creator가 나인 경우\n */\n\n const queryBuilder = getQueryBuilderFromListParams({\n params,\n repository: await getRepository(BoardTemplate),\n searchables: ['name', 'description']\n }).andWhere(\n new Brackets(qb => {\n qb.where({ visibility: 'public' })\n .orWhere({\n visibility: 'domain',\n domain: { id: In([domain.id, domain.parentId]) }\n })\n .orWhere({\n visibility: 'private',\n creator: { id: user.id }\n })\n })\n )\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => Boolean)\n async mine(@Root() boardTemplate: BoardTemplate, @Ctx() context: ResolverContext): Promise<boolean> {\n const { creatorId } = boardTemplate\n const { user } = context.state\n\n return creatorId == user.id\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() boardTemplate: BoardTemplate): Promise<Domain> {\n return boardTemplate.domainId && (await getRepository(Domain).findOneBy({ id: boardTemplate.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() boardTemplate: BoardTemplate): Promise<User> {\n return boardTemplate.updaterId && (await getRepository(User).findOneBy({ id: boardTemplate.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() boardTemplate: BoardTemplate): Promise<User> {\n return boardTemplate.creatorId && (await getRepository(User).findOneBy({ id: boardTemplate.creatorId }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"board-template-query.js","sourceRoot":"","sources":["../../../server/service/board-template/board-template-query.ts"],"names":[],"mappings":";;;;AAAA,qCAA0D;AAC1D,+CAA8F;AAC9F,iDAAyI;AACzI,yDAAgD;AAChD,2DAAmD;AACnD,qEAA4D;AAE5D;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAA0C,EAAE,MAAc,EAAE,IAAoB;IACxG,OAAO,OAAO,CAAC,QAAQ,CACrB,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE;QAChB,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;aAC/B,OAAO,CAAC;YACP,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;SACjD,CAAC;aACD,OAAO,CAAC;YACP,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;SACzB,CAAC,CAAA;IACN,CAAC,CAAC,CACH,CAAA;AACH,CAAC;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAGvB,AAAN,KAAK,CAAC,aAAa,CAAY,EAAU,EAAS,OAAwB;QACxE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEtC,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC;aAC1C,kBAAkB,CAAC,eAAe,CAAC;aACnC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC;aACvB,QAAQ,CACP,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE;YAChB,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;iBAC/B,OAAO,CAAC;gBACP,UAAU,EAAE,QAAQ;gBACpB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;aACjD,CAAC;iBACD,OAAO,CAAC;gBACP,UAAU,EAAE,SAAS;gBACrB,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;aACzB,CAAC,CAAA;QACN,CAAC,CAAC,CACH,CAAA;QAEH,OAAO,EAAE,CAAC,MAAM,EAAE,CAAA;QAElB,sDAAsD;QACtD,aAAa;QACb,wEAAwE;QACxE,SAAS;QACT,MAAM;QACN,KAAK;IACP,CAAC;IAGK,AAAN,KAAK,CAAC,yBAAyB,CACJ,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE9B,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,UAAU,EAAE,IAAA,qBAAa,EAAC,iCAAa,CAAC;YACxC,MAAM;YACN,KAAK,EAAE,UAAU;YACjB,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;SACrC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QAE1D,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAIK,AAAN,KAAK,CAAC,cAAc,CACO,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACtC;;;;;UAKE;QAEF,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,MAAM;YACN,UAAU,EAAE,MAAM,IAAA,qBAAa,EAAC,iCAAa,CAAC;YAC9C,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;SACrC,CAAC,CAAA;QACF,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;QAE5C,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAIK,AAAN,KAAK,CAAC,6BAA6B,CAA0B,MAAiB,EAAS,OAAwB;QAC7G,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACtC,MAAM,OAAO,GAAG,MAAM,IAAA,wBAAgB,EAAC;YACrC,MAAM;YACN,UAAU,EAAE,IAAA,qBAAa,EAAC,iCAAa,CAAC;YACxC,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;YACpC,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;SAC3D,CAAC,CAAA;QACF,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IAClG,CAAC;IAGK,AAAN,KAAK,CAAC,IAAI,CAAS,aAA4B,EAAS,OAAwB;QAC9E,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,CAAA;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE9B,OAAO,SAAS,IAAI,IAAI,CAAC,EAAE,CAAA;IAC7B,CAAC;IAGK,AAAN,KAAK,CAAC,MAAM,CAAS,aAA4B;QAC/C,OAAO,aAAa,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC1G,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAS,aAA4B;QAChD,OAAO,aAAa,CAAC,SAAS,IAAI,CAAC,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC1G,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAS,aAA4B;QAChD,OAAO,aAAa,CAAC,SAAS,IAAI,CAAC,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC1G,CAAC;CACF,CAAA;AAlHY,gDAAkB;AAGvB;IAFL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,iCAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;IAC7F,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IAC7E,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;uDA4BhD;AAGK;IADL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,0CAAiB,EAAE,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;IAE3F,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;mEAe3C;AAIK;IAFL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,0CAAiB,EAAE,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IACxF,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IAE/F,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;wDAqB3C;AAIK;IAFL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,sBAAc,CAAC,EAAE,EAAE,WAAW,EAAE,8IAA8I,EAAE,CAAC;IACnM,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IAC7D,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IAAqB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAAjB,iBAAS;;uEAU7E;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;IACnB,mBAAA,IAAA,mBAAI,GAAE,CAAA;IAAgC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAArB,iCAAa;;8CAK9C;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;IAChB,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAgB,iCAAa;;gDAEhD;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,CAAC;IACb,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAgB,iCAAa;;iDAEjD;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,CAAC;IACb,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAgB,iCAAa;;iDAEjD;6BAjHU,kBAAkB;IAD9B,IAAA,uBAAQ,EAAC,iCAAa,CAAC;GACX,kBAAkB,CAkH9B","sourcesContent":["import { Brackets, In, SelectQueryBuilder } from 'typeorm'\nimport { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { countListByField, Domain, getQueryBuilderFromListParams, getRepository, ListParam, ListValueCount } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { BoardTemplate } from './board-template.js'\nimport { BoardTemplateList } from './board-template-type.js'\n\n/**\n * The templates a person sees in the list: the public ones, the domain's (or its parent's) and their own private ones.\n * The list and its visibility counts narrow alike.\n */\nfunction visibleTemplates(builder: SelectQueryBuilder<BoardTemplate>, domain: Domain, user: { id: string }) {\n return builder.andWhere(\n new Brackets(qb => {\n qb.where({ visibility: 'public' })\n .orWhere({\n visibility: 'domain',\n domain: { id: In([domain.id, domain.parentId]) }\n })\n .orWhere({\n visibility: 'private',\n creator: { id: user.id }\n })\n })\n )\n}\n\n@Resolver(BoardTemplate)\nexport class BoardTemplateQuery {\n @Query(returns => BoardTemplate!, { nullable: true, description: 'To fetch a BoardTemplate' })\n @Directive('@privilege(category: \"board-template\", privilege: \"query\", domainOwnerGranted: true)')\n async boardTemplate(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<BoardTemplate> {\n const { domain, user } = context.state\n\n const qb = await getRepository(BoardTemplate)\n .createQueryBuilder('BoardTemplate')\n .where('id=:id', { id })\n .andWhere(\n new Brackets(qb => {\n qb.where({ visibility: 'public' })\n .orWhere({\n visibility: 'domain',\n domain: { id: In([domain.id, domain.parentId]) }\n })\n .orWhere({\n visibility: 'private',\n creator: { id: user.id }\n })\n })\n )\n\n return qb.getOne()\n\n // return await getRepository(BoardTemplate).findOne({\n // where: {\n // domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },\n // id\n // }\n // })\n }\n\n @Query(returns => BoardTemplateList, { description: 'To fetch BoardTemplates created by me' })\n async boardTemplatesCreatedByMe(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardTemplateList> {\n const { user } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(BoardTemplate),\n params,\n alias: 'template',\n searchables: ['name', 'description']\n }).andWhere('template.creator = :user', { user: user.id })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => BoardTemplateList, { description: 'To fetch multiple BoardTemplates' })\n @Directive('@privilege(category: \"board-template\", privilege: \"query\", domainOwnerGranted: true)')\n async boardTemplates(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<BoardTemplateList> {\n const { domain, user } = context.state\n /* \n 리스트에 포함되는 보드템플릿들 \n - visibility가 public 인 경우\n - visibility가 domain이며 컨텍스트의 도메인과 같은 경우\n - visibility가 private 이며, creator가 나인 경우\n */\n\n const queryBuilder = getQueryBuilderFromListParams({\n params,\n repository: await getRepository(BoardTemplate),\n searchables: ['name', 'description']\n })\n visibleTemplates(queryBuilder, domain, user)\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @Query(returns => [ListValueCount], { description: 'How many of the templates the list shows hold each visibility (private, domain, public), under the list conditions other than the visibility' })\n @Directive('@privilege(category: \"board-template\", privilege: \"query\", domainOwnerGranted: true)')\n async boardTemplateVisibilityCounts(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<ListValueCount[]> {\n const { domain, user } = context.state\n const counted = await countListByField({\n params,\n repository: getRepository(BoardTemplate),\n searchables: ['name', 'description'],\n field: 'visibility',\n narrow: builder => visibleTemplates(builder, domain, user)\n })\n return ['private', 'domain', 'public'].map(value => ({ value, count: counted.get(value) ?? 0 }))\n }\n\n @FieldResolver(type => Boolean)\n async mine(@Root() boardTemplate: BoardTemplate, @Ctx() context: ResolverContext): Promise<boolean> {\n const { creatorId } = boardTemplate\n const { user } = context.state\n\n return creatorId == user.id\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() boardTemplate: BoardTemplate): Promise<Domain> {\n return boardTemplate.domainId && (await getRepository(Domain).findOneBy({ id: boardTemplate.domainId }))\n }\n\n @FieldResolver(type => User)\n async updater(@Root() boardTemplate: BoardTemplate): Promise<User> {\n return boardTemplate.updaterId && (await getRepository(User).findOneBy({ id: boardTemplate.updaterId }))\n }\n\n @FieldResolver(type => User)\n async creator(@Root() boardTemplate: BoardTemplate): Promise<User> {\n return boardTemplate.creatorId && (await getRepository(User).findOneBy({ id: boardTemplate.creatorId }))\n }\n}\n"]}
|
|
@@ -6,5 +6,5 @@ export * from './play-group/play-group.js';
|
|
|
6
6
|
export declare const entities: any[];
|
|
7
7
|
export declare const subscribers: any[];
|
|
8
8
|
export declare const schema: {
|
|
9
|
-
resolverClasses: (typeof import("./board-template/board-template-query.js").BoardTemplateQuery | typeof import("./board-template/board-template-mutation.js").BoardTemplateMutation | typeof import("./theme/theme-query.js").ThemeQuery | typeof import("./theme/theme-mutation.js").ThemeMutation | typeof import("./board/board-query.js").BoardQuery | typeof import("./board/board-mutation.js").BoardMutation | typeof import("./board/board-subscription.js").BoardSubscription | typeof import("./group/group-query.js").GroupQuery | typeof import("./group/group-mutation.js").GroupMutation | typeof import("./play-group/play-group-query.js").PlayGroupQuery | typeof import("./play-group/play-group-mutation.js").PlayGroupMutation | typeof import("./play-group/play-group-subscription.js").PlayGroupSubscription | typeof import("./analysis/analysis-query.js").IntegrationAnalysisQuery
|
|
9
|
+
resolverClasses: (typeof import("./board-template/board-template-query.js").BoardTemplateQuery | typeof import("./board-template/board-template-mutation.js").BoardTemplateMutation | typeof import("./theme/theme-query.js").ThemeQuery | typeof import("./theme/theme-mutation.js").ThemeMutation | typeof import("./board-favorite/board-favorite-query.js").BoardFavoriteQuery | typeof import("./board/board-query.js").BoardQuery | typeof import("./board/board-mutation.js").BoardMutation | typeof import("./board/board-subscription.js").BoardSubscription | typeof import("./group/group-query.js").GroupQuery | typeof import("./group/group-mutation.js").GroupMutation | typeof import("./play-group/play-group-query.js").PlayGroupQuery | typeof import("./play-group/play-group-mutation.js").PlayGroupMutation | typeof import("./play-group/play-group-subscription.js").PlayGroupSubscription | typeof import("./analysis/analysis-query.js").IntegrationAnalysisQuery)[];
|
|
10
10
|
};
|