@things-factory/dataset 5.0.0-alpha.3 → 5.0.0-alpha.32

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 (99) hide show
  1. package/README.md +13 -0
  2. package/assets/data-samples.jpg +0 -0
  3. package/client/bootstrap.js +16 -1
  4. package/client/pages/data-entry/data-entry-form.js +85 -0
  5. package/client/pages/data-entry/data-entry-list-page.js +464 -0
  6. package/client/pages/data-ooc/data-ooc-list-page.js +488 -0
  7. package/client/pages/data-ooc/data-ooc-view.js +182 -0
  8. package/client/pages/{data-sample.js → data-sample/data-sample-list-page.js} +153 -59
  9. package/client/pages/data-sample/data-sample-view.js +97 -0
  10. package/client/pages/{data-sensor.js → data-sensor/data-sensor-list-page.js} +11 -16
  11. package/client/pages/{data-item-list.js → data-set/data-item-list.js} +70 -16
  12. package/client/pages/{data-set-importer.js → data-set/data-set-importer.js} +0 -0
  13. package/client/pages/{data-set.js → data-set/data-set-list-page.js} +282 -76
  14. package/client/route.js +14 -6
  15. package/dist-server/controllers/create-data-sample.js +133 -0
  16. package/dist-server/controllers/create-data-sample.js.map +1 -0
  17. package/dist-server/controllers/data-use-case.js +57 -0
  18. package/dist-server/controllers/data-use-case.js.map +1 -0
  19. package/dist-server/controllers/index.js +17 -0
  20. package/dist-server/controllers/index.js.map +1 -1
  21. package/dist-server/index.js +2 -0
  22. package/dist-server/index.js.map +1 -1
  23. package/dist-server/routes.js +9 -24
  24. package/dist-server/routes.js.map +1 -1
  25. package/dist-server/service/data-item/data-item-mutation.js +5 -1
  26. package/dist-server/service/data-item/data-item-mutation.js.map +1 -1
  27. package/dist-server/service/data-item/data-item-type.js +18 -6
  28. package/dist-server/service/data-item/data-item-type.js.map +1 -1
  29. package/dist-server/service/data-item/data-item.js +27 -7
  30. package/dist-server/service/data-item/data-item.js.map +1 -1
  31. package/dist-server/service/data-ooc/data-ooc-mutation.js +92 -0
  32. package/dist-server/service/data-ooc/data-ooc-mutation.js.map +1 -0
  33. package/dist-server/service/data-ooc/data-ooc-query.js +115 -0
  34. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -0
  35. package/dist-server/service/data-ooc/data-ooc-subscription.js +65 -0
  36. package/dist-server/service/data-ooc/data-ooc-subscription.js.map +1 -0
  37. package/dist-server/service/data-ooc/data-ooc-type.js +107 -0
  38. package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -0
  39. package/dist-server/service/data-ooc/data-ooc.js +237 -0
  40. package/dist-server/service/data-ooc/data-ooc.js.map +1 -0
  41. package/dist-server/service/data-ooc/index.js +10 -0
  42. package/dist-server/service/data-ooc/index.js.map +1 -0
  43. package/dist-server/service/data-sample/data-sample-mutation.js +3 -105
  44. package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
  45. package/dist-server/service/data-sample/data-sample-type.js +12 -42
  46. package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
  47. package/dist-server/service/data-sample/data-sample.js +34 -3
  48. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  49. package/dist-server/service/data-set/data-set-mutation.js +1 -2
  50. package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
  51. package/dist-server/service/data-set/data-set-query.js +110 -1
  52. package/dist-server/service/data-set/data-set-query.js.map +1 -1
  53. package/dist-server/service/data-set/data-set-type.js +48 -4
  54. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  55. package/dist-server/service/data-set/data-set.js +59 -15
  56. package/dist-server/service/data-set/data-set.js.map +1 -1
  57. package/dist-server/service/data-spec/data-spec-manager.js +20 -0
  58. package/dist-server/service/data-spec/data-spec-manager.js.map +1 -0
  59. package/dist-server/service/data-spec/data-spec-query.js +48 -0
  60. package/dist-server/service/data-spec/data-spec-query.js.map +1 -0
  61. package/dist-server/service/data-spec/data-spec.js +78 -0
  62. package/dist-server/service/data-spec/data-spec.js.map +1 -0
  63. package/dist-server/service/data-spec/index.js +8 -0
  64. package/dist-server/service/data-spec/index.js.map +1 -0
  65. package/dist-server/service/index.js +12 -4
  66. package/dist-server/service/index.js.map +1 -1
  67. package/package.json +18 -12
  68. package/server/controllers/create-data-sample.ts +175 -0
  69. package/server/controllers/data-use-case.ts +85 -0
  70. package/server/controllers/index.ts +1 -0
  71. package/server/index.ts +3 -0
  72. package/server/routes.ts +17 -31
  73. package/server/service/data-item/data-item-mutation.ts +6 -1
  74. package/server/service/data-item/data-item-type.ts +13 -6
  75. package/server/service/data-item/data-item.ts +21 -5
  76. package/server/service/data-ooc/data-ooc-mutation.ts +150 -0
  77. package/server/service/data-ooc/data-ooc-query.ts +63 -0
  78. package/server/service/data-ooc/data-ooc-subscription.ts +51 -0
  79. package/server/service/data-ooc/data-ooc-type.ts +68 -0
  80. package/server/service/data-ooc/data-ooc.ts +204 -0
  81. package/server/service/data-ooc/index.ts +7 -0
  82. package/server/service/data-sample/data-sample-mutation.ts +6 -128
  83. package/server/service/data-sample/data-sample-type.ts +7 -28
  84. package/server/service/data-sample/data-sample.ts +33 -3
  85. package/server/service/data-set/data-set-mutation.ts +1 -4
  86. package/server/service/data-set/data-set-query.ts +87 -2
  87. package/server/service/data-set/data-set-type.ts +37 -4
  88. package/server/service/data-set/data-set.ts +52 -12
  89. package/server/service/data-spec/data-spec-manager.ts +21 -0
  90. package/server/service/data-spec/data-spec-query.ts +21 -0
  91. package/server/service/data-spec/data-spec.ts +44 -0
  92. package/server/service/data-spec/index.ts +5 -0
  93. package/server/service/index.ts +16 -8
  94. package/things-factory.config.js +14 -6
  95. package/translations/en.json +30 -0
  96. package/translations/ko.json +30 -1
  97. package/translations/ms.json +29 -0
  98. package/translations/zh.json +29 -0
  99. package/yarn-error.log +23244 -0
