@things-factory/dataset 8.0.0-beta.9 → 8.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. package/client/activities/activity-data-collect-edit.ts +105 -0
  2. package/client/activities/activity-data-collect-view.ts +91 -0
  3. package/client/activities/activity-data-review-edit.ts +278 -0
  4. package/client/activities/activity-data-review-view.ts +226 -0
  5. package/client/activities/activity-ooc-resolve-edit.ts +195 -0
  6. package/client/activities/activity-ooc-resolve-view.ts +143 -0
  7. package/client/activities/activity-ooc-review-edit.ts +173 -0
  8. package/client/activities/activity-ooc-review-view.ts +129 -0
  9. package/client/bootstrap.ts +35 -0
  10. package/client/components/data-entry-form.ts +109 -0
  11. package/client/index.ts +1 -0
  12. package/client/pages/data-archive/data-archive-list-page.ts +277 -0
  13. package/client/pages/data-archive/data-archive-request-popup.ts +177 -0
  14. package/client/pages/data-entry/data-entry-list-page.ts +464 -0
  15. package/client/pages/data-key-set/data-key-item-list.ts +183 -0
  16. package/client/pages/data-key-set/data-key-set-importer.ts +89 -0
  17. package/client/pages/data-key-set/data-key-set-list-page.ts +413 -0
  18. package/client/pages/data-ooc/data-ooc-list-page.ts +549 -0
  19. package/client/pages/data-ooc/data-ooc-page.ts +164 -0
  20. package/client/pages/data-ooc/data-ooc-view.ts +236 -0
  21. package/client/pages/data-ooc/data-oocs-page.ts +200 -0
  22. package/client/pages/data-report/data-report-embed-page.ts +108 -0
  23. package/client/pages/data-report/data-report-list-page.ts +454 -0
  24. package/client/pages/data-report/data-report-samples-page.ts +174 -0
  25. package/client/pages/data-report/jasper-report-oocs-page.ts +110 -0
  26. package/client/pages/data-report/jasper-report-samples-crosstab-page.ts +110 -0
  27. package/client/pages/data-report/jasper-report-samples-page.ts +110 -0
  28. package/client/pages/data-sample/data-sample-list-page.ts +442 -0
  29. package/client/pages/data-sample/data-sample-page.ts +55 -0
  30. package/client/pages/data-sample/data-sample-search-page.ts +424 -0
  31. package/client/pages/data-sample/data-sample-view.ts +292 -0
  32. package/client/pages/data-sample/data-samples-page.ts +249 -0
  33. package/client/pages/data-sensor/data-sensor-list-page.ts +456 -0
  34. package/client/pages/data-set/data-item-list.ts +304 -0
  35. package/client/pages/data-set/data-set-importer.ts +89 -0
  36. package/client/pages/data-set/data-set-list-page.ts +1078 -0
  37. package/client/pages/data-summary/data-summary-list-page.ts +363 -0
  38. package/client/pages/data-summary/data-summary-period-page.ts +439 -0
  39. package/client/pages/data-summary/data-summary-search-page.ts +426 -0
  40. package/client/pages/data-summary/data-summary-view.ts +133 -0
  41. package/client/route.ts +91 -0
  42. package/client/tsconfig.json +13 -0
  43. package/dist-client/activities/activity-data-review-edit.js +19 -10
  44. package/dist-client/activities/activity-data-review-edit.js.map +1 -1
  45. package/dist-client/activities/activity-data-review-view.js +80 -0
  46. package/dist-client/activities/activity-data-review-view.js.map +1 -1
  47. package/dist-client/pages/data-entry/data-entry-list-page.js +2 -2
  48. package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
  49. package/dist-client/tsconfig.tsbuildinfo +1 -1
  50. package/dist-server/controllers/create-data-ooc.js +2 -0
  51. package/dist-server/controllers/create-data-ooc.js.map +1 -1
  52. package/dist-server/service/data-archive/index.d.ts +1 -1
  53. package/dist-server/service/data-ooc/index.d.ts +1 -1
  54. package/dist-server/service/data-sample/data-sample-query.d.ts +1 -1
  55. package/dist-server/service/data-sample/data-sample-query.js +3 -3
  56. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  57. package/dist-server/service/data-sample/index.d.ts +1 -1
  58. package/dist-server/service/data-set/index.d.ts +1 -1
  59. package/dist-server/service/index.d.ts +2 -2
  60. package/dist-server/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +26 -26
  62. package/server/activities/activity-data-collect.ts +100 -0
  63. package/server/activities/activity-data-review.ts +109 -0
  64. package/server/activities/activity-ooc-resolve.ts +123 -0
  65. package/server/activities/activity-ooc-review.ts +95 -0
  66. package/server/activities/index.ts +11 -0
  67. package/server/controllers/create-data-ooc.ts +80 -0
  68. package/server/controllers/create-data-sample.ts +323 -0
  69. package/server/controllers/data-use-case.ts +98 -0
  70. package/server/controllers/finalize-data-collection.ts +388 -0
  71. package/server/controllers/index.ts +6 -0
  72. package/server/controllers/issue-data-collection-task.ts +70 -0
  73. package/server/controllers/issue-ooc-resolve.ts +58 -0
  74. package/server/controllers/issue-ooc-review.ts +52 -0
  75. package/server/controllers/jasper-report.ts +186 -0
  76. package/server/controllers/query-data-summary-by-period.ts +178 -0
  77. package/server/controllers/shiny-report.ts +54 -0
  78. package/server/engine/index.ts +1 -0
  79. package/server/engine/task/create-data-sample.ts +100 -0
  80. package/server/engine/task/index.ts +2 -0
  81. package/server/engine/task/issue-collect-data.ts +45 -0
  82. package/server/index.ts +8 -0
  83. package/server/routes.ts +188 -0
  84. package/server/service/data-archive/data-archive-mutation.ts +273 -0
  85. package/server/service/data-archive/data-archive-query.ts +58 -0
  86. package/server/service/data-archive/data-archive-type.ts +48 -0
  87. package/server/service/data-archive/data-archive.ts +69 -0
  88. package/server/service/data-archive/index.ts +6 -0
  89. package/server/service/data-key-set/data-key-item-type.ts +31 -0
  90. package/server/service/data-key-set/data-key-set-mutation.ts +201 -0
  91. package/server/service/data-key-set/data-key-set-query.ts +68 -0
  92. package/server/service/data-key-set/data-key-set-type.ts +70 -0
  93. package/server/service/data-key-set/data-key-set.ts +86 -0
  94. package/server/service/data-key-set/index.ts +6 -0
  95. package/server/service/data-ooc/data-ooc-mutation.ts +154 -0
  96. package/server/service/data-ooc/data-ooc-query.ts +106 -0
  97. package/server/service/data-ooc/data-ooc-subscription.ts +48 -0
  98. package/server/service/data-ooc/data-ooc-type.ts +71 -0
  99. package/server/service/data-ooc/data-ooc.ts +259 -0
  100. package/server/service/data-ooc/index.ts +7 -0
  101. package/server/service/data-sample/data-sample-mutation.ts +18 -0
  102. package/server/service/data-sample/data-sample-query.ts +215 -0
  103. package/server/service/data-sample/data-sample-type.ts +47 -0
  104. package/server/service/data-sample/data-sample.ts +193 -0
  105. package/server/service/data-sample/index.ts +6 -0
  106. package/server/service/data-sensor/data-sensor-mutation.ts +116 -0
  107. package/server/service/data-sensor/data-sensor-query.ts +76 -0
  108. package/server/service/data-sensor/data-sensor-type.ts +104 -0
  109. package/server/service/data-sensor/data-sensor.ts +126 -0
  110. package/server/service/data-sensor/index.ts +6 -0
  111. package/server/service/data-set/data-item-type.ts +155 -0
  112. package/server/service/data-set/data-set-mutation.ts +552 -0
  113. package/server/service/data-set/data-set-query.ts +461 -0
  114. package/server/service/data-set/data-set-type.ts +204 -0
  115. package/server/service/data-set/data-set.ts +326 -0
  116. package/server/service/data-set/index.ts +6 -0
  117. package/server/service/data-set-history/data-set-history-query.ts +126 -0
  118. package/server/service/data-set-history/data-set-history-type.ts +12 -0
  119. package/server/service/data-set-history/data-set-history.ts +217 -0
  120. package/server/service/data-set-history/event-subscriber.ts +17 -0
  121. package/server/service/data-set-history/index.ts +7 -0
  122. package/server/service/data-spec/data-spec-manager.ts +21 -0
  123. package/server/service/data-spec/data-spec-query.ts +21 -0
  124. package/server/service/data-spec/data-spec.ts +45 -0
  125. package/server/service/data-spec/index.ts +5 -0
  126. package/server/service/data-summary/data-summary-mutation.ts +45 -0
  127. package/server/service/data-summary/data-summary-query.ts +179 -0
  128. package/server/service/data-summary/data-summary-type.ts +86 -0
  129. package/server/service/data-summary/data-summary.ts +170 -0
  130. package/server/service/data-summary/index.ts +7 -0
  131. package/server/service/index.ts +57 -0
  132. package/server/tsconfig.json +10 -0
  133. package/server/utils/config-resolver.ts +29 -0
  134. package/server/utils/index.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/dataset",
