@things-factory/dataset 6.1.185 → 6.1.186

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/dataset",
3
- "version": "6.1.185",
3
+ "version": "6.1.186",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -37,19 +37,19 @@
37
37
  "@operato/shell": "^1.0.1",
38
38
  "@operato/styles": "^1.0.0",
39
39
  "@operato/utils": "^1.0.1",
40
- "@things-factory/auth-base": "^6.1.185",
41
- "@things-factory/aws-base": "^6.1.185",
42
- "@things-factory/board-service": "^6.1.185",
40
+ "@things-factory/auth-base": "^6.1.186",
41
+ "@things-factory/aws-base": "^6.1.186",
42
+ "@things-factory/board-service": "^6.1.186",
43
43
  "@things-factory/env": "^6.1.175",
44
- "@things-factory/organization": "^6.1.185",
45
- "@things-factory/scheduler-client": "^6.1.185",
46
- "@things-factory/shell": "^6.1.182",
47
- "@things-factory/work-shift": "^6.1.185",
48
- "@things-factory/worklist": "^6.1.185",
44
+ "@things-factory/organization": "^6.1.186",
45
+ "@things-factory/scheduler-client": "^6.1.186",
46
+ "@things-factory/shell": "^6.1.186",
47
+ "@things-factory/work-shift": "^6.1.186",
48
+ "@things-factory/worklist": "^6.1.186",
49
49
  "cron-parser": "^4.3.0",
50
50
  "moment-timezone": "^0.5.40",
51
51
  "simple-statistics": "^7.8.3",
52
52
  "statistics": "^3.3.0"
53
53
  },
54
- "gitHead": "b6793ed8361e9fc5a4776fb48010007960ffdec8"
54
+ "gitHead": "ddf508496cdd7d4b9d0e020703a2f7a586a42ec5"
55
55
  }
@@ -9,7 +9,9 @@ import { logger } from '@things-factory/env'
9
9
  import {
10
10
  getDateRangeForWorkDate,
11
11
  getDateRangeForWorkShift,
12
- getLatestWorkDateAndShift
12
+ getLatestWorkDateAndShift,
13
+ getSummaryScheduleForWorkDate,
14
+ getSummaryScheduleForWorkShift
13
15
  } from '@things-factory/work-shift'
14
16
 
15
17
  import { DataSample } from '../service/data-sample/data-sample'
@@ -179,6 +181,26 @@ async function getTimesForPeriod(
179
181
  }
180
182
  }
181
183
 
184
+ export async function getDataSummaryCrontabSchedule(dataSet: DataSet, context: ResolverContext): Promise<string> {
185
+ const { domain, user, tx } = context.state
186
+
187
+ try {
188
+ const { summaryPeriod } = dataSet
189
+
190
+ if (summaryPeriod == DataSetSummaryPeriodType.Hour) {
191
+ return '0 5 * * * *'
192
+ } else if (summaryPeriod == DataSetSummaryPeriodType.WorkShift) {
193
+ return await getSummaryScheduleForWorkShift(domain)
194
+ } else if (summaryPeriod == DataSetSummaryPeriodType.WorkDate) {
195
+ return await getSummaryScheduleForWorkDate(domain)
196
+ } else if (summaryPeriod == DataSetSummaryPeriodType.Day) {
197
+ return '0 10 0 * * *'
198
+ }
199
+ } catch (err) {
200
+ console.error(err)
201
+ }
202
+ }
203
+
182
204
  export async function generateLatestDataSummaries(dataSetId: string, context: ResolverContext): Promise<boolean> {
183
205
  const { domain, user, tx } = context.state
184
206
 
@@ -6,8 +6,9 @@ import { Application, CallbackBase, registerSchedule, unregisterSchedule } from
6
6
  import { ApprovalLineItem, OrgMemberTargetType } from '@things-factory/organization'
7
7
  import { AssigneeItem } from '@things-factory/worklist'
8
8
 
9
- import { DataSet } from './data-set'
9
+ import { DataSet, DataSetSummaryPeriodType } from './data-set'
10
10
  import { DataSetPatch, NewDataSet } from './data-set-type'
11
+ import { getDataSummaryCrontabSchedule } from '../../controllers/generate-data-summary'
11
12
 
12
13
  const crypto = require('crypto')
13
14
 
@@ -325,6 +326,117 @@ export class DataSetMutation {
325
326
  }
326
327
  }
