mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-11 15:48:09 +00:00
added space link service
This commit is contained in:
5
libs/common/src/constants/direction.enum.ts
Normal file
5
libs/common/src/constants/direction.enum.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum Direction {
|
||||
LEFT = 'left',
|
||||
RIGHT = 'right',
|
||||
DOWN = 'down',
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||
import { SpaceEntity } from './space.entity';
|
||||
import { Direction } from '@app/common/constants/direction.enum';
|
||||
|
||||
@Entity({ name: 'space_link' })
|
||||
@Entity({ name: 'space-link' })
|
||||
export class SpaceLinkEntity extends AbstractEntity {
|
||||
@ManyToOne(() => SpaceEntity, { nullable: false, onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'start_space_id' })
|
||||
@ -13,9 +14,8 @@ export class SpaceLinkEntity extends AbstractEntity {
|
||||
public endSpace: SpaceEntity;
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 10,
|
||||
nullable: false,
|
||||
enum: Object.values(Direction),
|
||||
})
|
||||
direction: string;
|
||||
|
||||
|
@ -2,4 +2,5 @@ export * from './space.service';
|
||||
export * from './space-user.service';
|
||||
export * from './space-device.service';
|
||||
export * from './subspace';
|
||||
export * from './space-link';
|
||||
export * from './space-scene.service';
|
||||
|
1
src/space/services/space-link/index.ts
Normal file
1
src/space/services/space-link/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './space-link.service';
|
88
src/space/services/space-link/space-link.service.ts
Normal file
88
src/space/services/space-link/space-link.service.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import {
|
||||
SpaceLinkRepository,
|
||||
SpaceRepository,
|
||||
} from '@app/common/modules/space/repositories';
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceLinkService {
|
||||
constructor(
|
||||
private readonly spaceRepository: SpaceRepository,
|
||||
private readonly spaceLinkRepository: SpaceLinkRepository,
|
||||
) {}
|
||||
|
||||
async saveSpaceLink(
|
||||
startSpaceId: string,
|
||||
endSpaceId: string,
|
||||
direction: string,
|
||||
): Promise<void> {
|
||||
try {
|
||||
// Check if a link between the startSpace and endSpace already exists
|
||||
const existingLink = await this.spaceLinkRepository.findOne({
|
||||
where: {
|
||||
startSpace: { uuid: startSpaceId },
|
||||
endSpace: { uuid: endSpaceId },
|
||||
},
|
||||
});
|
||||
|
||||
if (existingLink) {
|
||||
// Update the direction if the link exists
|
||||
existingLink.direction = direction;
|
||||
await this.spaceLinkRepository.save(existingLink);
|
||||
return;
|
||||
}
|
||||
|
||||
const existingEndSpaceLink = await this.spaceLinkRepository.findOne({
|
||||
where: { endSpace: { uuid: endSpaceId } },
|
||||
});
|
||||
|
||||
if (
|
||||
existingEndSpaceLink &&
|
||||
existingEndSpaceLink.startSpace.uuid !== startSpaceId
|
||||
) {
|
||||
throw new Error(
|
||||
`Space with ID ${endSpaceId} is already an endSpace in another link and cannot be reused.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Find start space
|
||||
const startSpace = await this.spaceRepository.findOne({
|
||||
where: { uuid: startSpaceId },
|
||||
});
|
||||
|
||||
if (!startSpace) {
|
||||
throw new HttpException(
|
||||
`Start space with ID ${startSpaceId} not found.`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
// Find end space
|
||||
const endSpace = await this.spaceRepository.findOne({
|
||||
where: { uuid: endSpaceId },
|
||||
});
|
||||
|
||||
if (!endSpace) {
|
||||
throw new HttpException(
|
||||
`End space with ID ${endSpaceId} not found.`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
// Create and save the space link
|
||||
const spaceLink = this.spaceLinkRepository.create({
|
||||
startSpace,
|
||||
endSpace,
|
||||
direction,
|
||||
});
|
||||
|
||||
await this.spaceLinkRepository.save(spaceLink);
|
||||
} catch (error) {
|
||||
throw new HttpException(
|
||||
error.message ||
|
||||
`Failed to save space link. Internal Server Error: ${error.message}`,
|
||||
error.status || HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
import {
|
||||
SpaceLinkRepository,
|
||||
SpaceRepository,
|
||||
} from '@app/common/modules/space/repositories';
|
||||
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||
import {
|
||||
BadRequestException,
|
||||
HttpException,
|
||||
@ -14,47 +11,25 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
||||
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||
import { SpaceEntity } from '@app/common/modules/space/entities';
|
||||
import { generateRandomString } from '@app/common/helper/randomString';
|
||||
import { SpaceLinkService } from './space-link';
|
||||
|
||||
@Injectable()
|
||||
export class SpaceService {
|
||||
constructor(
|
||||
private readonly spaceRepository: SpaceRepository,
|
||||
private readonly spaceLinkRepository: SpaceLinkRepository,
|
||||
private readonly communityRepository: CommunityRepository,
|
||||
private readonly spaceLinkService: SpaceLinkService,
|
||||
) {}
|
||||
|
||||
async createSpace(
|
||||
addSpaceDto: AddSpaceDto,
|
||||
communityId: string,
|
||||
): Promise<BaseResponseDto> {
|
||||
let parent: SpaceEntity | null = null;
|
||||
|
||||
const { parentUuid, direction } = addSpaceDto;
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityId },
|
||||
});
|
||||
|
||||
// If the community doesn't exist, throw a 404 error
|
||||
if (!community) {
|
||||
throw new HttpException(
|
||||
`Community with ID ${communityId} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
const community = await this.validateCommunity(communityId);
|
||||
|
||||
if (parentUuid) {
|
||||
parent = await this.spaceRepository.findOne({
|
||||
where: { uuid: parentUuid },
|
||||
});
|
||||
|
||||
// If the community doesn't exist, throw a 404 error
|
||||
if (!parent) {
|
||||
throw new HttpException(
|
||||
`Parent with ID ${parentUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
const parent = parentUuid ? await this.validateSpace(parentUuid) : null;
|
||||
try {
|
||||
const newSpace = this.spaceRepository.create({
|
||||
...addSpaceDto,
|
||||
@ -65,13 +40,11 @@ export class SpaceService {
|
||||
await this.spaceRepository.save(newSpace);
|
||||
|
||||
if (direction && parent) {
|
||||
const spaceLink = await this.spaceLinkRepository.create({
|
||||
await this.spaceLinkService.saveSpaceLink(
|
||||
parent.uuid,
|
||||
newSpace.uuid,
|
||||
direction,
|
||||
endSpace: newSpace,
|
||||
startSpace: parent,
|
||||
});
|
||||
|
||||
await this.spaceLinkRepository.save(spaceLink);
|
||||
);
|
||||
}
|
||||
|
||||
return new SuccessResponseDto({
|
||||
@ -87,17 +60,7 @@ export class SpaceService {
|
||||
async getSpacesHierarchyForCommunity(
|
||||
communityUuid: string,
|
||||
): Promise<BaseResponseDto> {
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityUuid },
|
||||
});
|
||||
|
||||
// If the community doesn't exist, throw a 404 error
|
||||
if (!community) {
|
||||
throw new HttpException(
|
||||
`Community with ID ${communityUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
await this.validateCommunity(communityUuid);
|
||||
try {
|
||||
// Get all spaces related to the community, including the parent-child relations
|
||||
const spaces = await this.spaceRepository.find({
|
||||
@ -123,19 +86,8 @@ export class SpaceService {
|
||||
|
||||
async findOne(spaceUuid: string): Promise<BaseResponseDto> {
|
||||
try {
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: {
|
||||
uuid: spaceUuid,
|
||||
},
|
||||
});
|
||||
const space = await this.validateSpace(spaceUuid);
|
||||
|
||||
// If space is not found, throw a NotFoundException
|
||||
if (!space) {
|
||||
throw new HttpException(
|
||||
`Space with UUID ${spaceUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
return new SuccessResponseDto({
|
||||
message: `Space with ID ${spaceUuid} successfully fetched`,
|
||||
data: space,
|
||||
@ -158,28 +110,10 @@ export class SpaceService {
|
||||
): Promise<BaseResponseDto> {
|
||||
try {
|
||||
// First, check if the community exists
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityUuid },
|
||||
});
|
||||
|
||||
if (!community) {
|
||||
throw new HttpException(
|
||||
`Community with ID ${communityUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
const space = await this.validateCommunityAndSpace(
|
||||
spaceUuid,
|
||||
communityUuid,
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the space exists
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid, community: { uuid: communityUuid } },
|
||||
});
|
||||
|
||||
if (!space) {
|
||||
throw new HttpException(
|
||||
`Space with ID ${spaceUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
// Delete the space
|
||||
await this.spaceRepository.remove(space);
|
||||
@ -205,54 +139,17 @@ export class SpaceService {
|
||||
updateSpaceDto: AddSpaceDto,
|
||||
): Promise<BaseResponseDto> {
|
||||
try {
|
||||
// First, check if the community exists
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityId },
|
||||
});
|
||||
|
||||
if (!community) {
|
||||
throw new HttpException(
|
||||
`Community with ID ${communityId} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
const space = await this.validateCommunityAndSpace(
|
||||
communityId,
|
||||
spaceUuid,
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the space exists
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid, community: { uuid: communityId } },
|
||||
});
|
||||
|
||||
if (!space) {
|
||||
throw new HttpException(
|
||||
`Space with ID ${spaceUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
// If a parentId is provided, check if the parent exists
|
||||
const { parentUuid } = updateSpaceDto;
|
||||
let parent: SpaceEntity | null = null;
|
||||
if (parentUuid) {
|
||||
parent = await this.spaceRepository.findOne({
|
||||
where: { uuid: parentUuid, community: { uuid: communityId } },
|
||||
});
|
||||
|
||||
// If the parent doesn't exist, throw a 404 error
|
||||
if (!parent) {
|
||||
throw new HttpException(
|
||||
`Parent space with ID ${parentUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
// Set the parent of the current space
|
||||
space.parent = parent;
|
||||
} else {
|
||||
space.parent = null; // If no parent is provided, clear the parent
|
||||
}
|
||||
const parent = parentUuid ? await this.validateSpace(parentUuid) : null;
|
||||
|
||||
// Update other space properties from updateSpaceDto
|
||||
Object.assign(space, updateSpaceDto);
|
||||
Object.assign(space, updateSpaceDto, { parent });
|
||||
|
||||
// Save the updated space
|
||||
await this.spaceRepository.save(space);
|
||||
@ -276,17 +173,7 @@ export class SpaceService {
|
||||
async getSpacesHierarchyForSpace(
|
||||
spaceUuid: string,
|
||||
): Promise<BaseResponseDto> {
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid },
|
||||
});
|
||||
|
||||
// If the space doesn't exist, throw a 404 error
|
||||
if (!space) {
|
||||
throw new HttpException(
|
||||
`Space with ID ${spaceUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
await this.validateSpace(spaceUuid);
|
||||
|
||||
try {
|
||||
// Get all spaces that are children of the provided space, including the parent-child relations
|
||||
@ -315,18 +202,7 @@ export class SpaceService {
|
||||
try {
|
||||
const invitationCode = generateRandomString(6);
|
||||
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: {
|
||||
uuid: spaceUuid,
|
||||
},
|
||||
});
|
||||
|
||||
if (!space) {
|
||||
throw new HttpException(
|
||||
`Space with ID ${spaceUuid} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
const space = await this.validateSpace(spaceUuid);
|
||||
|
||||
space.invitationCode = invitationCode;
|
||||
await this.spaceRepository.save(space);
|
||||
@ -369,24 +245,37 @@ export class SpaceService {
|
||||
}
|
||||
});
|
||||
|
||||
return rootSpaces; // Return the root spaces with children nested within them
|
||||
return rootSpaces;
|
||||
}
|
||||
|
||||
private async validateCommunity(communityId: string) {
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityId },
|
||||
});
|
||||
if (!community) {
|
||||
throw new HttpException(
|
||||
`Community with ID ${communityId} not found`,
|
||||
HttpStatus.NOT_FOUND,
|
||||
);
|
||||
}
|
||||
return community;
|
||||
}
|
||||
|
||||
async validateCommunityAndSpace(communityUuid: string, spaceUuid: string) {
|
||||
const community = await this.communityRepository.findOne({
|
||||
where: { uuid: communityUuid },
|
||||
});
|
||||
const community = await this.validateCommunity(communityUuid);
|
||||
if (!community) {
|
||||
this.throwNotFound('Community', communityUuid);
|
||||
}
|
||||
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid, community: { uuid: communityUuid } },
|
||||
relations: ['devices', 'devices.productDevice'],
|
||||
});
|
||||
if (!space) {
|
||||
this.throwNotFound('Space', spaceUuid);
|
||||
const space = await this.validateSpace(spaceUuid);
|
||||
return space;
|
||||
}
|
||||
|
||||
private async validateSpace(spaceUuid: string) {
|
||||
const space = await this.spaceRepository.findOne({
|
||||
where: { uuid: spaceUuid },
|
||||
});
|
||||
if (!space) this.throwNotFound('Space', spaceUuid);
|
||||
return space;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
} from './controllers';
|
||||
import {
|
||||
SpaceDeviceService,
|
||||
SpaceLinkService,
|
||||
SpaceSceneService,
|
||||
SpaceService,
|
||||
SpaceUserService,
|
||||
@ -55,6 +56,7 @@ import { DeviceStatusLogRepository } from '@app/common/modules/device-status-log
|
||||
ProductRepository,
|
||||
SubSpaceService,
|
||||
SpaceDeviceService,
|
||||
SpaceLinkService,
|
||||
SubspaceDeviceService,
|
||||
SpaceRepository,
|
||||
DeviceRepository,
|
||||
|
Reference in New Issue
Block a user