3
- "version": "8.0.0-beta.9",
3
+ "version": "8.0.2",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -27,34 +27,34 @@
27
27
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create ./server/migrations/migration"
28
28
  },
29
29
  "dependencies": {
30
- "@operato/app": "^8.0.0-beta",
31
- "@operato/data-grist": "^8.0.0-beta",
32
- "@operato/dataset": "^8.0.0-beta",
33
- "@operato/ghost-print": "^8.0.0-beta",
34
- "@operato/graphql": "^8.0.0-beta",
35
- "@operato/grist-editor": "^8.0.0-beta",
36
- "@operato/i18n": "^8.0.0-beta",
37
- "@operato/layout": "^8.0.0-beta",
38
- "@operato/moment-timezone-es": "^8.0.0-beta",
39
- "@operato/p13n": "^8.0.0-beta",
40
- "@operato/shell": "^8.0.0-beta",
41
- "@operato/styles": "^8.0.0-beta",
42
- "@operato/utils": "^8.0.0-beta",
43
- "@things-factory/auth-base": "^8.0.0-beta.9",
44
- "@things-factory/aws-base": "^8.0.0-beta.9",
45
- "@things-factory/board-service": "^8.0.0-beta.9",
46
- "@things-factory/env": "^8.0.0-beta.4",
47
- "@things-factory/integration-base": "^8.0.0-beta.9",
48
- "@things-factory/organization": "^8.0.0-beta.9",
49
- "@things-factory/personalization": "^8.0.0-beta.9",
50
- "@things-factory/scheduler-client": "^8.0.0-beta.9",
51
- "@things-factory/shell": "^8.0.0-beta.9",
52
- "@things-factory/work-shift": "^8.0.0-beta.9",
53
- "@things-factory/worklist": "^8.0.0-beta.9",
30
+ "@operato/app": "^8.0.0",
31
+ "@operato/data-grist": "^8.0.0",
32
+ "@operato/dataset": "^8.0.0",
33
+ "@operato/ghost-print": "^8.0.0",
34
+ "@operato/graphql": "^8.0.0",
35
+ "@operato/grist-editor": "^8.0.0",
36
+ "@operato/i18n": "^8.0.0",
37
+ "@operato/layout": "^8.0.0",
38
+ "@operato/moment-timezone-es": "^8.0.0",
39
+ "@operato/p13n": "^8.0.0",
40
+ "@operato/shell": "^8.0.0",
41
+ "@operato/styles": "^8.0.0",
42
+ "@operato/utils": "^8.0.0",
43
+ "@things-factory/auth-base": "^8.0.2",
44
+ "@things-factory/aws-base": "^8.0.2",
45
+ "@things-factory/board-service": "^8.0.2",
46
+ "@things-factory/env": "^8.0.2",
47
+ "@things-factory/integration-base": "^8.0.2",
48
+ "@things-factory/organization": "^8.0.2",
49
+ "@things-factory/personalization": "^8.0.2",
50
+ "@things-factory/scheduler-client": "^8.0.2",
51
+ "@things-factory/shell": "^8.0.2",
52
+ "@things-factory/work-shift": "^8.0.2",
53
+ "@things-factory/worklist": "^8.0.2",
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": "86b1dfa26292926a2d5447fdc23bfa5a9e983245"
59
+ "gitHead": "39d60f56e142561233ddf6d47b539c637971357c"
60
60
  }