327
328
 
329
+ @Directive('@transaction')
330
+ @Mutation(returns => DataSet, { description: 'To start data summary schedule for the given dataset' })
331
+ async startDataSummarySchedule(
332
+ @Arg('dataSetId') dataSetId: string,
333
+ @Ctx() context: ResolverContext
334
+ ): Promise<DataSet> {
335
+ const { domain, tx } = context.state
336
+
337
+ var repository = tx.getRepository(DataSet)
338
+ var dataSet = await repository.findOne({
339
+ where: { domain: { id: domain.id }, id: dataSetId }
340
+ })
341
+
342
+ if (!dataSet) {
343
+ throw new Error(
344
+ context.t('error.data-set not found', {
345
+ dataSet: dataSetId
346
+ })
347
+ )
348
+ }
349
+
350
+ if (!dataSet.summaryPeriod) {
351
+ throw new Error(
352
+ context.t('error.data-set summary-period not set', {
353
+ dataSet: dataSetId
354
+ })
355
+ )
356
+ }
357
+
358
+ const schedule = await getDataSummaryCrontabSchedule(dataSet, context)
359
+
360
+ try {
361
+ var handle = await registerSchedule({
362
+ name: dataSet.name,
363
+ client: {
364
+ application: Application,
365
+ group: `${domain.id}`,
366
+ type: 'data-set',
367
+ key: dataSet.id,
368
+ operation: 'summary'
369
+ },
370
+ type: 'cron',
371
+ schedule,
372
+ timezone: dataSet.timezone,
373
+ task: {
374
+ type: 'rest',
375
+ connection: {
376
+ host: `${CallbackBase}/callback-schedule-for-dataset-summary`,
377
+ headers: {
378
+ 'Content-Type': 'application/json',
379
+ accept: '*/*'
380
+ }
381
+ },
382
+ data: {
383
+ domainId: domain.id,
384
+ dataSetId
385
+ },
386
+ history_check: true,
387
+ failed_policy: 'retry_dlq',
388
+ max_retry_count: 3,
389
+ retry_period: 60
390
+ }
391
+ })
392
+
393
+ return await repository.save({
394
+ ...dataSet,
395
+ summarySchedule: schedule,
396
+ summaryScheduleId: handle
397
+ })
398
+ } catch (err) {
399
+ console.error('startDataSummarySchedule', err)
400
+ }
401
+ }
402
+
403
+ @Directive('@transaction')
404
+ @Mutation(returns => DataSet, {
405
+ nullable: true,
406
+ description: 'To stop data summary schedule for the given dataset'
407
+ })
408
+ async stopDataSummarySchedule(
409
+ @Arg('dataSetId') dataSetId: string,
410
+ @Ctx() context: ResolverContext
411
+ ): Promise<DataSet | undefined> {
412
+ const { domain, tx } = context.state
413
+
414
+ var repository = tx.getRepository(DataSet)
415
+ var dataSet = await repository.findOne({
416
+ where: { domain: { id: domain.id }, id: dataSetId }
417
+ })
418
+
419
+ if (!dataSet) {
420
+ throw new Error(
421
+ context.t('error.data-set not found', {
422
+ dataSet: dataSetId
423
+ })
424
+ )
425
+ }
426
+
427
+ try {
428
+ await unregisterSchedule(dataSet.summaryScheduleId)
429
+
430
+ return await repository.save({
431
+ ...dataSet,
432
+ summarySchedule: null,
433
+ summaryScheduleId: null
434
+ })
435
+ } catch (err) {
436
+ console.error('stopDataSummarySchedule', err)
437
+ }
438
+ }
439
+
328
440
  @Directive('@privilege(category: "data-set", privilege: "mutation", domainOwnerGranted: true)')
329
441
  @Directive('@transaction')
330
442
  @Mutation(returns => Boolean, { description: 'To import multiple data-sets' })
@@ -7,6 +7,7 @@ import { Board } from '@things-factory/board-service'
7
7
  import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
8
8
  import { ApprovalLineItem } from '@things-factory/organization'
9
9
  import { AssigneeItem } from '@things-factory/worklist'
10
+ import { Application, getSchedules } from '@things-factory/scheduler-client'
10
11
 
11
12
  import { DataKeySet } from '../data-key-set/data-key-set'
