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 { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
import { AbstractEntity } from '../../abstract/entities/abstract.entity';
|
||||||
import { SpaceEntity } from './space.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 {
|
export class SpaceLinkEntity extends AbstractEntity {
|
||||||
@ManyToOne(() => SpaceEntity, { nullable: false, onDelete: 'CASCADE' })
|
@ManyToOne(() => SpaceEntity, { nullable: false, onDelete: 'CASCADE' })
|
||||||
@JoinColumn({ name: 'start_space_id' })
|
@JoinColumn({ name: 'start_space_id' })
|
||||||
@ -13,9 +14,8 @@ export class SpaceLinkEntity extends AbstractEntity {
|
|||||||
public endSpace: SpaceEntity;
|
public endSpace: SpaceEntity;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
type: 'varchar',
|
|
||||||
length: 10,
|
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
enum: Object.values(Direction),
|
||||||
})
|
})
|
||||||
direction: string;
|
direction: string;
|
||||||
|
|
||||||
|
@ -2,4 +2,5 @@ export * from './space.service';
|
|||||||
export * from './space-user.service';
|
export * from './space-user.service';
|
||||||
export * from './space-device.service';
|
export * from './space-device.service';
|
||||||
export * from './subspace';
|
export * from './subspace';
|
||||||
|
export * from './space-link';
|
||||||
export * from './space-scene.service';
|
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 {
|
import { SpaceRepository } from '@app/common/modules/space/repositories';
|
||||||
SpaceLinkRepository,
|
|
||||||
SpaceRepository,
|
|
||||||
} from '@app/common/modules/space/repositories';
|
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
HttpException,
|
HttpException,
|
||||||
@ -14,47 +11,25 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
|
|||||||
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
import { CommunityRepository } from '@app/common/modules/community/repositories';
|
||||||
import { SpaceEntity } from '@app/common/modules/space/entities';
|
import { SpaceEntity } from '@app/common/modules/space/entities';
|
||||||
import { generateRandomString } from '@app/common/helper/randomString';
|
import { generateRandomString } from '@app/common/helper/randomString';
|
||||||
|
import { SpaceLinkService } from './space-link';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SpaceService {
|
export class SpaceService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly spaceRepository: SpaceRepository,
|
private readonly spaceRepository: SpaceRepository,
|
||||||
private readonly spaceLinkRepository: SpaceLinkRepository,
|
|
||||||
private readonly communityRepository: CommunityRepository,
|
private readonly communityRepository: CommunityRepository,
|
||||||
|
private readonly spaceLinkService: SpaceLinkService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createSpace(
|
async createSpace(
|
||||||
addSpaceDto: AddSpaceDto,
|
addSpaceDto: AddSpaceDto,
|
||||||
communityId: string,
|
communityId: string,
|
||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
let parent: SpaceEntity | null = null;
|
|
||||||
|
|
||||||
const { parentUuid, direction } = addSpaceDto;
|
const { parentUuid, direction } = addSpaceDto;
|
||||||
const community = await this.communityRepository.findOne({
|
|
||||||
where: { uuid: communityId },
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the community doesn't exist, throw a 404 error
|
const community = await this.validateCommunity(communityId);
|
||||||
if (!community) {
|
|
||||||
throw new HttpException(
|
|
||||||
`Community with ID ${communityId} not found`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentUuid) {
|
const parent = parentUuid ? await this.validateSpace(parentUuid) : null;
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const newSpace = this.spaceRepository.create({
|
const newSpace = this.spaceRepository.create({
|
||||||
...addSpaceDto,
|
...addSpaceDto,
|
||||||
@ -65,13 +40,11 @@ export class SpaceService {
|
|||||||
await this.spaceRepository.save(newSpace);
|
await this.spaceRepository.save(newSpace);
|
||||||
|
|
||||||
if (direction && parent) {
|
if (direction && parent) {
|
||||||
const spaceLink = await this.spaceLinkRepository.create({
|
await this.spaceLinkService.saveSpaceLink(
|
||||||
|
parent.uuid,
|
||||||
|
newSpace.uuid,
|
||||||
direction,
|
direction,
|
||||||
endSpace: newSpace,
|
);
|
||||||
startSpace: parent,
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.spaceLinkRepository.save(spaceLink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SuccessResponseDto({
|
return new SuccessResponseDto({
|
||||||
@ -87,17 +60,7 @@ export class SpaceService {
|
|||||||
async getSpacesHierarchyForCommunity(
|
async getSpacesHierarchyForCommunity(
|
||||||
communityUuid: string,
|
communityUuid: string,
|
||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
const community = await this.communityRepository.findOne({
|
await this.validateCommunity(communityUuid);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
// Get all spaces related to the community, including the parent-child relations
|
// Get all spaces related to the community, including the parent-child relations
|
||||||
const spaces = await this.spaceRepository.find({
|
const spaces = await this.spaceRepository.find({
|
||||||
@ -123,19 +86,8 @@ export class SpaceService {
|
|||||||
|
|
||||||
async findOne(spaceUuid: string): Promise<BaseResponseDto> {
|
async findOne(spaceUuid: string): Promise<BaseResponseDto> {
|
||||||
try {
|
try {
|
||||||
const space = await this.spaceRepository.findOne({
|
const space = await this.validateSpace(spaceUuid);
|
||||||
where: {
|
|
||||||
uuid: 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({
|
return new SuccessResponseDto({
|
||||||
message: `Space with ID ${spaceUuid} successfully fetched`,
|
message: `Space with ID ${spaceUuid} successfully fetched`,
|
||||||
data: space,
|
data: space,
|
||||||
@ -158,28 +110,10 @@ export class SpaceService {
|
|||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
try {
|
try {
|
||||||
// First, check if the community exists
|
// First, check if the community exists
|
||||||
const community = await this.communityRepository.findOne({
|
const space = await this.validateCommunityAndSpace(
|
||||||
where: { uuid: communityUuid },
|
spaceUuid,
|
||||||
});
|
communityUuid,
|
||||||
|
);
|
||||||
if (!community) {
|
|
||||||
throw new HttpException(
|
|
||||||
`Community with ID ${communityUuid} not found`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
// Delete the space
|
||||||
await this.spaceRepository.remove(space);
|
await this.spaceRepository.remove(space);
|
||||||
@ -205,54 +139,17 @@ export class SpaceService {
|
|||||||
updateSpaceDto: AddSpaceDto,
|
updateSpaceDto: AddSpaceDto,
|
||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
try {
|
try {
|
||||||
// First, check if the community exists
|
const space = await this.validateCommunityAndSpace(
|
||||||
const community = await this.communityRepository.findOne({
|
communityId,
|
||||||
where: { uuid: communityId },
|
spaceUuid,
|
||||||
});
|
);
|
||||||
|
|
||||||
if (!community) {
|
|
||||||
throw new HttpException(
|
|
||||||
`Community with ID ${communityId} not found`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
// If a parentId is provided, check if the parent exists
|
||||||
const { parentUuid } = updateSpaceDto;
|
const { parentUuid } = updateSpaceDto;
|
||||||
let parent: SpaceEntity | null = null;
|
const parent = parentUuid ? await this.validateSpace(parentUuid) : 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update other space properties from updateSpaceDto
|
// Update other space properties from updateSpaceDto
|
||||||
Object.assign(space, updateSpaceDto);
|
Object.assign(space, updateSpaceDto, { parent });
|
||||||
|
|
||||||
// Save the updated space
|
// Save the updated space
|
||||||
await this.spaceRepository.save(space);
|
await this.spaceRepository.save(space);
|
||||||
@ -276,17 +173,7 @@ export class SpaceService {
|
|||||||
async getSpacesHierarchyForSpace(
|
async getSpacesHierarchyForSpace(
|
||||||
spaceUuid: string,
|
spaceUuid: string,
|
||||||
): Promise<BaseResponseDto> {
|
): Promise<BaseResponseDto> {
|
||||||
const space = await this.spaceRepository.findOne({
|
await this.validateSpace(spaceUuid);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get all spaces that are children of the provided space, including the parent-child relations
|
// Get all spaces that are children of the provided space, including the parent-child relations
|
||||||
@ -315,18 +202,7 @@ export class SpaceService {
|
|||||||
try {
|
try {
|
||||||
const invitationCode = generateRandomString(6);
|
const invitationCode = generateRandomString(6);
|
||||||
|
|
||||||
const space = await this.spaceRepository.findOne({
|
const space = await this.validateSpace(spaceUuid);
|
||||||
where: {
|
|
||||||
uuid: spaceUuid,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!space) {
|
|
||||||
throw new HttpException(
|
|
||||||
`Space with ID ${spaceUuid} not found`,
|
|
||||||
HttpStatus.NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
space.invitationCode = invitationCode;
|
space.invitationCode = invitationCode;
|
||||||
await this.spaceRepository.save(space);
|
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) {
|
async validateCommunityAndSpace(communityUuid: string, spaceUuid: string) {
|
||||||
const community = await this.communityRepository.findOne({
|
const community = await this.validateCommunity(communityUuid);
|
||||||
where: { uuid: communityUuid },
|
|
||||||
});
|
|
||||||
if (!community) {
|
if (!community) {
|
||||||
this.throwNotFound('Community', communityUuid);
|
this.throwNotFound('Community', communityUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const space = await this.validateSpace(spaceUuid);
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async validateSpace(spaceUuid: string) {
|
||||||
const space = await this.spaceRepository.findOne({
|
const space = await this.spaceRepository.findOne({
|
||||||
where: { uuid: spaceUuid, community: { uuid: communityUuid } },
|
where: { uuid: spaceUuid },
|
||||||
relations: ['devices', 'devices.productDevice'],
|
|
||||||
});
|
});
|
||||||
if (!space) {
|
if (!space) this.throwNotFound('Space', spaceUuid);
|
||||||
this.throwNotFound('Space', spaceUuid);
|
|
||||||
}
|
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
} from './controllers';
|
} from './controllers';
|
||||||
import {
|
import {
|
||||||
SpaceDeviceService,
|
SpaceDeviceService,
|
||||||
|
SpaceLinkService,
|
||||||
SpaceSceneService,
|
SpaceSceneService,
|
||||||
SpaceService,
|
SpaceService,
|
||||||
SpaceUserService,
|
SpaceUserService,
|
||||||
@ -55,6 +56,7 @@ import { DeviceStatusLogRepository } from '@app/common/modules/device-status-log
|
|||||||
ProductRepository,
|
ProductRepository,
|
||||||
SubSpaceService,
|
SubSpaceService,
|
||||||
SpaceDeviceService,
|
SpaceDeviceService,
|
||||||
|
SpaceLinkService,
|
||||||
SubspaceDeviceService,
|
SubspaceDeviceService,
|
||||||
SpaceRepository,
|
SpaceRepository,
|
||||||
DeviceRepository,
|
DeviceRepository,
|
||||||
|
Reference in New Issue
Block a user