@things-factory/dataset 6.0.27 → 6.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/assets/images/data-collect.png +0 -0
  2. package/client/activities/activity-data-collect-view.ts +100 -0
  3. package/client/activities/activity-ooc-resolve-view.ts +174 -0
  4. package/client/{components/data-ooc-activity-view.ts → activities/activity-ooc-review-view.ts} +16 -16
  5. package/client/bootstrap.ts +4 -2
  6. package/client/pages/data-ooc/data-ooc-list-page.ts +6 -0
  7. package/client/pages/data-ooc/data-ooc-view-page.ts +115 -0
  8. package/client/pages/data-ooc/data-ooc-view.ts +7 -61
  9. package/client/pages/data-set/data-set-list-page.ts +111 -4
  10. package/client/route.ts +4 -0
  11. package/config/config.development.js +30 -30
  12. package/config/config.production.js +31 -31
  13. package/dist-client/activities/activity-data-collect-view.d.ts +19 -0
  14. package/dist-client/activities/activity-data-collect-view.js +101 -0
  15. package/dist-client/activities/activity-data-collect-view.js.map +1 -0
  16. package/dist-client/activities/activity-ooc-resolve-view.d.ts +1 -0
  17. package/dist-client/activities/activity-ooc-resolve-view.js +175 -0
  18. package/dist-client/activities/activity-ooc-resolve-view.js.map +1 -0
  19. package/dist-client/activities/activity-ooc-review-view.d.ts +1 -0
  20. package/dist-client/activities/activity-ooc-review-view.js +155 -0
  21. package/dist-client/activities/activity-ooc-review-view.js.map +1 -0
  22. package/dist-client/bootstrap.d.ts +3 -1
  23. package/dist-client/bootstrap.js +4 -2
  24. package/dist-client/bootstrap.js.map +1 -1
  25. package/dist-client/components/data-collect-activity-view.d.ts +19 -0
  26. package/dist-client/components/data-collect-activity-view.js +101 -0
  27. package/dist-client/components/data-collect-activity-view.js.map +1 -0
  28. package/dist-client/components/ooc-resolve-activity-view.d.ts +1 -0
  29. package/dist-client/components/ooc-resolve-activity-view.js +175 -0
  30. package/dist-client/components/ooc-resolve-activity-view.js.map +1 -0
  31. package/dist-client/components/ooc-review-activity-view.d.ts +1 -0
  32. package/dist-client/components/ooc-review-activity-view.js +155 -0
  33. package/dist-client/components/ooc-review-activity-view.js.map +1 -0
  34. package/dist-client/pages/data-ooc/data-ooc-list-page.js +6 -0
  35. package/dist-client/pages/data-ooc/data-ooc-list-page.js.map +1 -1
  36. package/dist-client/pages/data-ooc/data-ooc-view-page.d.ts +18 -0
  37. package/dist-client/pages/data-ooc/data-ooc-view-page.js +114 -0
  38. package/dist-client/pages/data-ooc/data-ooc-view-page.js.map +1 -0
  39. package/dist-client/pages/data-ooc/data-ooc-view.d.ts +15 -1
  40. package/dist-client/pages/data-ooc/data-ooc-view.js +9 -58
  41. package/dist-client/pages/data-ooc/data-ooc-view.js.map +1 -1
  42. package/dist-client/pages/data-set/data-set-list-page.d.ts +2 -0
  43. package/dist-client/pages/data-set/data-set-list-page.js +106 -4
  44. package/dist-client/pages/data-set/data-set-list-page.js.map +1 -1
  45. package/dist-client/route.js +3 -0
  46. package/dist-client/route.js.map +1 -1
  47. package/dist-client/tsconfig.tsbuildinfo +1 -1
  48. package/dist-server/activities/activity-data-collect.js +82 -0
  49. package/dist-server/activities/activity-data-collect.js.map +1 -0
  50. package/dist-server/activities/activity-ooc-resolve.js +100 -0
  51. package/dist-server/activities/activity-ooc-resolve.js.map +1 -0
  52. package/dist-server/activities/activity-ooc-review.js +107 -0
  53. package/dist-server/activities/activity-ooc-review.js.map +1 -0
  54. package/dist-server/activities/index.js +10 -0
  55. package/dist-server/activities/index.js.map +1 -0
  56. package/dist-server/controllers/activity-template/activity-data-collect.js +82 -0
  57. package/dist-server/controllers/activity-template/activity-data-collect.js.map +1 -0
  58. package/dist-server/controllers/activity-template/activity-ooc-resolve.js +100 -0
  59. package/dist-server/controllers/activity-template/activity-ooc-resolve.js.map +1 -0
  60. package/dist-server/controllers/activity-template/activity-ooc-review.js +107 -0
  61. package/dist-server/controllers/activity-template/activity-ooc-review.js.map +1 -0
  62. package/dist-server/controllers/create-data-sample.js +44 -42
  63. package/dist-server/controllers/create-data-sample.js.map +1 -1
  64. package/dist-server/controllers/data-use-case.js +1 -1
  65. package/dist-server/controllers/data-use-case.js.map +1 -1
  66. package/dist-server/controllers/index.js +0 -5
  67. package/dist-server/controllers/index.js.map +1 -1
  68. package/dist-server/index.js +1 -1
  69. package/dist-server/index.js.map +1 -1
  70. package/dist-server/routes.js +45 -1
  71. package/dist-server/routes.js.map +1 -1
  72. package/dist-server/service/data-ooc/data-ooc-query.js +22 -2
  73. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -1
  74. package/dist-server/service/data-ooc/data-ooc.js +26 -0
  75. package/dist-server/service/data-ooc/data-ooc.js.map +1 -1
  76. package/dist-server/service/data-set/data-set-mutation.js +86 -0
  77. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  78. package/dist-server/service/data-set/data-set-query.js +33 -0
  79. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  80. package/dist-server/service/data-set/data-set-type.js +16 -0
  81. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  82. package/dist-server/service/data-set/data-set.js +52 -3
  83. package/dist-server/service/data-set/data-set.js.map +1 -1
  84. package/dist-server/tsconfig.tsbuildinfo +1 -1
  85. package/helps/dataset/data-ooc.md +5 -4
  86. package/package.json +10 -8
  87. package/server/activities/activity-data-collect.ts +84 -0
  88. package/server/activities/activity-ooc-resolve.ts +114 -0
  89. package/server/activities/activity-ooc-review.ts +118 -0
  90. package/server/activities/index.ts +10 -0
  91. package/server/controllers/create-data-sample.ts +48 -53
  92. package/server/controllers/data-use-case.ts +1 -1
  93. package/server/controllers/index.ts +0 -9
  94. package/server/index.ts +1 -1
  95. package/server/routes.ts +61 -2
  96. package/server/service/data-ooc/data-ooc-query.ts +12 -2
  97. package/server/service/data-ooc/data-ooc.ts +23 -0
  98. package/server/service/data-set/data-set-mutation.ts +97 -0
  99. package/server/service/data-set/data-set-query.ts +34 -1
  100. package/server/service/data-set/data-set-type.ts +14 -0
  101. package/server/service/data-set/data-set.ts +40 -2
  102. package/things-factory.config.js +4 -0
  103. package/translations/en.json +2 -0
  104. package/translations/ko.json +2 -0
  105. package/translations/ms.json +2 -0
  106. package/translations/zh.json +2 -0
  107. package/server/controllers/activity-template/activity-ooc.ts +0 -55
