Skip to content

Commit 2a974da

Browse files
authored
Optional metadata fields when managing an application (#152)
* Store application metadata * Application meta data fields with migration. Updated typeorm Part of the migration is updates to cascades due to updating typeorm * Cleanup * Revert to lockfile version 1 (npm 6) * PR fixes. Comment on constraints change. Revert lockfile to version 1
1 parent cf5f089 commit 2a974da

17 files changed

+643
-14134
lines changed

package-lock.json

Lines changed: 165 additions & 14108 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"rimraf": "^3.0.2",
6969
"rxjs": "^6.6.3",
7070
"swagger-ui-express": "^4.1.5",
71-
"typeorm": "^0.2.29",
71+
"typeorm": "^0.2.34",
7272
"uuid": "^8.3.2",
7373
"vm2": "^3.9.9",
7474
"wait-for-expect": "^3.0.2"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ApplicationDeviceTypeUnion } from "@enum/device-type.enum";
2+
import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
3+
import { Application } from "./application.entity";
4+
import { DbBaseEntity } from "./base.entity";
5+
6+
@Entity("application_device_type")
7+
export class ApplicationDeviceType extends DbBaseEntity {
8+
@Column()
9+
type: ApplicationDeviceTypeUnion;
10+
11+
@ManyToOne(() => Application, application => application.deviceTypes, {
12+
onDelete: "CASCADE",
13+
// Delete the row instead of null'ing application. Useful for updates
14+
orphanedRowAction: "delete",
15+
})
16+
application: Application;
17+
}

src/entities/application.entity.ts

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1+
import { DbBaseEntity } from "@entities/base.entity";
2+
import { DataTarget } from "@entities/data-target.entity";
3+
import { IoTDevice } from "@entities/iot-device.entity";
4+
import { OrganizationApplicationPermission } from "@entities/organization-application-permission.entity";
5+
import { Organization } from "@entities/organization.entity";
6+
import { ApplicationStatus } from "@enum/application-status.enum";
17
import {
28
Column,
9+
CreateDateColumn,
310
Entity,
411
JoinTable,
512
ManyToMany,
613
ManyToOne,
714
OneToMany,
815
Unique,
916
} from "typeorm";
10-
11-
import { DbBaseEntity } from "@entities/base.entity";
12-
import { DataTarget } from "@entities/data-target.entity";
13-
import { IoTDevice } from "@entities/iot-device.entity";
14-
import { OrganizationApplicationPermission } from "@entities/organization-application-permission.entity";
15-
import { Organization } from "@entities/organization.entity";
17+
import { ApplicationDeviceType } from "./application-device-type.entity";
18+
import { ControlledProperty } from "./controlled-property.entity";
1619
import { Multicast } from "./multicast.entity";
1720

18-
1921
@Entity("application")
2022
@Unique(["name"])
2123
export class Application extends DbBaseEntity {
@@ -64,4 +66,46 @@ export class Application extends DbBaseEntity {
6466
)
6567
@JoinTable()
6668
permissions: OrganizationApplicationPermission[];
69+
70+
@Column({ nullable: true })
71+
status?: ApplicationStatus;
72+
73+
@CreateDateColumn({ nullable: true })
74+
startDate?: Date;
75+
76+
@CreateDateColumn({ nullable: true })
77+
endDate?: Date;
78+
79+
@Column({ nullable: true })
80+
category?: string;
81+
82+
@Column({ nullable: true })
83+
owner?: string;
84+
85+
@Column({ nullable: true })
86+
contactPerson?: string;
87+
88+
@Column({ nullable: true })
89+
contactEmail?: string;
90+
91+
@Column({ nullable: true })
92+
contactPhone?: string;
93+
94+
@Column({ nullable: true })
95+
personalData?: boolean;
96+
97+
@Column({ nullable: true })
98+
hardware?: string;
99+
100+
@OneToMany(() => ControlledProperty, entity => entity.application, {
101+
nullable: true,
102+
cascade: true,
103+
})
104+
controlledProperties?: ControlledProperty[];
105+
106+
@OneToMany(() => ApplicationDeviceType, entity => entity.application, {
107+
nullable: true,
108+
cascade: true,
109+
})
110+
deviceTypes?: ApplicationDeviceType[];
67111
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ControlledPropertyTypes } from "@enum/controlled-property.enum";
2+
import { Column, Entity, ManyToOne } from "typeorm";
3+
import { Application } from "./application.entity";
4+
import { DbBaseEntity } from "./base.entity";
5+
6+
@Entity("controlled_property")
7+
export class ControlledProperty extends DbBaseEntity {
8+
@Column()
9+
type: ControlledPropertyTypes;
10+
11+
@ManyToOne(() => Application, application => application.controlledProperties, {
12+
onDelete: "CASCADE",
13+
// Delete the row instead of null'ing application. Useful for updates
14+
orphanedRowAction: "delete",
15+
})
16+
application: Application;
17+
}

src/entities/dto/controlled-property/create-controlled-property.dto.ts

Whitespace-only changes.

