Skip to content

Commit bbd2c42

Browse files
committed
TRX-develop add conflict check for room name during update
1 parent 50e6728 commit bbd2c42

2 files changed

Lines changed: 69 additions & 76 deletions

File tree

src/modules/devices/devices.repository.ts

Lines changed: 57 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
deviceTemplates,
2323
ServerVendor,
2424
} from '../drizzle/schema';
25-
import { eq, sql, and } from 'drizzle-orm';
25+
import { eq, sql, and, inArray } from 'drizzle-orm';
2626
import { unionAll } from 'drizzle-orm/pg-core';
2727
import { inferLinksForNewDevices } from '@/shared/utils/topology';
2828
import { interfaceLinks } from '../drizzle/schema';
@@ -36,8 +36,6 @@ export class DevicesRepository {
3636
private findByIdsAndProjectIdStmt;
3737
private deleteByIdStmt;
3838
private findByIdStmt;
39-
private findPhysicalDevicesByProjectIdStmt;
40-
private findPhysicalDevicesByIdsAndProjectIdStmt;
4139

4240
constructor(@Inject(DRIZZLE_CONNECTION) private readonly db: AppDatabase) {
4341
this.findByIdsStmt = this.db.query.devices
@@ -115,17 +113,61 @@ export class DevicesRepository {
115113
})
116114
.prepare('find_device_by_id');
117115

118-
const inRackSql = sql`
119-
(${sql.placeholder('inRack')}::boolean IS NULL)
120-
OR (${devices.rackId} IS NOT NULL) = ${sql.placeholder('inRack')}::boolean
121-
`;
116+
}
122117