@@ -0,0 +1,100 @@
1
+ import { In } from 'typeorm'
2
+
3
+ import { User } from '@things-factory/auth-base'
4
+ import {
5
+ Activity,
6
+ ActivityInstance,
7
+ ActivityInstanceStatus,
8
+ UpdateActivityInstanceStateAddendum
9
+ } from '@things-factory/worklist'
10
+ import { NewDataSample } from 'service/data-sample/data-sample-type'
11
+ import { createDataSample } from '../controllers/create-data-sample'
12
+
13
+ async function callback(
14
+ activityInstance: ActivityInstance,
15
+ addendum: UpdateActivityInstanceStateAddendum,
16
+ context: ResolverContext
17
+ ) {
18
+ const { domain, tx } = context.state
19
+ const { input, output, state } = activityInstance
20
+
21
+ if (state == ActivityInstanceStatus.Ended) {
22
+ const activity = (await tx.getRepository(Activity).findOneBy({
23
+ domain: { id: In([domain.id, domain.parentId].filter(Boolean)) },
24
+ name: 'Collect Data'
25
+ })) as Activity
26
+
27
+ /* collect-data 액티비티는 한명의 assignee(thread)만 수행하는 multiple: false 액티비티이다. 따라서, output에는 assignee key가 없이, 순수한 data만 들어있다. */
28
+ const data = output
29
+
30
+ if (activity) {
31
+ const dataSample: NewDataSample = {
32
+ dataSet: {
33
+ id: input.dataSetId
34
+ },
35
+ data
36
+ }
37
+
38
+ await createDataSample(dataSample, context)
39
+ } else {
40
+ console.error('Collect Data Activity not installed.')
41
+ }
42
+ }
43
+ }
44
+
45
+ export const ActivityDataCollect = {
46
+ name: 'Collect Data',
47
+ description: 'Tasks assigned for data collection',
48
+ release: '1.0.0',
49
+ provider: 'hatiolab.com',
50
+ category: 'quality',
51
+ activityType: 'user',
52
+ priority: 1,
53
+ searchKeys: [
54
+ {
55
+ name: 'dataSetName',
56
+ description: 'DataSet name',
57
+ inputKey: 'dataSetName',
58
+ tKey: 'data-set-name'
59
+ }
60
+ ],
61
+ startingType: '',
62
+ multiple: 'single',
63
+ model: [
64
+ {
65
+ name: 'dataSetId',
66
+ description: 'DataSet Id.',
67
+ tag: 'dataSetId',
68
+ hidden: true,
69
+ mandatory: true,
70
+ inout: 'in',
71
+ type: 'string',
72
+ options: {},
73
+ unit: null,
74
+ quantifier: [1],
75
+ spec: {}
76
+ },
77
+ {
78
+ name: 'dataSetName',
79
+ description: 'DataSet name',
80
+ tag: 'dataSetName',
81
+ hidden: true,
82
+ mandatory: true,
83
+ inout: 'in',
84
+ type: 'string',
85
+ options: {},
86
+ unit: null,
87
+ quantifier: [1],
88
+ spec: {}
89
+ }
90
+ ],
91
+ uiType: 'custom-element',
92
+ uiSource: 'activity-data-collect-edit',
93
+ viewType: 'custom-element',
94
+ viewSource: 'activity-data-collect-view',
95
+ reportType: 'custom-element',
96
+ reportSource: 'activity-data-collect-view',
97
+ thumbnail: '/assets/images/data-collect.png',
98
+ standardTime: 24 * 60 * 60, // seconds
99
+ callback /* Called when there is a change in the lifecycle of a task (activity-instance). */
100
+ }
@@ -0,0 +1,109 @@
1
+ import { ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'
2
+
3
+ import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
4
+ import { DataSample } from '../service/data-sample/data-sample'
5
+ import { createDataOoc } from '../controllers/create-data-ooc'
6
+ import { issueOocResolve } from '../controllers/issue-ooc-resolve'
7
+
8
+ async function callback(
9
+ activityInstance: ActivityInstance,
10
+ addendum: UpdateActivityInstanceStateAddendum,
11
+ context: ResolverContext
12
+ ) {
13
+ const { domain, tx } = context.state
14
+ const { input, output, state } = activityInstance
15
+
16
+ if (state == ActivityInstanceStatus.Ended) {
17
+ const { dataSampleId } = input || {}
18
+
19
+ if (!dataSampleId) {
20
+ throw new Error('Data sample ID is missing in the input.')
21
+ }
22
+
23
+ const dataSample = await tx.getRepository(DataSample).findOne({
24
+ where: { domain: { id: domain.id }, id: dataSampleId },
25
+ relations: ['domain', 'dataSet', 'creator', 'updater']
26
+ })
27
+
28
+ await tx.getRepository(DataSample).save({
29
+ ...dataSample,
30
+ output,
31
+ state: DataOocStatus.REVIEWED
32
+ })
33
+
34
+ const { judgment, instruction } = output
35
+
36
+ if (judgment == 'abnormal') {
37
+ /* Review 결과가 Ooc 조치가 필요하다고 하면, DataOoc를 생성하고, DataOocResolve를 이슈한다. */
38
+ var ooc = await createDataOoc(dataSample, dataSample.dataSet, context)
39
+
40
+ ooc = await tx.getRepository(DataOoc).save({
41
+ ...ooc,
42
+ reviewedAt: activityInstance.terminatedAt,
43
+ reviewer: activityInstance.updater,
44
+ correctiveInstruction: instruction,
45
+ reviewActivityInstance: activityInstance,
46
+ state: DataOocStatus.REVIEWED
47
+ })
48
+
49
+ await issueOocResolve(ooc, dataSample.dataSet, instruction, context)
50
+ }
51
+ }
52
+ }
53
+
54
+ export const ActivityDataReview = {
55
+ name: 'Data Review',
56
+ description: 'Tasks for data review',
57
+ release: '1.0.0',
58
+ provider: 'hatiolab.com',
59
+ category: 'quality',
60
+ activityType: 'user',
61
+ priority: 1,
62
+ searchKeys: [
63
+ {
64
+ name: 'dataSetName',
65
+ description: 'DataSet name',
66
+ inputKey: 'dataSetName',
67
+ tKey: 'data-set-name'
68
+ }
69
+ ],
70
+ startingType: '',
71
+ multiple: 'single',
72
+ model: [
73
+ {
74
+ name: 'dataSetId',
75
+ description: 'DataSet Id.',
76
+ tag: 'dataSetId',
77
+ hidden: true,
78
+ mandatory: true,
79
+ inout: 'in',
80
+ type: 'string',
81
+ options: {},
82
+ unit: null,
83
+ quantifier: [1],
84
+ spec: {}
85
+ },
86
+ {
87
+ name: 'dataSetName',
88
+ description: 'DataSet name',
89
+ tag: 'dataSetName',
90
+ hidden: true,
91
+ mandatory: true,
92
+ inout: 'in',
93
+ type: 'string',
94
+ options: {},
95
+ unit: null,
96
+ quantifier: [1],
97
+ spec: {}
98
+ }
99
+ ],
100
+ uiType: 'custom-element',
101
+ uiSource: 'activity-data-review-edit',
102
+ viewType: 'custom-element',
103
+ viewSource: 'activity-data-review-view',
104
+ reportType: 'custom-element',
105
+ reportSource: 'activity-data-review-view',
106
+ thumbnail: '/assets/images/data-collect.png',
107
+ standardTime: 24 * 60 * 60, // seconds
108
+ callback /* Called when there is a change in the lifecycle of a task (activity-instance). */
109
+ }
@@ -0,0 +1,123 @@
1
+ import {
2
+ ActivityInstance,
3
+ ActivityInstanceStatus,
4
+ ActivityThread,
5
+ ActivityThreadStatus,
6
+ UpdateActivityInstanceStateAddendum
7
+ } from '@things-factory/worklist'
8
+ import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
9
+
10
+ async function callback(
11
+ activityInstance: ActivityInstance,
12
+ addendum: UpdateActivityInstanceStateAddendum,
13
+ context: ResolverContext
14
+ ) {
15
+ const { tx, user, domain } = context.state
16
+ const { id, input, output, state, terminatedAt } = activityInstance
17
+ const { causedBy } = addendum || {}
18
+
19
+ /* Resolve Activity가 완료되면, 해당 data-ooc 엔티티의 correctiveAction, correctorId, correctedAt 을 update한다. */
20
+ if (state == ActivityInstanceStatus.Ended) {
21
+ const activityThreads = await tx.getRepository(ActivityThread).find({
22
+ where: {
23
+ domain: { id: domain.id },
24
+ activityInstance: { id },
25
+ state: ActivityThreadStatus.Ended
26
+ },
27
+ relations: ['assignee']
28
+ })
29
+
30
+ const corrector = activityThreads[0]?.assignee
31
+
32
+ const { dataOocId } = input
33
+ const correctiveAction = output?.action
34
+
35
+ var dataOoc = await tx.getRepository(DataOoc).findOne({
36
+ where: {
37
+ domain: { id: domain.id },
38
+ id: dataOocId
39
+ },
40
+ relations: ['dataSet']
41
+ })
42
+
43
+ /* dataOoc Review 결과를 dataOoc 엔티티에 반영한다. */
44
+ dataOoc = await tx.getRepository(DataOoc).save({
45
+ ...dataOoc,
46
+ correctedAt: terminatedAt,
47
+ corrector: corrector,
48
+ correctiveAction,
49
+ updater: user,
50
+ state: DataOocStatus.CORRECTED
51
+ })
52
+ }
53
+ }
54
+
55
+ export const ActivityOocResolve = {
56
+ name: 'OOC Resolve',
57
+ description: 'Task to take remedial action based on Out Of Control data',
58
+ release: '1.0.0',
59
+ provider: 'hatiolab.com',
60
+ category: 'quality',
61
+ activityType: 'user',
62
+ priority: 3,
63
+ searchKeys: [
64
+ {
65
+ name: 'dataOocId',
66
+ description: 'OOC Id.',
67
+ inputKey: 'dataOocId',
68
+ tKey: 'data-ooc-id'
69
+ }
70
+ ],
71
+ startingType: '',
72
+ multiple: 'single',
73
+ model: [
74
+ {
75
+ name: 'dataOocId',
76
+ description: 'OOC id',
77
+ tag: 'dataOocId',
78
+ hidden: true,
79
+ mandatory: true,
80
+ inout: 'in',
81
+ type: 'string',
82
+ options: {},
83
+ unit: null,
84
+ quantifier: [1],
85
+ spec: {}
86
+ },
87
+ {
88
+ name: 'instruction',
89
+ description: 'Instructions for resolving OOC',
90
+ tag: 'instruction',
91
+ hidden: false,
92
+ mandatory: true,
93
+ inout: 'in',
94
+ type: 'textarea',
95
+ options: {},
96
+ unit: null,
97
+ quantifier: [1],
98
+ spec: {}
99
+ },
100
+ {
101
+ name: 'action',
102
+ description: 'Action Description',
103
+ tag: 'action',
104
+ hidden: false,
105
+ mandatory: true,
106
+ inout: 'out',
107
+ type: 'textarea',
108
+ options: {},
109
+ unit: null,
110
+ quantifier: [1],
111
+ spec: {}
112
+ }
113
+ ],
114
+ uiType: 'custom-element',
115
+ uiSource: 'activity-ooc-resolve-edit',
116
+ viewType: 'custom-element',
117
+ viewSource: 'activity-ooc-resolve-view',
118
+ reportType: 'custom-element',
119
+ reportSource: 'data-ooc-report-page',
120
+ thumbnail: '/assets/images/ooc.png',
121
+ standardTime: 24 * 60 * 60, // seconds
122
+ callback /* Called when there is a change in the lifecycle of a task (activity-instance). */
123
+ }
@@ -0,0 +1,95 @@
1
+ import { ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'
2
+
3
+ import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
4
+ import { issueOocResolve } from '../controllers/issue-ooc-resolve'
5
+
6
+ async function callback(
7
+ activityInstance: ActivityInstance,
8
+ addendum: UpdateActivityInstanceStateAddendum,
9
+ context: ResolverContext
10
+ ) {
11
+ const { domain, user, tx } = context.state
12
+ const { input, output, state, terminatedAt } = activityInstance
13
+ const { causedBy } = addendum || {}
14
+
15
+ if (state == ActivityInstanceStatus.Ended) {
16
+ const { dataOocId } = input
17
+ const correctiveInstruction = output?.instruction
18
+
19
+ var dataOoc = await tx.getRepository(DataOoc).findOne({
20
+ where: {
21
+ domain: { id: domain.id },
22
+ id: dataOocId
23
+ },
24
+ relations: ['dataSet']
25
+ })
26
+
27
+ /* dataOoc Review 결과를 dataOoc 엔티티에 반영한다. */
28
+ dataOoc = await tx.getRepository(DataOoc).save({
29
+ ...dataOoc,
30
+ reviewedAt: terminatedAt,
31
+ reviewer: user,
32
+ correctiveInstruction,
33
+ state: DataOocStatus.REVIEWED
34
+ })
35
+
36
+ await issueOocResolve(dataOoc, dataOoc.dataSet, correctiveInstruction, context)
37
+ }
38
+ }
39
+
40
+ export const ActivityOocReview = {
41
+ name: 'OOC Review',
42
+ description: 'Task to take remedial action based on Out Of Control data',
43
+ release: '1.0.0',
44
+ provider: 'hatiolab.com',
45
+ category: 'quality',
46
+ activityType: 'user',
47
+ priority: 2,
48
+ searchKeys: [
49
+ {
50
+ name: 'dataOocId',
51
+ description: 'OOC Id.',
52
+ inputKey: 'dataOocId',
53
+ tKey: 'data-ooc-id'
54
+ }
55
+ ],
56
+ startingType: '',
57
+ multiple: 'single',
58
+ model: [
59
+ {
60
+ name: 'dataOocId',
61
+ description: 'OOC id',
62
+ tag: 'dataOocId',
63
+ hidden: true,
64
+ mandatory: true,
65
+ inout: 'in',
66
+ type: 'string',
67
+ options: {},
68
+ unit: null,
69
+ quantifier: [1],
70
+ spec: {}
71
+ },
72
+ {
73
+ name: 'Instruction',
74
+ description: 'Instructions for preventing OOC',
75
+ tag: 'instruction',
76
+ hidden: false,
77
+ mandatory: true,
78
+ inout: 'out',
79
+ type: 'textarea',
80
+ options: {},
81
+ unit: null,
82
+ quantifier: [1],
83
+ spec: {}
84
+ }
85
+ ],
86
+ uiType: 'custom-element',
87
+ uiSource: 'activity-ooc-review-edit',
88
+ viewType: 'custom-element',
89
+ viewSource: 'activity-ooc-review-view',
90
+ reportType: 'custom-element',
91
+ reportSource: 'data-ooc-report-page',
92
+ thumbnail: '/assets/images/ooc.png',
93
+ standardTime: 24 * 60 * 60, // seconds
94
+ callback /* Called when there is a change in the lifecycle of a task (activity-instance). */
95
+ }
@@ -0,0 +1,11 @@
1
+ import { ActivityInstallations } from '@things-factory/worklist'
2
+
3
+ import { ActivityDataCollect } from './activity-data-collect'
4
+ import { ActivityDataReview } from './activity-data-review'
5
+ import { ActivityOocResolve } from './activity-ooc-resolve'
6
+ import { ActivityOocReview } from './activity-ooc-review'
7
+
8
+ /* activity templates installation */
9
+ ;[ActivityOocReview, ActivityOocResolve, ActivityDataCollect, ActivityDataReview].forEach(template => {
10
+ ActivityInstallations.installActivityTemplate(template as any)
11
+ })
@@ -0,0 +1,80 @@
1
+ import { In } from 'typeorm'
2
+
3
+ import { Scenario } from '@things-factory/integration-base'
4
+
5
+ import { DataSet } from '../service/data-set/data-set'
6
+ import { DataSample } from '../service/data-sample/data-sample'
7
+ import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
8
+
9
+ export async function createDataOoc(
10
+ dataSample: DataSample,
11
+ dataSet: DataSet,
12
+ context: ResolverContext
13
+ ): Promise<DataOoc> {
14
+ const { domain, user, tx } = context.state
15
+ const { collectedAt, data, ooc, oos, judgment, workDate, workShift } = dataSample
16
+
17
+ const dataOoc = await tx.getRepository(DataOoc).save({
18
+ ...dataSample,
19
+ history: [
20
+ {
21
+ user: {
22
+ id: user?.id,
23
+ // @ts-ignore
24
+ username: user?.username || user?.email,
25
+ name: user?.name
26
+ },
27
+ state: DataOocStatus.ISSUED,
28
+ timestamp: collectedAt
29
+ }
30
+ ],
31
+ state: DataOocStatus.ISSUED,
32
+ dataSample: dataSample
33
+ })
34
+
35
+ if (dataSet.outlierScenarioId) {
36
+ const scenario = await tx.getRepository(Scenario).findOne({
37
+ where: {
38
+ domain: domain.parentId ? { id: In([domain.id, domain.parentId]) } : { id: domain.id },
39
+ id: dataSet.outlierScenarioId
40
+ },
41
+ relations: ['domain', 'steps', 'updater']
42
+ })
43
+
44
+ if (scenario) {
45
+ scenario.start({
46
+ instanceName: scenario.name + ':' + dataSet.name + ':' + dataSample.id,
47
+ domain,
48
+ user,
49
+ variables: {
50
+ dataOocId: dataOoc.id,
51
+ dataSampleId: dataSample.id,
52
+ dataSet: dataSet.id,
53
+ data,
54
+ ooc,
55
+ oos,
56
+ judgment,
57
+ collectedAt,
58
+ workDate,
59
+ workShift,
60
+ domain: {
61
+ id: domain.id,
62
+ subdomain: domain.subdomain,
63
+ name: domain.name
64
+ },
65
+ updator: {
66
+ id: user.id,
67
+ // @ts-ignore
68
+ username: user.username || user.email,
69
+ email: user.email,
70
+ name: user.name
71
+ }
72
+ }
73
+ })
74
+ } else {
75
+ console.error(`Cannot find the set outlier-scenario for the dataset(${dataSet.name}).`)
76
+ }
77
+ }
78
+
79
+ return dataOoc
80
+ }