@things-factory/dataset 6.2.105 → 6.2.111

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 (80) hide show
  1. package/client/activities/activity-data-collect-view.ts +7 -0
  2. package/client/activities/activity-data-review-edit.ts +66 -4
  3. package/client/activities/activity-data-review-view.ts +78 -4
  4. package/client/activities/activity-ooc-resolve-view.ts +12 -0
  5. package/client/activities/activity-ooc-review-view.ts +12 -0
  6. package/client/pages/data-ooc/data-ooc-list-page.ts +16 -4
  7. package/client/pages/data-ooc/data-ooc-page.ts +42 -0
  8. package/client/pages/data-ooc/data-ooc-view.ts +158 -19
  9. package/client/pages/data-ooc/data-oocs-page.ts +69 -3
  10. package/client/pages/data-sample/data-sample-page.ts +7 -0
  11. package/client/pages/data-sample/data-sample-search-page.ts +25 -20
  12. package/client/pages/data-sample/data-sample-view.ts +144 -22
  13. package/client/pages/data-sample/data-samples-page.ts +131 -5
  14. package/client/pages/data-set/data-item-list.ts +2 -2
  15. package/dist-client/activities/activity-data-collect-view.js +7 -0
  16. package/dist-client/activities/activity-data-collect-view.js.map +1 -1
  17. package/dist-client/activities/activity-data-review-edit.d.ts +1 -1
  18. package/dist-client/activities/activity-data-review-edit.js +63 -5
  19. package/dist-client/activities/activity-data-review-edit.js.map +1 -1
  20. package/dist-client/activities/activity-data-review-view.d.ts +1 -1
  21. package/dist-client/activities/activity-data-review-view.js +75 -5
  22. package/dist-client/activities/activity-data-review-view.js.map +1 -1
  23. package/dist-client/activities/activity-ooc-resolve-view.js +12 -0
  24. package/dist-client/activities/activity-ooc-resolve-view.js.map +1 -1
  25. package/dist-client/activities/activity-ooc-review-view.js +12 -0
  26. package/dist-client/activities/activity-ooc-review-view.js.map +1 -1
  27. package/dist-client/pages/data-ooc/data-ooc-list-page.js +16 -4
  28. package/dist-client/pages/data-ooc/data-ooc-list-page.js.map +1 -1
  29. package/dist-client/pages/data-ooc/data-ooc-page.js +42 -0
  30. package/dist-client/pages/data-ooc/data-ooc-page.js.map +1 -1
  31. package/dist-client/pages/data-ooc/data-ooc-view.d.ts +6 -3
  32. package/dist-client/pages/data-ooc/data-ooc-view.js +155 -22
  33. package/dist-client/pages/data-ooc/data-ooc-view.js.map +1 -1
  34. package/dist-client/pages/data-ooc/data-oocs-page.d.ts +1 -0
  35. package/dist-client/pages/data-ooc/data-oocs-page.js +69 -3
  36. package/dist-client/pages/data-ooc/data-oocs-page.js.map +1 -1
  37. package/dist-client/pages/data-sample/data-sample-page.js +7 -0
  38. package/dist-client/pages/data-sample/data-sample-page.js.map +1 -1
  39. package/dist-client/pages/data-sample/data-sample-search-page.d.ts +6 -1
  40. package/dist-client/pages/data-sample/data-sample-search-page.js +19 -13
  41. package/dist-client/pages/data-sample/data-sample-search-page.js.map +1 -1
  42. package/dist-client/pages/data-sample/data-sample-view.d.ts +18 -0
  43. package/dist-client/pages/data-sample/data-sample-view.js +143 -21
  44. package/dist-client/pages/data-sample/data-sample-view.js.map +1 -1
  45. package/dist-client/pages/data-sample/data-samples-page.d.ts +2 -0
  46. package/dist-client/pages/data-sample/data-samples-page.js +132 -5
  47. package/dist-client/pages/data-sample/data-samples-page.js.map +1 -1
  48. package/dist-client/pages/data-set/data-item-list.js +2 -2
  49. package/dist-client/pages/data-set/data-item-list.js.map +1 -1
  50. package/dist-client/tsconfig.tsbuildinfo +1 -1
  51. package/dist-server/activities/activity-data-review.js.map +1 -1
  52. package/dist-server/activities/activity-ooc-review.js +2 -1
  53. package/dist-server/activities/activity-ooc-review.js.map +1 -1
  54. package/dist-server/controllers/create-data-sample.js +27 -29
  55. package/dist-server/controllers/create-data-sample.js.map +1 -1
  56. package/dist-server/service/data-ooc/data-ooc-query.js +32 -0
  57. package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -1
  58. package/dist-server/service/data-ooc/data-ooc.js +15 -26
  59. package/dist-server/service/data-ooc/data-ooc.js.map +1 -1
  60. package/dist-server/service/data-sample/data-sample-query.js +24 -0
  61. package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
  62. package/dist-server/service/data-sample/data-sample.js +15 -20
  63. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  64. package/dist-server/service/data-set/data-item-type.js +1 -0
  65. package/dist-server/service/data-set/data-item-type.js.map +1 -1
  66. package/dist-server/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +6 -6
  68. package/server/activities/activity-data-review.ts +1 -5
  69. package/server/activities/activity-ooc-review.ts +5 -15
  70. package/server/controllers/create-data-sample.ts +31 -38
  71. package/server/service/data-ooc/data-ooc-query.ts +17 -0
  72. package/server/service/data-ooc/data-ooc.ts +17 -28
  73. package/server/service/data-sample/data-sample-query.ts +14 -0
  74. package/server/service/data-sample/data-sample.ts +15 -21
  75. package/server/service/data-set/data-item-type.ts +1 -0
  76. package/translations/en.json +5 -1
  77. package/translations/ja.json +5 -1
  78. package/translations/ko.json +4 -0
  79. package/translations/ms.json +4 -0
  80. package/translations/zh.json +5 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/dataset",
