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

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 (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
@@ -0,0 +1,48 @@
1
+ import { filter, pipe } from 'graphql-yoga'
2
+ import { Resolver, Root, Subscription } from 'type-graphql'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import { getRepository, pubsub } from '@things-factory/shell'
6
+
7
+ import { DataOoc } from './data-ooc'
8
+
9
+ @Resolver(DataOoc)
10
+ export class DataOocSubscription {
11
+ @Subscription({
12
+ subscribe: ({ args, context, info }) => {
13
+ const { domain, user } = context.state
14
+ const subdomain = domain?.subdomain
15
+
16
+ if (!domain) {
17
+ throw new Error('domain required')
18
+ }
19
+
20
+ if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {
21
+ throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)
22
+ }
23
+
24
+ return pipe(
25
+ pubsub.subscribe('data-ooc'),
26
+ filter(async (payload: { dataOoc: DataOoc; supervisoryRoleId: string }) => {
27
+ const { dataOoc, supervisoryRoleId } = payload
28
+ const { domain } = dataOoc
29
+
30
+ if (subdomain !== domain?.subdomain) {
31
+ return false
32
+ }
33
+
34
+ // check if the user has that role
35
+ const userWithRoles: User = await getRepository(User).findOne({
36
+ where: { id: user.id },
37
+ relations: ['roles']
38
+ })
39
+
40
+ return !!userWithRoles.roles.find(role => role.id === supervisoryRoleId)
41
+ })
42
+ )
43
+ }
44
+ })
45
+ dataOoc(@Root() payload: { dataOoc: DataOoc; supervisoryRoleId: string }): DataOoc {
46
+ return payload.dataOoc
47
+ }
48
+ }
@@ -0,0 +1,71 @@
1
+ import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
2
+
3
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
4
+
5
+ import { DataOoc, DataOocStatus } from './data-ooc'
6
+
7
+ @InputType()
8
+ export class NewDataOoc {
9
+ @Field()
10
+ name: string
11
+
12
+ @Field({ nullable: true })
13
+ description?: string
14
+
15
+ @Field(type => ObjectRef, { nullable: true })
16
+ dataSet?: ObjectRef
17
+
18
+ @Field({ nullable: true })
19
+ dataSetVersion?: number
20
+
21
+ @Field(type => ObjectRef, { nullable: true })
22
+ dataSample?: ObjectRef
23
+
24
+ @Field(type => DataOocStatus, { nullable: true })
25
+ state?: DataOocStatus
26
+
27
+ @Field(type => ScalarObject, { nullable: true })
28
+ data?: any
29
+
30
+ @Field({ nullable: true })
31
+ rawData?: string
32
+
33
+ @Field({ nullable: true })
34
+ source?: string
35
+
36
+ @Field({ nullable: true })
37
+ ooc?: boolean
38
+
39
+ @Field({ nullable: true })
40
+ oos?: boolean
41
+
42
+ @Field({ nullable: true })
43
+ workDate?: string
44
+
45
+ @Field({ nullable: true })
46
+ workShift?: string
47
+
48
+ @Field({ nullable: true })
49
+ collectedAt?: Date
50
+ }
51
+
52
+ @InputType()
53
+ export class DataOocPatch {
54
+ @Field(type => ID, { nullable: true })
55
+ id?: string
56
+
57
+ @Field(type => DataOocStatus, { nullable: true })
58
+ state?: DataOocStatus
59
+
60
+ @Field({ nullable: true })
61
+ correctiveAction?: string
62
+ }
63
+
64
+ @ObjectType()
65
+ export class DataOocList {
66
+ @Field(type => [DataOoc])
67
+ items: DataOoc[]
68
+
69
+ @Field(type => Int)
70
+ total: number
71
+ }
@@ -0,0 +1,259 @@
1
+ import { Field, ID, ObjectType, registerEnumType } from 'type-graphql'
2
+ import {
3
+ Column,
4
+ CreateDateColumn,
5
+ Entity,
6
+ Index,
7
+ JoinColumn,
8
+ ManyToOne,
9
+ OneToOne,
10
+ PrimaryGeneratedColumn,
11
+ RelationId,
12
+ UpdateDateColumn
13
+ } from 'typeorm'
14
+
15
+ import { User } from '@things-factory/auth-base'
16
+ import { config } from '@things-factory/env'
17
+ import { Domain, ScalarObject } from '@things-factory/shell'
18
+ import { ActivityInstance } from '@things-factory/worklist'
19
+
20
+ import { DataItem } from '../data-set/data-item-type'
21
+ import { DataSet } from '../data-set/data-set'
22
+ import { DataSample } from '../data-sample/data-sample'
23
+
24
+ const ORMCONFIG = config.get('ormconfig', {})
25
+ const DATABASE_TYPE = ORMCONFIG.type
26
+
27
+ export enum DataOocStatus {
28
+ ISSUED = 'ISSUED',
29
+ REVIEWED = 'REVIEWED',
30
+ CORRECTED = 'CORRECTED'
31
+ }
32
+
33
+ registerEnumType(DataOocStatus, {
34
+ name: 'DataOocStatus',
35
+ description: 'Out of control data corrective action process progress status'
36
+ })
37
+
38
+ @Entity()
39
+ @Index('ix_data_ooc_0', (dataOoc: DataOoc) => [dataOoc.domain, dataOoc.dataSet, dataOoc.collectedAt], { unique: false })
40
+ @ObjectType({ description: 'Entity for Out of control data' })
41
+ export class DataOoc {
42
+ @PrimaryGeneratedColumn('uuid')
43
+ @Field(type => ID)
44
+ readonly id: string
45
+
46
+ @ManyToOne(type => Domain)
47
+ @Field(type => Domain)
48
+ domain?: Domain
49
+
50
+ @RelationId((dataOoc: DataOoc) => dataOoc.domain)
51
+ domainId?: string
52
+
53
+ @Column()
54
+ @Field({ nullable: true })
55
+ name?: string
56
+
57
+ @Column({ nullable: true })
58
+ @Field({ nullable: true })
59
+ description?: string
60
+
61
+ @ManyToOne(type => DataSet)
62
+ @Field(type => DataSet, { nullable: true })
63
+ dataSet?: DataSet
64
+
65
+ @RelationId((dataOoc: DataOoc) => dataOoc.dataSet)
66
+ dataSetId?: string
67
+
68
+ @Column({ nullable: true })
69
+ @Field({ nullable: true })
70
+ dataSetVersion?: number
71
+
72
+ @Column({ nullable: true })
73
+ @Field({ nullable: true })
74
+ ooc?: boolean
75
+
76
+ @Column({ nullable: true })
77
+ @Field({ nullable: true })
78
+ oos?: boolean
79
+
80
+ @Column({ nullable: true })
81
+ @Field({ nullable: true })
82
+ state?: DataOocStatus
83
+
84
+ @Column({
85
+ nullable: true,
86
+ type:
87
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
88
+ ? 'longtext'
89
+ : DATABASE_TYPE == 'oracle'
90
+ ? 'clob'
91
+ : DATABASE_TYPE == 'mssql'
92
+ ? 'nvarchar'
93
+ : 'varchar',
94
+ length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined
95
+ })
96
+ @Field({ nullable: true })
97
+ correctiveInstruction?: string
98
+
99
+ @Column({
100
+ nullable: true,
101
+ type:
102
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
103
+ ? 'longtext'
104
+ : DATABASE_TYPE == 'oracle'
105
+ ? 'clob'
106
+ : DATABASE_TYPE == 'mssql'
107
+ ? 'nvarchar'
108
+ : 'varchar',
109
+ length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined
110
+ })
111
+ @Field({ nullable: true })
112
+ correctiveAction?: string
113
+
114
+ @Column({ nullable: true })
115
+ @Field({ nullable: true })
116
+ type?: string
117
+
118
+ @Column({ nullable: true })
119
+ @Field({ nullable: true })
120
+ useCase?: string
121
+
122
+ @Column({ nullable: true, default: '' })
123
+ @Field({ nullable: true })
124
+ key01?: string = ''
125
+
126
+ @Column({ nullable: true, default: '' })
127
+ @Field({ nullable: true })
128
+ key02?: string = ''
129
+
130
+ @Column({ nullable: true, default: '' })
131
+ @Field({ nullable: true })
132
+ key03?: string = ''
133
+
134
+ @Column({ nullable: true, default: '' })
135
+ @Field({ nullable: true })
136
+ key04?: string = ''
137
+
138
+ @Column({ nullable: true, default: '' })
139
+ @Field({ nullable: true })
140
+ key05?: string = ''
141
+
142
+ @Column('simple-json', { nullable: true })
143
+ @Field(type => ScalarObject, { nullable: true })
144
+ partitionKeys?: { [key: string]: any }
145
+
146
+ @Column('simple-json', { nullable: true })
147
+ @Field(type => ScalarObject, { nullable: true })
148
+ data?: any
149
+
150
+ @Column('simple-json', { nullable: true })
151
+ @Field(type => ScalarObject, { nullable: true })
152
+ judgment?: any
153
+
154
+ @Field(type => [DataItem], { nullable: true })
155
+ dataItems?: DataItem[]
156
+
157
+ @Column('simple-json', { nullable: true })
158
+ @Field(type => ScalarObject, { nullable: true })
159
+ history?: any
160
+
161
+ @Column({
162
+ nullable: true,
163
+ type:
164
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
165
+ ? 'longtext'
166
+ : DATABASE_TYPE == 'oracle'
167
+ ? 'clob'
168
+ : DATABASE_TYPE == 'mssql'
169
+ ? 'nvarchar'
170
+ : 'varchar',
171
+ length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined
172
+ })
173
+ @Field({ nullable: true })
174
+ rawData?: string
175
+
176
+ @Column({ nullable: true })
177
+ @Field({ nullable: true })
178
+ source?: string
179
+
180
+ @OneToOne(type => DataSample, { nullable: true })
181
+ @JoinColumn()
182
+ @Field(type => DataSample, { nullable: true })
183
+ dataSample?: DataSample
184
+
185
+ @RelationId((dataOoc: DataOoc) => dataOoc.dataSample)
186
+ dataSampleId?: string
187
+
188
+ @OneToOne(type => ActivityInstance, { nullable: true })
189
+ @JoinColumn()
190
+ @Field({ nullable: true })
191
+ reviewActivityInstance?: ActivityInstance
192
+
193
+ @RelationId((dataOoc: DataOoc) => dataOoc.reviewActivityInstance)
194
+ reviewActivityInstanceId?: string
195
+
196
+ @OneToOne(type => ActivityInstance, { nullable: true })
197
+ @JoinColumn()
198
+ @Field({ nullable: true })
199
+ resolveActivityInstance?: ActivityInstance
200
+
201
+ @RelationId((dataOoc: DataOoc) => dataOoc.resolveActivityInstance)
202
+ resolveActivityInstanceId?: string
203
+
204
+ @Column({ nullable: true })
205
+ @Field({ nullable: true })
206
+ workDate?: string
207
+
208
+ @Column({ nullable: true })
209
+ @Field({ nullable: true })
210
+ workShift?: string
211
+
212
+ @Column({ nullable: true })
213
+ @Field({ nullable: true })
214
+ collectedAt?: Date
215
+
216
+ @Column({ nullable: true })
217
+ @Field({ nullable: true })
218
+ reviewedAt?: Date
219
+
220
+ @Column({ nullable: true })
221
+ @Field({ nullable: true })
222
+ correctedAt?: Date
223
+
224
+ @CreateDateColumn()
225
+ @Field({ nullable: true })
226
+ createdAt?: Date
227
+
228
+ @UpdateDateColumn()
229
+ @Field({ nullable: true })
230
+ updatedAt?: Date
231
+
232
+ @ManyToOne(type => User, { nullable: true })
233
+ @Field({ nullable: true })
234
+ reviewer?: User
235
+
236
+ @RelationId((dataOoc: DataOoc) => dataOoc.reviewer)
237
+ reviewerId?: string
238
+
239
+ @ManyToOne(type => User, { nullable: true })
240
+ @Field({ nullable: true })
241
+ corrector?: User
242
+
243
+ @RelationId((dataOoc: DataOoc) => dataOoc.corrector)
244
+ correctorId?: string
245
+
246
+ @ManyToOne(type => User, { nullable: true })
247
+ @Field(type => User, { nullable: true })
248
+ creator?: User
249
+
250
+ @RelationId((dataOoc: DataOoc) => dataOoc.creator)
251
+ creatorId?: string
252
+
253
+ @ManyToOne(type => User, { nullable: true })
254
+ @Field(type => User, { nullable: true })
255
+ updater?: User
256
+
257
+ @RelationId((dataOoc: DataOoc) => dataOoc.updater)
258
+ updaterId?: string
259
+ }
@@ -0,0 +1,7 @@
1
+ import { DataOoc } from './data-ooc'
2
+ import { DataOocMutation } from './data-ooc-mutation'
3
+ import { DataOocQuery } from './data-ooc-query'
4
+ import { DataOocSubscription } from './data-ooc-subscription'
5
+
6
+ export const entities = [DataOoc]
7
+ export const resolvers = [DataOocQuery, DataOocMutation, DataOocSubscription]
@@ -0,0 +1,18 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { createDataSample } from '../../controllers/create-data-sample'
4
+ import { DataSample } from './data-sample'
5
+ import { NewDataSample } from './data-sample-type'
6
+
7
+ @Resolver(DataSample)
8
+ export class DataSampleMutation {
9
+ @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
10
+ @Directive('@transaction')
11
+ @Mutation(returns => DataSample, { description: 'To create new data sample' })
12
+ async createDataSample(
13
+ @Arg('dataSample') dataSample: NewDataSample,
14
+ @Ctx() context: ResolverContext
15
+ ): Promise<DataSample> {
16
+ return await createDataSample(dataSample, context)
17
+ }
18
+ }
@@ -0,0 +1,215 @@
1
+ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { User } from '@things-factory/auth-base'
5
+ import {
6
+ Domain,
7
+ getISOStringsForPeriod,
8
+ getQueryBuilderFromListParams,
9
+ getRepository,
10
+ ListParam
11
+ } from '@things-factory/shell'
12
+ import { ActivityInstance } from '@things-factory/worklist'
13
+
14
+ import { DataKeySet } from '../data-key-set/data-key-set'
15
+ import { DataOoc } from '../data-ooc/data-ooc'
16
+ import { DataSetHistory } from '../data-set-history/data-set-history'
17
+ import { DataItem } from '../data-set/data-item-type'
18
+ import { DataSet } from '../data-set/data-set'
19
+ import { DataSample } from './data-sample'
20
+ import { DataSampleList } from './data-sample-type'
21
+
22
+ @Resolver(DataSample)
23
+ export class DataSampleQuery {
24
+ @Directive('@privilege(category: "data-sample", privilege: "query", domainOwnerGranted: true)')
25
+ @Query(returns => DataSample, { description: 'To fetch a data sample' })
26
+ async dataSample(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<DataSample> {
27
+ const { domain } = context.state
28
+
29
+ return await getRepository(DataSample).findOne({
30
+ where: { domain: { id: domain.id }, id }
31
+ })
32
+ }
33
+
34
+ @Directive('@privilege(category: "data-sample", privilege: "query", domainOwnerGranted: true)')
35
+ @Query(returns => DataSampleList, { description: 'To fetch multiple data samples' })
36
+ async dataSamples(
37
+ @Args(type => ListParam) params: ListParam,
38
+ @Ctx() context: ResolverContext
39
+ ): Promise<DataSampleList> {
40
+ const { domain } = context.state
41
+
42
+ const queryBuilder = getQueryBuilderFromListParams({
43
+ repository: getRepository(DataSample),
44
+ params,
45
+ domain,
46
+ searchables: ['name', 'description', 'key01', 'key02', 'key03', 'key04', 'key05']
47
+ })
48
+
49
+ const [items, total] = await queryBuilder.getManyAndCount()
50
+
51
+ return { items, total }
52
+ }
53
+
54
+ @Directive('@privilege(category: "data-sample", privilege: "query", domainOwnerGranted: true)')
55
+ @Query(returns => DataSampleList, { description: 'To fetch multiple data samples by data set' })
56
+ async dataSamplesByDataSet(
57
+ @Arg('dataSetId') dataSetId: string,
58
+ @Args(type => ListParam) params: ListParam,
59
+ @Ctx() context: ResolverContext
60
+ ): Promise<DataSampleList> {
61
+ const { domain } = context.state
62
+
63
+ const dataSet = await getRepository(DataSet).findOne({
64
+ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id: dataSetId },
65
+ relations: ['dataKeySet']
66
+ })
67
+
68
+ if (!dataSet) {
69
+ throw new Error(`dataSet not found by the given dataSetId(${dataSetId})`)
70
+ }
71
+
72
+ const dataKeyItems = dataSet.dataKeySet?.dataKeyItems || []
73
+ const searchables = dataKeyItems.map((item, index) => `key0${index + 1}`)
74
+
75
+ const queryBuilder = getQueryBuilderFromListParams({
76
+ repository: getRepository(DataSample),
77
+ params,
78
+ domain,
79
+ alias: 'sample',
80
+ searchables: ['name', 'description'].concat(searchables)
81
+ }).innerJoin('sample.dataSet', 'ds', 'ds.id = :dataSetId', {
82
+ dataSetId
83
+ })
84
+
85
+ const [items, total] = await queryBuilder.getManyAndCount()
86
+
87
+ return { items, total }
88
+ }
89
+
90
+ @Directive('@privilege(category: "data-sample", privilege: "query", domainOwnerGranted: true)')
91
+ @Query(returns => DataSampleList, { description: 'To fetch multiple data samples by data key set' })
92
+ async dataSamplesByDataKeySet(
93
+ @Arg('dataKeySetId') dataKeySetId: string,
94
+ @Args(type => ListParam) params: ListParam,
95
+ @Ctx() context: ResolverContext
96
+ ): Promise<DataSampleList> {
97
+ const { domain } = context.state
98
+
99
+ const dataKeySet = await getRepository(DataKeySet).findOneBy({ id: dataKeySetId })
100
+ const dataKeyItems = dataKeySet?.dataKeyItems || []
101
+ const searchables = dataKeyItems.map((item, index) => `key0${index + 1}`)
102
+
103
+ const queryBuilder = getQueryBuilderFromListParams({
104
+ repository: getRepository(DataSample),
105
+ params,
106
+ domain,
107
+ alias: 'sample',
108
+ searchables: ['name', 'description'].concat(searchables)
109
+ }).innerJoin('sample.dataSet', 'ds', 'ds.dataKeySet = :dataKeySetId', {
110
+ dataKeySetId
111
+ })
112
+
113
+ const [items, total] = await queryBuilder.getManyAndCount()
114
+
115
+ return { items, total }
116
+ }
117
+
118
+ @Query(returns => DataSampleList, { description: 'To fetch multiple DataSamples by period' })
119
+ async dataSamplesByPeriod(
120
+ @Arg('period') period: 'today' | 'this month' | '30 days' | 'this year' | '12 months',
121
+ @Arg('dataSetName') dataSetName: string,
122
+ @Args(type => ListParam) params: ListParam,
123
+ @Ctx() context: ResolverContext
124
+ ): Promise<DataSampleList> {
125
+ const { domain } = context.state
126
+ const { from, to } = await getISOStringsForPeriod(period, context)
127
+
128
+ const dataSet = await getRepository(DataSet).findOne({
129
+ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, name: dataSetName },
130
+ relations: ['dataKeySet']
131
+ })
132
+
133
+ if (!dataSet) {
134
+ throw new Error(`dataSet not found by the given dataSetName(${dataSetName})`)
135
+ }
136
+
137
+ const { filters = [] } = params || {}
138
+ const alteredFilters = filters.concat([
139
+ {
140
+ name: 'collectedAt',
141
+ operator: 'between',
142
+ value: [from, to]
143
+ }
144
+ ])
145
+
146
+ const dataKeyItems = dataSet.dataKeySet?.dataKeyItems || []
147
+ const searchables = dataKeyItems.map((item, index) => `key0${index + 1}`)
148
+
149
+ const queryBuilder = getQueryBuilderFromListParams({
150
+ repository: getRepository(DataSample),
151
+ params: {
152
+ ...params,
153
+ filters: alteredFilters
154
+ },
155
+ domain,
156
+ alias: 'sample',
157
+ searchables: ['name', 'description'].concat(searchables)
158
+ }).innerJoin('sample.dataSet', 'ds', 'ds.id = :dataSetId', {
159
+ dataSetId: dataSet.id
160
+ })
161
+
162
+ const [items, total] = await queryBuilder.getManyAndCount()
163
+
164
+ return { items, total }
165
+ }
166
+
167
+ @FieldResolver(type => [DataItem])
168
+ async dataItems(@Root() dataSample: DataSample): Promise<DataItem[]> {
169
+ const dataSetHistory: DataSetHistory =
170
+ dataSample.dataSetId &&
171
+ (await getRepository(DataSetHistory).findOne({
172
+ where: {
173
+ originalId: dataSample.dataSetId,
174
+ version: dataSample.dataSetVersion
175
+ }
176
+ }))
177
+
178
+ return dataSetHistory?.dataItems.filter(item => item.active) || []
179
+ }
180
+
181
+ @FieldResolver(type => DataSet)
182
+ async dataSet(@Root() dataSample: DataSample): Promise<DataSet> {
183
+ return dataSample.dataSetId && (await getRepository(DataSet).findOneBy({ id: dataSample.dataSetId }))
184
+ }
185
+
186
+ @FieldResolver(type => DataOoc)
187
+ async dataOoc(@Root() dataSample: DataSample): Promise<DataOoc> {
188
+ if (dataSample.ooc || dataSample.oos) {
189
+ return await getRepository(DataOoc).findOneBy({ dataSample: { id: dataSample.id } })
190
+ }
191
+ }
192
+
193
+ @FieldResolver(type => ActivityInstance)
194
+ async reviewActivityInstance(@Root() dataSample: DataSample): Promise<ActivityInstance> {
195
+ return (
196
+ dataSample.reviewActivityInstanceId &&
197
+ (await getRepository(ActivityInstance).findOneBy({ id: dataSample.reviewActivityInstanceId }))
198
+ )
199
+ }
200
+
201
+ @FieldResolver(type => Domain)
202
+ async domain(@Root() dataSample: DataSample): Promise<Domain> {
203
+ return dataSample.domainId && (await getRepository(Domain).findOneBy({ id: dataSample.domainId }))
204
+ }
205
+
206
+ @FieldResolver(type => User)
207
+ async updater(@Root() dataSample: DataSample): Promise<User> {
208
+ return dataSample.updaterId && (await getRepository(User).findOneBy({ id: dataSample.updaterId }))
209
+ }
210
+
211
+ @FieldResolver(type => User)
212
+ async creator(@Root() dataSample: DataSample): Promise<User> {
213
+ return dataSample.creatorId && (await getRepository(User).findOneBy({ id: dataSample.creatorId }))
214
+ }
215
+ }
@@ -0,0 +1,47 @@
1
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
2
+
3
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
4
+
5
+ import { DataSample } from './data-sample'
6
+
7
+ @InputType()
8
+ export class NewDataSample {
9
+ @Field({ nullable: true })
10
+ name?: string
11
+
12
+ @Field({ nullable: true })
13
+ description?: string
14
+
15
+ @Field(type => ObjectRef, { nullable: true })
16
+ dataSet?: ObjectRef
17
+
18
+ @Field({ nullable: true })
19
+ dataSetVersion?: number
20
+
21
+ @Field(type => ScalarObject, { nullable: true })
22
+ data?: any
23
+
24
+ @Field({ nullable: true })
25
+ rawData?: string
26
+
27
+ @Field({ nullable: true })
28
+ source?: string
29
+
30
+ @Field({ nullable: true })
31
+ workDate?: string
32
+
33
+ @Field({ nullable: true })
34
+ workShift?: string
35
+
36
+ @Field({ nullable: true })
37
+ collectedAt?: Date
38
+ }
39
+
40
+ @ObjectType()
41
+ export class DataSampleList {
42
+ @Field(type => [DataSample])
43
+ items: DataSample[]
44
+
45
+ @Field(type => Int)
46
+ total: number
47
+ }