@things-factory/dataset 7.1.34 → 7.1.37
Sign up to get free protection for your applications and to get access to all the features.
- package/client/activities/activity-ooc-resolve-edit.ts +1 -1
- package/client/activities/activity-ooc-review-edit.ts +1 -1
- package/client/pages/data-entry/data-entry-list-page.ts +7 -0
- package/client/pages/data-set/data-set-list-page.ts +14 -15
- package/dist-client/activities/activity-ooc-resolve-edit.js +1 -1
- package/dist-client/activities/activity-ooc-resolve-edit.js.map +1 -1
- package/dist-client/activities/activity-ooc-review-edit.js +1 -1
- package/dist-client/activities/activity-ooc-review-edit.js.map +1 -1
- package/dist-client/pages/data-entry/data-entry-list-page.js +7 -0
- package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
- package/dist-client/pages/data-set/data-set-list-page.js +14 -15
- package/dist-client/pages/data-set/data-set-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/activities/activity-data-collect.js.map +1 -1
- package/dist-server/activities/activity-ooc-review.js +12 -4
- package/dist-server/activities/activity-ooc-review.js.map +1 -1
- package/dist-server/controllers/create-data-sample.js +16 -10
- package/dist-server/controllers/create-data-sample.js.map +1 -1
- package/dist-server/controllers/issue-data-collection-task.d.ts +2 -0
- package/dist-server/controllers/{issue-collect-data.js → issue-data-collection-task.js} +13 -9
- package/dist-server/controllers/issue-data-collection-task.js.map +1 -0
- package/dist-server/engine/task/issue-collect-data.js +2 -2
- package/dist-server/engine/task/issue-collect-data.js.map +1 -1
- package/dist-server/routes.js +5 -3
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
- package/dist-server/service/data-sample/data-sample-query.js +3 -3
- package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
- package/dist-server/service/data-set/data-set-mutation.js +8 -65
- package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
- package/dist-server/service/data-set/data-set-query.d.ts +1 -0
- package/dist-server/service/data-set/data-set-query.js +15 -0
- package/dist-server/service/data-set/data-set-query.js.map +1 -1
- package/dist-server/service/data-set/data-set-type.d.ts +2 -3
- package/dist-server/service/data-set/data-set-type.js +6 -6
- package/dist-server/service/data-set/data-set-type.js.map +1 -1
- package/dist-server/service/data-set/data-set.d.ts +2 -0
- package/dist-server/service/data-set/data-set.js +12 -0
- package/dist-server/service/data-set/data-set.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/dataset/task/issue-collect-data.ja.md +1 -1
- package/helps/dataset/task/issue-collect-data.ko.md +1 -1
- package/helps/dataset/task/issue-collect-data.md +1 -1
- package/helps/dataset/task/issue-collect-data.ms.md +1 -1
- package/helps/dataset/task/issue-collect-data.zh.md +1 -1
- package/package.json +3 -3
- package/server/activities/activity-data-collect.ts +11 -2
- package/server/activities/activity-ooc-review.ts +28 -7
- package/server/controllers/create-data-sample.ts +16 -10
- package/server/controllers/{issue-collect-data.ts → issue-data-collection-task.ts} +13 -7
- package/server/engine/task/issue-collect-data.ts +2 -2
- package/server/routes.ts +5 -3
- package/server/service/data-sample/data-sample-query.ts +4 -4
- package/server/service/data-set/data-set-mutation.ts +4 -75
- package/server/service/data-set/data-set-query.ts +12 -0
- package/server/service/data-set/data-set-type.ts +4 -4
- package/server/service/data-set/data-set.ts +10 -0
- package/translations/en.json +1 -0
- package/translations/ja.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
- package/dist-server/controllers/issue-collect-data.d.ts +0 -2
- package/dist-server/controllers/issue-collect-data.js.map +0 -1
@@ -20,7 +20,7 @@
|
|
20
20
|
|
21
21
|
## 機能
|
22
22
|
|
23
|
-
実行時に、タスクはデータセット ID の存在を確認します。ID が提供されていない場合、タスクはデータセットが見つからないことを示すエラーを投げます。有効なデータセット ID が提供された場合、タスクはそのデータセットに特定のデータ収集活動を発行します。`
|
23
|
+
実行時に、タスクはデータセット ID の存在を確認します。ID が提供されていない場合、タスクはデータセットが見つからないことを示すエラーを投げます。有効なデータセット ID が提供された場合、タスクはそのデータセットに特定のデータ収集活動を発行します。`IssueCollectData` によって処理される基本的なプロセスには、データセットの存在の検証、データ収集環境の準備、およびデータセットの構成および関連するデータソースに従ってデータ収集プロセスを開始するなどの操作が含まれます。
|
24
24
|
|
25
25
|
タスクは開始された活動のインスタンスを返し、これを使用して進行状況を追跡し、データ収集ワークフローを管理するか、収集したデータを処理するための後続のタスクと統合することができます。
|
26
26
|
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
## 기능
|
19
19
|
|
20
|
-
실행 시, 작업은 데이터셋 ID의 존재를 확인합니다. ID가 제공되지 않으면, 데이터셋이 발견되지 않았다는 오류를 발생시킵니다. 유효한 데이터셋 ID가 제공되면, 작업은 해당 데이터셋에 특정한 데이터 수집 활동을 발행합니다. `
|
20
|
+
실행 시, 작업은 데이터셋 ID의 존재를 확인합니다. ID가 제공되지 않으면, 데이터셋이 발견되지 않았다는 오류를 발생시킵니다. 유효한 데이터셋 ID가 제공되면, 작업은 해당 데이터셋에 특정한 데이터 수집 활동을 발행합니다. `IssueCollectData`에 의해 처리되는 기본 프로세스는 데이터셋의 존재를 확인, 데이터 수집 환경 준비, 데이터셋의 구성 및 관련 데이터 소스에 따라 데이터 수집 프로세스 시작과 같은 작업을 포함합니다.
|
21
21
|
|
22
22
|
작업은 시작된 활동의 인스턴스를 반환하며, 이는 진행 상황을 추적하고, 데이터 수집 워크플로를 관리하거나, 수집된 데이터를 처리하기 위한 후속 작업과 통합하는 데 사용할 수 있습니다.
|
23
23
|
|
@@ -17,7 +17,7 @@ The `IssueCollectData` task is an automated function that triggers a data collec
|
|
17
17
|
|
18
18
|
## Functionality
|
19
19
|
|
20
|
-
Upon execution, the task checks for the presence of a dataset ID. If the ID is not provided, the task will throw an error indicating that no dataset has been found. If a valid dataset ID is provided, the task proceeds to issue a data collection activity specific to that dataset. The underlying process handled by `
|
20
|
+
Upon execution, the task checks for the presence of a dataset ID. If the ID is not provided, the task will throw an error indicating that no dataset has been found. If a valid dataset ID is provided, the task proceeds to issue a data collection activity specific to that dataset. The underlying process handled by `IssueCollectData` involves operations such as validating the dataset's existence, preparing the data collection environment, and initiating the data collection process according to the dataset's configuration and associated data sources.
|
21
21
|
|
22
22
|
The task returns an instance of the activity initiated, which can be used to track the progress, manage the data collection workflow, or integrate with subsequent tasks for processing the collected data.
|
23
23
|
|
@@ -19,7 +19,7 @@ Tugas `IssueCollectData` adalah fungsi automatik yang memicu proses pengumpulan
|
|
19
19
|
|
20
20
|
## Fungsi
|
21
21
|
|
22
|
-
Saat dieksekusi, tugas memeriksa keberadaan ID set data. Jika ID tidak disediakan, tugas akan melempar kesalahan yang menunjukkan bahwa tidak ada set data yang ditemukan. Jika ID set data yang valid disediakan, tugas melanjutkan untuk mengeluarkan aktiviti pengumpulan data yang spesifik untuk set data tersebut. Proses dasar yang ditangani oleh `
|
22
|
+
Saat dieksekusi, tugas memeriksa keberadaan ID set data. Jika ID tidak disediakan, tugas akan melempar kesalahan yang menunjukkan bahwa tidak ada set data yang ditemukan. Jika ID set data yang valid disediakan, tugas melanjutkan untuk mengeluarkan aktiviti pengumpulan data yang spesifik untuk set data tersebut. Proses dasar yang ditangani oleh `IssueCollectData` melibatkan operasi seperti validasi keberadaan set data, persiapan lingkungan pengumpulan data, dan memulai proses pengumpulan data sesuai dengan konfigurasi set data dan sumber data terkait.
|
23
23
|
|
24
24
|
Tugas mengembalikan instansi aktivitas yang dimulai, yang dapat digunakan untuk melacak kemajuan, mengurus alur kerja pengumpulan data, atau mengintegrasikan dengan tugas berikutnya untuk memproses data yang dikumpulkan.
|
25
25
|
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
## 功能
|
19
19
|
|
20
|
-
执行时,任务会检查数据集 ID 的存在。如果未提供 ID,则任务会抛出错误,指示未找到数据集。如果提供了有效的数据集 ID,则任务将继续针对该数据集发起数据收集活动。`
|
20
|
+
执行时,任务会检查数据集 ID 的存在。如果未提供 ID,则任务会抛出错误,指示未找到数据集。如果提供了有效的数据集 ID,则任务将继续针对该数据集发起数据收集活动。`IssueCollectData` 处理的底层过程涉及验证数据集的存在、准备数据收集环境以及根据数据集的配置和关联数据源启动数据收集过程。
|
21
21
|
|
22
22
|
任务返回启动的活动实例,可用于跟踪进度、管理数据收集工作流或与后续任务集成以处理收集的数据。
|
23
23
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/dataset",
|
3
|
-
"version": "7.1.
|
3
|
+
"version": "7.1.37",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "dist-client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -50,11 +50,11 @@
|
|
50
50
|
"@things-factory/scheduler-client": "^7.1.34",
|
51
51
|
"@things-factory/shell": "^7.1.24",
|
52
52
|
"@things-factory/work-shift": "^7.1.33",
|
53
|
-
"@things-factory/worklist": "^7.1.
|
53
|
+
"@things-factory/worklist": "^7.1.37",
|
54
54
|
"cron-parser": "^4.3.0",
|
55
55
|
"moment-timezone": "^0.5.45",
|
56
56
|
"simple-statistics": "^7.8.3",
|
57
57
|
"statistics": "^3.3.0"
|
58
58
|
},
|
59
|
-
"gitHead": "
|
59
|
+
"gitHead": "db253ce61911ce6bcf543b2f90850faa905b5ae0"
|
60
60
|
}
|
@@ -1,11 +1,20 @@
|
|
1
1
|
import { In } from 'typeorm'
|
2
2
|
|
3
3
|
import { User } from '@things-factory/auth-base'
|
4
|
-
import {
|
4
|
+
import {
|
5
|
+
Activity,
|
6
|
+
ActivityInstance,
|
7
|
+
ActivityInstanceStatus,
|
8
|
+
UpdateActivityInstanceStateAddendum
|
9
|
+
} from '@things-factory/worklist'
|
5
10
|
import { NewDataSample } from 'service/data-sample/data-sample-type'
|
6
11
|
import { createDataSample } from '../controllers/create-data-sample'
|
7
12
|
|
8
|
-
async function callback(
|
13
|
+
async function callback(
|
14
|
+
activityInstance: ActivityInstance,
|
15
|
+
addendum: UpdateActivityInstanceStateAddendum,
|
16
|
+
context: ResolverContext
|
17
|
+
) {
|
9
18
|
const { domain, tx } = context.state
|
10
19
|
const { input, output, state } = activityInstance
|
11
20
|
|
@@ -1,10 +1,20 @@
|
|
1
1
|
import { In } from 'typeorm'
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
Activity,
|
4
|
+
ActivityInstance,
|
5
|
+
ActivityInstanceStatus,
|
6
|
+
UpdateActivityInstanceStateAddendum
|
7
|
+
} from '@things-factory/worklist'
|
3
8
|
import { issue } from '@things-factory/worklist/dist-server/controllers/activity-instance/issue'
|
9
|
+
import { Role } from '@things-factory/auth-base'
|
4
10
|
|
5
11
|
import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
|
6
12
|
|
7
|
-
async function callback(
|
13
|
+
async function callback(
|
14
|
+
activityInstance: ActivityInstance,
|
15
|
+
addendum: UpdateActivityInstanceStateAddendum,
|
16
|
+
context: ResolverContext
|
17
|
+
) {
|
8
18
|
const { domain, user, tx } = context.state
|
9
19
|
const { input, output, state, terminatedAt } = activityInstance
|
10
20
|
const { causedBy } = addendum || {}
|
@@ -28,7 +38,7 @@ async function callback(activityInstance: ActivityInstance, addendum: UpdateActi
|
|
28
38
|
})
|
29
39
|
|
30
40
|
const dataSet = dataOoc.dataSet
|
31
|
-
const {
|
41
|
+
const { resolverRoleId, outlierApprovalLine } = dataSet
|
32
42
|
|
33
43
|
/* dataOoc Review 결과를 dataOoc 엔티티에 반영한다. */
|
34
44
|
dataOoc = await tx.getRepository(DataOoc).save({
|
@@ -39,8 +49,15 @@ async function callback(activityInstance: ActivityInstance, addendum: UpdateActi
|
|
39
49
|
state: DataOocStatus.REVIEWED
|
40
50
|
})
|
41
51
|
|
42
|
-
|
43
|
-
|
52
|
+
const assigneeRole =
|
53
|
+
resolverRoleId &&
|
54
|
+
(await tx.getRepository(Role).findOneBy({
|
55
|
+
domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },
|
56
|
+
id: resolverRoleId
|
57
|
+
}))
|
58
|
+
|
59
|
+
/* 해당 dataset의 작업 담당자(resolverRole)에게 OOC 해결을 위한 태스크를 지시한다. */
|
60
|
+
if (assigneeRole) {
|
44
61
|
const activityInstance = {
|
45
62
|
name: `[OOC 조치] ${dataSet.name}`,
|
46
63
|
description: dataSet.description,
|
@@ -50,14 +67,18 @@ async function callback(activityInstance: ActivityInstance, addendum: UpdateActi
|
|
50
67
|
dataOocId,
|
51
68
|
instruction: correctiveInstruction
|
52
69
|
},
|
53
|
-
|
70
|
+
assigneeRole,
|
71
|
+
threadsMin: 1,
|
72
|
+
threadsMax: 1,
|
54
73
|
approvalLine: outlierApprovalLine
|
55
74
|
}
|
56
75
|
|
57
76
|
dataOoc.resolveActivityInstance = await issue(activityInstance, context)
|
58
77
|
await tx.getRepository(DataOoc).save(dataOoc)
|
59
78
|
} else {
|
60
|
-
console.error(
|
79
|
+
console.error(
|
80
|
+
`Assignees are not set. So, Data OOC Resolve task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`
|
81
|
+
)
|
61
82
|
}
|
62
83
|
} else {
|
63
84
|
console.error('OOC Resolve Activity not installed.')
|
@@ -260,17 +260,19 @@ export async function createDataSample(newDataSample: NewDataSample, context: Re
|
|
260
260
|
})) as Activity
|
261
261
|
|
262
262
|
if (activity) {
|
263
|
-
const
|
263
|
+
const assigneeRole =
|
264
264
|
dataSet.supervisoryRoleId &&
|
265
265
|
(await tx.getRepository(Role).findOneBy({
|
266
266
|
domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },
|
267
267
|
id: dataSet.supervisoryRoleId
|
268
268
|
}))
|
269
269
|
|
270
|
-
const assignees = dataSet.supervisoryRoleId
|
270
|
+
// const assignees = dataSet.supervisoryRoleId
|
271
|
+
// ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assigneeRole }]
|
272
|
+
// : []
|
271
273
|
|
272
274
|
/* 해당 dataset의 supervisor로 하여금, OOC를 리뷰하고 instruction을 작성해서, OOC 해결을 위한 태스크를 dataset assignees에게 지시하도록 한다. */
|
273
|
-
if (
|
275
|
+
if (assigneeRole) {
|
274
276
|
const activityInstance = {
|
275
277
|
name: `[OOC 검토] ${dataSet.name}`,
|
276
278
|
description: dataSet.description,
|
@@ -279,7 +281,9 @@ export async function createDataSample(newDataSample: NewDataSample, context: Re
|
|
279
281
|
input: {
|
280
282
|
dataOocId: dataOoc.id
|
281
283
|
},
|
282
|
-
|
284
|
+
assigneeRole,
|
285
|
+
threadsMin: 1,
|
286
|
+
threadsMax: 1,
|
283
287
|
approvalLine: []
|
284
288
|
}
|
285
289
|
|
@@ -362,19 +366,19 @@ export async function createDataSample(newDataSample: NewDataSample, context: Re
|
|
362
366
|
})) as Activity
|
363
367
|
|
364
368
|
if (activity) {
|
365
|
-
const
|
369
|
+
const assigneeRole =
|
366
370
|
dataSet.supervisoryRoleId &&
|
367
371
|
(await tx.getRepository(Role).findOneBy({
|
368
372
|
domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },
|
369
373
|
id: dataSet.supervisoryRoleId
|
370
374
|
}))
|
371
375
|
|
372
|
-
const assignees = dataSet.supervisoryRoleId
|
373
|
-
|
374
|
-
|
376
|
+
// const assignees = dataSet.supervisoryRoleId
|
377
|
+
// ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assigneeRole }]
|
378
|
+
// : []
|
375
379
|
|
376
380
|
/* 해당 dataset의 supervisor로 하여금, data를 리뷰하고 instruction을 작성해서, approvalLine을 이용해서 승인을 한다. */
|
377
|
-
if (
|
381
|
+
if (assigneeRole) {
|
378
382
|
dataSample.dataItems = dataItems
|
379
383
|
const activityInstance = {
|
380
384
|
name: `[Data 검토] ${dataSet.name}`,
|
@@ -384,7 +388,9 @@ export async function createDataSample(newDataSample: NewDataSample, context: Re
|
|
384
388
|
input: {
|
385
389
|
dataSampleId: dataSample.id
|
386
390
|
},
|
387
|
-
|
391
|
+
assigneeRole,
|
392
|
+
threadsMin: 1,
|
393
|
+
threadsMax: 1,
|
388
394
|
approvalLine: dataSet.reviewApprovalLine
|
389
395
|
}
|
390
396
|
|
@@ -4,8 +4,9 @@ import { Domain, getDataSource } from '@things-factory/shell'
|
|
4
4
|
import { Activity, ActivityInstance, issue } from '@things-factory/worklist'
|
5
5
|
|
6
6
|
import { DataSet } from '../service/data-set/data-set'
|
7
|
+
import { OrgMemberTargetType } from '@things-factory/organization'
|
7
8
|
|
8
|
-
export async function
|
9
|
+
export async function issueDataCollectionTask(
|
9
10
|
domainId: string,
|
10
11
|
dataSetId: string,
|
11
12
|
context: ResolverContext
|
@@ -23,7 +24,8 @@ export async function issueCollectData(
|
|
23
24
|
id: In([domain.id, domain.parentId].filter(Boolean))
|
24
25
|
},
|
25
26
|
id: dataSetId
|
26
|
-
}
|
27
|
+
},
|
28
|
+
relations: ['entryRole']
|
27
29
|
})
|
28
30
|
|
29
31
|
const activity = (await tx.getRepository(Activity).findOneBy({
|
@@ -32,10 +34,12 @@ export async function issueCollectData(
|
|
32
34
|
})) as Activity
|
33
35
|
|
34
36
|
if (activity) {
|
35
|
-
const {
|
37
|
+
const { entryRole } = dataSet
|
38
|
+
|
39
|
+
// const assignees = entryRole ? [{ type: OrgMemberTargetType.Role, value: entryRole.id, assignee: entryRole }] : []
|
36
40
|
|
37
|
-
/* 해당 dataset에 대한 데이타 수집 태스크를 dataset
|
38
|
-
if (
|
41
|
+
/* 해당 dataset에 대한 데이타 수집 태스크를 dataset entryRole에게 할당한다. */
|
42
|
+
if (entryRole) {
|
39
43
|
const activityInstance = {
|
40
44
|
name: `[Data 수집] ${dataSet.name}`,
|
41
45
|
description: dataSet.description,
|
@@ -45,7 +49,9 @@ export async function issueCollectData(
|
|
45
49
|
dataSetId: dataSet.id,
|
46
50
|
dataSetName: dataSet.name
|
47
51
|
},
|
48
|
-
|
52
|
+
assigneeRole: entryRole,
|
53
|
+
threadsMin: 1,
|
54
|
+
threadsMax: 1
|
49
55
|
}
|
50
56
|
|
51
57
|
context.state = {
|
@@ -57,7 +63,7 @@ export async function issueCollectData(
|
|
57
63
|
return await issue(activityInstance, context)
|
58
64
|
} else {
|
59
65
|
throw new Error(
|
60
|
-
`
|
66
|
+
`Data Entry Role not set. So Data Collect Activity for ${dataSet.name}($dataSet.id) could not be issued.`
|
61
67
|
)
|
62
68
|
}
|
63
69
|
} else {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { TaskRegistry, InputStep, Context } from '@things-factory/integration-base'
|
2
|
-
import {
|
2
|
+
import { issueDataCollectionTask } from '../../controllers/issue-data-collection-task'
|
3
3
|
import i18next from 'i18next'
|
4
4
|
|
5
5
|
async function IssueCollectData(step: InputStep, context: Context) {
|
@@ -12,7 +12,7 @@ async function IssueCollectData(step: InputStep, context: Context) {
|
|
12
12
|
throw new Error(`no dataset found`)
|
13
13
|
}
|
14
14
|
|
15
|
-
const activityInstance = await
|
15
|
+
const activityInstance = await issueDataCollectionTask(domain.id, dataSetId, {
|
16
16
|
t: i18next.t,
|
17
17
|
state: {
|
18
18
|
domain,
|
package/server/routes.ts
CHANGED
@@ -8,7 +8,7 @@ import { ScheduleRegisterRequest } from '@things-factory/scheduler-client'
|
|
8
8
|
import { createDataSample } from './controllers/create-data-sample'
|
9
9
|
import { renderJasperReport } from './controllers/jasper-report'
|
10
10
|
import { renderShinyReport } from './controllers/shiny-report'
|
11
|
-
import {
|
11
|
+
import { issueDataCollectionTask } from './controllers/issue-data-collection-task'
|
12
12
|
import { DataSensor } from './service/data-sensor/data-sensor'
|
13
13
|
import { DataSet } from './service/data-set/data-set'
|
14
14
|
|
@@ -120,7 +120,7 @@ process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRout
|
|
120
120
|
throw new Error(`group(${domainId}) and key(${dataSetId}) properties should not be empty`)
|
121
121
|
}
|
122
122
|
|
123
|
-
await
|
123
|
+
await issueDataCollectionTask(domainId, dataSetId, context)
|
124
124
|
|
125
125
|
context.status = 200
|
126
126
|
})
|
@@ -146,7 +146,9 @@ process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRout
|
|
146
146
|
throw new Error(`domain(${domainId}) not found`)
|
147
147
|
}
|
148
148
|
|
149
|
-
const dataSet = await tx
|
149
|
+
const dataSet = await tx
|
150
|
+
.getRepository(DataSet)
|
151
|
+
.findOne({ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id: dataSetId } })
|
150
152
|
|
151
153
|
// do what you gotta do
|
152
154
|
})
|
@@ -1,21 +1,21 @@
|
|
1
|
-
import { In } from 'typeorm'
|
2
1
|
import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
|
2
|
+
import { In } from 'typeorm'
|
3
3
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
5
5
|
import {
|
6
6
|
Domain,
|
7
|
+
getISOStringsForPeriod,
|
7
8
|
getQueryBuilderFromListParams,
|
8
9
|
getRepository,
|
9
|
-
getISOStringsForPeriod,
|
10
10
|
ListParam
|
11
11
|
} from '@things-factory/shell'
|
12
12
|
import { ActivityInstance } from '@things-factory/worklist'
|
13
13
|
|
14
14
|
import { DataKeySet } from '../data-key-set/data-key-set'
|
15
|
+
import { DataOoc } from '../data-ooc/data-ooc'
|
15
16
|
import { DataSetHistory } from '../data-set-history/data-set-history'
|
16
17
|
import { DataItem } from '../data-set/data-item-type'
|
17
18
|
import { DataSet } from '../data-set/data-set'
|
18
|
-
import { DataOoc } from '../data-ooc/data-ooc'
|
19
19
|
import { DataSample } from './data-sample'
|
20
20
|
import { DataSampleList } from './data-sample-type'
|
21
21
|
|
@@ -43,7 +43,7 @@ export class DataSampleQuery {
|
|
43
43
|
repository: getRepository(DataSample),
|
44
44
|
params,
|
45
45
|
domain,
|
46
|
-
searchables: ['name', 'description']
|
46
|
+
searchables: ['name', 'description', 'key01', 'key02', 'key03', 'key04', 'key05']
|
47
47
|
})
|
48
48
|
|
49
49
|
const [items, total] = await queryBuilder.getManyAndCount()
|
@@ -6,11 +6,11 @@ import { User } from '@things-factory/auth-base'
|
|
6
6
|
import { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'
|
7
7
|
import { ApprovalLineItem, OrgMemberTargetType } from '@things-factory/organization'
|
8
8
|
import { Application, CallbackBase, registerSchedule, unregisterSchedule } from '@things-factory/scheduler-client'
|
9
|
-
import { Activity, AssigneeItem, issue } from '@things-factory/worklist'
|
10
9
|
|
11
10
|
import { getDataFinalizeCrontabSchedule } from '../../controllers/finalize-data-collection'
|
12
11
|
import { DataSet } from './data-set'
|
13
12
|
import { DataSetPatch, NewDataSet } from './data-set-type'
|
13
|
+
import { issueDataCollectionTask } from '../../controllers/issue-data-collection-task'
|
14
14
|
|
15
15
|
const crypto = require('crypto')
|
16
16
|
|
@@ -80,39 +80,6 @@ function getOutlierApprovalLineValue(patch: NewDataSet | DataSetPatch): Approval
|
|
80
80
|
})
|
81
81
|
}
|
82
82
|
|
83
|
-
function getAssigneesValue(patch: NewDataSet | DataSetPatch): AssigneeItem[] {
|
84
|
-
const { assignees } = patch
|
85
|
-
|
86
|
-
if (!('assignees' in patch)) {
|
87
|
-
/* assignees이 언급되지 않았다면, 업데이트하지 않는다. */
|
88
|
-
return
|
89
|
-
}
|
90
|
-
|
91
|
-
if (!assignees || !(assignees instanceof Array)) {
|
92
|
-
/* assignees의 값이 없거나 배열이 아니라면, 클리어시킨다. */
|
93
|
-
return null
|
94
|
-
}
|
95
|
-
|
96
|
-
return assignees
|
97
|
-
.map(m => {
|
98
|
-
return {
|
99
|
-
type: m.type,
|
100
|
-
assignee: m.assignee
|
101
|
-
}
|
102
|
-
})
|
103
|
-
.filter(m => m.type)
|
104
|
-
.filter(m => {
|
105
|
-
switch (m.type) {
|
106
|
-
case OrgMemberTargetType.Employee:
|
107
|
-
case OrgMemberTargetType.Department:
|
108
|
-
case OrgMemberTargetType.Role:
|
109
|
-
return !!m.assignee?.id
|
110
|
-
default:
|
111
|
-
return true
|
112
|
-
}
|
113
|
-
})
|
114
|
-
}
|
115
|
-
|
116
83
|
@Resolver(DataSet)
|
117
84
|
export class DataSetMutation {
|
118
85
|
@Directive('@privilege(category: "data-set", privilege: "mutation", domainOwnerGranted: true)')
|
@@ -125,7 +92,6 @@ export class DataSetMutation {
|
|
125
92
|
const result = await dataSetRepo.save({
|
126
93
|
...dataSet,
|
127
94
|
approvalLine: getApprovalLineValue(dataSet),
|
128
|
-
assignees: getAssigneesValue(dataSet),
|
129
95
|
outlierApprovalLineValue: getOutlierApprovalLineValue(dataSet),
|
130
96
|
version: 1,
|
131
97
|
domain,
|
@@ -160,7 +126,6 @@ export class DataSetMutation {
|
|
160
126
|
...patch,
|
161
127
|
approvalLine: getApprovalLineValue(patch),
|
162
128
|
outlierApprovalLineValue: getOutlierApprovalLineValue(patch),
|
163
|
-
assignees: getAssigneesValue(patch),
|
164
129
|
updater: user
|
165
130
|
})
|
166
131
|
|
@@ -191,7 +156,6 @@ export class DataSetMutation {
|
|
191
156
|
const result = await dataSetRepo.save({
|
192
157
|
...newRecord,
|
193
158
|
approvalLine: getApprovalLineValue(newRecord),
|
194
|
-
assignees: getAssigneesValue(newRecord),
|
195
159
|
outlierApprovalLineValue: getOutlierApprovalLineValue(newRecord),
|
196
160
|
domain,
|
197
161
|
creator: user,
|
@@ -222,7 +186,6 @@ export class DataSetMutation {
|
|
222
186
|
...updateRecord,
|
223
187
|
approvalLine: getApprovalLineValue(updateRecord),
|
224
188
|
outlierApprovalLineValue: getOutlierApprovalLineValue(updateRecord),
|
225
|
-
assignees: getAssigneesValue(updateRecord),
|
226
189
|
updater: user
|
227
190
|
})
|
228
191
|
|
@@ -266,7 +229,6 @@ export class DataSetMutation {
|
|
266
229
|
return true
|
267
230
|
}
|
268
231
|
|
269
|
-
// @Directive('@privilege(category: "data-set", privilege: "mutation")')
|
270
232
|
@Directive('@transaction')
|
271
233
|
@Mutation(returns => Boolean, { description: 'To issue data-collection task for the given dataset' })
|
272
234
|
async issueDataCollection(@Arg('dataSetId') dataSetId: string, @Ctx() context: ResolverContext): Promise<boolean> {
|
@@ -281,9 +243,8 @@ export class DataSetMutation {
|
|
281
243
|
}
|
282
244
|
})
|
283
245
|
|
284
|
-
const {
|
246
|
+
const { supervisoryRoleId } = dataSet
|
285
247
|
|
286
|
-
// role check
|
287
248
|
const me = await getRepository(User, tx).findOne({
|
288
249
|
where: { id: user.id },
|
289
250
|
relations: ['roles']
|
@@ -293,41 +254,9 @@ export class DataSetMutation {
|
|
293
254
|
throw new Error(`You don't have permission to issue data collection task for this dataset.`)
|
294
255
|
}
|
295
256
|
|
296
|
-
const
|
297
|
-
domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },
|
298
|
-
name: 'Collect Data'
|
299
|
-
})) as Activity
|
300
|
-
|
301
|
-
if (activity) {
|
302
|
-
/* 해당 dataset에 대한 데이타 수집 태스크를 dataset assignees에게 할당한다. */
|
303
|
-
if (assignees && assignees instanceof Array && assignees.length > 0) {
|
304
|
-
const activityInstance = {
|
305
|
-
name: `[Data 수집] ${dataSet.name}`,
|
306
|
-
description: dataSet.description,
|
307
|
-
activityId: activity.id,
|
308
|
-
dueAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
309
|
-
input: {
|
310
|
-
dataSetId: dataSet.id,
|
311
|
-
dataSetName: dataSet.name
|
312
|
-
},
|
313
|
-
assignees
|
314
|
-
}
|
315
|
-
|
316
|
-
context.state = {
|
317
|
-
...context.state,
|
318
|
-
domain,
|
319
|
-
tx
|
320
|
-
}
|
321
|
-
|
322
|
-
await issue(activityInstance, context)
|
323
|
-
} else {
|
324
|
-
throw new Error(
|
325
|
-
`Assignees not set. So Data Collect Activity for ${dataSet.name}($dataSet.id) could not be issued.`
|
326
|
-
)
|
327
|
-
}
|
328
|
-
}
|
257
|
+
const activityInstance = await issueDataCollectionTask(domain.id, dataSet.id, context)
|
329
258
|
|
330
|
-
return
|
259
|
+
return !!activityInstance
|
331
260
|
}
|
332
261
|
|
333
262
|
@Directive('@transaction')
|
@@ -184,6 +184,18 @@ export class DataSetQuery {
|
|
184
184
|
)
|
185
185
|
}
|
186
186
|
|
187
|
+
// 데이터셋의 resolver 역할을 조회
|
188
|
+
@FieldResolver(type => Role, { description: 'Retrieves the resolver role for the dataset' })
|
189
|
+
async resolverRole(@Root() dataSet: DataSet): Promise<Role> {
|
190
|
+
return (
|
191
|
+
dataSet.resolverRole ||
|
192
|
+
(dataSet.resolverRoleId &&
|
193
|
+
(await getRepository(Role).findOneBy({
|
194
|
+
id: dataSet.resolverRoleId
|
195
|
+
})))
|
196
|
+
)
|
197
|
+
}
|
198
|
+
|
187
199
|
@FieldResolver(type => [AssigneeItem], { description: 'Retrieves the assignee items for the dataset' })
|
188
200
|
async assignees(@Root() dataSet: DataSet, @Ctx() context: ResolverContext): Promise<AssigneeItem[]> {
|
189
201
|
const { domain, user } = context.state
|
@@ -29,8 +29,8 @@ export class NewDataSet {
|
|
29
29
|
@Field(type => ObjectRef, { nullable: true })
|
30
30
|
supervisoryRole?: ObjectRef
|
31
31
|
|
32
|
-
@Field(type =>
|
33
|
-
|
32
|
+
@Field(type => ObjectRef, { nullable: true })
|
33
|
+
resolverRole?: ObjectRef
|
34
34
|
|
35
35
|
@Field(type => ScalarObject, { nullable: true })
|
36
36
|
reviewApprovalLine?: ApprovalLineItem[]
|
@@ -116,8 +116,8 @@ export class DataSetPatch {
|
|
116
116
|
@Field(type => ObjectRef, { nullable: true })
|
117
117
|
entryRole?: ObjectRef
|
118
118
|
|
119
|
-
@Field(type =>
|
120
|
-
|
119
|
+
@Field(type => ObjectRef, { nullable: true })
|
120
|
+
resolverRole?: ObjectRef
|
121
121
|
|
122
122
|
@Field(type => ScalarObject, { nullable: true })
|
123
123
|
reviewApprovalLine?: ApprovalLineItem[]
|
@@ -150,6 +150,16 @@ export class DataSet {
|
|
150
150
|
@RelationId((dataSet: DataSet) => dataSet.supervisoryRole)
|
151
151
|
supervisoryRoleId?: string
|
152
152
|
|
153
|
+
@ManyToOne(type => Role, { nullable: true })
|
154
|
+
@Field(type => Role, {
|
155
|
+
nullable: true,
|
156
|
+
description: 'The final authority on resolving outlier related to that dataset.'
|
157
|
+
})
|
158
|
+
resolverRole?: Role
|
159
|
+
|
160
|
+
@RelationId((dataSet: DataSet) => dataSet.resolverRole)
|
161
|
+
resolverRoleId?: string
|
162
|
+
|
153
163
|
@Column('simple-json', { nullable: true })
|
154
164
|
@Field(type => [AssigneeItem], { nullable: true, description: 'Who to contact for OOC issues' })
|
155
165
|
assignees?: AssigneeItem[]
|
package/translations/en.json
CHANGED
@@ -70,6 +70,7 @@
|
|
70
70
|
"field.report-view": "report view",
|
71
71
|
"field.request-params": "request parameters",
|
72
72
|
"field.requires-review": "requires review",
|
73
|
+
"field.resolver-role": "resolver role",
|
73
74
|
"field.review-approval-line": "review approval line",
|
74
75
|
"field.role": "role",
|
75
76
|
"field.serial-no": "serial #",
|
package/translations/ja.json
CHANGED
package/translations/ko.json
CHANGED
package/translations/ms.json
CHANGED
@@ -71,6 +71,7 @@
|
|
71
71
|
"field.report-view": "paparan laporan",
|
72
72
|
"field.request-params": "parameter permintaan",
|
73
73
|
"field.requires-review": "memerlukan semakan",
|
74
|
+
"field.resolver-role": "peranan penyelesai",
|
74
75
|
"field.review-approval-line": "baris kelulusan",
|
75
76
|
"field.role": "peranan",
|
76
77
|
"field.serial-no": "no. siri",
|
package/translations/zh.json
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"issue-collect-data.js","sourceRoot":"","sources":["../../server/controllers/issue-collect-data.ts"],"names":[],"mappings":";;AAOA,4CA2DC;AAlED,qCAA4B;AAE5B,iDAA6D;AAC7D,uDAA4E;AAE5E,2DAAsD;AAE/C,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,SAAiB,EACjB,OAAwB;IAExB,MAAM,IAAA,qBAAa,GAAE,CAAC,WAAW,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,cAAM,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;QAEzE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,UAAU,QAAQ,aAAa,CAAC,CAAA;QAClD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,kBAAO,CAAC,CAAC,OAAO,CAAC;YACtD,KAAK,EAAE;gBACL,MAAM,EAAE;oBACN,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;iBACrD;gBACD,EAAE,EAAE,SAAS;aACd;SACF,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,mBAAQ,CAAC,CAAC,SAAS,CAAC;YAC3D,MAAM,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE;YAChE,IAAI,EAAE,cAAc;SACrB,CAAC,CAAa,CAAA;QAEf,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;YAE7B,0DAA0D;YAC1D,IAAI,SAAS,IAAI,SAAS,YAAY,KAAK,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpE,MAAM,gBAAgB,GAAG;oBACvB,IAAI,EAAE,aAAa,OAAO,CAAC,IAAI,EAAE;oBACjC,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,UAAU,EAAE,QAAQ,CAAC,EAAE;oBACvB,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;oBACjD,KAAK,EAAE;wBACL,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,WAAW,EAAE,OAAO,CAAC,IAAI;qBAC1B;oBACD,SAAS;iBACV,CAAA;gBAED,OAAO,CAAC,KAAK,mCACR,OAAO,CAAC,KAAK,KAChB,MAAM;oBACN,EAAE,GACH,CAAA;gBAED,OAAO,MAAM,IAAA,gBAAK,EAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;YAC/C,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,mDAAmD,OAAO,CAAC,IAAI,oCAAoC,CACpG,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { In } from 'typeorm'\n\nimport { Domain, getDataSource } from '@things-factory/shell'\nimport { Activity, ActivityInstance, issue } from '@things-factory/worklist'\n\nimport { DataSet } from '../service/data-set/data-set'\n\nexport async function issueCollectData(\n domainId: string,\n dataSetId: string,\n context: ResolverContext\n): Promise<ActivityInstance | void> {\n await getDataSource().transaction(async tx => {\n const domain = await tx.getRepository(Domain).findOneBy({ id: domainId })\n\n if (!domain) {\n throw new Error(`domain(${domainId}) not found`)\n }\n\n const dataSet = await tx.getRepository(DataSet).findOne({\n where: {\n domain: {\n id: In([domain.id, domain.parentId].filter(Boolean))\n },\n id: dataSetId\n }\n })\n\n const activity = (await tx.getRepository(Activity).findOneBy({\n domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },\n name: 'Collect Data'\n })) as Activity\n\n if (activity) {\n const { assignees } = dataSet\n\n /* 해당 dataset에 대한 데이타 수집 태스크를 dataset assignees에게 할당한다. */\n if (assignees && assignees instanceof Array && assignees.length > 0) {\n const activityInstance = {\n name: `[Data 수집] ${dataSet.name}`,\n description: dataSet.description,\n activityId: activity.id,\n dueAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n input: {\n dataSetId: dataSet.id,\n dataSetName: dataSet.name\n },\n assignees\n }\n\n context.state = {\n ...context.state,\n domain,\n tx\n }\n\n return await issue(activityInstance, context)\n } else {\n throw new Error(\n `Assignees not set. So Data Collect Activity for ${dataSet.name}($dataSet.id) could not be issued.`\n )\n }\n } else {\n throw new Error(`Data Collect Activity is not installed.`)\n }\n })\n}\n"]}
|