@things-factory/dataset 7.1.11 → 7.1.12-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/dataset",
3
- "version": "7.1.11",
3
+ "version": "7.1.12-alpha.0",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -40,21 +40,21 @@
40
40
  "@operato/shell": "^7.0.0",
41
41
  "@operato/styles": "^7.0.0",
42
42
  "@operato/utils": "^7.0.0",
43
- "@things-factory/auth-base": "^7.1.11",
44
- "@things-factory/aws-base": "^7.1.11",
45
- "@things-factory/board-service": "^7.1.11",
46
- "@things-factory/env": "^7.1.11",
47
- "@things-factory/integration-base": "^7.1.11",
48
- "@things-factory/organization": "^7.1.11",
49
- "@things-factory/personalization": "^7.1.11",
50
- "@things-factory/scheduler-client": "^7.1.11",
51
- "@things-factory/shell": "^7.1.11",
52
- "@things-factory/work-shift": "^7.1.11",
53
- "@things-factory/worklist": "^7.1.11",
43
+ "@things-factory/auth-base": "^7.1.12-alpha.0",
44
+ "@things-factory/aws-base": "^7.1.12-alpha.0",
45
+ "@things-factory/board-service": "^7.1.12-alpha.0",
46
+ "@things-factory/env": "^7.1.12-alpha.0",
47
+ "@things-factory/integration-base": "^7.1.12-alpha.0",
48
+ "@things-factory/organization": "^7.1.12-alpha.0",
49
+ "@things-factory/personalization": "^7.1.12-alpha.0",
50
+ "@things-factory/scheduler-client": "^7.1.12-alpha.0",
51
+ "@things-factory/shell": "^7.1.12-alpha.0",
52
+ "@things-factory/work-shift": "^7.1.12-alpha.0",
53
+ "@things-factory/worklist": "^7.1.12-alpha.0",
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": "039ece6ca36faf7fcfadb53c4f6335f584692968"
59
+ "gitHead": "2be45c33868b2cc01d55b7b540b9a4877805ff8a"
60
60
  }
@@ -1,5 +1,5 @@
1
1
  import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
- import { In } from 'typeorm'
2
+ import { Brackets, In } from 'typeorm'
3
3
 
4
4
  import { Attachment } from '@things-factory/attachment-base'
5
5
  import { Role, User } from '@things-factory/auth-base'
@@ -19,6 +19,7 @@ var parser = require('cron-parser')
19
19
 
20
20
  @Resolver(DataSet)