3
- "version": "6.2.105",
3
+ "version": "6.2.111",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -42,18 +42,18 @@
42
42
  "@operato/utils": "^1.0.1",
43
43
  "@things-factory/auth-base": "^6.2.103",
44
44
  "@things-factory/aws-base": "^6.2.103",
45
- "@things-factory/board-service": "^6.2.105",
45
+ "@things-factory/board-service": "^6.2.111",
46
46
  "@things-factory/env": "^6.2.103",
47
- "@things-factory/integration-base": "^6.2.103",
48
- "@things-factory/organization": "^6.2.103",
47
+ "@things-factory/integration-base": "^6.2.111",
48
+ "@things-factory/organization": "^6.2.111",
49
49
  "@things-factory/scheduler-client": "^6.2.103",
50
50
  "@things-factory/shell": "^6.2.103",
51
51
  "@things-factory/work-shift": "^6.2.103",
52
- "@things-factory/worklist": "^6.2.105",
52
+ "@things-factory/worklist": "^6.2.111",
53
53
  "cron-parser": "^4.3.0",
54
54
  "moment-timezone": "^0.5.40",
55
55
  "simple-statistics": "^7.8.3",
56
56
  "statistics": "^3.3.0"
57
57
  },
58
- "gitHead": "891a2aea81fd948e4e8b342f88914ed579252c41"
58
+ "gitHead": "8424feb14ae84e99377321dc36454358631a560c"
59
59
  }
