@things-factory/worklist 10.1.18 → 10.1.20
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-client/components/activity-fields.d.ts +20 -0
- package/dist-client/components/activity-fields.js +23 -0
- package/dist-client/components/activity-fields.js.map +1 -1
- package/dist-client/components/decision-slots.d.ts +26 -0
- package/dist-client/components/decision-slots.js +24 -0
- package/dist-client/components/decision-slots.js.map +1 -1
- package/dist-client/pages/activity-approval/activity-approval-page.d.ts +13 -0
- package/dist-client/pages/activity-approval/activity-approval-page.js +29 -7
- package/dist-client/pages/activity-approval/activity-approval-page.js.map +1 -1
- package/dist-client/pages/activity-instance/activity-instance-search-page.js +2 -1
- package/dist-client/pages/activity-instance/activity-instance-search-page.js.map +1 -1
- package/dist-client/pages/activity-instance/activity-instance-view.js +2 -1
- package/dist-client/pages/activity-instance/activity-instance-view.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/activity-approval/check-authority.d.ts +17 -0
- package/dist-server/controllers/activity-approval/check-authority.js +53 -0
- package/dist-server/controllers/activity-approval/check-authority.js.map +1 -1
- package/dist-server/controllers/activity-approval/own-request.d.ts +162 -0
- package/dist-server/controllers/activity-approval/own-request.js +135 -0
- package/dist-server/controllers/activity-approval/own-request.js.map +1 -0
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.d.ts +21 -0
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.js +59 -0
- package/dist-server/controllers/activity-approval/resolve-judgeable-seats.js.map +1 -0
- package/dist-server/controllers/activity-installation/activity-installation-controller.js +2 -0
- package/dist-server/controllers/activity-installation/activity-installation-controller.js.map +1 -1
- package/dist-server/controllers/activity-installation/registry-conflict.d.ts +15 -0
- package/dist-server/controllers/activity-installation/registry-conflict.js +26 -0
- package/dist-server/controllers/activity-installation/registry-conflict.js.map +1 -1
- package/dist-server/controllers/activity-instance/approval-expectation.d.ts +1 -1
- package/dist-server/controllers/activity-instance/approval-expectation.js +1 -1
- package/dist-server/controllers/activity-instance/approval-expectation.js.map +1 -1
- package/dist-server/controllers/activity-instance/issue.js +38 -0
- package/dist-server/controllers/activity-instance/issue.js.map +1 -1
- package/dist-server/service/activity/activity-decision-key-item-type.d.ts +49 -0
- package/dist-server/service/activity/activity-decision-key-item-type.js +9 -0
- package/dist-server/service/activity/activity-decision-key-item-type.js.map +1 -1
- package/dist-server/service/activity/decision-key-declaration.d.ts +32 -0
- package/dist-server/service/activity/decision-key-declaration.js +81 -0
- package/dist-server/service/activity/decision-key-declaration.js.map +1 -1
- package/dist-server/service/activity-approval/my-pending-approvals.d.ts +16 -4
- package/dist-server/service/activity-approval/my-pending-approvals.js +19 -4
- package/dist-server/service/activity-approval/my-pending-approvals.js.map +1 -1
- package/dist-server/service/activity-summary/activity-summary-query.js +35 -14
- package/dist-server/service/activity-summary/activity-summary-query.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
|
@@ -3,11 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.myPendingApprovalsWhere = myPendingApprovalsWhere;
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
const approval_line_js_1 = require("../../controllers/activity-approval/approval-line.js");
|
|
6
|
+
const own_request_js_1 = require("../../controllers/activity-approval/own-request.js");
|
|
6
7
|
/**
|
|
7
|
-
* The approvals waiting on me — one definition,
|
|
8
|
+
* The approvals waiting on me — one definition, three readers.
|
|
8
9
|
*
|
|
9
|
-
* 내 결재함 asks this, and so does the
|
|
10
|
-
* to get wrong separately:
|
|
10
|
+
* 내 결재함 asks this, the calendar asks it, and so does the badge on the collapsed menu. All three
|
|
11
|
+
* have to agree on three things that are easy to get wrong separately:
|
|
11
12
|
*
|
|
12
13
|
* - **참조는 승인 대기가 아니다.** Asking a reference to approve destroys what a reference is. An
|
|
13
14
|
* empty column is an approval: rows created before the column existed have nothing there.
|
|
@@ -16,14 +17,28 @@ const approval_line_js_1 = require("../../controllers/activity-approval/approval
|
|
|
16
17
|
* everyone holding that role, forever.
|
|
17
18
|
* - **끝난 것의 정의는 한 자리에 있다** (TERMINATED_JUDGMENTS). Counted again here, a new judgment
|
|
18
19
|
* value would land in one reader and not the other.
|
|
20
|
+
* - **내가 올린 것은 내 결재가 아니다** (ADR-0052 ②). 누르는 자리(`checkAuthority`)가 거절하는 것을
|
|
21
|
+
* 여기서도 빼야 한다 — 갈리면 목록에 떴는데 누르면 거절된다. 두 표현은 `own-request.ts` 에 나란히 있다.
|
|
19
22
|
*
|
|
20
|
-
*
|
|
23
|
+
* ── What a caller has to bring ───────────────────────────────────────────────
|
|
24
|
+
* `ap` (ActivityApproval) as the alias, and **`at` and `ai` joined** — the thread and its instance.
|
|
25
|
+
* The clause reads only `ap` today. It is about to read the instance as well, to answer whether the
|
|
26
|
+
* person judging is the one who raised it (ADR-0052 ②), and a caller that has not joined does not
|
|
27
|
+
* return a wrong number — it throws at query time.
|
|
28
|
+
*
|
|
29
|
+
* Two of the three readers already joined, for their own reasons: the inbox list for sorting, the
|
|
30
|
+
* calendar to read the thread it draws. The badge joined nothing, because counting rows needs no
|
|
31
|
+
* columns. So the clause would have started working for two readers and started failing for the
|
|
32
|
+
* third, and the third is the one nobody opens a screen to check. The badge joins too, and
|
|
33
|
+
* `joined-for-the-shared-clause.test.ts` counts that every reader does.
|
|
21
34
|
*/
|
|
22
35
|
function myPendingApprovalsWhere({ userId, roles }) {
|
|
23
36
|
const judgment = [...approval_line_js_1.TERMINATED_JUDGMENTS];
|
|
24
37
|
return new typeorm_1.Brackets(outer => {
|
|
25
38
|
outer
|
|
26
39
|
.where(`(ap.participation IS NULL OR ap.participation != 'reference')`)
|
|
40
|
+
/* 값을 쓰는 자리에서 묶는다 — 옆 bracket 이 같은 이름을 묶어 준 덕에 도는 것은 우연이다. */
|
|
41
|
+
.andWhere(own_request_js_1.NOT_RAISED_BY_ME_SQL, { userId })
|
|
27
42
|
.andWhere(new typeorm_1.Brackets(qb => {
|
|
28
43
|
qb.where('ap.judgment NOT IN (:...judgment)', { judgment }).andWhere('ap.approver = :userId', { userId });
|
|
29
44
|
if (roles.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"my-pending-approvals.js","sourceRoot":"","sources":["../../../server/service/activity-approval/my-pending-approvals.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"my-pending-approvals.js","sourceRoot":"","sources":["../../../server/service/activity-approval/my-pending-approvals.ts"],"names":[],"mappings":";;AAiCA,0DAyBC;AA1DD,qCAAkC;AAElC,2FAA2F;AAC3F,uFAAyF;AAEzF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,uBAAuB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAuC;IAC5F,MAAM,QAAQ,GAAG,CAAC,GAAG,uCAAoB,CAAC,CAAA;IAE1C,OAAO,IAAI,kBAAQ,CAAC,KAAK,CAAC,EAAE;QAC1B,KAAK;aACF,KAAK,CAAC,+DAA+D,CAAC;YACvE,6DAA6D;aAC5D,QAAQ,CAAC,qCAAoB,EAAE,EAAE,MAAM,EAAE,CAAC;aAC1C,QAAQ,CACP,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE;YAChB,EAAE,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YAEzG,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,EAAE,CAAC,OAAO,CACR,IAAI,kBAAQ,CAAC,MAAM,CAAC,EAAE;oBACpB,MAAM;yBACH,KAAK,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,CAAC;yBACxD,QAAQ,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,CAAC;yBACrD,QAAQ,CAAC,qBAAqB,CAAC,CAAA;gBACpC,CAAC,CAAC,CACH,CAAA;YACH,CAAC;QACH,CAAC,CAAC,CACH,CAAA;IACL,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { Brackets } from 'typeorm'\n\nimport { TERMINATED_JUDGMENTS } from '../../controllers/activity-approval/approval-line.js'\nimport { NOT_RAISED_BY_ME_SQL } from '../../controllers/activity-approval/own-request.js'\n\n/**\n * The approvals waiting on me — one definition, three readers.\n *\n * 내 결재함 asks this, the calendar asks it, and so does the badge on the collapsed menu. All three\n * have to agree on three things that are easy to get wrong separately:\n *\n * - **참조는 승인 대기가 아니다.** Asking a reference to approve destroys what a reference is. An\n * empty column is an approval: rows created before the column existed have nothing there.\n * - **역할로 걸린 결재도 내 것이다** — but only while unclaimed. A role-held row keeps `approver`\n * empty until someone presses, so without a judgment test finished work stays in the list of\n * everyone holding that role, forever.\n * - **끝난 것의 정의는 한 자리에 있다** (TERMINATED_JUDGMENTS). Counted again here, a new judgment\n * value would land in one reader and not the other.\n * - **내가 올린 것은 내 결재가 아니다** (ADR-0052 ②). 누르는 자리(`checkAuthority`)가 거절하는 것을\n * 여기서도 빼야 한다 — 갈리면 목록에 떴는데 누르면 거절된다. 두 표현은 `own-request.ts` 에 나란히 있다.\n *\n * ── What a caller has to bring ───────────────────────────────────────────────\n * `ap` (ActivityApproval) as the alias, and **`at` and `ai` joined** — the thread and its instance.\n * The clause reads only `ap` today. It is about to read the instance as well, to answer whether the\n * person judging is the one who raised it (ADR-0052 ②), and a caller that has not joined does not\n * return a wrong number — it throws at query time.\n *\n * Two of the three readers already joined, for their own reasons: the inbox list for sorting, the\n * calendar to read the thread it draws. The badge joined nothing, because counting rows needs no\n * columns. So the clause would have started working for two readers and started failing for the\n * third, and the third is the one nobody opens a screen to check. The badge joins too, and\n * `joined-for-the-shared-clause.test.ts` counts that every reader does.\n */\nexport function myPendingApprovalsWhere({ userId, roles }: { userId: string; roles: string[] }): Brackets {\n const judgment = [...TERMINATED_JUDGMENTS]\n\n return new Brackets(outer => {\n outer\n .where(`(ap.participation IS NULL OR ap.participation != 'reference')`)\n /* 값을 쓰는 자리에서 묶는다 — 옆 bracket 이 같은 이름을 묶어 준 덕에 도는 것은 우연이다. */\n .andWhere(NOT_RAISED_BY_ME_SQL, { userId })\n .andWhere(\n new Brackets(qb => {\n qb.where('ap.judgment NOT IN (:...judgment)', { judgment }).andWhere('ap.approver = :userId', { userId })\n\n if (roles.length > 0) {\n qb.orWhere(\n new Brackets(roleQb => {\n roleQb\n .where('ap.judgment NOT IN (:...judgment)', { judgment })\n .andWhere('ap.approverRole IN (:...roles)', { roles })\n .andWhere(`ap.approver IS NULL`)\n })\n )\n }\n })\n )\n })\n}\n"]}
|
|
@@ -9,6 +9,7 @@ const shell_1 = require("@things-factory/shell");
|
|
|
9
9
|
const activity_summary_js_1 = require("./activity-summary.js");
|
|
10
10
|
const activity_thread_js_1 = require("../activity-thread/activity-thread.js");
|
|
11
11
|
const activity_approval_js_1 = require("../activity-approval/activity-approval.js");
|
|
12
|
+
const my_pending_approvals_js_1 = require("../activity-approval/my-pending-approvals.js");
|
|
12
13
|
const activity_instance_js_1 = require("../activity-instance/activity-instance.js");
|
|
13
14
|
let ActivitySummaryQuery = class ActivitySummaryQuery {
|
|
14
15
|
async activitySummary(context) {
|
|
@@ -50,25 +51,45 @@ let ActivitySummaryQuery = class ActivitySummaryQuery {
|
|
|
50
51
|
relations: ['roles']
|
|
51
52
|
});
|
|
52
53
|
const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
/*
|
|
55
|
+
* The badge asks the same question the inbox does, through the same clause.
|
|
56
|
+
*
|
|
57
|
+
* ── What the badge was counting ───────────────────────────────────────
|
|
58
|
+
* It had its own copy of "not finished yet", written as NOT IN four judgments, and that copy
|
|
59
|
+
* had drifted three ways from the list it labels:
|
|
60
|
+
*
|
|
61
|
+
* closed a reference seat the case closed when it ended
|
|
62
|
+
* aborted an approval closed because the thread was aborted
|
|
63
|
+
* reference a seat that comments and never decides
|
|
64
|
+
*
|
|
65
|
+
* TERMINATED_JUDGMENTS holds six; this named four. So every ended thread and every case a
|
|
66
|
+
* reference had been on kept adding to the number, and a role-held row had no judgment test at
|
|
67
|
+
* all — once closed with nobody having pressed, `approver` stays empty and it would have been
|
|
68
|
+
* counted forever, for everyone holding that role.
|
|
69
|
+
*
|
|
70
|
+
* The badge therefore read higher than the inbox it points at. Opening it showed fewer, or
|
|
71
|
+
* nothing: a number that sends someone to an empty screen teaches them to stop believing it.
|
|
72
|
+
*
|
|
73
|
+
* ── Why the clause is borrowed rather than fixed here ─────────────────
|
|
74
|
+
* Naming the six here would make the count right today and drift again at the seventh. The
|
|
75
|
+
* inbox list and the calendar already share one clause for this; the badge is the third reader
|
|
76
|
+
* and now asks through it too. `myPendingApprovalsWhere` carries why each part is there.
|
|
77
|
+
*/
|
|
59
78
|
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
60
79
|
repository: (0, shell_1.getRepository)(activity_approval_js_1.ActivityApproval),
|
|
61
80
|
params: {},
|
|
62
81
|
domain,
|
|
63
82
|
alias: 'ap'
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
})
|
|
84
|
+
/*
|
|
85
|
+
* Counting rows needs no columns, so this query joined nothing while the other two readers
|
|
86
|
+
* joined for their own reasons. The clause is what decides: it is about to read the instance
|
|
87
|
+
* to answer whether the person judging raised it, and an unjoined caller throws rather than
|
|
88
|
+
* counting wrong. Joining here keeps the three readers answering the same question.
|
|
89
|
+
*/
|
|
90
|
+
.leftJoin('ap.activityThread', 'at')
|
|
91
|
+
.leftJoin('at.activityInstance', 'ai')
|
|
92
|
+
.andWhere((0, my_pending_approvals_js_1.myPendingApprovalsWhere)({ userId: user.id, roles }));
|
|
72
93
|
return await queryBuilder.getCount();
|
|
73
94
|
}
|
|
74
95
|
async numberOfPicks(activitySummary, context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-summary-query.js","sourceRoot":"","sources":["../../../server/service/activity-summary/activity-summary-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets } from 'typeorm'\nimport { Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { getQueryBuilderFromListParams, getRepository } from '@things-factory/shell'\n\nimport { ActivitySummary } from './activity-summary.js'\nimport { ActivityThread, ActivityThreadStatus } from '../activity-thread/activity-thread.js'\nimport { ActivityApproval, ActivityApprovalJudgment } from '../activity-approval/activity-approval.js'\nimport { ActivityInstance, ActivityInstanceStatus } from '../activity-instance/activity-instance.js'\n\n@Resolver(ActivitySummary)\nexport class ActivitySummaryQuery {\n @Query(returns => ActivitySummary!, { nullable: true, description: 'To fetch a Activity Summary' })\n async activitySummary(@Ctx() context: ResolverContext): Promise<ActivitySummary> {\n return {}\n }\n\n @FieldResolver(type => Number)\n async numberOfToDos(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n const excludedStatuses = [ActivityThreadStatus.Unassigned, ActivityThreadStatus.Ended, ActivityThreadStatus.Aborted]\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityThread),\n params: {},\n domain,\n alias: 'at'\n })\n .innerJoinAndSelect('at.activityInstance', 'ai')\n .andWhere(\n new Brackets(qb => {\n qb.where('at.state NOT IN (:...excludedStatuses)', { excludedStatuses }).andWhere('at.assignee = :userId', {\n userId: user.id\n })\n\n if (roles.length > 0) {\n qb.orWhere(\n new Brackets(subQb => {\n subQb\n .where('ai.assigneeRole IN (:...roles)', { roles })\n .andWhere(`at.state = '${ActivityThreadStatus.Unassigned}'`)\n })\n )\n }\n })\n )\n\n return await queryBuilder.getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfApprovalPendings(\n @Root() activitySummary: ActivitySummary,\n @Ctx() context: ResolverContext\n ): Promise<number> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n const judgment = [\n ActivityApprovalJudgment.Escalated,\n ActivityApprovalJudgment.Delegated,\n ActivityApprovalJudgment.Approved,\n ActivityApprovalJudgment.Rejected\n ]\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params: {},\n domain,\n alias: 'ap'\n }).andWhere(\n new Brackets(qb => {\n qb.where('ap.judgment NOT IN (:...judgment)', { judgment }).andWhere('ap.approver = :user', { user: user.id })\n\n if (roles.length > 0) {\n qb.orWhere(\n new Brackets(qb => {\n qb.where('ap.approverRole IN (:...roles)', { roles }).andWhere(`ap.approver IS NULL`)\n })\n )\n }\n })\n )\n\n return await queryBuilder.getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfPicks(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n /* \n activity-instance 중에서 아직 created 상태이면서, \n activity-instance의 assigneeRole 이 지정되지 않았거나,\n assigneeRole이 지정되었으면 그 Role에 내가 해당된 경우이면서,\n 나는 아직 해당 activity-instance의 thread를 할당받지 않은 경우에 해당하는\n activity-instance 리스트를 모두 가져오는 쿼리이다.\n */\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n if (!roles.length) {\n return 0\n }\n\n return await getQueryBuilderFromListParams({\n repository: getRepository(ActivityInstance),\n params: {},\n domain,\n alias: 'ai'\n })\n .leftJoinAndSelect('ai.activityThreads', 'threads', 'threads.assignee = :user', { user: user.id })\n .andWhere('ai.state IN (:...status)', {\n status: [ActivityInstanceStatus.Issued, ActivityInstanceStatus.Unassigned]\n })\n .andWhere('ai.assigneeRole IN (:...roles)', { roles })\n .andWhere('threads.id IS NULL') /* 이미 내가 할당된 경우는 제외한다. */\n .getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfDrafts(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n /* 생성자가 자신이면서, 아직 Draft 상태인 activity-instance 리스트만 반환 */\n const status = [ActivityInstanceStatus.Draft]\n\n return await getQueryBuilderFromListParams({\n repository: getRepository(ActivityInstance),\n params: {},\n domain,\n alias: 'ai'\n })\n .andWhere('ai.state IN (:...status)', { status })\n .andWhere('ai.creator = :user', { user: user.id })\n .getCount()\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"activity-summary-query.js","sourceRoot":"","sources":["../../../server/service/activity-summary/activity-summary-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets } from 'typeorm'\nimport { Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { getQueryBuilderFromListParams, getRepository } from '@things-factory/shell'\n\nimport { ActivitySummary } from './activity-summary.js'\nimport { ActivityThread, ActivityThreadStatus } from '../activity-thread/activity-thread.js'\nimport { ActivityApproval } from '../activity-approval/activity-approval.js'\nimport { myPendingApprovalsWhere } from '../activity-approval/my-pending-approvals.js'\nimport { ActivityInstance, ActivityInstanceStatus } from '../activity-instance/activity-instance.js'\n\n@Resolver(ActivitySummary)\nexport class ActivitySummaryQuery {\n @Query(returns => ActivitySummary!, { nullable: true, description: 'To fetch a Activity Summary' })\n async activitySummary(@Ctx() context: ResolverContext): Promise<ActivitySummary> {\n return {}\n }\n\n @FieldResolver(type => Number)\n async numberOfToDos(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n const excludedStatuses = [ActivityThreadStatus.Unassigned, ActivityThreadStatus.Ended, ActivityThreadStatus.Aborted]\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityThread),\n params: {},\n domain,\n alias: 'at'\n })\n .innerJoinAndSelect('at.activityInstance', 'ai')\n .andWhere(\n new Brackets(qb => {\n qb.where('at.state NOT IN (:...excludedStatuses)', { excludedStatuses }).andWhere('at.assignee = :userId', {\n userId: user.id\n })\n\n if (roles.length > 0) {\n qb.orWhere(\n new Brackets(subQb => {\n subQb\n .where('ai.assigneeRole IN (:...roles)', { roles })\n .andWhere(`at.state = '${ActivityThreadStatus.Unassigned}'`)\n })\n )\n }\n })\n )\n\n return await queryBuilder.getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfApprovalPendings(\n @Root() activitySummary: ActivitySummary,\n @Ctx() context: ResolverContext\n ): Promise<number> {\n var { domain, user } = context.state\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n /*\n * The badge asks the same question the inbox does, through the same clause.\n *\n * ── What the badge was counting ───────────────────────────────────────\n * It had its own copy of \"not finished yet\", written as NOT IN four judgments, and that copy\n * had drifted three ways from the list it labels:\n *\n * closed a reference seat the case closed when it ended\n * aborted an approval closed because the thread was aborted\n * reference a seat that comments and never decides\n *\n * TERMINATED_JUDGMENTS holds six; this named four. So every ended thread and every case a\n * reference had been on kept adding to the number, and a role-held row had no judgment test at\n * all — once closed with nobody having pressed, `approver` stays empty and it would have been\n * counted forever, for everyone holding that role.\n *\n * The badge therefore read higher than the inbox it points at. Opening it showed fewer, or\n * nothing: a number that sends someone to an empty screen teaches them to stop believing it.\n *\n * ── Why the clause is borrowed rather than fixed here ─────────────────\n * Naming the six here would make the count right today and drift again at the seventh. The\n * inbox list and the calendar already share one clause for this; the badge is the third reader\n * and now asks through it too. `myPendingApprovalsWhere` carries why each part is there.\n */\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(ActivityApproval),\n params: {},\n domain,\n alias: 'ap'\n })\n /*\n * Counting rows needs no columns, so this query joined nothing while the other two readers\n * joined for their own reasons. The clause is what decides: it is about to read the instance\n * to answer whether the person judging raised it, and an unjoined caller throws rather than\n * counting wrong. Joining here keeps the three readers answering the same question.\n */\n .leftJoin('ap.activityThread', 'at')\n .leftJoin('at.activityInstance', 'ai')\n .andWhere(myPendingApprovalsWhere({ userId: user.id, roles }))\n\n return await queryBuilder.getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfPicks(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n /* \n activity-instance 중에서 아직 created 상태이면서, \n activity-instance의 assigneeRole 이 지정되지 않았거나,\n assigneeRole이 지정되었으면 그 Role에 내가 해당된 경우이면서,\n 나는 아직 해당 activity-instance의 thread를 할당받지 않은 경우에 해당하는\n activity-instance 리스트를 모두 가져오는 쿼리이다.\n */\n\n user = await getRepository(User).findOne({\n where: { id: user.id },\n relations: ['roles']\n })\n const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)\n\n if (!roles.length) {\n return 0\n }\n\n return await getQueryBuilderFromListParams({\n repository: getRepository(ActivityInstance),\n params: {},\n domain,\n alias: 'ai'\n })\n .leftJoinAndSelect('ai.activityThreads', 'threads', 'threads.assignee = :user', { user: user.id })\n .andWhere('ai.state IN (:...status)', {\n status: [ActivityInstanceStatus.Issued, ActivityInstanceStatus.Unassigned]\n })\n .andWhere('ai.assigneeRole IN (:...roles)', { roles })\n .andWhere('threads.id IS NULL') /* 이미 내가 할당된 경우는 제외한다. */\n .getCount()\n }\n\n @FieldResolver(type => Number)\n async numberOfDrafts(@Root() activitySummary: ActivitySummary, @Ctx() context: ResolverContext): Promise<number> {\n var { domain, user } = context.state\n\n /* 생성자가 자신이면서, 아직 Draft 상태인 activity-instance 리스트만 반환 */\n const status = [ActivityInstanceStatus.Draft]\n\n return await getQueryBuilderFromListParams({\n repository: getRepository(ActivityInstance),\n params: {},\n domain,\n alias: 'ai'\n })\n .andWhere('ai.state IN (:...status)', { status })\n .andWhere('ai.creator = :user', { user: user.id })\n .getCount()\n }\n}\n"]}
|