Skip to content

Commit 5ab0240

Browse files
change from pr
1 parent 48f74eb commit 5ab0240

File tree

3 files changed

+109
-15
lines changed

3 files changed

+109
-15
lines changed

src/controllers/admin-controller/application.controller.ts

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ import { ListAllApplicationsDto } from "@dto/list-all-applications.dto";
3838
import { ListAllEntitiesDto } from "@dto/list-all-entities.dto";
3939
import { ListAllIoTDevicesResponseDto } from "@dto/list-all-iot-devices-response.dto";
4040
import { IoTDevicesListToMapResponseDto } from "@dto/list-all-iot-devices-to-map-response.dto";
41+
import { ListAllIotDevicesDto } from "@dto/list-all-iot-devices.dto";
4142
import { UpdateApplicationOrganizationDto } from "@dto/update-application-organization.dto";
4243
import { UpdateApplicationDto } from "@dto/update-application.dto";
4344
import { Application } from "@entities/application.entity";
4445
import { ActionType } from "@entities/audit-log-entry";
4546
import { AuthenticatedRequest } from "@entities/dto/internal/authenticated-request";
47+
import { IoTDevice } from "@entities/iot-device.entity";
4648
import { ErrorCodes } from "@enum/error-codes.enum";
4749
import {
4850
ApplicationAccessScope,
@@ -111,7 +113,11 @@ export class ApplicationController {
111113
@Param("id", new ParseIntPipe()) id: number
112114
): Promise<ApplicationDashboardResponseDto> {
113115
try {
114-
return await this.getApplicationsWithError(req, id, req.user.permissions.isGlobalAdmin);
116+
const whitelist = await this.getApplicationsWhiteList(req, id, req.user.permissions.isGlobalAdmin);
117+
return {
118+
...(await this.applicationService.countApplicationsWithError(id, whitelist)),
119+
totalDevices: await this.applicationService.countAllDevices(id, whitelist),
120+
};
115121
} catch (err) {
116122
throw new NotFoundException(ErrorCodes.IdDoesNotExists);
117123
}
@@ -149,6 +155,23 @@ export class ApplicationController {
149155
}
150156
}
151157

158+
@Read()
159+
@Get(":id/iot-devices-org")
160+
@ApiOperation({ summary: "Find the IoTDevice of an organization" })
161+
@ApiNotFoundResponse()
162+
async findIoTDevicesForOrganization(
163+
@Req() req: AuthenticatedRequest,
164+
@Param("id", new ParseIntPipe()) organizationId: number,
165+
@Query() query?: ListAllIotDevicesDto
166+
): Promise<IoTDevice[]> {
167+
try {
168+
const whitelist = await this.getApplicationsWhiteList(req, organizationId, req.user.permissions.isGlobalAdmin);
169+
return await this.applicationService.getAllDevices(organizationId, query);
170+
} catch (err) {
171+
throw new NotFoundException(ErrorCodes.IdDoesNotExists);
172+
}
173+
}
174+
152175
@Read()
153176
@Get(":id/iot-devices-map")
154177
@ApiOperation({ summary: "Find the IoTDevices of an Application" })
@@ -313,27 +336,21 @@ export class ApplicationController {
313336
return await this.applicationService.findFilterInformation(allowedApplications, organizationId);
314337
}
315338

316-
private async getApplicationsWithError(req: AuthenticatedRequest, organizationId: number, isGlobalAdmin: boolean) {
339+
private async getApplicationsWhiteList(
340+
req: AuthenticatedRequest,
341+
organizationId: number,
342+
isGlobalAdmin: boolean
343+
): Promise<number[] | null> {
317344
if (isGlobalAdmin) {
318-
return {
319-
...(await this.applicationService.countApplicationsWithError(organizationId)),
320-
totalDevices: await this.applicationService.countAllDevices(organizationId),
321-
};
345+
return null;
322346
}
323347

324348
const allFromOrg = req.user.permissions.getAllOrganizationsWithUserAdmin();
325349

326350
if (allFromOrg.some(x => x === organizationId)) {
327-
return {
328-
...(await this.applicationService.countApplicationsWithError(organizationId)),
329-
totalDevices: await this.applicationService.countAllDevices(organizationId),
330-
};
351+
return null;
331352
}
332353

333-
const allowedApplications = req.user.permissions.getAllApplicationsWithAtLeastRead();
334-
return {
335-
...(await this.applicationService.countApplicationsWithError(organizationId, allowedApplications)),
336-
totalDevices: await this.applicationService.countAllDevices(organizationId, allowedApplications),
337-
};
354+
return req.user.permissions.getAllApplicationsWithAtLeastRead();
338355
}
339356
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ApplicationStatus } from "@enum/application-status.enum";
2+
import { NullableApplicationStatus, NullableString } from "@helpers/string-to-number-validator";
3+
import { ApiProperty } from "@nestjs/swagger";
4+
import { Transform } from "class-transformer";
5+
import { IsOptional, IsString } from "class-validator";
6+
7+
export class ListAllIotDevicesDto {
8+
@ApiProperty({ type: Number, required: false })
9+
@IsOptional()
10+
@IsString()
11+
@Transform(({ value }) => NullableApplicationStatus(value))
12+
status?: ApplicationStatus | undefined;
13+
14+
@ApiProperty({ type: String, required: false })
15+
@IsOptional()
16+
@IsString()
17+
@Transform(({ value }) => NullableString(value))
18+
statusCheck?: "stable" | "alert" | null;
19+
20+
@ApiProperty({ type: Number, required: false })
21+
@IsOptional()
22+
@IsString()
23+
@Transform(({ value }) => NullableString(value))
24+
owner?: string | null;
25+
}

src/services/device-management/application.service.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ListAllApplicationsDto } from "@dto/list-all-applications.dto";
88
import { ListAllEntitiesDto } from "@dto/list-all-entities.dto";
99
import { ListAllIoTDevicesResponseDto } from "@dto/list-all-iot-devices-response.dto";
1010
import { IoTDevicesListToMapResponseDto } from "@dto/list-all-iot-devices-to-map-response.dto";
11+
import { ListAllIotDevicesDto } from "@dto/list-all-iot-devices.dto";
1112
import { LoRaWANDeviceWithChirpstackDataDto } from "@dto/lorawan-device-with-chirpstack-data.dto";
1213
import { UpdateApplicationOrganizationDto } from "@dto/update-application-organization.dto";
1314
import { UpdateApplicationDto } from "@dto/update-application.dto";
@@ -105,6 +106,57 @@ export class ApplicationService {
105106
throw new Error("Database query failed");
106107
}
107108
}
109+
110+
async getAllDevices(
111+
organizationId: number,
112+
query?: ListAllIotDevicesDto,
113+
whitelist?: number[] | null
114+
): Promise<IoTDevice[]> {
115+
const queryBuilder = this.iotDeviceRepository
116+
.createQueryBuilder("device")
117+
.leftJoin("device.application", "app")
118+
.leftJoin("app.dataTargets", "dataTargets")
119+
.leftJoinAndSelect("device.latestReceivedMessage", "latestMessage")
120+
.addSelect(["latestMessage.id", "latestMessage.sentTime"])
121+
.where("app.belongsToId = :organizationId", { organizationId });
122+
123+
if (whitelist && whitelist.length > 0) {
124+
queryBuilder.andWhere("app.id IN (:...whitelist)", { whitelist });
125+
}
126+
127+
if (query.status) {
128+
queryBuilder.andWhere("app.status = :status", { status: query.status });
129+
}
130+
131+
if (query.owner) {
132+
queryBuilder.andWhere("app.owner = :owner", { owner: query.owner });
133+
}
134+
135+
if (query.statusCheck === "alert") {
136+
queryBuilder.andWhere(
137+
new Brackets(qb => {
138+
qb.where("dataTargets.id IS NULL").orWhere("latestMessage.sentTime < NOW() - INTERVAL '24 HOURS'");
139+
})
140+
);
141+
}
142+
143+
if (query.statusCheck === "stable") {
144+
queryBuilder.andWhere(
145+
new Brackets(qb => {
146+
qb.where("dataTargets.id IS NOT NULL").orWhere("latestMessage.sentTime > NOW() - INTERVAL '24 HOURS'");
147+
})
148+
);
149+
}
150+
151+
try {
152+
const test = await queryBuilder.getMany();
153+
return test;
154+
} catch (error) {
155+
console.error("Database query failed:", error);
156+
throw new Error("Database query failed");
157+
}
158+
}
159+
108160
async findAndCountInList(
109161
query?: ListAllApplicationsDto,
110162
whitelist?: number[]

0 commit comments

Comments
 (0)