@@ -3,11 +3,7 @@ import { ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAd
3
3
  import { DataOocStatus } from '../service/data-ooc/data-ooc'
4
4
  import { DataSample } from '../service/data-sample/data-sample'
5
5
 
6
- async function callback(
7
- activityInstance: ActivityInstance,
8
- addendum: UpdateActivityInstanceStateAddendum,
9
- context: ResolverContext
10
- ) {
6
+ async function callback(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {
11
7
  const { domain, tx, user } = context.state
12
8
  const { input, output, state } = activityInstance
13
9
 
@@ -1,18 +1,9 @@
1
- import {
2
- Activity,
3
- ActivityInstance,
4
- ActivityInstanceStatus,
5
- UpdateActivityInstanceStateAddendum
6
- } from '@things-factory/worklist'
1
+ import { Activity, ActivityInstance, ActivityInstanceStatus, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'
7
2
  import { issue } from '@things-factory/worklist/dist-server/controllers/activity-instance/issue'
8
3
 
9
4
  import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
10
5
 
11
- async function callback(
12
- activityInstance: ActivityInstance,
13
- addendum: UpdateActivityInstanceStateAddendum,
14
- context: ResolverContext
15
- ) {
6
+ async function callback(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {
16
7
  const { domain, user, tx } = context.state
17
8
  const { input, output, state, terminatedAt } = activityInstance
18
9
  const { causedBy } = addendum || {}
@@ -62,11 +53,10 @@ async function callback(
62
53
  approvalLine: outlierApprovalLine
63
54
  }
64
55
 
65
- await issue(activityInstance, context)
56
+ dataOoc.resolveActivityInstance = await issue(activityInstance, context)
57
+ await tx.getRepository(DataOoc).save(dataOoc)
66
58
  } else {
67
- console.error(
68
- `Assignees are not set. So, Data OOC Resolve task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`
69
- )
59
+ console.error(`Assignees are not set. So, Data OOC Resolve task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`)
70
60
  }
71
61
  } else {
72
62
  console.error('OOC Resolve Activity not installed.')
@@ -55,16 +55,16 @@ const formatDate = (keys, _moment) => {
55
55
  return keys
56
56
  }
57
57
 
58
- export async function createDataSample(dataSample: NewDataSample, context: ResolverContext): Promise<DataSample> {
58
+ export async function createDataSample(newDataSample: NewDataSample, context: ResolverContext): Promise<DataSample> {
59
59
  const { domain, user, tx } = context.state
60
60
 
61
61
  const dataSet = await tx.getRepository(DataSet).findOne({
62
- where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id: dataSample.dataSet.id },
62
+ where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id: newDataSample.dataSet.id },
63
63
  relations: ['dataKeySet']
64
64
  })
65
65
 
66
66
  const { dataItems, tag: publishTag, normalScenarioId, outlierScenarioId } = dataSet
67
- const collectedAt = dataSample.collectedAt || new Date()
67
+ const collectedAt = newDataSample.collectedAt || new Date()
68
68
 
69
69
  const timezone = dataSet.timezone || domain.timezone || 'UTC'
70
70
  const format = 'YYYY-MM-DD'
@@ -77,7 +77,7 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
77
77
  const localDateTz = moment(collectedAt).tz(timezone)
78
78
  const defaultPartitionKeys = {
79
79
  domain: domain.subdomain,
80
- datasetid: dataSample.dataSet.id /* It should not be 'data_set_id' as column name duplicated for Glue */,
80
+ datasetid: newDataSample.dataSet.id /* It should not be 'data_set_id' as column name duplicated for Glue */,
81
81
  date: localDateTz.format(format) /* local time date */,
82
82
  workdate: workDate /* working date */,
83
83
  workshift: workShift
@@ -89,11 +89,11 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
89
89
  }
90
90
 
91
91
  partitionKeys = formatDate(partitionKeys, localDateTz)
92
- partitionKeys = replaceVariables(partitionKeys, dataSample.data)
92
+ partitionKeys = replaceVariables(partitionKeys, newDataSample.data)
93
93
 
94
- const dataKeys = fillDataKeys(dataSet?.dataKeySet, dataSample.data)
94
+ const dataKeys = fillDataKeys(dataSet?.dataKeySet, newDataSample.data)
95
95
 
96
- const { ooc, oos, judgment } = DataUseCase.evaluate(dataSet, dataItems, dataSample.data) || {}
96
+ const { ooc, oos, judgment } = DataUseCase.evaluate(dataSet, dataItems, newDataSample.data) || {}
97
97
 
98
98
  const old = await tx.getRepository(DataSample).findOne({
99
99
  where: {
@@ -110,7 +110,7 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
110
110
  If [FileUpload[]] type needed, add 'files' type for dataset
111
111
  */
112
112
 
113
- const data = dataSample.data
113
+ const data = newDataSample.data
114
114
  const attachments = []
115
115
 
116
116
  for (let dataItem of dataItems) {
@@ -164,13 +164,13 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
164
164
  }
165
165
  }
166
166
 
167
- const result = await tx.getRepository(DataSample).save({
167
+ const dataSample = await tx.getRepository(DataSample).save({
168
168
  ...old,
169
169
  name: dataSet.name,
170
170
  description: dataSet.description,
171
171
  useCase: dataSet.useCase,
172
172
  type: dataSet.type,
173
- ...dataSample,
173
+ ...newDataSample,
174
174
  ...dataKeys,
175
175
  dataSetVersion: dataSet.version,
176
176
  domain,
@@ -197,13 +197,13 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
197
197
 
198
198
  /* post-process for for file attachment. */
199
199
  if (attachments.length > 0) {
200
- attachments.forEach(attachment => (attachment.refId = result.id))
200
+ attachments.forEach(attachment => (attachment.refId = dataSample.id))
201
201
  tx.getRepository(Attachment).save(attachments)
202
202
  }
203
203
 
204
204
  if (ooc || oos) {
205
205
  const dataOoc = await tx.getRepository(DataOoc).save({
206
- ...result,
206
+ ...dataSample,
207
207
  history: [
208
208
  {
209
209
  user: {
@@ -214,7 +214,8 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
214
214
  timestamp: collectedAt
215
215
  }
216
216
  ],
217
- state: DataOocStatus.ISSUED
217
+ state: DataOocStatus.ISSUED,
218
+ dataSample: dataSample
218
219
  })
219
220
 
220
221
  if (outlierScenarioId) {
@@ -227,9 +228,9 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
227
228
  })
228
229
 
229
230
  if (scenario) {
230
- scenario.start(scenario.name + ':' + dataSet.name + ':' + result.id, {
231
+ scenario.start(scenario.name + ':' + dataSet.name + ':' + dataSample.id, {
231
232
  dataOocId: dataOoc.id,
232
- dataSampleId: result.id,
233
+ dataSampleId: dataSample.id,
233
234
  dataSet: dataSet.id,
234
235
  data,
235
236
  ooc,
@@ -260,9 +261,7 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
260
261
  })) as Activity
261
262
 
262
263
  if (activity) {
263
- const assignee =
264
- dataSet.supervisoryRoleId &&
265
- (await tx.getRepository(Role).findOneBy({ domain: { id: domain.id }, id: dataSet.supervisoryRoleId }))
264
+ const assignee = dataSet.supervisoryRoleId && (await tx.getRepository(Role).findOneBy({ domain: { id: domain.id }, id: dataSet.supervisoryRoleId }))
266
265
 
267
266
  const assignees = dataSet.supervisoryRoleId ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assignee }] : []
268
267
 
@@ -280,11 +279,10 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
280
279
  approvalLine: []
281
280
  }
282
281
 
283
- await issue(activityInstance, context)
282
+ dataOoc.reviewActivityInstance = await issue(activityInstance, context)
283
+ await tx.getRepository(DataOoc).save(dataOoc)
284
284
  } else {
285
- console.error(
286
- `Assignees are not set. So Data OOC Review task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`
287
- )
285
+ console.error(`Assignees are not set. So Data OOC Review task for ${dataOoc.name}(${dataOoc.id}) could not be issued.`)
288
286
  }
289
287
  } else {
290
288
  console.error('OOC Review Activity not installed.')
@@ -320,8 +318,8 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
320
318
  })
321
319
 
322
320
  if (scenario) {
323
- scenario.start(scenario.name + ':' + dataSet.name + ':' + result.id, {
324
- dataSampleId: result.id,
321
+ scenario.start(scenario.name + ':' + dataSet.name + ':' + dataSample.id, {
322
+ dataSampleId: dataSample.id,
325
323
  dataSet: dataSet.id,
326
324
  data,
327
325
  ooc,
@@ -353,30 +351,27 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
353
351
  })) as Activity
354
352
 
355
353
  if (activity) {
356
- const assignee =
357
- dataSet.supervisoryRoleId &&
358
- (await tx.getRepository(Role).findOneBy({ domain: { id: domain.id }, id: dataSet.supervisoryRoleId }))
354
+ const assignee = dataSet.supervisoryRoleId && (await tx.getRepository(Role).findOneBy({ domain: { id: domain.id }, id: dataSet.supervisoryRoleId }))
359
355
 
360
- const assignees = dataSet.supervisoryRoleId
361
- ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assignee }]
362
- : []
356
+ const assignees = dataSet.supervisoryRoleId ? [{ type: 'Role', value: dataSet.supervisoryRoleId, assignee }] : []
363
357
 
364
358
  /* 해당 dataset의 supervisor로 하여금, data를 리뷰하고 instruction을 작성해서, approvalLine을 이용해서 승인을 한다. */
365
359
  if (assignees && assignees instanceof Array && assignees.length > 0) {
366
- result.dataItems = dataItems
360
+ dataSample.dataItems = dataItems
367
361
  const activityInstance = {
368
362
  name: `[Data 검토] ${dataSet.name}`,
369
363
  description: dataSet.description,
370
364
  activityId: activity.id,
371
365
  dueAt: new Date(collectedAt.getTime() + 24 * 60 * 60 * 1000),
372
366
  input: {
373
- dataSample: result
367
+ dataSampleId: dataSample.id
374
368
  },
375
369
  assignees,
376
370
  approvalLine: dataSet.reviewApprovalLine
377
371
  }
378
372
 
379
- await issue(activityInstance, context)
373
+ dataSample.reviewActivityInstance = await issue(activityInstance, context)
374
+ await tx.getRepository(DataSample).save(dataSample)
380
375
 
381
376
  try {
382
377
  pubsub.publish('notification', {
@@ -385,7 +380,7 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
385
380
  type: 'info',
386
381
  title: `[Data Review] ${dataSet.name}`,
387
382
  body: `Data Review occurred on '${dataSet.name}'`,
388
- url: getRedirectSubdomainPath(context, domain.subdomain, `/data-sample/${result.id}`),
383
+ url: getRedirectSubdomainPath(context, domain.subdomain, `/data-sample/${dataSample.id}`),
389
384
  timestamp: collectedAt
390
385
  }
391
386
  })
@@ -393,9 +388,7 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
393
388
  logger.error('Notification', err)
394
389
  }
395
390
  } else {
396
- console.error(
397
- `Assignees are not set. So Data Review task for ${dataSet.name}(${dataSet.id}) could not be issued.`
398
- )
391
+ console.error(`Assignees are not set. So Data Review task for ${dataSet.name}(${dataSet.id}) could not be issued.`)
399
392
  }
400
393
  } else {
401
394
  console.error('Data Review Activity not installed.')
@@ -403,5 +396,5 @@ export async function createDataSample(dataSample: NewDataSample, context: Resol
403
396
  }
404
397
  }
405
398
 
406
- return result
399
+ return dataSample
407
400
  }
@@ -2,10 +2,12 @@ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from
2
2
 
3
3
  import { User } from '@things-factory/auth-base'
4
4
  import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
5
+ import { ActivityInstance } from '@things-factory/worklist'
5
6
 
6
7
  import { DataSetHistory } from '../data-set-history/data-set-history'
7
8
  import { DataItem } from '../data-set/data-item-type'
8
9
  import { DataSet } from '../data-set/data-set'
10
+ import { DataSample } from '../data-sample/data-sample'
9
11
  import { DataOoc } from './data-ooc'
10
12
  import { DataOocList } from './data-ooc-type'
11
13
 
@@ -51,11 +53,26 @@ export class DataOocQuery {
51
53
  return dataSetHistory?.dataItems || []
52
54
  }
53
55
 
56
+ @FieldResolver(type => DataSample)
57
+ async dataSample(@Root() dataOoc: DataOoc): Promise<DataSample> {
58
+ return dataOoc.dataSampleId && (await getRepository(DataSample).findOneBy({ id: dataOoc.dataSampleId }))
59
+ }
60
+
54
61
  @FieldResolver(type => DataSet)
55
62
  async dataSet(@Root() dataOoc: DataOoc): Promise<DataSet> {
56
63
  return dataOoc.dataSetId && (await getRepository(DataSet).findOneBy({ id: dataOoc.dataSetId }))
57
64
  }
58
65
 
66
+ @FieldResolver(type => ActivityInstance)
67
+ async reviewActivityInstance(@Root() dataOoc: DataOoc): Promise<ActivityInstance> {
68
+ return dataOoc.reviewActivityInstanceId && (await getRepository(ActivityInstance).findOneBy({ id: dataOoc.reviewActivityInstanceId }))
69
+ }
70
+
71
+ @FieldResolver(type => ActivityInstance)
72
+ async resolveActivityInstance(@Root() dataOoc: DataOoc): Promise<ActivityInstance> {
73
+ return dataOoc.resolveActivityInstanceId && (await getRepository(ActivityInstance).findOneBy({ id: dataOoc.resolveActivityInstanceId }))
74
+ }
75
+
59
76
  @FieldResolver(type => User)
60
77
  async corrector(@Root() dataOoc: DataOoc): Promise<User> {
61
78
  return dataOoc.correctorId && (await getRepository(User).findOneBy({ id: dataOoc.correctorId }))
@@ -1,5 +1,5 @@
1
1
  import { Field, ID, ObjectType, registerEnumType } from 'type-graphql'
2
- import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
2
+ import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
3
3
 
4
4
  import { User } from '@things-factory/auth-base'
5
5
  import { config } from '@things-factory/env'
@@ -40,12 +40,10 @@ export class DataOoc {
40
40
  domainId?: string
41
41
 
42
42
  @Column()
43
- @Field()
44
- name: string
43
+ @Field({ nullable: true })
44
+ name?: string
45
45
 
46
- @Column({
47
- nullable: true
48
- })
46
+ @Column({ nullable: true })
49
47
  @Field({ nullable: true })
50
48
  description?: string
51
49
 
@@ -60,21 +58,15 @@ export class DataOoc {
60
58
  @Field({ nullable: true })
61
59
  dataSetVersion?: number
62
60
 
63
- @Column({
64
- nullable: true
65
- })
61
+ @Column({ nullable: true })
66
62
  @Field({ nullable: true })
67
63
  ooc?: boolean
68
64
 
69
- @Column({
70
- nullable: true
71
- })
65
+ @Column({ nullable: true })
72
66
  @Field({ nullable: true })
73
67
  oos?: boolean
74
68
 
75
- @Column({
76
- nullable: true
77
- })
69
+ @Column({ nullable: true })
78
70
  @Field({ nullable: true })
79
71
  state?: DataOocStatus
80
72
 
@@ -92,15 +84,11 @@ export class DataOoc {
92
84
  @Field({ nullable: true })
93
85
  correctiveAction?: string
94
86
 
95
- @Column({
96
- nullable: true
97
- })
87
+ @Column({ nullable: true })
98
88
  @Field({ nullable: true })
99
89
  type?: string
100
90
 
101
- @Column({
102
- nullable: true
103
- })
91
+ @Column({ nullable: true })
104
92
  @Field({ nullable: true })
105
93
  useCase?: string
106
94
 
@@ -150,27 +138,28 @@ export class DataOoc {
150
138
  @Field({ nullable: true })
151
139
  rawData?: string
152
140
 
153
- @Column({
154
- nullable: true
155
- })
141
+ @Column({ nullable: true })
156
142
  @Field({ nullable: true })
157
143
  source?: string
158
144
 
159
- @ManyToOne(type => DataSample, { nullable: true })
160
- @Field({ nullable: true })
145
+ @OneToOne(type => DataSample, { nullable: true })
146
+ @JoinColumn()
147
+ @Field(type => DataSample, { nullable: true })
161
148
  dataSample?: DataSample
162
149
 
163
150
  @RelationId((dataOoc: DataOoc) => dataOoc.dataSample)
164
151
  dataSampleId?: string
165
152
 
166
- @ManyToOne(type => ActivityInstance, { nullable: true })
153
+ @OneToOne(type => ActivityInstance, { nullable: true })
154
+ @JoinColumn()
167
155
  @Field({ nullable: true })
168
156
  reviewActivityInstance?: ActivityInstance
169
157
 
170
158
  @RelationId((dataOoc: DataOoc) => dataOoc.reviewActivityInstance)
171
159
  reviewActivityInstanceId?: string
172
160
 
173
- @ManyToOne(type => ActivityInstance, { nullable: true })
161
+ @OneToOne(type => ActivityInstance, { nullable: true })
162
+ @JoinColumn()
174
163
  @Field({ nullable: true })
175
164
  resolveActivityInstance?: ActivityInstance
176
165
 
@@ -3,11 +3,13 @@ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from
3
3
 
4
4
  import { User } from '@things-factory/auth-base'
5
5
  import { Domain, getQueryBuilderFromListParams, getRepository, getISOStringsForPeriod, ListParam } from '@things-factory/shell'
6
+ import { ActivityInstance } from '@things-factory/worklist'
6
7
 
7
8
  import { DataKeySet } from '../data-key-set/data-key-set'
8
9
  import { DataSetHistory } from '../data-set-history/data-set-history'
9
10
  import { DataItem } from '../data-set/data-item-type'
10
11
  import { DataSet } from '../data-set/data-set'
12
+ import { DataOoc } from '../data-ooc/data-ooc'
11
13
  import { DataSample } from './data-sample'
12
14
  import { DataSampleList } from './data-sample-type'
13
15
 
@@ -164,6 +166,18 @@ export class DataSampleQuery {
164
166
  return dataSample.dataSetId && (await getRepository(DataSet).findOneBy({ id: dataSample.dataSetId }))
165
167
  }
166
168
 
169
+ @FieldResolver(type => DataOoc)
170
+ async dataOoc(@Root() dataSample: DataSample): Promise<DataOoc> {
171
+ if (dataSample.ooc || dataSample.oos) {
172
+ return await getRepository(DataOoc).findOneBy({ dataSample: { id: dataSample.id } })
173
+ }
174
+ }
175
+
176
+ @FieldResolver(type => ActivityInstance)
177
+ async reviewActivityInstance(@Root() dataSample: DataSample): Promise<ActivityInstance> {
178
+ return dataSample.reviewActivityInstanceId && (await getRepository(ActivityInstance).findOneBy({ id: dataSample.reviewActivityInstanceId }))
179
+ }
180
+
167
181
  @FieldResolver(type => Domain)
168
182
  async domain(@Root() dataSample: DataSample): Promise<Domain> {
169
183
  return dataSample.domainId && (await getRepository(Domain).findOneBy({ id: dataSample.domainId }))
@@ -1,5 +1,5 @@
1
1
  import { Field, ID, ObjectType } from 'type-graphql'
2
- import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
2
+ import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
3
3
 
4
4
  import { User } from '@things-factory/auth-base'
5
5
  import { config } from '@things-factory/env'
@@ -8,6 +8,7 @@ import { ActivityInstance } from '@things-factory/worklist'
8
8
 
9
9
  import { DataItem } from '../data-set/data-item-type'
10
10
  import { DataSet } from '../data-set/data-set'
11
+ import { DataOoc } from '../data-ooc/data-ooc'
11
12
 
12
13
  const ORMCONFIG = config.get('ormconfig', {})
13
14
  const DATABASE_TYPE = ORMCONFIG.type
@@ -30,24 +31,18 @@ export class DataSample {
30
31
  domainId?: string
31
32
 
32
33
  @Column()
33
- @Field()
34
+ @Field({ nullable: true })
34
35
  name: string
35
36
 
36
- @Column({
37
- nullable: true
38
- })
37
+ @Column({ nullable: true })
39
38
  @Field({ nullable: true })
40
39
  description?: string
41
40
 
42
- @Column({
43
- nullable: true
44
- })
41
+ @Column({ nullable: true })
45
42
  @Field({ nullable: true })
46
43
  type?: string
47
44
 
48
- @Column({
49
- nullable: true
50
- })
45
+ @Column({ nullable: true })
51
46
  @Field({ nullable: true })
52
47
  useCase?: string
53
48
 
@@ -84,21 +79,15 @@ export class DataSample {
84
79
  @Field({ nullable: true })
85
80
  rawData?: string
86
81
 
87
- @Column({
88
- nullable: true
89
- })
82
+ @Column({ nullable: true })
90
83
  @Field({ nullable: true })
91
84
  source?: string
92
85
 
93
- @Column({
94
- nullable: true
95
- })
86
+ @Column({ nullable: true })
96
87
  @Field({ nullable: true })
97
88
  ooc?: boolean
98
89
 
99
- @Column({
100
- nullable: true
101
- })
90
+ @Column({ nullable: true })
102
91
  @Field({ nullable: true })
103
92
  oos?: boolean
104
93
 
@@ -130,13 +119,18 @@ export class DataSample {
130
119
  @Field({ nullable: true })
131
120
  workShift?: string
132
121
 
133
- @ManyToOne(type => ActivityInstance, { nullable: true })
122
+ @OneToOne(type => ActivityInstance, { nullable: true })
123
+ @JoinColumn()
134
124
  @Field({ nullable: true })
135
125
  reviewActivityInstance?: ActivityInstance
136
126
 
137
127
  @RelationId((dataSample: DataSample) => dataSample.reviewActivityInstance)
138
128
  reviewActivityInstanceId?: string
139
129
 
130
+ @OneToOne(type => DataOoc, dataOoc => dataOoc.dataSample, { nullable: true })
131
+ @Field(type => DataOoc, { nullable: true })
132
+ dataOoc?: DataOoc
133
+
140
134
  @Column({ nullable: true })
141
135
  @Field({ nullable: true })
142
136
  collectedAt?: Date
@@ -7,6 +7,7 @@ export enum DataItemType {
7
7
  text = 'text',
8
8
  boolean = 'boolean',
9
9
  select = 'select',
10
+ radio = 'radio',
10
11
  date = 'date',
11
12
  datetime = 'datetime',
12
13
  file = 'file'
@@ -10,7 +10,8 @@
10
10
  "field.assignees": "assignees",
11
11
  "field.collected-at": "collected at",
12
12
  "field.corrected-at": "corrected at",
13
- "field.corrective-action": "corrective action",
13
+ "field.corrective-action": "action",
14
+ "field.corrective-instruction": "instruction",
14
15
  "field.corrector": "corrector",
15
16
  "field.count": "count",
16
17
  "field.count-ooc": "oos count",
@@ -85,10 +86,13 @@
85
86
  "label.corrective instruction": "corrective instruction",
86
87
  "label.critical-limits": "critical limits",
87
88
  "label.data-set-type": "type",
89
+ "label.datasample review timeline": "data sample review timeline",
88
90
  "label.end-date": "end date",
89
91
  "label.group-by data-keys": "group by each data-keys",
90
92
  "label.maximum value": "maximum value",
91
93
  "label.minimum value": "minimum value",
94
+ "label.ooc resolve timeline": "OOC resolve timeline",
95
+ "label.ooc review timeline": "OOC review timeline",
92
96
  "label.pass-limits": "pass limits",
93
97
  "label.period-12-months": "12 months",
94
98
  "label.period-30-days": "30 days",
@@ -10,7 +10,8 @@
10
10
  "field.assignees": "譲渡人リスト",
11
11
  "field.collected-at": "取集日時",
12
12
  "field.corrected-at": "措置時間",
13
- "field.corrective-action": "措置活動",
13
+ "field.corrective-action": "是正措置",
14
+ "field.corrective-instruction": "是正指示",
14
15
  "field.corrector": "措置者",
15
16
  "field.count": "件数",
16
17
  "field.count-ooc": "管理限界離脱件数",
@@ -85,10 +86,13 @@
85
86
  "label.corrective instruction": "是正指示",
86
87
  "label.critical-limits": "許容限界範囲",
87
88
  "label.data-set-type": "タイプ",
89
+ "label.datasample review timeline": "データサンプルレビュータイムライン",
88
90
  "label.end-date": "終了日",
89
91
  "label.group-by data-keys": "各データキーごとにグループ化",
90
92
  "label.maximum value": "最大値",
91
93
  "label.minimum value": "最小値",
94
+ "label.ooc resolve timeline": "OOC 解決タイムライン",
95
+ "label.ooc review timeline": "OOC レビュータイムライン",
92
96
  "label.pass-limits": "通過許容範囲",
93
97
  "label.period-12-months": "12ヶ月",
94
98
  "label.period-30-days": "30日",
@@ -11,6 +11,7 @@
11
11
  "field.collected-at": "수집일시",
12
12
  "field.corrected-at": "조치 시간",
13
13
  "field.corrective-action": "조치 활동",
14
+ "field.corrective-instruction": "조치 지시",
14
15
  "field.corrector": "조치자",
15
16
  "field.count": "건수",
16
17
  "field.count-ooc": "관리한계이탈 건수",
@@ -85,10 +86,13 @@
85
86
  "label.corrective instruction": "수정 지시",
86
87
  "label.critical-limits": "허용 한계범위",
87
88
  "label.data-set-type": "유형",
89
+ "label.datasample review timeline": "데이타샘플 리뷰 타임라인",
88
90
  "label.end-date": "종료일",
89
91
  "label.group-by data-keys": "각 데이터 키별로 그룹화",
90
92
  "label.maximum value": "최대값",
91
93
  "label.minimum value": "최소값",
94
+ "label.ooc resolve timeline": "OOC 조치 타임라인",
95
+ "label.ooc review timeline": "OOC 검토 타임라인",
92
96
  "label.pass-limits": "통과 허용범위",
93
97
  "label.period-12-months": "최근 12개월",
94
98
  "label.period-30-days": "최근 30일",
@@ -11,6 +11,7 @@
11
11
  "field.collected-at": "dikumpulkan pada",
12
12
  "field.corrected-at": "diperbetulkan pada",
13
13
  "field.corrective-action": "tindakan pembetulan",
14
+ "field.corrective-instruction": "arahan pembetulan",
14
15
  "field.corrector": "pembetul",
15
16
  "field.count": "jumlah",
16
17
  "field.count-ooc": "jumlah ooc",
@@ -85,10 +86,13 @@
85
86
  "label.corrective instruction": "instruksi pembetulan",
86
87
  "label.critical-limits": "had kritikal",
87
88
  "label.data-set-type": "jenis",
89
+ "label.datasample review timeline": "garis masa ulasan sampel data",
88
90
  "label.end-date": "tarikh tamat",
89
91
  "label.group-by data-keys": "kumpulkan mengikut setiap data-keys",
90
92
  "label.maximum value": "nilai maksimum",
91
93
  "label.minimum value": "nilai minimum",
94
+ "label.ooc resolve timeline": "garis masa penyelesaian OOC",
95
+ "label.ooc review timeline": "garis masa ulasan OOC",
92
96
  "label.pass-limits": "had lulus",
93
97
  "label.period-12-months": "12 bulan",
94
98
  "label.period-30-days": "30 hari",