@things-factory/dataset 5.0.0-zeta.8 → 5.0.1
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/README.md +25 -0
- package/assets/data-samples.jpg +0 -0
- package/client/bootstrap.js +2 -3
- package/client/{pages/data-entry → components}/data-entry-form.js +1 -1
- package/client/index.js +1 -0
- package/client/pages/data-entry/data-entry-list-page.js +2 -3
- package/client/pages/data-ooc/data-ooc-list-page.js +13 -18
- package/client/pages/data-ooc/data-ooc-view.js +19 -14
- package/client/pages/data-report/data-report-list-page.js +1 -2
- package/client/pages/data-sample/data-sample-list-page.js +12 -13
- package/client/pages/data-sample/data-sample-view.js +3 -2
- package/client/pages/data-sensor/data-sensor-list-page.js +1 -1
- package/client/pages/data-set/data-item-list.js +32 -98
- package/client/pages/data-set/data-set-list-page.js +3 -3
- package/config/config.development.js +1 -1
- package/config/config.production.js +13 -1
- package/dist-server/controllers/create-data-sample.js +10 -44
- package/dist-server/controllers/create-data-sample.js.map +1 -1
- package/dist-server/controllers/data-use-case.js +11 -5
- package/dist-server/controllers/data-use-case.js.map +1 -1
- package/dist-server/controllers/index.js +1 -1
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/jasper-report.js +14 -9
- package/dist-server/controllers/jasper-report.js.map +1 -1
- package/dist-server/service/data-item/index.js +1 -4
- package/dist-server/service/data-item/index.js.map +1 -1
- package/dist-server/service/data-ooc/data-ooc-query.js +15 -10
- package/dist-server/service/data-ooc/data-ooc-query.js.map +1 -1
- package/dist-server/service/data-ooc/data-ooc-type.js +4 -0
- package/dist-server/service/data-ooc/data-ooc-type.js.map +1 -1
- package/dist-server/service/data-ooc/data-ooc.js +11 -14
- package/dist-server/service/data-ooc/data-ooc.js.map +1 -1
- package/dist-server/service/data-sample/data-sample-query.js +18 -0
- package/dist-server/service/data-sample/data-sample-query.js.map +1 -1
- package/dist-server/service/data-sample/data-sample-type.js +4 -0
- package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
- package/dist-server/service/data-sample/data-sample.js +12 -3
- package/dist-server/service/data-sample/data-sample.js.map +1 -1
- package/dist-server/service/{data-item → data-set}/data-item-type.js +60 -33
- package/dist-server/service/data-set/data-item-type.js.map +1 -0
- package/dist-server/service/data-set/data-set-mutation.js +21 -61
- package/dist-server/service/data-set/data-set-mutation.js.map +1 -1
- package/dist-server/service/data-set/data-set-query.js +4 -0
- package/dist-server/service/data-set/data-set-query.js.map +1 -1
- package/dist-server/service/data-set/data-set-type.js +21 -9
- package/dist-server/service/data-set/data-set-type.js.map +1 -1
- package/dist-server/service/data-set/data-set.js +11 -3
- package/dist-server/service/data-set/data-set.js.map +1 -1
- package/dist-server/service/data-set-history/data-set-history-query.js +173 -0
- package/dist-server/service/data-set-history/data-set-history-query.js.map +1 -0
- package/dist-server/service/data-set-history/data-set-history-type.js +29 -0
- package/dist-server/service/data-set-history/data-set-history-type.js.map +1 -0
- package/dist-server/service/data-set-history/data-set-history.js +196 -0
- package/dist-server/service/data-set-history/data-set-history.js.map +1 -0
- package/dist-server/service/data-set-history/event-subscriber.js +26 -0
- package/dist-server/service/data-set-history/event-subscriber.js.map +1 -0
- package/dist-server/service/data-set-history/index.js +10 -0
- package/dist-server/service/data-set-history/index.js.map +1 -0
- package/dist-server/service/index.js +11 -4
- package/dist-server/service/index.js.map +1 -1
- package/package.json +18 -17
- package/server/controllers/create-data-sample.ts +13 -50
- package/server/controllers/data-use-case.ts +19 -7
- package/server/controllers/index.ts +1 -1
- package/server/controllers/jasper-report.ts +58 -48
- package/server/service/data-item/index.ts +0 -3
- package/server/service/data-ooc/data-ooc-query.ts +13 -8
- package/server/service/data-ooc/data-ooc-type.ts +3 -0
- package/server/service/data-ooc/data-ooc.ts +9 -14
- package/server/service/data-sample/data-sample-query.ts +14 -1
- package/server/service/data-sample/data-sample-type.ts +3 -0
- package/server/service/data-sample/data-sample.ts +10 -3
- package/server/service/data-set/data-item-type.ts +82 -0
- package/server/service/data-set/data-set-mutation.ts +33 -60
- package/server/service/data-set/data-set-query.ts +5 -0
- package/server/service/data-set/data-set-type.ts +9 -1
- package/server/service/data-set/data-set.ts +8 -4
- package/server/service/data-set-history/data-set-history-query.ts +110 -0
- package/server/service/data-set-history/data-set-history-type.ts +12 -0
- package/server/service/data-set-history/data-set-history.ts +161 -0
- package/server/service/data-set-history/event-subscriber.ts +17 -0
- package/server/service/data-set-history/index.ts +7 -0
- package/server/service/index.ts +16 -4
- package/translations/en.json +5 -5
- package/translations/ko.json +10 -10
- package/translations/ms.json +5 -5
- package/translations/zh.json +5 -5
- package/dist-server/service/data-item/data-item-mutation.js +0 -73
- package/dist-server/service/data-item/data-item-mutation.js.map +0 -1
- package/dist-server/service/data-item/data-item-query.js +0 -104
- package/dist-server/service/data-item/data-item-query.js.map +0 -1
- package/dist-server/service/data-item/data-item-type.js.map +0 -1
- package/server/service/data-item/data-item-mutation.ts +0 -61
- package/server/service/data-item/data-item-query.ts +0 -58
- package/server/service/data-item/data-item-type.ts +0 -57
@@ -3,15 +3,13 @@ import { EntityManager } from 'typeorm'
|
|
3
3
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
5
5
|
import { Domain, getRedirectSubdomainPath, pubsub } from '@things-factory/shell'
|
6
|
+
import { getWorkDateAndShift } from '@things-factory/work-shift'
|
6
7
|
|
7
|
-
import { DataItem } from '../service/data-item/data-item'
|
8
8
|
import { DataOoc, DataOocStatus } from '../service/data-ooc/data-ooc'
|
9
9
|
import { DataSample } from '../service/data-sample/data-sample'
|
10
10
|
import { NewDataSample } from '../service/data-sample/data-sample-type'
|
11
11
|
import { DataSet } from '../service/data-set/data-set'
|
12
12
|
import { DataUseCase } from './data-use-case'
|
13
|
-
import { getWorkDateAndShift } from '@things-factory/work-shift'
|
14
|
-
|
15
13
|
|
16
14
|
const debug = require('debug')('things-factory:dataset:controller/save-data-sample')
|
17
15
|
|
@@ -56,26 +54,7 @@ export async function createDataSample(
|
|
56
54
|
where: { id: dataSample.dataSet.id }
|
57
55
|
})
|
58
56
|
|
59
|
-
const dataItems =
|
60
|
-
where: {
|
61
|
-
domain,
|
62
|
-
dataSet
|
63
|
-
},
|
64
|
-
order: {
|
65
|
-
sequence: 'DESC'
|
66
|
-
}
|
67
|
-
})
|
68
|
-
|
69
|
-
const spec = dataItems.reduce((spec, dataItem) => {
|
70
|
-
spec[dataItem.tag] = {
|
71
|
-
...dataItem.spec,
|
72
|
-
name: dataItem.name, /* do we need ? */
|
73
|
-
hidden: dataItem.hidden
|
74
|
-
}
|
75
|
-
|
76
|
-
return spec
|
77
|
-
}, {})
|
78
|
-
|
57
|
+
const dataItems = dataSet.dataItems
|
79
58
|
const collectedAt = dataSample.collectedAt || new Date()
|
80
59
|
|
81
60
|
const timezone = dataSet.timezone || domain.timezone || 'UTC'
|
@@ -83,16 +62,15 @@ export async function createDataSample(
|
|
83
62
|
|
84
63
|
// workDate ex) 2022-04-04
|
85
64
|
const { workDate, workShift } = await getWorkDateAndShift(domain, collectedAt, { timezone, format })
|
86
|
-
|
65
|
+
|
87
66
|
// local time dataSet timezone or domain timezone or default 'UTC'
|
88
|
-
|
89
|
-
// const collectedAt = dataSample.collectedAt || new Date()
|
67
|
+
|
90
68
|
const localDateTz = moment(collectedAt).tz(timezone)
|
91
69
|
const defaultPartitionKeys = {
|
92
70
|
domain: domain.subdomain,
|
93
|
-
datasetid: dataSample.dataSet.id
|
94
|
-
date: localDateTz.format(format)
|
95
|
-
workdate: workDate
|
71
|
+
datasetid: dataSample.dataSet.id /* It should not be 'data_set_id' as column name duplicated for Glue */,
|
72
|
+
date: localDateTz.format(format) /* local time date */,
|
73
|
+
workdate: workDate /* working date */,
|
96
74
|
workshift: workShift
|
97
75
|
}
|
98
76
|
|
@@ -106,17 +84,18 @@ export async function createDataSample(
|
|
106
84
|
...dataSample.data
|
107
85
|
})
|
108
86
|
|
109
|
-
const { ooc, oos } = DataUseCase.evaluate(dataSet, dataItems, dataSample.data) || {}
|
87
|
+
const { ooc, oos, judgment } = DataUseCase.evaluate(dataSet, dataItems, dataSample.data) || {}
|
110
88
|
const result = await tx.getRepository(DataSample).save({
|
111
89
|
name: dataSet.name,
|
112
90
|
description: dataSet.description,
|
113
91
|
useCase: dataSet.useCase,
|
114
92
|
...dataSample,
|
93
|
+
dataSetVersion: dataSet.version,
|
115
94
|
domain,
|
116
95
|
partitionKeys,
|
117
|
-
spec,
|
118
96
|
ooc,
|
119
97
|
oos,
|
98
|
+
judgment,
|
120
99
|
collectedAt,
|
121
100
|
workDate,
|
122
101
|
workShift,
|
@@ -126,18 +105,7 @@ export async function createDataSample(
|
|
126
105
|
|
127
106
|
if (ooc || oos) {
|
128
107
|
const dataOoc = await tx.getRepository(DataOoc).save({
|
129
|
-
|
130
|
-
description: dataSet.description,
|
131
|
-
useCase: dataSet.useCase,
|
132
|
-
dataSet,
|
133
|
-
dataSample: result,
|
134
|
-
data: dataSample.data,
|
135
|
-
rawData: dataSample.rawData,
|
136
|
-
domain,
|
137
|
-
partitionKeys,
|
138
|
-
spec,
|
139
|
-
ooc,
|
140
|
-
oos,
|
108
|
+
...result,
|
141
109
|
history: [
|
142
110
|
{
|
143
111
|
user: {
|
@@ -148,12 +116,7 @@ export async function createDataSample(
|
|
148
116
|
timestamp: Date.now()
|
149
117
|
}
|
150
118
|
],
|
151
|
-
state: DataOocStatus.CREATED
|
152
|
-
workDate,
|
153
|
-
workShift,
|
154
|
-
collectedAt,
|
155
|
-
creator: user,
|
156
|
-
updater: user
|
119
|
+
state: DataOocStatus.CREATED
|
157
120
|
})
|
158
121
|
|
159
122
|
pubsub.publish('data-ooc', {
|
@@ -174,4 +137,4 @@ export async function createDataSample(
|
|
174
137
|
}
|
175
138
|
|
176
139
|
return result
|
177
|
-
}
|
140
|
+
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import { DataItem
|
1
|
+
import { DataItem } from '../service/data-set/data-item-type'
|
2
|
+
import { DataSet } from '../service/data-set/data-set'
|
2
3
|
|
3
4
|
export type DataItemSpec = {
|
4
5
|
type: string
|
@@ -13,7 +14,11 @@ export type DataItemSpecSet = {
|
|
13
14
|
specs: DataItemSpec[]
|
14
15
|
}
|
15
16
|
|
16
|
-
export type EvaluationResult = {
|
17
|
+
export type EvaluationResult = {
|
18
|
+
oos: boolean
|
19
|
+
ooc: boolean
|
20
|
+
judgment?: { [tag: string]: { ooc: boolean; oos: boolean } }
|
21
|
+
}
|
17
22
|
|
18
23
|
export abstract class DataUseCase {
|
19
24
|
static registry: { [name: string]: DataUseCase } = {}
|
@@ -33,6 +38,7 @@ export abstract class DataUseCase {
|
|
33
38
|
public static evaluate(dataSet: DataSet, dataItems: DataItem[], data: any): EvaluationResult {
|
34
39
|
var ooc = false
|
35
40
|
var oos = false
|
41
|
+
var judgment: { [tag: string]: { ooc: boolean; oos: boolean } } = {}
|
36
42
|
|
37
43
|
if (!dataSet.useCase) {
|
38
44
|
return { ooc, oos }
|
@@ -49,7 +55,7 @@ export abstract class DataUseCase {
|
|
49
55
|
}
|
50
56
|
|
51
57
|
let values: any | any[] = data[tag]
|
52
|
-
if (
|
58
|
+
if (values == null) {
|
53
59
|
continue // TODO what if in case no value ?
|
54
60
|
}
|
55
61
|
|
@@ -57,6 +63,9 @@ export abstract class DataUseCase {
|
|
57
63
|
values = [values]
|
58
64
|
}
|
59
65
|
|
66
|
+
let oocForTag = false
|
67
|
+
let oosForTag = false
|
68
|
+
|
60
69
|
for (let j = 0; j < useCases.length; j++) {
|
61
70
|
const useCase = useCases[j]
|
62
71
|
|
@@ -68,17 +77,20 @@ export abstract class DataUseCase {
|
|
68
77
|
const result = useCase.evaluate(specs, values)
|
69
78
|
|
70
79
|
if (result) {
|
80
|
+
oocForTag ||= result.ooc
|
81
|
+
oosForTag ||= result.oos
|
71
82
|
ooc ||= result.ooc
|
72
83
|
oos ||= result.oos
|
73
84
|
}
|
85
|
+
}
|
74
86
|
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
judgment[tag] = {
|
88
|
+
ooc: oocForTag,
|
89
|
+
oos: oosForTag
|
78
90
|
}
|
79
91
|
}
|
80
92
|
|
81
|
-
return { ooc, oos }
|
93
|
+
return { ooc, oos, judgment }
|
82
94
|
}
|
83
95
|
|
84
96
|
public abstract evaluate(specs: any, values: any[]): EvaluationResult
|
@@ -6,47 +6,53 @@ import { AthenaController } from '@things-factory/aws-base'
|
|
6
6
|
import { config } from '@things-factory/env'
|
7
7
|
|
8
8
|
const dataReportConfig = config.get('dataReport')
|
9
|
-
const {
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
const {
|
10
|
+
jasper: {
|
11
|
+
endpoint: { protocol: PROTOCOL, host: HOST, port: PORT },
|
12
|
+
datasource: { database: DATABASE }
|
13
|
+
}
|
14
|
+
} = dataReportConfig || {
|
15
|
+
jasper: {
|
16
|
+
endpoint: {},
|
17
|
+
datasource: {}
|
18
|
+
}
|
19
|
+
}
|
13
20
|
|
14
|
-
/** author: ywnam123 */
|
15
21
|
function transformValuesToRows(queryResult) {
|
16
22
|
var parseData = []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}
|
23
|
+
let index = 1
|
24
|
+
for (let i = 0; i < queryResult.Items.length; i++) {
|
25
|
+
var j = 0
|
26
|
+
const data = JSON.parse(queryResult.Items[i].data)
|
27
|
+
const spec = JSON.parse(queryResult.Items[i].spec)
|
28
|
+
|
29
|
+
for (let key in data) {
|
30
|
+
if (Array.isArray(data[key])) {
|
31
|
+
for (j = 0; j < data[key].length; j++) {
|
32
|
+
for (let specKey in spec) {
|
33
|
+
if (key === specKey) {
|
34
|
+
parseData.push({
|
35
|
+
item: spec[specKey].name,
|
36
|
+
index: index + j,
|
37
|
+
value: String(data[key][j])
|
38
|
+
})
|
34
39
|
}
|
35
40
|
}
|
36
|
-
} else {
|
37
|
-
parseData.push({
|
38
|
-
item: key,
|
39
|
-
index,
|
40
|
-
value: String(data[key])
|
41
|
-
})
|
42
41
|
}
|
43
|
-
}
|
44
|
-
if (j !== 0) {
|
45
|
-
index = index + j
|
46
42
|
} else {
|
47
|
-
|
43
|
+
parseData.push({
|
44
|
+
item: key,
|
45
|
+
index,
|
46
|
+
value: String(data[key])
|
47
|
+
})
|
48
48
|
}
|
49
49
|
}
|
50
|
+
if (j !== 0) {
|
51
|
+
index = index + j
|
52
|
+
} else {
|
53
|
+
index = index + 1
|
54
|
+
}
|
55
|
+
}
|
50
56
|
}
|
51
57
|
|
52
58
|
/** @todo considering trasformation in lambda, as massive dataset */
|
@@ -61,11 +67,12 @@ function pivotData(rows) {
|
|
61
67
|
for (let key in data) {
|
62
68
|
/** @todo rule to display or not, about unspecified spec */
|
63
69
|
const value = data[key]
|
64
|
-
!
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
!spec[key]?.hidden &&
|
71
|
+
parsedData.push({
|
72
|
+
item: spec[key]?.name || key,
|
73
|
+
index,
|
74
|
+
value: Array.isArray(value) ? value.join(', ') : value
|
75
|
+
})
|
69
76
|
}
|
70
77
|
if (j !== 0) {
|
71
78
|
index = index + j
|
@@ -95,6 +102,7 @@ function parseJsonDataField(rows) {
|
|
95
102
|
}
|
96
103
|
|
97
104
|
const athenaClient = new AthenaController()
|
105
|
+
|
98
106
|
async function queryAthena(params) {
|
99
107
|
const { table, domain, dataSetId, fromWorkDate, toWorkDate, workShift, timezone } = params
|
100
108
|
const queryData = {
|
@@ -108,7 +116,7 @@ async function queryAthena(params) {
|
|
108
116
|
AND datasetid = '${dataSetId}'
|
109
117
|
AND workdate >= '${fromWorkDate}'
|
110
118
|
AND workdate <= '${toWorkDate}'
|
111
|
-
${workShift ?
|
119
|
+
${workShift ? "AND workshift = '" + workShift + "'" : ''}
|
112
120
|
ORDER BY collected_at`,
|
113
121
|
db: DATABASE
|
114
122
|
}
|
@@ -116,19 +124,23 @@ async function queryAthena(params) {
|
|
116
124
|
|
117
125
|
return await athenaClient.query(queryData)
|
118
126
|
}
|
119
|
-
|
120
|
-
|
127
|
+
|
128
|
+
export async function renderJasperReport(context: any) {
|
129
|
+
const {
|
130
|
+
state: { domain },
|
131
|
+
query
|
132
|
+
} = context
|
121
133
|
|
122
134
|
const template = await STORAGE.readFile(query['template'] || 'dynamic_header_sample.jrxml', 'utf-8')
|
123
135
|
let templateType = query['templateType'] || 'crosstab'
|
124
136
|
let parsedData = []
|
125
137
|
|
126
138
|
// @todo: get dataset timezone
|
127
|
-
/**
|
139
|
+
/**
|
128
140
|
* const variables = await gql(dataSet(id:${dataSetId}) {
|
129
141
|
* name, description, partition_keys, timezone
|
130
142
|
* })
|
131
|
-
|
143
|
+
*/
|
132
144
|
|
133
145
|
query['domain'] = domain?.subdomain
|
134
146
|
query['timezone'] = domain?.timezone
|
@@ -137,8 +149,7 @@ export async function renderJasperReport(context: any) {
|
|
137
149
|
|
138
150
|
if (!rows.length) {
|
139
151
|
return '<h3>Not found result.</h3>'
|
140
|
-
}
|
141
|
-
else {
|
152
|
+
} else {
|
142
153
|
const firstRow = rows[0]
|
143
154
|
// uses the first row values as data-set has no history data.
|
144
155
|
const parameters = {
|
@@ -146,18 +157,18 @@ export async function renderJasperReport(context: any) {
|
|
146
157
|
description: firstRow.description,
|
147
158
|
...query
|
148
159
|
}
|
149
|
-
|
160
|
+
|
150
161
|
if (templateType === 'crosstab') {
|
151
162
|
parsedData = pivotData(rows)
|
152
163
|
} else {
|
153
164
|
parsedData = parseJsonDataField(rows)
|
154
165
|
}
|
155
|
-
|
166
|
+
|
156
167
|
const formData = new FormData()
|
157
168
|
formData.append('template', template)
|
158
169
|
formData.append('jsonString', JSON.stringify(parsedData))
|
159
170
|
formData.append('parameters', JSON.stringify(parameters))
|
160
|
-
|
171
|
+
|
161
172
|
const reportUrl = `${PROTOCOL || 'http'}://${HOST}:${PORT}/rest/report/show_html`
|
162
173
|
const response = await fetch(reportUrl, {
|
163
174
|
method: 'POST',
|
@@ -166,5 +177,4 @@ export async function renderJasperReport(context: any) {
|
|
166
177
|
|
167
178
|
return await response.text()
|
168
179
|
}
|
169
|
-
|
170
180
|
}
|
@@ -4,7 +4,8 @@ import { getRepository } from 'typeorm'
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
5
5
|
import { Domain, getQueryBuilderFromListParams, ListParam } from '@things-factory/shell'
|
6
6
|
|
7
|
-
import {
|
7
|
+
import { DataSetHistory } from '../data-set-history/data-set-history'
|
8
|
+
import { DataItem } from '../data-set/data-item-type'
|
8
9
|
import { DataSet } from '../data-set/data-set'
|
9
10
|
import { DataOoc } from './data-ooc'
|
10
11
|
import { DataOocList } from './data-ooc-type'
|
@@ -38,6 +39,17 @@ export class DataOocQuery {
|
|
38
39
|
return { items, total }
|
39
40
|
}
|
40
41
|
|
42
|
+
@FieldResolver(type => [DataItem])
|
43
|
+
async dataItems(@Root() dataOoc: DataOoc): Promise<DataItem[]> {
|
44
|
+
const dataSetHistory: DataSetHistory = await getRepository(DataSetHistory).findOne({
|
45
|
+
where: {
|
46
|
+
originalId: dataOoc.dataSetId,
|
47
|
+
version: dataOoc.dataSetVersion
|
48
|
+
}
|
49
|
+
})
|
50
|
+
return dataSetHistory?.dataItems || []
|
51
|
+
}
|
52
|
+
|
41
53
|
@FieldResolver(type => DataSet)
|
42
54
|
async dataSet(@Root() dataOoc: DataOoc): Promise<DataSet> {
|
43
55
|
return await getRepository(DataSet).findOne({
|
@@ -45,13 +57,6 @@ export class DataOocQuery {
|
|
45
57
|
})
|
46
58
|
}
|
47
59
|
|
48
|
-
@FieldResolver(type => DataSample)
|
49
|
-
async dataSample(@Root() dataOoc: DataOoc): Promise<DataSample> {
|
50
|
-
return await getRepository(DataSample).findOne({
|
51
|
-
id: dataOoc.dataSampleId
|
52
|
-
})
|
53
|
-
}
|
54
|
-
|
55
60
|
@FieldResolver(type => Domain)
|
56
61
|
async domain(@Root() dataOoc: DataOoc): Promise<Domain> {
|
57
62
|
return await getRepository(Domain).findOne(dataOoc.domainId)
|
@@ -4,9 +4,7 @@ import {
|
|
4
4
|
CreateDateColumn,
|
5
5
|
Entity,
|
6
6
|
Index,
|
7
|
-
JoinColumn,
|
8
7
|
ManyToOne,
|
9
|
-
OneToOne,
|
10
8
|
PrimaryGeneratedColumn,
|
11
9
|
RelationId,
|
12
10
|
UpdateDateColumn
|
@@ -16,7 +14,7 @@ import { User } from '@things-factory/auth-base'
|
|
16
14
|
import { config } from '@things-factory/env'
|
17
15
|
import { Domain, ScalarObject } from '@things-factory/shell'
|
18
16
|
|
19
|
-
import {
|
17
|
+
import { DataItem } from '../data-set/data-item-type'
|
20
18
|
import { DataSet } from '../data-set/data-set'
|
21
19
|
|
22
20
|
const ORMCONFIG = config.get('ormconfig', {})
|
@@ -34,9 +32,7 @@ registerEnumType(DataOocStatus, {
|
|
34
32
|
})
|
35
33
|
|
36
34
|
@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 })
|
35
|
+
@Index('ix_data_ooc_0', (dataOoc: DataOoc) => [dataOoc.domain, dataOoc.dataSet, dataOoc.collectedAt], { unique: false })
|
40
36
|
@ObjectType({ description: 'Entity for Out of control data' })
|
41
37
|
export class DataOoc {
|
42
38
|
@PrimaryGeneratedColumn('uuid')
|
@@ -67,13 +63,9 @@ export class DataOoc {
|
|
67
63
|
@RelationId((dataOoc: DataOoc) => dataOoc.dataSet)
|
68
64
|
dataSetId?: string
|
69
65
|
|
70
|
-
@
|
71
|
-
@
|
72
|
-
|
73
|
-
dataSample?: DataSample
|
74
|
-
|
75
|
-
@RelationId((dataOoc: DataOoc) => dataOoc.dataSample)
|
76
|
-
dataSampleId?: string
|
66
|
+
@Column({ nullable: true })
|
67
|
+
@Field({ nullable: true })
|
68
|
+
dataSetVersion?: number
|
77
69
|
|
78
70
|
@Column({
|
79
71
|
nullable: true
|
@@ -127,7 +119,10 @@ export class DataOoc {
|
|
127
119
|
|
128
120
|
@Column('simple-json', { nullable: true })
|
129
121
|
@Field(type => ScalarObject, { nullable: true })
|
130
|
-
|
122
|
+
judgment?: ScalarObject
|
123
|
+
|
124
|
+
@Field(type => [DataItem], { nullable: true })
|
125
|
+
dataItems?: DataItem[]
|
131
126
|
|
132
127
|
@Column('simple-json', { nullable: true })
|
133
128
|
@Field(type => ScalarObject, { nullable: true })
|
@@ -4,6 +4,8 @@ import { getRepository } from 'typeorm'
|
|
4
4
|
import { User } from '@things-factory/auth-base'
|
5
5
|
import { Domain, getQueryBuilderFromListParams, ListParam } from '@things-factory/shell'
|
6
6
|
|
7
|
+
import { DataSetHistory } from '../data-set-history/data-set-history'
|
8
|
+
import { DataItem } from '../data-set/data-item-type'
|
7
9
|
import { DataSet } from '../data-set/data-set'
|
8
10
|
import { DataSample } from './data-sample'
|
9
11
|
import { DataSampleList } from './data-sample-type'
|
@@ -37,8 +39,19 @@ export class DataSampleQuery {
|
|
37
39
|
return { items, total }
|
38
40
|
}
|
39
41
|
|
42
|
+
@FieldResolver(type => [DataItem])
|
43
|
+
async dataItems(@Root() dataSample: DataSample): Promise<DataItem[]> {
|
44
|
+
const dataSetHistory: DataSetHistory = await getRepository(DataSetHistory).findOne({
|
45
|
+
where: {
|
46
|
+
originalId: dataSample.dataSetId,
|
47
|
+
version: dataSample.dataSetVersion
|
48
|
+
}
|
49
|
+
})
|
50
|
+
return dataSetHistory?.dataItems || []
|
51
|
+
}
|
52
|
+
|
40
53
|
@FieldResolver(type => DataSet)
|
41
|
-
async dataSet(@Root() dataSample: DataSample): Promise<
|
54
|
+
async dataSet(@Root() dataSample: DataSample): Promise<DataSet> {
|
42
55
|
return await getRepository(DataSet).findOne(dataSample.dataSetId)
|
43
56
|
}
|
44
57
|
|
@@ -14,14 +14,14 @@ import { User } from '@things-factory/auth-base'
|
|
14
14
|
import { config } from '@things-factory/env'
|
15
15
|
import { Domain, ScalarObject } from '@things-factory/shell'
|
16
16
|
|
17
|
+
import { DataItem } from '../data-set/data-item-type'
|
17
18
|
import { DataSet } from '../data-set/data-set'
|
18
19
|
|
19
20
|
const ORMCONFIG = config.get('ormconfig', {})
|
20
21
|
const DATABASE_TYPE = ORMCONFIG.type
|
21
22
|
@Entity()
|
22
|
-
@Index('ix_data_sample_0', (dataSample: DataSample) => [dataSample.domain, dataSample.dataSet], { unique: false })
|
23
23
|
@Index(
|
24
|
-
'
|
24
|
+
'ix_data_sample_0',
|
25
25
|
(dataSample: DataSample) => [dataSample.domain, dataSample.dataSet, dataSample.collectedAt],
|
26
26
|
{ unique: false }
|
27
27
|
)
|
@@ -71,13 +71,20 @@ export class DataSample {
|
|
71
71
|
@RelationId((dataSample: DataSample) => dataSample.dataSet)
|
72
72
|
dataSetId?: string
|
73
73
|
|
74
|
+
@Column({ nullable: true })
|
75
|
+
@Field({ nullable: true })
|
76
|
+
dataSetVersion?: number
|
77
|
+
|
74
78
|
@Column('simple-json', { nullable: true })
|
75
79
|
@Field(type => ScalarObject, { nullable: true })
|
76
80
|
data?: ScalarObject
|
77
81
|
|
78
82
|
@Column('simple-json', { nullable: true })
|
79
83
|
@Field(type => ScalarObject, { nullable: true })
|
80
|
-
|
84
|
+
judgment?: ScalarObject
|
85
|
+
|
86
|
+
@Field(type => [DataItem], { nullable: true })
|
87
|
+
dataItems?: DataItem[]
|
81
88
|
|
82
89
|
@Column({
|
83
90
|
nullable: true,
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import { Field, InputType, Int, ObjectType, registerEnumType } from 'type-graphql'
|
2
|
+
|
3
|
+
import { ScalarObject } from '@things-factory/shell'
|
4
|
+
|
5
|
+
export enum DataItemType {
|
6
|
+
number = 'number',
|
7
|
+
text = 'text',
|
8
|
+
boolean = 'boolean',
|
9
|
+
select = 'select',
|
10
|
+
file = 'file'
|
11
|
+
}
|
12
|
+
|
13
|
+
registerEnumType(DataItemType, {
|
14
|
+
name: 'DataItemType',
|
15
|
+
description: 'state enumeration of a data-item'
|
16
|
+
})
|
17
|
+
|
18
|
+
@ObjectType({ description: 'Entity for DataItem' })
|
19
|
+
export class DataItem {
|
20
|
+
@Field()
|
21
|
+
name: string
|
22
|
+
|
23
|
+
@Field({ nullable: true })
|
24
|
+
description?: string
|
25
|
+
|
26
|
+
@Field({ nullable: true })
|
27
|
+
tag?: string
|
28
|
+
|
29
|
+
@Field({ nullable: true })
|
30
|
+
active?: boolean
|
31
|
+
|
32
|
+
@Field({ nullable: true })
|
33
|
+
hidden?: boolean
|
34
|
+
|
35
|
+
@Field({ nullable: true })
|
36
|
+
type?: DataItemType
|
37
|
+
|
38
|
+
@Field(type => ScalarObject, { nullable: true })
|
39
|
+
options?: ScalarObject
|
40
|
+
|
41
|
+
@Field({ nullable: true })
|
42
|
+
unit?: string
|
43
|
+
|
44
|
+
@Field(type => Int, { nullable: true })
|
45
|
+
quota: number
|
46
|
+
|
47
|
+
@Field(type => ScalarObject, { nullable: true })
|
48
|
+
spec?: ScalarObject
|
49
|
+
}
|
50
|
+
|
51
|
+
@InputType()
|
52
|
+
export class DataItemPatch {
|
53
|
+
@Field({ nullable: true })
|
54
|
+
name?: string
|
55
|
+
|
56
|
+
@Field({ nullable: true })
|
57
|
+
description?: string
|
58
|
+
|
59
|
+
@Field({ nullable: true })
|
60
|
+
tag?: string
|
61
|
+
|
62
|
+
@Field(type => DataItemType, { nullable: true })
|
63
|
+
type?: DataItemType
|
64
|
+
|
65
|
+
@Field(type => ScalarObject, { nullable: true })
|
66
|
+
options?: ScalarObject
|
67
|
+
|
68
|
+
@Field({ nullable: true })
|
69
|
+
unit?: string
|
70
|
+
|
71
|
+
@Field(type => Int, { nullable: true })
|
72
|
+
quota?: number
|
73
|
+
|
74
|
+
@Field({ nullable: true })
|
75
|
+
active?: boolean
|
76
|
+
|
77
|
+
@Field({ nullable: true })
|
78
|
+
hidden?: boolean
|
79
|
+
|
80
|
+
@Field(type => ScalarObject, { nullable: true })
|
81
|
+
spec?: ScalarObject
|
82
|
+
}
|