backend: Improves data fetching efficiency
Refactors repository methods to accept an array of fields instead of a comma-separated string, optimizing data retrieval and reducing unnecessary string manipulation. Also, modifies services and validators to use array of fields instead of strings.
This commit is contained in:
parent
d4a87f8a45
commit
80ce1a3efd
@ -214,7 +214,7 @@ export const roomMemberTokenValidator: AuthValidator = {
|
||||
} else {
|
||||
// If the token has no memberId (anonymous access), validate that room roles/anonymous haven't been updated
|
||||
const roomRepository = container.get(RoomRepository);
|
||||
const room = await roomRepository.findByRoomId(roomId, 'rolesUpdatedAt');
|
||||
const room = await roomRepository.findByRoomId(roomId, ['rolesUpdatedAt']);
|
||||
|
||||
// If room not found or roles/anonymous were updated after token issuance, invalidate token
|
||||
if (!room || iat < room.rolesUpdatedAt) {
|
||||
|
||||
@ -38,6 +38,8 @@ export abstract class BaseRepository<TDomain, TDocument extends Document> {
|
||||
let query = this.model.findOne(filter);
|
||||
|
||||
if (fields) {
|
||||
//!FIXME: This transform should be optimized to avoid unnecessary string manipulation
|
||||
|
||||
const fieldSelection = fields
|
||||
.split(',')
|
||||
.map((field) => field.trim())
|
||||
@ -127,6 +129,8 @@ export abstract class BaseRepository<TDomain, TDocument extends Document> {
|
||||
|
||||
// Apply field selection if specified
|
||||
if (fields) {
|
||||
// !FIXME: This transform should be optimized to avoid unnecessary string manipulation.
|
||||
// !The argument method should ideally accept an array of fields instead of a comma-separated string to avoid this overhead.
|
||||
// Convert comma-separated string to space-separated format for MongoDB select()
|
||||
const fieldSelection = fields
|
||||
.split(',')
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { MeetRecordingFilters, MeetRecordingInfo, MeetRecordingStatus } from '@openvidu-meet/typings';
|
||||
import { MeetRecordingInfo, MeetRecordingStatus } from '@openvidu-meet/typings';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { uid as secureUid } from 'uid/secure';
|
||||
import { MeetRecordingDocument, MeetRecordingModel } from '../models/mongoose-schemas/recording.schema.js';
|
||||
import { MeetRecordingField, MeetRecordingFilters } from '../models/recording-request.js';
|
||||
import { LoggerService } from '../services/logger.service.js';
|
||||
import { BaseRepository } from './base.repository.js';
|
||||
|
||||
@ -76,8 +77,10 @@ export class RecordingRepository<TRecording extends MeetRecordingInfo = MeetReco
|
||||
* @param fields - Comma-separated list of fields to include in the result
|
||||
* @returns The recording (without access secrets), or null if not found
|
||||
*/
|
||||
async findByRecordingId(recordingId: string, fields?: string): Promise<TRecording | null> {
|
||||
const document = await this.findOne({ recordingId }, fields);
|
||||
async findByRecordingId(recordingId: string, fields?: MeetRecordingField[]): Promise<TRecording | null> {
|
||||
//!FIXME: This transform should be removed because the findOne method should accept an array of fields instead of a comma-separated string, to avoid unnecessary string manipulation
|
||||
const fieldsString = fields ? fields.join(',') : undefined;
|
||||
const document = await this.findOne({ recordingId }, fieldsString);
|
||||
return document ? this.toDomain(document) : null;
|
||||
}
|
||||
|
||||
@ -149,7 +152,8 @@ export class RecordingRepository<TRecording extends MeetRecordingInfo = MeetReco
|
||||
sortField,
|
||||
sortOrder
|
||||
},
|
||||
fields
|
||||
//! FIXME: This transform should be removed because the findMany method should accept an array of fields instead of a comma-separated string, to avoid unnecessary string manipulation
|
||||
fields?.join(',')
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { MeetRoom, MeetRoomFilters, MeetRoomStatus } from '@openvidu-meet/typings';
|
||||
import { MeetRoom, MeetRoomStatus } from '@openvidu-meet/typings';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { MeetRoomDocument, MeetRoomModel } from '../models/mongoose-schemas/room.schema.js';
|
||||
import { MeetRoomField, MeetRoomFilters } from '../models/room-request.js';
|
||||
import { LoggerService } from '../services/logger.service.js';
|
||||
import { getBasePath } from '../utils/html-injection.utils.js';
|
||||
import { getBaseUrl } from '../utils/url.utils.js';
|
||||
@ -64,8 +65,10 @@ export class RoomRepository<TRoom extends MeetRoom = MeetRoom> extends BaseRepos
|
||||
* @param fields - Comma-separated list of fields to include in the result
|
||||
* @returns The room or null if not found
|
||||
*/
|
||||
async findByRoomId(roomId: string, fields?: string): Promise<TRoom | null> {
|
||||
const document = await this.findOne({ roomId }, fields);
|
||||
async findByRoomId(roomId: string, fields?: MeetRoomField[]): Promise<TRoom | null> {
|
||||
//!FIXME: This transform should be removed once the controller is updated to pass the fields as an array of MeetRoomField instead of a comma-separated string.
|
||||
const fieldsString = fields ? fields.join(',') : undefined;
|
||||
const document = await this.findOne({ roomId }, fieldsString);
|
||||
return document ? this.enrichRoomWithBaseUrls(document) : null;
|
||||
}
|
||||
|
||||
@ -146,7 +149,8 @@ export class RoomRepository<TRoom extends MeetRoom = MeetRoom> extends BaseRepos
|
||||
sortField,
|
||||
sortOrder
|
||||
},
|
||||
fields
|
||||
//! FIXME: This transform should be removed because the findMany method should accept an array of fields instead of a comma-separated string, to avoid unnecessary string manipulation
|
||||
fields?.join(',')
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import {
|
||||
MeetRecordingEncodingOptions,
|
||||
MeetRecordingEncodingPreset,
|
||||
MeetRecordingFilters,
|
||||
MeetRecordingInfo,
|
||||
MeetRecordingLayout,
|
||||
MeetRecordingStatus,
|
||||
@ -35,6 +34,7 @@ import {
|
||||
isErrorRecordingNotFound,
|
||||
OpenViduMeetError
|
||||
} from '../models/error.model.js';
|
||||
import { MeetRecordingField, MeetRecordingFilters } from '../models/recording-request.js';
|
||||
import { RecordingRepository } from '../repositories/recording.repository.js';
|
||||
import { DistributedEventService } from './distributed-event.service.js';
|
||||
import { FrontendEventService } from './frontend-event.service.js';
|
||||
@ -453,9 +453,10 @@ export class RecordingService {
|
||||
/**
|
||||
* Retrieves the recording information for a given recording ID.
|
||||
* @param recordingId - The unique identifier of the recording.
|
||||
* @param fields - Array of {@link MeetRecordingField} to include in the response
|
||||
* @returns A promise that resolves to a MeetRecordingInfo object.
|
||||
*/
|
||||
async getRecording(recordingId: string, fields?: string): Promise<MeetRecordingInfo> {
|
||||
async getRecording(recordingId: string, fields?: MeetRecordingField[]): Promise<MeetRecordingInfo> {
|
||||
const recordingInfo = await this.recordingRepository.findByRecordingId(recordingId, fields);
|
||||
|
||||
if (!recordingInfo) {
|
||||
|
||||
@ -109,7 +109,7 @@ export class RoomMemberService {
|
||||
}
|
||||
|
||||
// Compute effective permissions
|
||||
const room = await this.roomService.getMeetRoom(roomId);
|
||||
const room = await this.roomService.getMeetRoom(roomId, { fields: ['roles'] });
|
||||
const effectivePermissions = this.computeEffectivePermissions(room.roles, baseRole, customPermissions);
|
||||
|
||||
const now = Date.now();
|
||||
@ -154,7 +154,7 @@ export class RoomMemberService {
|
||||
*/
|
||||
async isRoomMember(roomId: string, memberId: string): Promise<boolean> {
|
||||
// Verify room exists first
|
||||
await this.roomService.getMeetRoom(roomId);
|
||||
await this.roomService.getMeetRoom(roomId, { fields: ['roomId'] });
|
||||
const member = await this.roomMemberRepository.findByRoomAndMemberId(roomId, memberId);
|
||||
return !!member;
|
||||
}
|
||||
@ -219,7 +219,7 @@ export class RoomMemberService {
|
||||
}
|
||||
|
||||
// Recompute effective permissions
|
||||
const room = await this.roomService.getMeetRoom(roomId);
|
||||
const room = await this.roomService.getMeetRoom(roomId, { fields: ['roles'] });
|
||||
member.effectivePermissions = this.computeEffectivePermissions(
|
||||
room.roles,
|
||||
member.baseRole,
|
||||
@ -420,7 +420,7 @@ export class RoomMemberService {
|
||||
} else {
|
||||
// If secret matches anonymous access URL secret, assign role and permissions based on it
|
||||
baseRole = await this.getRoomMemberRoleBySecret(roomId, secret);
|
||||
const room = await this.roomService.getMeetRoom(roomId);
|
||||
const room = await this.roomService.getMeetRoom(roomId, { fields: ['roles', 'anonymous'] });
|
||||
|
||||
// Check that anonymous access is enabled for the role
|
||||
if (!room.anonymous[baseRole].enabled) {
|
||||
@ -492,7 +492,7 @@ export class RoomMemberService {
|
||||
userId?: string
|
||||
): Promise<string> {
|
||||
// Check that room is open
|
||||
const room = await this.roomService.getMeetRoom(roomId);
|
||||
const room = await this.roomService.getMeetRoom(roomId, { fields: ['status', 'config'] });
|
||||
|
||||
if (room.status === MeetRoomStatus.CLOSED) {
|
||||
throw errorRoomClosed(roomId);
|
||||
@ -611,7 +611,7 @@ export class RoomMemberService {
|
||||
* @throws Error if the provided secret doesn't match any of the room's secrets (unauthorized)
|
||||
*/
|
||||
protected async getRoomMemberRoleBySecret(roomId: string, secret: string): Promise<MeetRoomMemberRole> {
|
||||
const room = await this.roomService.getMeetRoom(roomId);
|
||||
const room = await this.roomService.getMeetRoom(roomId, { fields: ['roomId', 'anonymous'] });
|
||||
const { moderatorSecret, speakerSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
||||
|
||||
switch (secret) {
|
||||
@ -780,8 +780,7 @@ export class RoomMemberService {
|
||||
newRole: MeetRoomMemberRole
|
||||
): Promise<void> {
|
||||
try {
|
||||
const meetRoom = await this.roomService.getMeetRoom(roomId);
|
||||
|
||||
const meetRoom = await this.roomService.getMeetRoom(roomId, { fields: ['roles', 'anonymous'] });
|
||||
const participant = await this.getParticipantFromMeeting(roomId, participantIdentity);
|
||||
const metadata: MeetRoomMemberTokenMetadata = this.tokenService.parseRoomMemberTokenMetadata(
|
||||
participant.metadata
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user