@@ -85,6 +85,18 @@ export class DataOoc {
85
85
  @Field({ nullable: true })
86
86
  state?: DataOocStatus
87
87
 
88
+ @Column({
89
+ nullable: true,
90
+ type:
91
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
92
+ ? 'longtext'
93
+ : DATABASE_TYPE == 'oracle'
94
+ ? 'clob'
95
+ : 'varchar'
96
+ })
97
+ @Field({ nullable: true })
98
+ correctiveInstruction?: string
99
+
88
100
  @Column({
89
101
  nullable: true,
90
102
  type:
@@ -178,6 +190,10 @@ export class DataOoc {
178
190
  @Field({ nullable: true })
179
191
  collectedAt?: Date
180
192
 
193
+ @Column({ nullable: true })
194
+ @Field({ nullable: true })
195
+ reviewedAt?: Date
196
+
181
197
  @Column({ nullable: true })
182
198
  @Field({ nullable: true })
183
199
  correctedAt?: Date
@@ -190,6 +206,13 @@ export class DataOoc {
190
206
  @Field({ nullable: true })
191
207
  updatedAt?: Date
192
208
 
209
+ @ManyToOne(type => User, { nullable: true })
210
+ @Field({ nullable: true })
211
+ reviewer?: User
212
+
213
+ @RelationId((dataOoc: DataOoc) => dataOoc.reviewer)
214
+ reviewerId?: string
215
+
193
216
  @ManyToOne(type => User, { nullable: true })
194
217
  @Field({ nullable: true })
195
218
  corrector?: User
@@ -2,6 +2,7 @@ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
2
  import { In } from 'typeorm'
3
3
 
4
4
  import { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'
5
+ import { registerSchedule, unregisterSchedule } from '@things-factory/scheduler-client'
5
6
 
6
7
  import { DataSet } from './data-set'
7
8
  import { DataSetPatch, NewDataSet } from './data-set-type'
@@ -129,6 +130,7 @@ export class DataSetMutation {
129
130
 
130
131
  await tx.getRepository(DataSet).delete({ domain: { id: domain.id }, id })
131
132
  await deleteAttachmentsByRef(null, { refBys: [`report-${id}`] }, context)
133
+
132
134
  return true
133
135
  }
134
136
 
@@ -148,6 +150,101 @@ export class DataSetMutation {
148
150
  return true
149
151
  }
150
152
 
153
+ @Directive('@transaction')
154
+ @Mutation(returns => DataSet, { description: 'To start data collection schedule for the given dataset' })
155
+ async startDataCollectionSchedule(
156
+ @Arg('dataSetId') dataSetId: string,
157
+ @Ctx() context: ResolverContext
158
+ ): Promise<DataSet> {
159
+ const { domain, tx } = context.state
160
+
161
+ var repository = tx.getRepository(DataSet)
162
+ var dataSet = await repository.findOne({
163
+ where: { domain: { id: domain.id }, id: dataSetId }
164
+ })
165
+
166
+ if (!dataSet) {
167
+ throw new Error(
168
+ context.t('error.data-set not found', {
169
+ dataSet: dataSetId
170
+ })
171
+ )
172
+ }
173
+
174
+ try {
175
+ var handle = await registerSchedule({
176
+ name: dataSet.name,
177
+ client: {
178
+ application: 'operato-dataset',
179
+ group: `${domain.id}`,
180
+ key: dataSet.id
181
+ },
182
+ type: 'cron',
183
+ schedule: dataSet.schedule,
184
+ task: {
185
+ type: 'rest',
186
+ connection: {
187
+ host: 'http://localhost:3000/callback-schedule-for-dataset',
188
+ headers: {
189
+ 'Content-Type': 'application/json',
190
+ accept: '*/*'
191
+ }
192
+ },
193
+ data: {
194
+ application: 'dataset',
195
+ id: dataSet.id
196
+ },
197
+ history_check: true,
198
+ failed_policy: 'retry_dlq',
199
+ max_retry_count: 3
200
+ }
201
+ })
202
+
203
+ return await repository.save({
204
+ ...dataSet,
205
+ schedulerHandle: handle
206
+ })
207
+ } catch (err) {
208
+ console.error('stopDataCollectionSchedule', err)
209
+ }
210
+ }
211
+
212
+ @Directive('@transaction')
213
+ @Mutation(returns => DataSet, {
214
+ nullable: true,
215
+ description: 'To stop data collection schedule for the given dataset'
216
+ })
217
+ async stopDataCollectionSchedule(
218
+ @Arg('dataSetId') dataSetId: string,
219
+ @Ctx() context: ResolverContext
220
+ ): Promise<DataSet | undefined> {
221
+ const { domain, tx } = context.state
222
+
223
+ var repository = tx.getRepository(DataSet)
224
+ var dataSet = await repository.findOne({
225
+ where: { domain: { id: domain.id }, id: dataSetId }
226
+ })
227
+
228
+ if (!dataSet) {
229
+ throw new Error(
230
+ context.t('error.data-set not found', {
231
+ dataSet: dataSetId
232
+ })
233
+ )
234
+ }
235
+
236
+ try {
237
+ await unregisterSchedule(dataSet.schedulerHandle)
238
+
239
+ return await repository.save({
240
+ ...dataSet,
241
+ schedulerHandle: null
242
+ })
243
+ } catch (err) {
244
+ console.error('stopDataCollectionSchedule', err)
245
+ }
246
+ }
247
+
151
248
  @Directive('@privilege(category: "data-set", privilege: "mutation", domainOwnerGranted: true)')
152
249
  @Directive('@transaction')
153
250
  @Mutation(returns => Boolean, { description: 'To import multiple data-sets' })
@@ -8,7 +8,7 @@ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from
8
8
  import { DataKeySet } from '../data-key-set/data-key-set'
9
9
  import { DataSample } from '../data-sample/data-sample'
10
10
  import { DataItem } from './data-item-type'
11
- import { DataSet } from './data-set'
11
+ import { DataSet, DataSetState } from './data-set'
12
12
  import { DataSetList } from './data-set-type'
13
13
 
14
14
  var parser = require('cron-parser')
@@ -43,6 +43,27 @@ export class DataSetQuery {
43
43
  return { items, total }
44
44
  }
45
45
 
46
+ // @Directive('@privilege(category: "data-set", privilege: "query", domainOwnerGranted: true)')
47
+ // @Query(returns => DataSetStateList, { description: 'To fetch multiple status of DataSets' })
48
+ // async dataSetsStatus(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<DataSetStateList> {
49
+ // const { domain } = context.state
50
+
51
+ // // scheduler server에 group내 schedule list를 조회한다.
52
+ // const queryBuilder = getQueryBuilderFromListParams({
53
+ // repository: getRepository(DataSet),
54
+ // params,
55
+ // domain,
56
+ // alias: 'dataset',
57
+ // searchables: ['name', 'description', 'supervisoryRole']
58
+ // })
59
+
60
+ // const [items, total] = await queryBuilder.getManyAndCount()
61
+
62
+ // return { items: [{
63
+
64
+ // }], total }
65
+ // }
66
+
46
67
  @Query(returns => DataSetList, { description: 'To fetch multiple DataSets for data entry manually' })
47
68
  async dataSetsForEntry(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<DataSetList> {
48
69
  var { domain, user } = context.state
@@ -101,6 +122,18 @@ export class DataSetQuery {
101
122
  return { items, total }
102
123
  }
103
124
 
125
+ @FieldResolver(type => DataSetState)
126
+ async status(@Root() dataSet: DataSet): Promise<DataSetState> {
127
+ // get information from scheduler service
128
+ return {
129
+ id: '',
130
+ schedulerHandle: '',
131
+ state: '',
132
+ startedAt: new Date(),
133
+ nextSchedule: new Date()
134
+ }
135
+ }
136
+
104
137
  @FieldResolver(type => [DataItem])
105
138
  async dataItems(@Root() dataSet: DataSet): Promise<DataItem[]> {
106
139
  if (dataSet.dataItems instanceof Array) {
@@ -3,6 +3,8 @@ import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
3
3
  import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
4
4
 
5
5
  import { ObjectRef, ScalarObject } from '@things-factory/shell'
6
+ import { ApprovalLineItem } from '@things-factory/organization'
7
+ import { AssigneeItem } from '@things-factory/worklist'
6
8
 
7
9
  import { DataItemPatch } from './data-item-type'
8
10
  import { DataSet, DataSetEntryType, DataSetMonitorType, DataSetReportType } from './data-set'
@@ -24,6 +26,12 @@ export class NewDataSet {
24
26
  @Field(type => ObjectRef, { nullable: true })
25
27
  supervisoryRole?: ObjectRef
26
28
 
29
+ @Field(type => ScalarObject, { nullable: true })
30
+ assignees?: AssigneeItem[]
31
+
32
+ @Field(type => ScalarObject, { nullable: true })
33
+ approvalLine?: ApprovalLineItem[]
34
+
27
35
  @Field({ nullable: true })
28
36
  active?: boolean
29
37
 
@@ -87,6 +95,12 @@ export class DataSetPatch {
87
95
  @Field(type => ObjectRef, { nullable: true })
88
96
  entryRole?: ObjectRef
89
97
 
98
+ @Field(type => ScalarObject, { nullable: true })
99
+ assignees?: AssigneeItem[]
100
+
101
+ @Field(type => ScalarObject, { nullable: true })
102
+ approvalLine?: ApprovalLineItem[]
103
+
90
104
  @Field({ nullable: true })
91
105
  active?: boolean
92
106
 
@@ -13,6 +13,8 @@ import {
13
13
 
14
14
  import { Role, User } from '@things-factory/auth-base'
15
15
  import { Domain, ScalarObject } from '@things-factory/shell'
16
+ import { ApprovalLineItem } from '@things-factory/organization'
17
+ import { AssigneeItem } from '@things-factory/worklist'
16
18
 
17
19
  import { DataKeySet } from '../data-key-set/data-key-set'
18
20
  import { DataItem } from './data-item-type'
@@ -58,6 +60,24 @@ registerEnumType(DataSetReportType, {
58
60
  description: 'report type enumeration for data-set'
59
61
  })
60
62
 
63
+ @ObjectType()
64
+ export class DataSetState {
65
+ @Field()
66
+ id: string
67
+
68
+ @Field()
69
+ schedulerHandle: string
70
+
71
+ @Field()
72
+ state: string
73
+
74
+ @Field()
75
+ startedAt: Date
76
+
77
+ @Field()
78
+ nextSchedule: Date
79
+ }
80
+
61
81
  @Entity()
62
82
  @Index('ix_data_set_0', (dataSet: DataSet) => [dataSet.domain, dataSet.name], { unique: true })
63
83
  @ObjectType({ description: 'Entity for DataSet' })
@@ -97,19 +117,33 @@ export class DataSet {
97
117
  dataKeySetId?: string
98
118
 
99
119
  @ManyToOne(type => Role, { nullable: true })
100
- @Field(type => Role, { nullable: true })
120
+ @Field(type => Role, {
121
+ nullable: true,
122
+ description: 'The person responsible for manually entering the data for that dataset'
123
+ })
101
124
  entryRole?: Role
102
125
 
103
126
  @RelationId((dataSet: DataSet) => dataSet.entryRole)
104
127
  entryRoleId?: string
105
128
 
106
129
  @ManyToOne(type => Role, { nullable: true })
107
- @Field(type => Role, { nullable: true })
130
+ @Field(type => Role, { nullable: true, description: 'The final authority on issues related to that dataset.' })
108
131
  supervisoryRole?: Role
109
132
 
110
133
  @RelationId((dataSet: DataSet) => dataSet.supervisoryRole)
111
134
  supervisoryRoleId?: string
112
135
 
136
+ @Column('simple-json', { nullable: true })
137
+ @Field(type => [AssigneeItem], { nullable: true, description: 'Who to contact for OOC issues' })
138
+ assignees?: AssigneeItem[]
139
+
140
+ @Column('simple-json', { nullable: true })
141
+ @Field(type => [ApprovalLineItem], {
142
+ nullable: true,
143
+ description: 'Approval line for handling OOC issues for that dataset'
144
+ })
145
+ approvalLine?: ApprovalLineItem[]
146
+
113
147
  @Column({ nullable: true })
114
148
  @Field({ nullable: true })
115
149
  type?: 'manual' | 'automatic' | string
@@ -161,6 +195,10 @@ export class DataSet {
161
195
  @Field({ nullable: true })
162
196
  timezone?: string
163
197
 
198
+ @Column({ nullable: true })
199
+ @Field({ nullable: true })
200
+ schedulerHandle?: string
201
+
164
202
  @CreateDateColumn()
165
203
  @Field({ nullable: true })
166
204
  createdAt?: Date
@@ -20,6 +20,10 @@ export default {
20
20
  tagname: 'data-sample-search-page',
21
21
  page: 'data-sample-search'
22
22
  },
23
+ {
24
+ tagname: 'data-ooc-view-page',
25
+ page: 'data-ooc'
26
+ },
23
27
  {
24
28
  tagname: 'data-ooc-list-page',
25
29
  page: 'data-ooc-list'
@@ -3,6 +3,8 @@
3
3
  "button.request-archive": "request archive",
4
4
  "button.reviewed": "reviewed",
5
5
  "field.appliance": "appliance",
6
+ "field.approval-line": "approval line",
7
+ "field.assignees": "assignees",
6
8
  "field.collected_at": "collected at",
7
9
  "field.corrective-action": "corrective action",
8
10
  "field.corrector": "corrector",
@@ -3,6 +3,8 @@
3
3
  "button.reviewed": "검토완료",
4
4
  "button.request-archive": "자료보관 신규 요청",
5
5
  "field.appliance": "어플라이언스",
6
+ "field.approval-line": "결재라인",
7
+ "field.assignees": "할당자 목록",
6
8
  "field.collected_at": "수집일시",
7
9
  "field.corrected-at": "조치 시간",
8
10
  "field.corrective-action": "조치 활동",
@@ -3,6 +3,8 @@
3
3
  "button.request-archive": "request archive",
4
4
  "button.reviewed": "reviewed",
5
5
  "field.appliance": "appliance",
6
+ "field.approval-line": "approval line",
7
+ "field.assignees": "assignees",
6
8
  "field.collected_at": "collected at",
7
9
  "field.corrective-action": "corrective action",
8
10
  "field.corrector": "corrector",
@@ -3,6 +3,8 @@
3
3
  "button.request-archive": "request archive",
4
4
  "button.reviewed": "reviewed",
5
5
  "field.appliance": "appliance",
6
+ "field.approval-line": "approval line",
7
+ "field.assignees": "assignees",
6
8
  "field.collected_at": "collected at",
7
9
  "field.corrective-action": "corrective action",
8
10
  "field.corrector": "corrector",
@@ -1,55 +0,0 @@
1
- export const ActivityOoc = {
2
- name: 'OOC Review',
3
- description: 'Task to take remedial action based on Out Of Control data',
4
- release: '1.0.0',
5
- provider: 'hatiolab.com',
6
- category: 'quality',
7
- activityType: 'user',
8
- startable: true,
9
- model: [
10
- {
11
- name: 'dataOocId',
12
- description: 'OOC id',
13
- tag: 'dataOocId',
14
- hidden: true,
15
- mandatory: true,
16
- inout: 'in',
17
- type: 'string',
18
- options: {},
19
- unit: null,
20
- quantifier: [1],
21
- spec: {}
22
- },
23
- {
24
- name: 'Instruction',
25
- description: 'Instructions for preventing OOC',
26
- tag: 'instruction',
27
- hidden: false,
28
- mandatory: true,
29
- inout: 'in',
30
- type: 'textarea',
31
- options: {},
32
- unit: null,
33
- quantifier: [1],
34
- spec: {}
35
- },
36
- {
37
- name: 'action',
38
- description: 'Action Description',
39
- tag: 'action',
40
- hidden: false,
41
- mandatory: true,
42
- inout: 'out',
43
- type: 'textarea',
44
- options: {},
45
- unit: null,
46
- quantifier: [1],
47
- spec: {}
48
- }
49
- ],
50
- uiType: 'custom-element',
51
- uiSource: 'data-ooc-activity-view',
52
- reportType: 'page',
53
- reportSource: 'data-ooc-report-page',
54
- thumbnail: '/assets/images/ooc.png'
55
- }