123-
const inRackServerSql = sql`
124-
(${sql.placeholder('inRack')}::boolean IS NULL)
125-
OR (${servers.rackId} IS NOT NULL) = ${sql.placeholder('inRack')}::boolean
126-
`;
118+
async createDeviceStack(newStack: NewDeviceStack): Promise<DeviceStack> {
119+
const [createdDeviceStack] = await this.insertDeviceStackStmt.execute({
120+
name: newStack.name,
121+
projectId: newStack.projectId,
122+
});
123+
124+
return createdDeviceStack;
125+
}
126+
127+
async findDevicesByProjectId(projectId: string) {
128+
return this.findManyByProjectIdStmt.execute({ projectId });
129+
}
130+
131+
async findPhysicalDevicesByProjectId(projectId: string, inRack?: boolean) {
132+
const inRackCondition =
133+
inRack === undefined
134+
? undefined
135+
: sql`(${devices.rackId} IS NOT NULL) = ${inRack}`;
136+
const inRackServerCondition =
137+
inRack === undefined
138+
? undefined
139+
: sql`(${servers.rackId} IS NOT NULL) = ${inRack}`;
140+
141+
const devicesQuery = this.buildBaseDevicesQuery().where(
142+
and(eq(devices.projectId, projectId), inRackCondition),
143+
);
144+
const serversQuery = this.buildBaseServersQuery().where(
145+
and(eq(servers.projectId, projectId), inRackServerCondition),
146+
);
127147

128-
const baseDevicesQuery = this.db
148+
return this.db
149+
.select()
150+
.from(unionAll(devicesQuery, serversQuery).as('combined_devices'));
151+
}
152+
153+
async findPhysicalDevicesByIdsAndProjectId(
154+
ids: string[],
155+
projectId: string,
156+
): Promise<DeviceWithRelations[]> {
157+
const devicesQuery = this.buildBaseDevicesQuery().where(
158+
and(eq(devices.projectId, projectId), inArray(devices.id, ids)),
159+
);
160+
const serversQuery = this.buildBaseServersQuery().where(
161+
and(eq(servers.projectId, projectId), inArray(servers.id, ids)),
162+
);
163+
164+
return this.db
165+
.select()
166+
.from(unionAll(devicesQuery, serversQuery).as('combined_devices_by_ids')) as unknown as Promise<DeviceWithRelations[]>;
167+
}
168+
169+
private buildBaseDevicesQuery() {
170+
return this.db
129171
.select({
130172
id: devices.id,
131173
name: devices.name,
@@ -152,8 +194,10 @@ export class DevicesRepository {
152194
})
153195
.from(devices)
154196
.leftJoin(deviceTemplates, eq(devices.deviceTemplateId, deviceTemplates.id));
197+
}
155198

156-
const baseServersQuery = this.db
199+
private buildBaseServersQuery() {
200+
return this.db
157201
.select({
158202
id: servers.id,
159203
name: servers.name,
@@ -180,68 +224,6 @@ export class DevicesRepository {
180224
})
181225
.from(servers)
182226
.leftJoin(deviceTemplates, eq(servers.deviceTemplateId, deviceTemplates.id));
183-
184-
const devicesQuery = baseDevicesQuery.where(
185-
and(eq(devices.projectId, sql.placeholder('projectId')), inRackSql),
186-
);
187-
188-
const serversQuery = baseServersQuery.where(
189-
and(eq(servers.projectId, sql.placeholder('projectId')), inRackServerSql),
190-
);
191-
192-
this.findPhysicalDevicesByProjectIdStmt = this.db
193-
.select()
194-
.from(unionAll(devicesQuery, serversQuery).as('combined_devices'))
195-
.prepare('find_physical_devices');
196-
197-
const devicesQueryByIds = baseDevicesQuery.where(
198-
and(
199-
eq(devices.projectId, sql.placeholder('projectId')),
200-
sql`${devices.id} = ANY(${sql.placeholder('ids')}::uuid[])`,
201-
),
202-
);
203-
204-
const serversQueryByIds = baseServersQuery.where(
205-
and(
206-
eq(servers.projectId, sql.placeholder('projectId')),
207-
sql`${servers.id} = ANY(${sql.placeholder('ids')}::uuid[])`,
208-
),
209-
);
210-
211-
this.findPhysicalDevicesByIdsAndProjectIdStmt = this.db
212-
.select()
213-
.from(unionAll(devicesQueryByIds, serversQueryByIds).as('combined_devices_by_ids'))
214-
.prepare('find_physical_devices_by_ids_and_project_id');
215-
}
216-
217-
async createDeviceStack(newStack: NewDeviceStack): Promise<DeviceStack> {
218-
const [createdDeviceStack] = await this.insertDeviceStackStmt.execute({
219-
name: newStack.name,
220-
projectId: newStack.projectId,
221-
});
222-
223-
return createdDeviceStack;
224-
}
225-
226-
async findDevicesByProjectId(projectId: string) {
227-
return this.findManyByProjectIdStmt.execute({ projectId });
228-
}
229-
230-
async findPhysicalDevicesByProjectId(projectId: string, inRack?: boolean) {
231-
return this.findPhysicalDevicesByProjectIdStmt.execute({
232-
projectId,
233-
inRack: inRack ?? null,
234-
});
235-
}
236-
237-
async findPhysicalDevicesByIdsAndProjectId(
238-
ids: string[],
239-
projectId: string,
240-
): Promise<DeviceWithRelations[]> {
241-
return this.findPhysicalDevicesByIdsAndProjectIdStmt.execute({
242-
ids,
243-
projectId,
244-
});
245227
}
246228

247229
async createDevicesTransaction(

src/modules/rooms/rooms.service.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class RoomsService {
1717
constructor(
1818
private readonly roomsRepository: RoomsRepository,
1919
private readonly racksService: RacksService,
20-
) {}
20+
) { }
2121

2222
async createRoom(floorId: string, buildingId: string, createRoomDto: CreateRoomDto) {
2323
const existingRoom = await this.roomsRepository.findByNameAndBuildingId(
@@ -59,6 +59,17 @@ export class RoomsService {
5959
async updateRoom(roomId: string, userId: string, updateRoomDto: UpdateRoomDto) {
6060
const existingRoom = await this.getRoomByIdOrThrow(roomId, userId);
6161

62+
if (updateRoomDto.name) {
63+
const room = await this.roomsRepository.findByNameAndBuildingId(
64+
updateRoomDto.name,
65+
existingRoom.floor.buildingId,
66+
);
67+
68+
if (room && room.id !== existingRoom.id) {
69+
throw new ConflictException('Room with the same name already exists in this building');
70+
}
71+
}
72+
6273
return await this.roomsRepository.update(existingRoom.id, {
6374
...existingRoom,
6475
...updateRoomDto,

0 commit comments

Comments
 (0)