@@ -0,0 +1,204 @@
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
+
19
+ import { DataSample } from '../data-sample/data-sample'
20
+ import { DataSet } from '../data-set/data-set'
21
+
22
+ const ORMCONFIG = config.get('ormconfig', {})
23
+ const DATABASE_TYPE = ORMCONFIG.type
24
+
25
+ export enum DataOocStatus {
26
+ CREATED = 'CREATED',
27
+ REVIEWED = 'REVIEWED',
28
+ CORRECTED = 'CORRECTED'
29
+ }
30
+
31
+ registerEnumType(DataOocStatus, {
32
+ name: 'DataOocStatus',
33
+ description: 'Out of control data corrective action process progress status'
34
+ })
35
+
36
+ @Entity()
37
+ @Index('ix_data_ooc_0', (dataOoc: DataOoc) => [dataOoc.domain, dataOoc.dataSet], { unique: false })
38
+ @Index('ix_data_ooc_1', (dataOoc: DataOoc) => [dataOoc.domain, dataOoc.dataSample], { unique: true })
39
+ @Index('ix_data_ooc_2', (dataOoc: DataOoc) => [dataOoc.domain, 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({ nullable: true })
48
+ domain?: Domain
49
+
50
+ @RelationId((dataOoc: DataOoc) => dataOoc.domain)
51
+ domainId?: string
52
+
53
+ @Column()
54
+ @Field()
55
+ name: string
56
+
57
+ @Column({
58
+ nullable: true
59
+ })
60
+ @Field({ nullable: true })
61
+ description?: string
62
+
63
+ @ManyToOne(type => DataSet)
64
+ @Field(type => DataSet, { nullable: true })
65
+ dataSet?: DataSet
66
+
67
+ @RelationId((dataOoc: DataOoc) => dataOoc.dataSet)
68
+ dataSetId?: string
69
+
70
+ @OneToOne(type => DataSample)
71
+ @JoinColumn()
72
+ @Field(type => DataSample, { nullable: true })
73
+ dataSample?: DataSample
74
+
75
+ @RelationId((dataOoc: DataOoc) => dataOoc.dataSample)
76
+ dataSampleId?: string
77
+
78
+ @Column({
79
+ nullable: true
80
+ })
81
+ @Field({ nullable: true })
82
+ ooc?: boolean
83
+
84
+ @Column({
85
+ nullable: true
86
+ })
87
+ @Field({ nullable: true })
88
+ oos?: boolean
89
+
90
+ @Column({
91
+ nullable: true
92
+ })
93
+ @Field({ nullable: true })
94
+ state?: DataOocStatus
95
+
96
+ @Column({
97
+ nullable: true,
98
+ type:
99
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
100
+ ? 'longtext'
101
+ : DATABASE_TYPE == 'oracle'
102
+ ? 'clob'
103
+ : 'varchar'
104
+ })
105
+ @Field({ nullable: true })
106
+ correctiveAction?: string
107
+
108
+ @Column({
109
+ nullable: true
110
+ })
111
+ @Field({ nullable: true })
112
+ type?: string
113
+
114
+ @Column({
115
+ nullable: true
116
+ })
117
+ @Field({ nullable: true })
118
+ useCase?: string
119
+
120
+ @Column('simple-json', { nullable: true })
121
+ @Field(type => ScalarObject, { nullable: true })
122
+ partitionKeys?: ScalarObject
123
+
124
+ @Column('simple-json', { nullable: true })
125
+ @Field(type => ScalarObject, { nullable: true })
126
+ data?: ScalarObject
127
+
128
+ @Column('simple-json', { nullable: true })
129
+ @Field(type => ScalarObject, { nullable: true })
130
+ spec?: ScalarObject
131
+
132
+ @Column('simple-json', { nullable: true })
133
+ @Field(type => ScalarObject, { nullable: true })
134
+ history?: ScalarObject
135
+
136
+ @Column({
137
+ nullable: true,
138
+ type:
139
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
140
+ ? 'longtext'
141
+ : DATABASE_TYPE == 'oracle'
142
+ ? 'clob'
143
+ : 'varchar'
144
+ })
145
+ @Field({ nullable: true })
146
+ rawData?: string
147
+
148
+ @Column({
149
+ nullable: true
150
+ })
151
+ @Field({ nullable: true })
152
+ source?: string
153
+
154
+ @Column({ nullable: true })
155
+ @Field({ nullable: true })
156
+ workDate?: string
157
+
158
+ @Column({ nullable: true })
159
+ @Field({ nullable: true })
160
+ workShift?: string
161
+
162
+ @Column({ nullable: true })
163
+ @Field({ nullable: true })
164
+ collectedAt?: Date
165
+
166
+ @Column({ nullable: true })
167
+ @Field({ nullable: true })
168
+ correctedAt?: Date
169
+
170
+ @CreateDateColumn()
171
+ @Field({ nullable: true })
172
+ createdAt?: Date
173
+
174
+ @UpdateDateColumn()
175
+ @Field({ nullable: true })
176
+ updatedAt?: Date
177
+
178
+ @ManyToOne(type => User, {
179
+ nullable: true
180
+ })
181
+ @Field({ nullable: true })
182
+ corrector?: User
183
+
184
+ @RelationId((dataOoc: DataOoc) => dataOoc.corrector)
185
+ correctorId?: string
186
+
187
+ @ManyToOne(type => User, {
188
+ nullable: true
189
+ })
190
+ @Field({ nullable: true })
191
+ creator?: User
192
+
193
+ @RelationId((dataOoc: DataOoc) => dataOoc.creator)
194
+ creatorId?: string
195
+
196
+ @ManyToOne(type => User, {
197
+ nullable: true
198
+ })
199
+ @Field({ nullable: true })
200
+ updater?: User
201
+
202
+ @RelationId((dataOoc: DataOoc) => dataOoc.creator)
203
+ updaterId?: string
204
+ }
@@ -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]
@@ -1,10 +1,11 @@
1
1
  import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
