@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.
- package/client/activities/activity-data-collect-edit.ts +105 -0
- package/client/activities/activity-data-collect-view.ts +91 -0
- package/client/activities/activity-data-review-edit.ts +278 -0
- package/client/activities/activity-data-review-view.ts +226 -0
- package/client/activities/activity-ooc-resolve-edit.ts +195 -0
- package/client/activities/activity-ooc-resolve-view.ts +143 -0
- package/client/activities/activity-ooc-review-edit.ts +173 -0
- package/client/activities/activity-ooc-review-view.ts +129 -0
- package/client/bootstrap.ts +35 -0
- package/client/components/data-entry-form.ts +109 -0
- package/client/index.ts +1 -0
- package/client/pages/data-archive/data-archive-list-page.ts +277 -0
- package/client/pages/data-archive/data-archive-request-popup.ts +177 -0
- package/client/pages/data-entry/data-entry-list-page.ts +464 -0
- package/client/pages/data-key-set/data-key-item-list.ts +183 -0
- package/client/pages/data-key-set/data-key-set-importer.ts +89 -0
- package/client/pages/data-key-set/data-key-set-list-page.ts +413 -0
- package/client/pages/data-ooc/data-ooc-list-page.ts +549 -0
- package/client/pages/data-ooc/data-ooc-page.ts +164 -0
- package/client/pages/data-ooc/data-ooc-view.ts +236 -0
- package/client/pages/data-ooc/data-oocs-page.ts +200 -0
- package/client/pages/data-report/data-report-embed-page.ts +108 -0
- package/client/pages/data-report/data-report-list-page.ts +454 -0
- package/client/pages/data-report/data-report-samples-page.ts +174 -0
- package/client/pages/data-report/jasper-report-oocs-page.ts +110 -0
- package/client/pages/data-report/jasper-report-samples-crosstab-page.ts +110 -0
- package/client/pages/data-report/jasper-report-samples-page.ts +110 -0
- package/client/pages/data-sample/data-sample-list-page.ts +442 -0
- package/client/pages/data-sample/data-sample-page.ts +55 -0
- package/client/pages/data-sample/data-sample-search-page.ts +424 -0
- package/client/pages/data-sample/data-sample-view.ts +292 -0
- package/client/pages/data-sample/data-samples-page.ts +249 -0
- package/client/pages/data-sensor/data-sensor-list-page.ts +456 -0
- package/client/pages/data-set/data-item-list.ts +304 -0
- package/client/pages/data-set/data-set-importer.ts +89 -0
- package/client/pages/data-set/data-set-list-page.ts +1078 -0
- package/client/pages/data-summary/data-summary-list-page.ts +363 -0
- package/client/pages/data-summary/data-summary-period-page.ts +439 -0
- package/client/pages/data-summary/data-summary-search-page.ts +426 -0
- package/client/pages/data-summary/data-summary-view.ts +133 -0
- package/client/route.ts +91 -0
- package/client/tsconfig.json +13 -0
- package/dist-client/activities/activity-data-review-edit.js +19 -10
- package/dist-client/activities/activity-data-review-edit.js.map +1 -1
- package/dist-client/activities/activity-data-review-view.js +80 -0
- package/dist-client/activities/activity-data-review-view.js.map +1 -1
- package/dist-client/pages/data-entry/data-entry-list-page.js +2 -2
- package/dist-client/pages/data-entry/data-entry-list-page.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/create-data-ooc.js +2 -0
- package/dist-server/controllers/create-data-ooc.js.map +1 -1
- package/dist-server/service/data-archive/index.d.ts +1 -1
- package/dist-server/service/data-ooc/index.d.ts +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-sample/index.d.ts +1 -1
- package/dist-server/service/data-set/index.d.ts +1 -1
- package/dist-server/service/index.d.ts +2 -2
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -26
- package/server/activities/activity-data-collect.ts +100 -0
- package/server/activities/activity-data-review.ts +109 -0
- package/server/activities/activity-ooc-resolve.ts +123 -0
- package/server/activities/activity-ooc-review.ts +95 -0
- package/server/activities/index.ts +11 -0
- package/server/controllers/create-data-ooc.ts +80 -0
- package/server/controllers/create-data-sample.ts +323 -0
- package/server/controllers/data-use-case.ts +98 -0
- package/server/controllers/finalize-data-collection.ts +388 -0
- package/server/controllers/index.ts +6 -0
- package/server/controllers/issue-data-collection-task.ts +70 -0
- package/server/controllers/issue-ooc-resolve.ts +58 -0
- package/server/controllers/issue-ooc-review.ts +52 -0
- package/server/controllers/jasper-report.ts +186 -0
- package/server/controllers/query-data-summary-by-period.ts +178 -0
- package/server/controllers/shiny-report.ts +54 -0
- package/server/engine/index.ts +1 -0
- package/server/engine/task/create-data-sample.ts +100 -0
- package/server/engine/task/index.ts +2 -0
- package/server/engine/task/issue-collect-data.ts +45 -0
- package/server/index.ts +8 -0
- package/server/routes.ts +188 -0
- package/server/service/data-archive/data-archive-mutation.ts +273 -0
- package/server/service/data-archive/data-archive-query.ts +58 -0
- package/server/service/data-archive/data-archive-type.ts +48 -0
- package/server/service/data-archive/data-archive.ts +69 -0
- package/server/service/data-archive/index.ts +6 -0
- package/server/service/data-key-set/data-key-item-type.ts +31 -0
- package/server/service/data-key-set/data-key-set-mutation.ts +201 -0
- package/server/service/data-key-set/data-key-set-query.ts +68 -0
- package/server/service/data-key-set/data-key-set-type.ts +70 -0
- package/server/service/data-key-set/data-key-set.ts +86 -0
- package/server/service/data-key-set/index.ts +6 -0
- package/server/service/data-ooc/data-ooc-mutation.ts +154 -0
- package/server/service/data-ooc/data-ooc-query.ts +106 -0
- package/server/service/data-ooc/data-ooc-subscription.ts +48 -0
- package/server/service/data-ooc/data-ooc-type.ts +71 -0
- package/server/service/data-ooc/data-ooc.ts +259 -0
- package/server/service/data-ooc/index.ts +7 -0
- package/server/service/data-sample/data-sample-mutation.ts +18 -0
- package/server/service/data-sample/data-sample-query.ts +215 -0
- package/server/service/data-sample/data-sample-type.ts +47 -0
- package/server/service/data-sample/data-sample.ts +193 -0
- package/server/service/data-sample/index.ts +6 -0
- package/server/service/data-sensor/data-sensor-mutation.ts +116 -0
- package/server/service/data-sensor/data-sensor-query.ts +76 -0
- package/server/service/data-sensor/data-sensor-type.ts +104 -0
- package/server/service/data-sensor/data-sensor.ts +126 -0
- package/server/service/data-sensor/index.ts +6 -0
- package/server/service/data-set/data-item-type.ts +155 -0
- package/server/service/data-set/data-set-mutation.ts +552 -0
- package/server/service/data-set/data-set-query.ts +461 -0
- package/server/service/data-set/data-set-type.ts +204 -0
- package/server/service/data-set/data-set.ts +326 -0
- package/server/service/data-set/index.ts +6 -0
- package/server/service/data-set-history/data-set-history-query.ts +126 -0
- package/server/service/data-set-history/data-set-history-type.ts +12 -0
- package/server/service/data-set-history/data-set-history.ts +217 -0
- package/server/service/data-set-history/event-subscriber.ts +17 -0
- package/server/service/data-set-history/index.ts +7 -0
- package/server/service/data-spec/data-spec-manager.ts +21 -0
- package/server/service/data-spec/data-spec-query.ts +21 -0
- package/server/service/data-spec/data-spec.ts +45 -0
- package/server/service/data-spec/index.ts +5 -0
- package/server/service/data-summary/data-summary-mutation.ts +45 -0
- package/server/service/data-summary/data-summary-query.ts +179 -0
- package/server/service/data-summary/data-summary-type.ts +86 -0
- package/server/service/data-summary/data-summary.ts +170 -0
- package/server/service/data-summary/index.ts +7 -0
- package/server/service/index.ts +57 -0
- package/server/tsconfig.json +10 -0
- package/server/utils/config-resolver.ts +29 -0
- 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.
|
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
|
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.
|
44
|
-
"@things-factory/aws-base": "^8.0.
|
45
|
-
"@things-factory/board-service": "^8.0.
|
46
|
-
"@things-factory/env": "^8.0.
|
47
|
-
"@things-factory/integration-base": "^8.0.
|
48
|
-
"@things-factory/organization": "^8.0.
|
49
|
-
"@things-factory/personalization": "^8.0.
|
50
|
-
"@things-factory/scheduler-client": "^8.0.
|
51
|
-
"@things-factory/shell": "^8.0.
|
52
|
-
"@things-factory/work-shift": "^8.0.
|
53
|
-
"@things-factory/worklist": "^8.0.
|
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": "
|
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
|
+
}
|