12
13
  import { DataSample } from '../data-sample/data-sample'
@@ -322,6 +323,33 @@ export class DataSetQuery {
322
323
  return interval.prev().toDate()
323
324
  }
324
325
 
326
+ @FieldResolver(type => Date, { nullable: true })
327
+ async nextSummarySchedule(@Root() dataSet: DataSet): Promise<Date> {
328
+ const { domainId, summarySchedule, timezone } = dataSet
329
+
330
+ if (!summarySchedule) {
331
+ return
332
+ }
333
+
334
+ var interval = parser.parseExpression(summarySchedule, {
335
+ tz: timezone || ((await getRepository(Domain).findOneBy({ id: domainId })) as Domain).timezone || 'UTC'
336
+ })
337
+
338
+ return interval.next().toDate()
339
+
340
+ // /* FIXME: getSchedules 의 파라미터를 수정해야한다. scheduler 가 없거나 커넥션이 끊겨있어서 오래걸리는 문제는 어떻게 ?? 비동기로 처리한다. 어떻게???
341
+ // client: {
342
+ // application: Application,
343
+ // group: `${domain.id}`,
344
+ // type: 'data-set',
345
+ // key: dataSet.id,
346
+ // operation: 'summary'
347
+ // },
348
+ // */
349
+ // const schedule = getSchedules('name', 'group', false)
350
+ // return schedule.nextSchedule
351
+ }
352
+
325
353
  @FieldResolver(type => String)
326
354
  async reportTemplate(@Root() dataset: DataSet): Promise<string | undefined> {
327
355
  const attachment: Attachment = await getRepository(Attachment).findOne({
@@ -215,6 +215,10 @@ export class DataSet {
215
215
  @Field({ nullable: true })
216
216
  summaryPeriod?: DataSetSummaryPeriodType
217
217
 
218
+ @Column({ nullable: true })
219
+ @Field({ nullable: true })
220
+ summarySchedule?: string
221
+
218
222
  @Column({ nullable: true })
219
223
  @Field({ nullable: true })
220
224
  summaryScheduleId?: string
@@ -69,6 +69,8 @@
69
69
  "field.work-date": "work date",
70
70
  "field.work-shift": "work shift",
71
71
  "label.acceptables": "acceptables",
72
+ "label.corrective action": "corrective action",
73
+ "label.corrective instruction": "corrective instruction",
72
74
  "label.critical-limits": "critical limits",
73
75
  "label.data-set-type": "type",
74
76
  "label.end-date": "end date",
@@ -69,6 +69,8 @@
69
69
  "field.work-date": "作業基準日",
70
70
  "field.work-shift": "交代勤務組",
71
71
  "label.acceptables": "許容値",
72
+ "label.corrective action": "是正措置",
73
+ "label.corrective instruction": "是正指示",
72
74
  "label.critical-limits": "許容限界範囲",
73
75
  "label.data-set-type": "タイプ",
74
76
  "label.end-date": "終了日",
@@ -69,6 +69,8 @@
69
69
  "field.work-date": "작업기준일",
70
70
  "field.work-shift": "교대근무조",
71
71
  "label.acceptables": "허용값",
72
+ "label.corrective action": "수정 조치",
73
+ "label.corrective instruction": "수정 지시",
72
74
  "label.critical-limits": "허용 한계범위",
73
75
  "label.data-set-type": "유형",
74
76
  "label.end-date": "종료일",
@@ -66,6 +66,8 @@
66
66
  "field.work-date": "work date",
67
67
  "field.work-shift": "work shift",
68
68
  "label.acceptables": "acceptables",
69
+ "label.corrective action": "tindakan pembetulan",
70
+ "label.corrective instruction": "arahan pembetulan",
69
71
  "label.critical-limits": "critical limits",
70
72
  "label.data-set-type": "type",
71
73
  "label.minimum value": "minimum value",
@@ -66,6 +66,8 @@
66
66
  "field.work-date": "work date",
67
67
  "field.work-shift": "work shift",
68
68
  "label.acceptables": "acceptables",
69
+ "label.corrective action": "纠正措施",
70
+ "label.corrective instruction": "纠正指示",
69
71
  "label.critical-limits": "critical limits",
70
72
  "label.data-set-type": "type",
71
73
  "label.minimum value": "minimum value",