21
21
  export class DataSetQuery {
22
+ // 데이터셋을 ID로 조회
22
23
  @Directive('@privilege(category: "data-set", privilege: "query", domainOwnerGranted: true)')
23
24
  @Query(returns => DataSet, { description: 'To fetch a DataSet' })
24
25
  async dataSet(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<DataSet> {
@@ -29,6 +30,7 @@ export class DataSetQuery {
29
30
  })
30
31
  }
31
32
 
33
+ // 데이터셋을 이름으로 조회
32
34
  @Directive('@privilege(category: "data-set", privilege: "query", domainOwnerGranted: true)')
33
35
  @Query(returns => DataSet, { description: 'To fetch a DataSet by name' })
34
36
  async dataSetByName(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<DataSet> {
@@ -39,6 +41,7 @@ export class DataSetQuery {
39
41
  })
40
42
  }
41
43
 
44
+ // 여러 데이터셋을 조회
42
45
  @Directive('@privilege(category: "data-set", privilege: "query", domainOwnerGranted: true)')
43
46
  @Query(returns => DataSetList, { description: 'To fetch multiple DataSets' })
44
47
  async dataSets(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<DataSetList> {
@@ -57,6 +60,7 @@ export class DataSetQuery {
57
60
  return { items, total }
58
61
  }
59
62
 
63
+ // 데이터 입력을 위한 데이터셋 조회
60
64
  @Query(returns => DataSetList, { description: 'To fetch multiple DataSets for data entry manually' })
61
65
  async dataSetsForEntry(
62
66
  @Args(type => ListParam) params: ListParam,
@@ -64,7 +68,7 @@ export class DataSetQuery {
64
68
  ): Promise<DataSetList> {
65
69
  var { domain, user } = context.state
66
70
 
67
- /* 조회한 사용자가 entry-role을 가진 data-set 리스트만 반환 */
71
+ // 조회한 사용자가 entry-role을 가진 data-set 리스트만 반환
68
72
  user = await getRepository(User).findOne({
69
73
  where: { id: user.id },
70
74
  relations: ['roles']
@@ -86,12 +90,23 @@ export class DataSetQuery {
86
90
  searchables: ['name', 'description']
87
91
  })
88
92
  .andWhere('dataset.active = :active', { active: true })
89
- .andWhere('dataset.entryRole IN (:...roles)', { roles })
93
+ .andWhere(
94
+ new Brackets(qb => {
95
+ qb.where('dataset.supervisoryRole IN (:...roles)', { roles }).orWhere('dataset.entryRole IN (:...roles)', {
96
+ roles
97
+ })
98
+ })
99
+ )
100
+ .setParameter('roles', roles)
90
101
  .getManyAndCount()
91
102
 
92
- return { items, total }
103
+ return {
104
+ items,
105
+ total
106
+ }
93
107
  }
94
108
 
109
+ // 데이터 보고를 위한 데이터셋 조회
95
110
  @Query(returns => DataSetList, { description: 'To fetch multiple DataSets to see data report' })
96
111
  async dataSetsForReport(
97
112
  @Args(type => ListParam) params: ListParam,
@@ -99,7 +114,7 @@ export class DataSetQuery {
99
114
  ): Promise<DataSetList> {
100
115
  var { domain, user } = context.state
101
116
 
102
- /* 조회한 사용자가 supervisory 역할을 가진 data-set 리스트만 반환 */
117
+ // 조회한 사용자가 supervisory 역할을 가진 data-set 리스트만 반환
103
118
  user = await getRepository(User).findOne({
104
119
  where: { id: user.id },
105
120
  relations: ['roles']
@@ -124,9 +139,10 @@ export class DataSetQuery {
124
139
  return { items, total }
125
140
  }
126
141
 
142
+ // 데이터셋의 상태를 조회
127
143
  @FieldResolver(type => DataSetState)
128
144
  async status(@Root() dataSet: DataSet): Promise<DataSetState> {
129
- // get information from scheduler service
145
+ // 스케줄러 서비스에서 정보 가져오기
130
146
  return {
131
147
  id: '',
132
148
  scheduleId: '',
@@ -136,6 +152,7 @@ export class DataSetQuery {
136
152
  }
137
153
  }
138
154
 
155
+ // 데이터셋의 데이터 항목을 조회
139
156
  @FieldResolver(type => [DataItem])
140
157
  async dataItems(@Root() dataSet: DataSet): Promise<DataItem[]> {
141
158
  if (dataSet.dataItems instanceof Array) {
@@ -145,6 +162,7 @@ export class DataSetQuery {
145
162
  return []
146
163
  }
147
164
 
165
+ // 데이터셋의 entry 역할을 조회
148
166
  @FieldResolver(type => Role)
149
167
  async entryRole(@Root() dataSet: DataSet): Promise<Role> {
150
168
  return (
@@ -156,7 +174,8 @@ export class DataSetQuery {
156
174
  )
157
175
  }
158
176
 
159
- @FieldResolver(type => Role)
177
+ // 데이터셋의 supervisory 역할을 조회
178
+ @FieldResolver(type => Role, { description: 'Retrieves the supervisory role for the dataset' })
160
179
  async supervisoryRole(@Root() dataSet: DataSet): Promise<Role> {
161
180
  return (
162
181
  dataSet.supervisoryRole ||
@@ -167,7 +186,7 @@ export class DataSetQuery {
167
186
  )
168
187
  }
169
188
 
170
- @FieldResolver(type => [AssigneeItem])
189
+ @FieldResolver(type => [AssigneeItem], { description: 'Retrieves the assignee items for the dataset' })
171
190
  async assignees(@Root() dataSet: DataSet, @Ctx() context: ResolverContext): Promise<AssigneeItem[]> {
172
191
  const { domain, user } = context.state
173
192
  const { assignees } = dataSet
@@ -208,7 +227,7 @@ export class DataSetQuery {
208
227
  return assigneeItemList
209
228
  }
210
229
 
211
- @FieldResolver(type => [ApprovalLineItem])
230
+ @FieldResolver(type => [ApprovalLineItem], { description: 'Retrieves the approval line items for the dataset' })
212
231
  async approvalLine(@Root() dataSet: DataSet, @Ctx() context: ResolverContext): Promise<ApprovalLineItem[]> {
213
232
  const { domain, user } = context.state
214
233
  const { reviewApprovalLine } = dataSet
@@ -250,21 +269,21 @@ export class DataSetQuery {
250
269
  return approvalLineItems
251
270
  }
252
271
 
253
- @FieldResolver(type => Board, { nullable: true })
272
+ @FieldResolver(type => Board, { nullable: true, description: 'Retrieves the entry board for the dataset' })
254
273
  async entryBoard(@Root() dataSet: DataSet): Promise<Board> {
255
274
  if (dataSet.entryType == 'board' && dataSet.entryView) {
256
275
  return await getRepository(Board).findOneBy({ id: dataSet.entryView })
257
276
  }
258
277
  }
259
278
 
260
- @FieldResolver(type => Board, { nullable: true })
279
+ @FieldResolver(type => Board, { nullable: true, description: 'Retrieves the monitor board for the dataset' })
261
280
  async monitorBoard(@Root() dataSet: DataSet): Promise<Board> {
262
281
  if (dataSet.monitorType == 'board' && dataSet.monitorView) {
263
282
  return await getRepository(Board).findOneBy({ id: dataSet.monitorView })
264
283
  }
265
284
  }
266
285
 
267
- @FieldResolver(type => DataKeySet, { nullable: true })
286
+ @FieldResolver(type => DataKeySet, { nullable: true, description: 'Retrieves the data key set for the dataset' })
268
287
  async dataKeySet(@Root() dataSet: DataSet): Promise<DataKeySet> {
269
288
  return (
270
289
  dataSet.dataKeySet ||
@@ -275,7 +294,7 @@ export class DataSetQuery {
275
294
  )
276
295
  }
277
296
 
278
- @FieldResolver(type => Scenario)
297
+ @FieldResolver(type => Scenario, { description: 'Retrieves the normal scenario for the dataset.' })
279
298
  async normalScenario(@Root() dataSet: DataSet): Promise<Scenario> {
280
299
  return (
281
300
  dataSet.normalScenario ||
@@ -286,7 +305,7 @@ export class DataSetQuery {
286
305
  )
287
306
  }
288
307
 
289
- @FieldResolver(type => Scenario)
308
+ @FieldResolver(type => Scenario, { description: 'Retrieves the outlier scenario for the dataset.' })
290
309
  async outlierScenario(@Root() dataSet: DataSet): Promise<Scenario> {
291
310
  return (
292
311
  dataSet.outlierScenario ||
@@ -297,22 +316,25 @@ export class DataSetQuery {
297
316
  )
298
317
  }
299
318
 
319
+ // 데이터셋의 도메인을 조회
300
320
  @FieldResolver(type => Domain)
301
321
  async domain(@Root() dataSet: DataSet): Promise<Domain> {
302
322
  return dataSet.domainId && (await getRepository(Domain).findOneBy({ id: dataSet.domainId }))
303
323
  }
304
324
 
325
+ // 데이터셋의 업데이트한 사용자를 조회
305
326
  @FieldResolver(type => User)
306
327
  async updater(@Root() dataSet: DataSet): Promise<User> {
307
328
  return dataSet.updaterId && (await getRepository(User).findOneBy({ id: dataSet.updaterId }))
308
329
  }
309
330
 
331
+ // 데이터셋의 생성자를 조회
310
332
  @FieldResolver(type => User)
311
333
  async creator(@Root() dataSet: DataSet): Promise<User> {
312
334
  return dataSet.creatorId && (await getRepository(User).findOneBy({ id: dataSet.creatorId }))
313
335
  }
314
336
 
315
- @FieldResolver(type => Date, { nullable: true })
337
+ @FieldResolver(type => Date, { nullable: true, description: 'Retrieves the latest collection time for the dataset.' })
316
338
  async latestCollectedAt(@Root() dataSet: DataSet): Promise<Date> {
317
339
  const sample = await getRepository(DataSample).findOne({
318
340
  select: ['id', 'collectedAt'],
@@ -323,7 +345,7 @@ export class DataSetQuery {
323
345
  return sample?.collectedAt
324
346
  }
325
347
 
326
- @FieldResolver(type => Date, { nullable: true })
348
+ @FieldResolver(type => Date, { nullable: true, description: 'Retrieves the next schedule time for the dataset.' })
327
349
  async nextSchedule(@Root() dataSet: DataSet): Promise<Date> {
328
350
  const { domainId, schedule, timezone } = dataSet
329
351
 
@@ -338,7 +360,7 @@ export class DataSetQuery {
338
360
  return interval.next().toDate()
339
361
  }
340
362
 
341
- @FieldResolver(type => Date, { nullable: true })
363
+ @FieldResolver(type => Date, { nullable: true, description: 'Retrieves the previous schedule time for the dataset.' })
342
364
  async prevSchedule(@Root() dataSet: DataSet): Promise<Date> {
343
365
  const { domainId, schedule, timezone } = dataSet
344
366
 
@@ -353,7 +375,10 @@ export class DataSetQuery {
353
375
  return interval.prev().toDate()
354
376
  }
355
377
 
356
- @FieldResolver(type => Date, { nullable: true })
378
+ @FieldResolver(type => Date, {
379
+ nullable: true,
380
+ description: 'Retrieves the next summary schedule time for the dataset.'
381
+ })
357
382
  async nextSummarySchedule(@Root() dataSet: DataSet): Promise<Date> {
358
383
  const { domainId, summarySchedule, timezone } = dataSet
359
384
 
@@ -367,20 +392,19 @@ export class DataSetQuery {
367
392
 
368
393
  return interval.next().toDate()
369
394
 
370
- // /* FIXME: getSchedules 의 파라미터를 수정해야한다. scheduler 가 없거나 커넥션이 끊겨있어서 오래걸리는 문제는 어떻게 ?? 비동기로 처리한다. 어떻게???
371
- // client: {
372
- // application: Application,
373
- // group: `${domain.id}`,
374
- // type: 'data-set',
375
- // key: dataSet.id,
376
- // operation: 'summary'
377
- // },
378
- // */
395
+ // FIXME: getSchedules 의 파라미터를 수정해야한다. scheduler 가 없거나 커넥션이 끊겨있어서 오래걸리는 문제는 어떻게 ?? 비동기로 처리한다. 어떻게???
396
+ // client: {
397
+ // application: Application,
398
+ // group: `${domain.id}`,
399
+ // type: 'data-set',
400
+ // key: dataSet.id,
401
+ // operation: 'summary'
402
+ // }
379
403
  // const schedule = getSchedules('name', 'group', false)
380
404
  // return schedule.nextSchedule
381
405
  }
382
406
 
383
- @FieldResolver(type => String)
407
+ @FieldResolver(type => String, { description: 'Retrieves the report template for the dataset.' })
384
408
  async reportTemplate(@Root() dataset: DataSet): Promise<string | undefined> {
385
409
  const attachment: Attachment = await getRepository(Attachment).findOne({
386
410
  where: {
@@ -392,4 +416,36 @@ export class DataSetQuery {
392
416
 
393
417
  return attachment?.path
394
418
  }
419
+
420
+ @FieldResolver(returns => Boolean, { description: 'Whether the user is a supervisor for this dataset' })
421
+ async isSupervisor(@Root() dataset: DataSet, @Ctx() context: ResolverContext): Promise<boolean> {
422
+ const { user, domain } = context.state
423
+
424
+ const foundUser = await getRepository(User).findOne({
425
+ where: { id: user.id },
426
+ relations: ['roles']
427
+ })
428
+
429
+ const roles = foundUser.roles
430
+ .filter(role => role.domainId === domain.id || (domain.parentId && role.domainId === domain.parentId))
431
+ .map(role => role.id)
432
+
433
+ return roles.includes(dataset.supervisoryRoleId)
434
+ }
435
+
436
+ @FieldResolver(returns => Boolean, { description: 'Whether the user is allowed to enter data for this dataset' })
437
+ async isEntryAllowed(@Root() dataset: DataSet, @Ctx() context: ResolverContext): Promise<boolean> {
438
+ const { user, domain } = context.state
439
+
440
+ const foundUser = await getRepository(User).findOne({
441
+ where: { id: user.id },
442
+ relations: ['roles']
443
+ })
444
+
445
+ const roles = foundUser.roles
446
+ .filter(role => role.domainId === domain.id || (domain.parentId && role.domainId === domain.parentId))
447
+ .map(role => role.id)
448
+
449
+ return roles.includes(dataset.entryRoleId)
450
+ }
395
451
  }