- import { In } from 'typeorm'
3
2
 
4
- import { DataItem } from '../data-item/data-item'
5
- import { DataSet } from '../data-set/data-set'
6
3
  import { DataSample } from './data-sample'
7
- import { DataSamplePatch, NewDataSample } from './data-sample-type'
4
+ import { NewDataSample } from './data-sample-type'
5
+
6
+ import { createDataSample } from '../../controllers/create-data-sample'
7
+
8
+ const debug = require('debug')('things-factory:dataset:data-sample:data-sample-mutation')
8
9
 
9
10
  @Resolver(DataSample)
10
11
  export class DataSampleMutation {
@@ -12,129 +13,6 @@ export class DataSampleMutation {
12
13
  @Directive('@transaction')
13
14
  @Mutation(returns => DataSample, { description: 'To create new data sample' })
14
15
  async createDataSample(@Arg('dataSample') dataSample: NewDataSample, @Ctx() context: any): Promise<DataSample> {
15
- const { domain, user, tx } = context.state
16
-
17
- const dataSet = await tx.getRepository(DataSet).findOne({ id: dataSample.dataSetId })
18
- const dataItems = await tx.getRepository(DataItem).find({
19
- where: {
20
- domain,
21
- dataSet
22
- },
23
- order: {
24
- sequence: 'DESC'
25
- }
26
- })
27
-
28
- var spec = {} as any
29
-
30
- dataItems.forEach(dataItem => {
31
- spec[dataItem.name] = dataItem.spec
32
- // TODO 변수형 스펙값은 처리 결과값을 spec의 아이템 value로 반영하여야 한다.
33
- })
34
-
35
- return await tx.getRepository(DataSample).save({
36
- name: dataSet.name,
37
- description: dataSet.description,
38
- collectedAt: new Date(),
39
- ...dataSample,
40
- domain,
41
- partitionKeys: dataSet.partitionKeys,
42
- spec,
43
- creator: user,
44
- updater: user
45
- })
46
- }
47
-
48
- @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
49
- @Directive('@transaction')
50
- @Mutation(returns => DataSample, { description: 'To modify data sample information' })
51
- async updateDataSample(
52
- @Arg('id') id: string,
53
- @Arg('patch') patch: DataSamplePatch,
54
- @Ctx() context: any
55
- ): Promise<DataSample> {
56
- const { domain, user, tx } = context.state
57
-
58
- const repository = tx.getRepository(DataSample)
59
- const dataSample = await repository.findOne({
60
- where: { domain, id }
61
- })
62
-
63
- return await repository.save({
64
- ...dataSample,
65
- ...patch,
66
- updater: user
67
- })
68
- }
69
-
70
- @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
71
- @Directive('@transaction')
72
- @Mutation(returns => [DataSample], { description: "To modify multiple data samples' information" })
73
- async updateMultipleDataSample(
74
- @Arg('patches', type => [DataSamplePatch]) patches: DataSamplePatch[],
75
- @Ctx() context: any
76
- ): Promise<DataSample[]> {
77
- const { domain, user, tx } = context.state
78
-
79
- let results = []
80
- const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
81
- const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
82
- const dataSampleRepo = tx.getRepository(DataSample)
83
-
84
- if (_createRecords.length > 0) {
85
- for (let i = 0; i < _createRecords.length; i++) {
86
- const newRecord = _createRecords[i]
87
-
88
- const result = await dataSampleRepo.save({
89
- ...newRecord,
90
- domain,
91
- creator: user,
92
- updater: user
93
- })
94
-
95
- results.push({ ...result, cuFlag: '+' })
96
- }
97
- }
98
-
99
- if (_updateRecords.length > 0) {
100
- for (let i = 0; i < _updateRecords.length; i++) {
101
- const newRecord = _updateRecords[i]
102
- const dataSample = await dataSampleRepo.findOne(newRecord.id)
103
-
104
- const result = await dataSampleRepo.save({
105
- ...dataSample,
106
- ...newRecord,
107
- updater: user
108
- })
109
-
110
- results.push({ ...result, cuFlag: 'M' })
111
- }
112
- }
113
-
114
- return results
115
- }
116
-
117
- @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
118
- @Directive('@transaction')
119
- @Mutation(returns => Boolean, { description: 'To delete a data sample' })
120
- async deleteDataSample(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
121
- const { domain, tx } = context.state
122
-
123
- await tx.getRepository(DataSample).delete({ domain, id })
124
- return true
125
- }
126
-
127
- @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
128
- @Directive('@transaction')
129
- @Mutation(returns => Boolean, { description: 'To delete multiple data samples' })
130
- async deleteDataSamples(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
131
- const { domain, tx } = context.state
132
-
133
- await tx.getRepository(DataSample).delete({
134
- domain,
135
- id: In(ids)
136
- })
137
-
138
- return true
16
+ return await createDataSample(dataSample, context)
139
17
  }
140
18
  }
@@ -1,6 +1,6 @@
1
- import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
1
+ import { Field, InputType, Int, ObjectType } from 'type-graphql'
2
2
 
3
- import { ScalarObject } from '@things-factory/shell'
3
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
4
4
 
5
5
  import { DataSample } from './data-sample'
6
6
 
@@ -12,8 +12,8 @@ export class NewDataSample {
12
12
  @Field({ nullable: true })
13
13
  description?: string
14
14
 
15
- @Field({ nullable: true })
16
- dataSetId?: string
15
+ @Field(type => ObjectRef, { nullable: true })
16
+ dataSet?: ObjectRef
17
17
 
18
18
  @Field(type => ScalarObject, { nullable: true })
19
19
  data?: ScalarObject
@@ -25,34 +25,13 @@ export class NewDataSample {
25
25
  source?: string
26
26
 
27
27
  @Field({ nullable: true })
28
- collectedAt?: Date
29
- }
30
-
31
- @InputType()
32
- export class DataSamplePatch {
33
- @Field(type => ID, { nullable: true })
34
- id?: string
35
-
36
- @Field({ nullable: true })
37
- name?: string
38
-
39
- @Field({ nullable: true })
40
- description?: string
41
-
42
- @Field({ nullable: true })
43
- dataSetId?: string
44
-
45
- @Field(type => ScalarObject, { nullable: true })
46
- data?: ScalarObject
28
+ workDate?: string
47
29
 
48
30
  @Field({ nullable: true })
49
- rawData?: string
31
+ workShift?: string
50
32
 
51
33
  @Field({ nullable: true })
52
- source?: string
53
-
54
- @Field()
55
- cuFlag: string
34
+ collectedAt?: Date
56
35
  }
57
36
 
58
37
  @ObjectType()
@@ -20,6 +20,11 @@ const ORMCONFIG = config.get('ormconfig', {})
20
20
  const DATABASE_TYPE = ORMCONFIG.type
21
21
  @Entity()
22
22
  @Index('ix_data_sample_0', (dataSample: DataSample) => [dataSample.domain, dataSample.dataSet], { unique: false })
23
+ @Index(
24
+ 'ix_data_sample_2',
25
+ (dataSample: DataSample) => [dataSample.domain, dataSample.dataSet, dataSample.collectedAt],
26
+ { unique: false }
27
+ )
23
28
  @ObjectType({ description: 'Entity for DataSample' })
24
29
  export class DataSample {
25
30
  @PrimaryGeneratedColumn('uuid')
@@ -49,16 +54,21 @@ export class DataSample {
49
54
  @Field({ nullable: true })
50
55
  type?: string
51
56
 
57
+ @Column({
58
+ nullable: true
59
+ })
60
+ @Field({ nullable: true })
61
+ useCase?: string
62
+
52
63
  @Column('simple-json', { nullable: true })
53
64
  @Field(type => ScalarObject, { nullable: true })
54
65
  partitionKeys?: ScalarObject
55
66
 
56
- @ManyToOne(type => DataSet, dataSet => dataSet.dataSamples)
57
- @Field(type => DataSet, { nullable: true })
67
+ @ManyToOne(type => DataSet)
68
+ @Field(type => DataSet, { nullable: false })
58
69
  dataSet?: DataSet
59
70
 
60
71
  @RelationId((dataSample: DataSample) => dataSample.dataSet)
61
- @Field({ nullable: true })
62
72
  dataSetId?: string
63
73
 
64
74
  @Column('simple-json', { nullable: true })
@@ -87,6 +97,26 @@ export class DataSample {
87
97
  @Field({ nullable: true })
88
98
  source?: string
89
99
 
100
+ @Column({
101
+ nullable: true
102
+ })
103
+ @Field({ nullable: true })
104
+ ooc?: boolean
105
+
106
+ @Column({
107
+ nullable: true
108
+ })
109
+ @Field({ nullable: true })
110
+ oos?: boolean
111
+
112
+ @Column({ nullable: true })
113
+ @Field({ nullable: true })
114
+ workDate?: string
115
+
116
+ @Column({ nullable: true })
117
+ @Field({ nullable: true })
118
+ workShift?: string
119
+
90
120
  @Column({ nullable: true })
91
121
  @Field({ nullable: true })
92
122
  collectedAt?: Date
@@ -200,10 +200,7 @@ export class DataSetMutation {
200
200
 
201
201
  return copiedDataSets.map(dataSet => {
202
202
  dataSet.dataItems = copiedDataItems.filter(dataItem => dataItem.dataSet == dataSet.id)
203
- return {
204
- ...dataSet,
205
- state: 'UNLOADED' // DataSetInstanceStatus.UNLOADED
206
- }
203
+ return dataSet
207
204
  })
208
205
  }
209
206
  }
@@ -1,13 +1,17 @@
1
1
  import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
- import { getRepository } from 'typeorm'
2
+ import { Equal, getRepository } from 'typeorm'
3
3
 
4
- import { User } from '@things-factory/auth-base'
4
+ import { Role, User } from '@things-factory/auth-base'
5
+ import { Board } from '@things-factory/board-service'
5
6
  import { convertListParams, Domain, ListParam } from '@things-factory/shell'
6
7
 
7
8
  import { DataItem } from '../data-item/data-item'
9
+ import { DataSample } from '../data-sample/data-sample'
8
10
  import { DataSet } from './data-set'
9
11
  import { DataSetList } from './data-set-type'
10
12
 
13
+ var parser = require('cron-parser')
14
+
11
15
  @Resolver(DataSet)
12
16
  export class DataSetQuery {
13
17
  @Directive('@privilege(category: "data-set", privilege: "query", domainOwnerGranted: true)')
@@ -31,6 +35,25 @@ export class DataSetQuery {
31
35
  return { items, total }
32
36
  }
33
37
 
38
+ @Query(returns => DataSetList, { description: 'To fetch multiple DataSets for data entry manually' })
39
+ async dataSetsForEntry(@Args() params: ListParam, @Ctx() context: any): Promise<DataSetList> {
40
+ const { domain } = context.state
41
+
42
+ /* TODO. 조회한 사용자가 supervisory 역할을 가진 data-set 리스트만 반환 */
43
+
44
+ const { where = {}, order, skip, take } = convertListParams(params, domain.id)
45
+ where.active = Equal(true)
46
+
47
+ const [items, total] = await getRepository(DataSet).findAndCount({
48
+ where,
49
+ order,
50
+ skip,
51
+ take
52
+ })
53
+
54
+ return { items, total }
55
+ }
56
+
34
57
  @FieldResolver(type => [DataItem])
35
58
  async dataItems(@Root() dataSet: DataSet): Promise<DataItem[]> {
36
59
  return await getRepository(DataItem).find({
@@ -38,6 +61,27 @@ export class DataSetQuery {
38
61
  })
39
62
  }
40
63
 
64
+ @FieldResolver(type => Role)
65
+ async supervisoryRole(@Root() dataSet: DataSet): Promise<Role> {
66
+ return await getRepository(Role).findOne({
67
+ id: dataSet.supervisoryRoleId
68
+ })
69
+ }
70
+
71
+ @FieldResolver(type => Board, { nullable: true })
72
+ async entryBoard(@Root() dataSet: DataSet) {
73
+ if (dataSet.entryType == 'board' && dataSet.entryView) {
74
+ return await getRepository(Board).findOne({ id: dataSet.entryView })
75
+ }
76
+ }
77
+
78
+ @FieldResolver(type => Board, { nullable: true })
79
+ async monitorBoard(@Root() dataSet: DataSet) {
80
+ if (dataSet.monitorType == 'board' && dataSet.monitorView) {
81
+ return await getRepository(Board).findOne({ id: dataSet.monitorView })
82
+ }
83
+ }
84
+
41
85
  @FieldResolver(type => Domain)
42
86
  async domain(@Root() dataSet: DataSet): Promise<Domain> {
43
87
  return await getRepository(Domain).findOne(dataSet.domainId)
@@ -52,4 +96,45 @@ export class DataSetQuery {
52
96
  async creator(@Root() dataSet: DataSet): Promise<User> {
53
97
  return await getRepository(User).findOne(dataSet.creatorId)
54
98
  }
99
+
100
+ @FieldResolver(type => Date, { nullable: true })
101
+ async latestCollectedAt(@Root() dataSet: DataSet): Promise<Date> {
102
+ const sample = await getRepository(DataSample).findOne({
103
+ select: ['collectedAt'],
104
+ where: { dataSet },
105
+ order: { collectedAt: 'DESC' }
106
+ })
107
+
108
+ return sample?.collectedAt
109
+ }
110
+
111
+ @FieldResolver(type => Date, { nullable: true })
112
+ async nextSchedule(@Root() dataSet: DataSet): Promise<Date> {
113
+ const { timezone, schedule } = dataSet
114
+
115
+ if (!schedule) {
116
+ return
117
+ }
118
+
119
+ var interval = parser.parseExpression(schedule, {
120
+ tz: timezone
121
+ })
122
+
123
+ return interval.next().toDate()
124
+ }
125
+
126
+ @FieldResolver(type => Date, { nullable: true })
127
+ async prevSchedule(@Root() dataSet: DataSet): Promise<Date> {
128
+ const { timezone, schedule } = dataSet
129
+
130
+ if (!schedule) {
131
+ return
132
+ }
133
+
134
+ var interval = parser.parseExpression(schedule, {
135
+ tz: timezone
136
+ })
137
+
138
+ return interval.prev().toDate()
139
+ }
55
140
  }
@@ -1,8 +1,8 @@
1
1
  import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
2
2
 
3
- import { ScalarObject } from '@things-factory/shell'
3
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
4
4
 
5
- import { DataSet } from './data-set'
5
+ import { DataSet, DataSetViewType } from './data-set'
6
6
 
7
7
  @InputType()
8
8
  export class NewDataSet {
@@ -12,11 +12,17 @@ export class NewDataSet {
12
12
  @Field({ nullable: true })
13
13
  description?: string
14
14
 
15
+ @Field(type => ObjectRef, { nullable: true })
16
+ supervisoryRole?: ObjectRef
17
+
15
18
  @Field({ nullable: true })
16
19
  active?: boolean
17
20
 
18
21
  @Field({ nullable: true })
19
- type?: string
22
+ type?: 'manual' | 'automatic' | string
23
+
24
+ @Field({ nullable: true })
25
+ useCase?: string
20
26
 
21
27
  @Field(type => ScalarObject, { nullable: true })
22
28
  partitionKeys?: ScalarObject
@@ -26,6 +32,18 @@ export class NewDataSet {
26
32
 
27
33
  @Field({ nullable: true })
28
34
  timezone?: string
35
+
36
+ @Field({ nullable: true })
37
+ entryType?: DataSetViewType
38
+
39
+ @Field({ nullable: true })
40
+ entryView?: string
41
+
42
+ @Field({ nullable: true })
43
+ monitorType?: DataSetViewType
44
+
45
+ @Field({ nullable: true })
46
+ monitorView?: string
29
47
  }
30
48
 
31
49
  @InputType()
@@ -39,11 +57,14 @@ export class DataSetPatch {
39
57
  @Field({ nullable: true })
40
58
  description?: string
41
59
 
60
+ @Field(type => ObjectRef, { nullable: true })
61
+ supervisoryRole?: ObjectRef
62
+
42
63
  @Field({ nullable: true })
43
64
  active?: boolean
44
65
 
45
66
  @Field({ nullable: true })
46
- type?: string
67
+ useCase?: string
47
68
 
48
69
  @Field(type => ScalarObject, { nullable: true })
49
70
  partitionKeys?: ScalarObject
@@ -54,6 +75,18 @@ export class DataSetPatch {
54
75
  @Field({ nullable: true })
55
76
  timezone?: string
56
77
 
78
+ @Field({ nullable: true })
79
+ entryType?: DataSetViewType
80
+
81
+ @Field({ nullable: true })
82
+ entryView?: string
83
+
84
+ @Field({ nullable: true })
85
+ monitorType?: DataSetViewType
86
+
87
+ @Field({ nullable: true })
88
+ monitorView?: string
89
+
57
90
  @Field()
58
91
  cuFlag: string
59
92
  }