diff --git a/meet-ce/backend/src/services/livekit-webhook.service.ts b/meet-ce/backend/src/services/livekit-webhook.service.ts index 74fb7bf9..d7f8c512 100644 --- a/meet-ce/backend/src/services/livekit-webhook.service.ts +++ b/meet-ce/backend/src/services/livekit-webhook.service.ts @@ -18,6 +18,7 @@ import { OpenViduWebhookService } from './openvidu-webhook.service.js'; import { RecordingService } from './recording.service.js'; import { RoomMemberService } from './room-member.service.js'; import { RoomService } from './room.service.js'; +import { RoomMemberRepository } from '../repositories/room-member.repository.js'; @injectable() export class LivekitWebhookService { @@ -33,6 +34,7 @@ export class LivekitWebhookService { @inject(DistributedEventService) protected distributedEventService: DistributedEventService, @inject(FrontendEventService) protected frontendEventService: FrontendEventService, @inject(RoomMemberService) protected roomMemberService: RoomMemberService, + @inject(RoomMemberRepository) protected roomMemberRepository: RoomMemberRepository, @inject(LoggerService) protected logger: LoggerService ) { this.webhookReceiver = new WebhookReceiver(MEET_ENV.LIVEKIT_API_KEY, MEET_ENV.LIVEKIT_API_SECRET); @@ -260,7 +262,8 @@ export class LivekitWebhookService { this.logger.info( `Deleting room '${roomId}' (and its recordings if any) after meeting finished because it was scheduled to be deleted` ); - await this.recordingService.deleteAllRoomRecordings(roomId); // This operation must complete before deleting the room + tasks.push(this.recordingService.deleteAllRoomRecordings(roomId)); + tasks.push(this.roomMemberRepository.deleteAllByRoomId(roomId)); tasks.push(this.roomRepository.deleteByRoomId(roomId)); break; case MeetingEndAction.CLOSE: diff --git a/meet-ce/backend/src/services/room.service.ts b/meet-ce/backend/src/services/room.service.ts index 5aab1672..828045a8 100644 --- a/meet-ce/backend/src/services/room.service.ts +++ b/meet-ce/backend/src/services/room.service.ts @@ -420,10 +420,10 @@ export class RoomService { /** * Executes the deletion strategy for a room based on its state and the provided deletion policies. * - Validates the deletion policies (throws if not allowed). - * - If no active meeting and no recordings, deletes the room directly. + * - If no active meeting and no recordings, deletes the room directly (and its members). * - If there is an active meeting, sets the meeting end action (DELETE or CLOSE) and optionally ends the meeting. * - If there are recordings and policy is CLOSE, closes the room. - * - If force delete is requested, deletes all recordings and the room. + * - If force delete is requested, deletes the room and all recordings and members. */ protected async executeDeletionStrategy( roomId: string, @@ -437,7 +437,10 @@ export class RoomService { // No meeting, no recordings: simple deletion if (!hasActiveMeeting && !hasRecordings) { - await this.roomRepository.deleteByRoomId(roomId); + await Promise.all([ + this.roomMemberRepository.deleteAllByRoomId(roomId), + this.roomRepository.deleteByRoomId(roomId) + ]); return undefined; } @@ -467,9 +470,10 @@ export class RoomService { return room; } - // Force delete: delete room and all recordings + // Force delete: delete room and all recordings and members await Promise.all([ this.recordingService.deleteAllRoomRecordings(roomId), + this.roomMemberRepository.deleteAllByRoomId(roomId), this.roomRepository.deleteByRoomId(roomId) ]); return undefined;