src/entities/dto/create-application.dto.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1+
import { ApplicationStatus } from "@enum/application-status.enum";
2+
import { ControlledPropertyTypes } from "@enum/controlled-property.enum";
3+
import { ApplicationDeviceTypes, ApplicationDeviceTypeUnion } from "@enum/device-type.enum";
4+
import { ValidateDate } from "@helpers/date.validator";
5+
import { IsSwaggerOptional } from "@helpers/optional-validator";
6+
import { IsPhoneNumberString } from "@helpers/phone-number.validator";
7+
import { nameof } from "@helpers/type-helper";
18
import { ApiProperty } from "@nestjs/swagger";
2-
import { IsOptional, IsString, MaxLength, MinLength } from "class-validator";
9+
import {
10+
ArrayUnique,
11+
IsArray,
12+
IsBoolean,
13+
IsEnum,
14+
IsOptional,
15+
IsString,
16+
MaxLength,
17+
MinLength,
18+
} from "class-validator";
319

420
export class CreateApplicationDto {
521
@ApiProperty({ required: true })
@@ -16,4 +32,62 @@ export class CreateApplicationDto {
1632
@IsString()
1733
@MaxLength(1024)
1834
description?: string;
35+
36+
@IsSwaggerOptional()
37+
@IsEnum(ApplicationStatus)
38+
status?: ApplicationStatus;
39+
40+
@IsSwaggerOptional()
41+
@ValidateDate()
42+
startDate?: Date;
43+
44+
@IsSwaggerOptional()
45+
@ValidateDate()
46+
endDate?: Date;
47+
48+
@IsSwaggerOptional()
49+
@IsString()
50+
@MaxLength(100)
51+
category?: string;
52+
53+
@IsSwaggerOptional()
54+
@IsString()
55+
@MaxLength(100)
56+
owner?: string;
57+
58+
@IsSwaggerOptional()
59+
@IsString()
60+
@MaxLength(100)
61+
contactPerson?: string;
62+
63+
@IsSwaggerOptional()
64+
@IsString()
65+
@MaxLength(100)
66+
contactEmail?: string;
67+
68+
@IsSwaggerOptional()
69+
@IsPhoneNumberString(nameof<CreateApplicationDto>("contactPhone"))
70+
@MaxLength(12)
71+
contactPhone?: string;
72+
73+
@IsSwaggerOptional()
74+
@IsBoolean()
75+
personalData?: boolean;
76+
77+
@IsSwaggerOptional()
78+
@IsString()
79+
@MaxLength(1024)
80+
hardware?: string;
81+
82+
@IsSwaggerOptional()
83+
@IsArray()
84+
@ArrayUnique()
85+
@IsEnum(ControlledPropertyTypes, { each: true })
86+
controlledProperties?: ControlledPropertyTypes[];
87+
88+
@IsSwaggerOptional()
89+
@IsArray()
90+
@ArrayUnique()
91+
@IsEnum(ApplicationDeviceTypes, { each: true })
92+
deviceTypes?: ApplicationDeviceTypeUnion[];
1993
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export enum ApplicationStatus {
2+
"NONE" = "NONE",
3+
"IN-OPERATION" = "IN-OPERATION",
4+
"PROJECT" = "PROJECT",
5+
"PROTOTYPE" = "PROTOTYPE",
6+
"OTHER" = "OTHER",
7+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
export enum ControlledPropertyTypes {
2+
AIRPOLLUTION = "airPollution",
3+
ATMOSPHERICPRESSURE = "atmosphericPressure",
4+
CDOM = "cdom",
5+
CONDUCTANCE = "conductance",
6+
CONDUCTIVITY = "conductivity",
7+
DEPTH = "depth",
8+
EATINGACTIVITY = "eatingActivity",
9+
ELECTRICITYCONSUMPTION = "electricityConsumption",
10+
ENERGY = "energy",
11+
FILLINGLEVEL = "fillingLevel",
12+
GASCOMSUMPTION = "gasComsumption",
13+
HEADING = "heading",
14+
HUMIDITY = "humidity",
15+
LIGHT = "light",
16+
LOCATION = "location",
17+
MILKING = "milking",
18+
MOTION = "motion",
19+
MOVEMENTACTIVITY = "movementActivity",
20+
NOISELEVEL = "noiseLevel",
21+
OCCUPANCY = "occupancy",
22+
ORP = "orp",
23+
PH = "pH",
24+
POWER = "power",
25+
PRECIPITATION = "precipitation",
26+
PRESSURE = "pressure",
27+
SALINITY = "salinity",
28+
SMOKE = "smoke",
29+
SOILMOISTURE = "soilMoisture",
30+
SOLARRADIATION = "solarRadiation",
31+
SPEED = "speed",
32+
TDS = "tds",
33+
TEMPERATURE = "temperature",
34+
TRAFFICFLOW = "trafficFlow",
35+
TSS = "tss",
36+
TURBIDITY = "turbidity",
37+
WATERCONSUMPTION = "waterConsumption",
38+
WATERPOLLUTION = "waterPollution",
39+
WEATHERCONDITIONS = "weatherConditions",
40+
WEIGHT = "weight",
41+
WINDDIRECTION = "windDirection",
42+
WINDSPEED = "windSpeed",
43+
}

src/entities/enum/device-type.enum.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ export enum IoTDeviceType {
33
LoRaWAN = "LORAWAN",
44
SigFox = "SIGFOX",
55
}
6+
7+
enum ApplicationDeviceTypeExtra {
8+
Other = "OTHER",
9+
}
10+
11+
export type ApplicationDeviceTypeUnion = IoTDeviceType | ApplicationDeviceTypeExtra;
12+
// Enums cannot be extended like types
13+
export const ApplicationDeviceTypes = { ...IoTDeviceType, ...ApplicationDeviceTypeExtra };

0 commit comments

Comments
 (0)