@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.
Files changed (64) hide show
  1. package/client/activities/activity-ooc-resolve-edit.ts +1 -1
  2. package/client/activities/activity-ooc-review-edit.ts +1 -1
  3. package/client/pages/data-entry/data-entry-list-page.ts +7 -0
  4. package/client/pages/data-set/data-set-list-page.ts +14 -15
  5. package/dist-client/activities/activity-ooc-resolve-edit.js +1 -1
  6. package/dist-client/activities/activity-ooc-resolve-edit.js.map +1 -1
  7. package/dist-client/activities/activity-ooc-review-edit.js +1 -1
  8. package/dist-client/activities/activity-ooc-review-edit.js.map +1 -1
  9. package/dist-client/pages/data-entry/data-entry-list-page.js +7 -0
  10. package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
  11. package/dist-client/pages/data-set/data-set-list-page.js +14 -15
  12. package/dist-client/pages/data-set/data-set-list-page.js.map +1 -1
  13. package/dist-client/tsconfig.tsbuildinfo +1 -1
  14. package/dist-server/activities/activity-data-collect.js.map +1 -1
  15. package/dist-server/activities/activity-ooc-review.js +12 -4
  16. package/dist-server/activities/activity-ooc-review.js.map +1 -1
  17. package/dist-server/controllers/create-data-sample.js +16 -10
  18. package/dist-server/controllers/create-data-sample.js.map +1 -1
  19. package/dist-server/controllers/issue-data-collection-task.d.ts +2 -0
  20. package/dist-server/controllers/{issue-collect-data.js → issue-data-collection-task.js} +13 -9
  21. package/dist-server/controllers/issue-data-collection-task.js.map +1 -0
  22. package/dist-server/engine/task/issue-collect-data.js +2 -2
  23. package/dist-server/engine/task/issue-collect-data.js.map +1 -1
  24. package/dist-server/routes.js +5 -3
  25. package/dist-server/routes.js.map +1 -1
  26. package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
  27. package/dist-server/service/data-sample/data-sample-query.js +3 -3
  28. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  29. package/dist-server/service/data-set/data-set-mutation.js +8 -65
  30. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  31. package/dist-server/service/data-set/data-set-query.d.ts +1 -0
  32. package/dist-server/service/data-set/data-set-query.js +15 -0
  33. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  34. package/dist-server/service/data-set/data-set-type.d.ts +2 -3
  35. package/dist-server/service/data-set/data-set-type.js +6 -6
  36. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  37. package/dist-server/service/data-set/data-set.d.ts +2 -0
  38. package/dist-server/service/data-set/data-set.js +12 -0
  39. package/dist-server/service/data-set/data-set.js.map +1 -1
  40. package/dist-server/tsconfig.tsbuildinfo +1 -1
  41. package/helps/dataset/task/issue-collect-data.ja.md +1 -1
  42. package/helps/dataset/task/issue-collect-data.ko.md +1 -1
  43. package/helps/dataset/task/issue-collect-data.md +1 -1
  44. package/helps/dataset/task/issue-collect-data.ms.md +1 -1
  45. package/helps/dataset/task/issue-collect-data.zh.md +1 -1
  46. package/package.json +3 -3
  47. package/server/activities/activity-data-collect.ts +11 -2
  48. package/server/activities/activity-ooc-review.ts +28 -7
  49. package/server/controllers/create-data-sample.ts +16 -10
  50. package/server/controllers/{issue-collect-data.ts → issue-data-collection-task.ts} +13 -7
  51. package/server/engine/task/issue-collect-data.ts +2 -2
  52. package/server/routes.ts +5 -3
  53. package/server/service/data-sample/data-sample-query.ts +4 -4
  54. package/server/service/data-set/data-set-mutation.ts +4 -75
  55. package/server/service/data-set/data-set-query.ts +12 -0
  56. package/server/service/data-set/data-set-type.ts +4 -4
  57. package/server/service/data-set/data-set.ts +10 -0
  58. package/translations/en.json +1 -0
  59. package/translations/ja.json +1 -0
  60. package/translations/ko.json +1 -0
  61. package/translations/ms.json +1 -0
  62. package/translations/zh.json +1 -0
  63. package/dist-server/controllers/issue-collect-data.d.ts +0 -2
  64. 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 が提供された場合、タスクはそのデータセットに特定のデータ収集活動を発行します。`issueCollectData` によって処理される基本的なプロセスには、データセットの存在の検証、データ収集環境の準備、およびデータセットの構成および関連するデータソースに従ってデータ収集プロセスを開始するなどの操作が含まれます。
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가 제공되면, 작업은 해당 데이터셋에 특정한 데이터 수집 활동을 발행합니다. `issueCollectData`에 의해 처리되는 기본 프로세스는 데이터셋의 존재를 확인, 데이터 수집 환경 준비, 데이터셋의 구성 및 관련 데이터 소스에 따라 데이터 수집 프로세스 시작과 같은 작업을 포함합니다.
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 `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.
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 `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.
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,则任务将继续针对该数据集发起数据收集活动。`issueCollectData` 处理的底层过程涉及验证数据集的存在、准备数据收集环境以及根据数据集的配置和关联数据源启动数据收集过程。
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.34",
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.34",
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": "22830c9e51c9fffb3c95d1d1f8cacc7706f7d2d1"
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 { Activity, ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'
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(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {
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 { Activity, ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'
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(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {
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 { assignees, outlierApprovalLine } = dataSet
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
- /* 해당 dataset의 작업 담당자(assignees)에게 OOC 해결을 위한 태스크를 지시한다. */
43
- if (assignees && assignees instanceof Array && assignees.length > 0) {
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
- assignees,
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(`Assignees are not set. So, Data OOC Resolve task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`)
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 assignee =
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 ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assignee }] : []
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 (assignees && assignees instanceof Array && assignees.length > 0) {
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
- assignees,
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 assignee =
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
- ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assignee }]
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 (assignees && assignees instanceof Array && assignees.length > 0) {
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
- assignees,
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 issueCollectData(
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 { assignees } = dataSet
37
+ const { entryRole } = dataSet
38
+
39
+ // const assignees = entryRole ? [{ type: OrgMemberTargetType.Role, value: entryRole.id, assignee: entryRole }] : []
36
40
 
37
- /* 해당 dataset에 대한 데이타 수집 태스크를 dataset assignees에게 할당한다. */
38
- if (assignees && assignees instanceof Array && assignees.length > 0) {
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
- assignees
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
- `Assignees not set. So Data Collect Activity for ${dataSet.name}($dataSet.id) could not be issued.`
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 { issueCollectData } from '../../controllers/issue-collect-data'
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 issueCollectData(domain.id, dataSetId, {
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 { issueCollectData } from './controllers/issue-collect-data'
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 issueCollectData(domainId, dataSetId, context)
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.getRepository(DataSet).findOne({ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id: dataSetId } })
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 { assignees, supervisoryRoleId } = dataSet
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 activity = (await getRepository(Activity, tx).findOneBy({
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 true
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 => ScalarObject, { nullable: true })
33
- assignees?: AssigneeItem[]
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 => ScalarObject, { nullable: true })
120
- assignees?: AssigneeItem[]
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[]
@@ -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 #",
@@ -71,6 +71,7 @@
71
71
  "field.report-view": "レポート用画面",
72
72
  "field.request-params": "リクエスト パラメータ",
73
73
  "field.requires-review": "見直しが必要",
74
+ "field.resolver-role": "解決者役割",
74
75
  "field.review-approval-line": "決済ライン",
75
76
  "field.role": "ロール",
76
77
  "field.serial-no": "シリアル番号",
@@ -71,6 +71,7 @@
71
71
  "field.report-view": "리포트용 화면",
72
72
  "field.request-params": "요청 매개변수",
73
73
  "field.requires-review": "검토 요청",
74
+ "field.resolver-role": "해결자 역할",
74
75
  "field.review-approval-line": "결재라인",
75
76
  "field.role": "역할",
76
77
  "field.serial-no": "시리얼번호",
@@ -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",
@@ -71,6 +71,7 @@
71
71
  "field.report-view": "报告界面",
72
72
  "field.request-params": "请求参数",
73
73
  "field.requires-review": "需要审查",
74
+ "field.resolver-role": "解决者角色",
74
75
  "field.review-approval-line": "审批线",
75
76
  "field.role": "角色",
76
77
  "field.serial-no": "序列号",
@@ -1,2 +0,0 @@
1
- import { ActivityInstance } from '@things-factory/worklist';
2
- export declare function issueCollectData(domainId: string, dataSetId: string, context: ResolverContext): Promise<ActivityInstance | void>;
@@ -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"]}