From a9818f0cdc4482ae8c111b1fc2e639d86a3b32db Mon Sep 17 00:00:00 2001 From: juancarmore Date: Sun, 22 Feb 2026 13:39:35 +0100 Subject: [PATCH] backend: streamline migration models by removing Document extension and integrating schemaVersion for migration tracking --- meet-ce/backend/src/models/migration.model.ts | 24 ++++------- .../models/mongoose-schemas/api-key.schema.ts | 35 +++++++-------- .../mongoose-schemas/global-config.schema.ts | 23 +++------- .../mongoose-schemas/migration.schema.ts | 25 ++++------- .../mongoose-schemas/recording.schema.ts | 32 +++++--------- .../mongoose-schemas/room-member.schema.ts | 25 ++++------- .../models/mongoose-schemas/room.schema.ts | 43 +++++++------------ .../models/mongoose-schemas/user.schema.ts | 25 ++++------- 8 files changed, 85 insertions(+), 147 deletions(-) diff --git a/meet-ce/backend/src/models/migration.model.ts b/meet-ce/backend/src/models/migration.model.ts index 9bf3d03f..6509d9ee 100644 --- a/meet-ce/backend/src/models/migration.model.ts +++ b/meet-ce/backend/src/models/migration.model.ts @@ -1,4 +1,4 @@ -import { Document, Model } from 'mongoose'; +import { Model } from 'mongoose'; /** * Interface representing a migration document in MongoDB. @@ -8,27 +8,22 @@ export interface MeetMigration { * Unique identifier for the migration (e.g., 'legacy_storage_to_mongodb'). */ name: MigrationName; - /** * Current status of the migration. */ status: MigrationStatus; - /** * Timestamp when the migration started. */ startedAt: number; - /** * Timestamp when the migration completed (success or failure). */ completedAt?: number; - /** * Error message if the migration failed. */ error?: string; - /** * Optional metadata about the migration execution. * Can include statistics like number of items migrated, duration, etc. @@ -44,12 +39,10 @@ export enum MigrationStatus { * Migration is currently running. */ RUNNING = 'running', - /** * Migration completed successfully. */ COMPLETED = 'completed', - /** * Migration failed with an error. */ @@ -110,19 +103,20 @@ export function parseSchemaMigrationName( }; } -/** - * Base document shape required for schema migrations. - */ -export interface SchemaMigratableDocument extends Document { - schemaVersion?: number; -} - /** * Represents a schema version number. * Versions start at 1 and increment sequentially. */ export type SchemaVersion = number; +/** + * Base document shape required for schema migrations. + */ +export interface SchemaMigratableDocument { + /** Schema version for migration tracking (internal use only) */ + schemaVersion: SchemaVersion; +} + /** * Function that transforms a document and returns the updated document. */ diff --git a/meet-ce/backend/src/models/mongoose-schemas/api-key.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/api-key.schema.ts index 9c8c7503..1f53380c 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/api-key.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/api-key.schema.ts @@ -1,16 +1,18 @@ import { MeetApiKey } from '@openvidu-meet/typings'; -import { Document, model, Schema } from 'mongoose'; +import { model, Schema } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** * Mongoose Document interface for API keys. - * Extends the MeetApiKey interface with MongoDB Document functionality. + * Extends the MeetApiKey interface with schemaVersion for migration tracking. */ -export interface MeetApiKeyDocument extends MeetApiKey, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; -} +export interface MeetApiKeyDocument extends MeetApiKey, SchemaMigratableDocument {} +/** + * Mongoose schema for MeetApiKey entity. + * Defines the structure and validation rules for API key documents in MongoDB. + */ const MeetApiKeySchema = new Schema( { schemaVersion: { @@ -18,18 +20,17 @@ const MeetApiKeySchema = new Schema( required: true, default: INTERNAL_CONFIG.API_KEY_SCHEMA_VERSION }, - key: { type: String, required: true }, - creationDate: { type: Number, required: true } + key: { + type: String, + required: true + }, + creationDate: { + type: Number, + required: true + } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - delete ret._id; - delete ret.schemaVersion; - return ret; - } - } + versionKey: false } ); @@ -39,6 +40,6 @@ MeetApiKeySchema.index({ key: 1 }, { unique: true }); export const meetApiKeyCollectionName = 'MeetApiKey'; /** - * Mongoose model for API key entity. + * Mongoose model for MeetApiKey entity. */ export const MeetApiKeyModel = model(meetApiKeyCollectionName, MeetApiKeySchema); diff --git a/meet-ce/backend/src/models/mongoose-schemas/global-config.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/global-config.schema.ts index fd116e4b..7d6d8158 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/global-config.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/global-config.schema.ts @@ -1,16 +1,14 @@ import { GlobalConfig, OAuthProvider } from '@openvidu-meet/typings'; -import { Document, model, Schema } from 'mongoose'; +import { model, Schema } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; import { MeetAppearanceConfigSchema } from './room.schema.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** - * Mongoose Document interface for GlobalConfig. - * Extends the GlobalConfig interface with MongoDB Document functionality. + * Mongoose Document interface for global config. + * Extends the GlobalConfig interface with schemaVersion for migration tracking. */ -export interface MeetGlobalConfigDocument extends GlobalConfig, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; -} +export interface MeetGlobalConfigDocument extends GlobalConfig, SchemaMigratableDocument {} /** * Sub-schema for OAuth provider configuration. @@ -96,7 +94,7 @@ const RoomsConfigSchema = new Schema( /** * Mongoose schema for GlobalConfig entity. - * Defines the structure for the global configuration document in MongoDB. + * Defines the structure and validation rules for the global configuration document in MongoDB. */ const MeetGlobalConfigSchema = new Schema( { @@ -123,14 +121,7 @@ const MeetGlobalConfigSchema = new Schema( } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - delete ret._id; - delete ret.schemaVersion; - return ret; - } - } + versionKey: false } ); diff --git a/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts index 8c15ea28..442bd58d 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts @@ -1,15 +1,14 @@ -import { Document, model, Schema } from 'mongoose'; +import { model, Schema } from 'mongoose'; import { isSchemaMigrationName, MeetMigration, MigrationStatus } from '../migration.model.js'; /** - * Mongoose Document interface for MeetMigration. - * Extends the MeetMigration interface with MongoDB Document functionality. + * Mongoose Document interface for migrations. */ -export interface MeetMigrationDocument extends MeetMigration, Document {} +export type MeetMigrationDocument = MeetMigration; /** - * Mongoose schema for the migrations collection. - * Tracks which migrations have been executed and their status. + * Mongoose schema for MeetMigration. + * Defines the structure and validation rules for migration documents in MongoDB. */ const MigrationSchema = new Schema( { @@ -24,13 +23,11 @@ const MigrationSchema = new Schema( status: { type: String, required: true, - enum: Object.values(MigrationStatus), - default: MigrationStatus.RUNNING + enum: Object.values(MigrationStatus) }, startedAt: { type: Number, - required: true, - default: Date.now + required: true }, completedAt: { type: Number, @@ -46,13 +43,7 @@ const MigrationSchema = new Schema( } }, { - versionKey: false, - toObject: { - transform: (_doc, ret) => { - delete ret._id; - return ret; - } - } + versionKey: false } ); diff --git a/meet-ce/backend/src/models/mongoose-schemas/recording.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/recording.schema.ts index 6beb6a48..1256da0f 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/recording.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/recording.schema.ts @@ -1,23 +1,23 @@ import { MeetRecordingInfo, MeetRecordingLayout, MeetRecordingStatus } from '@openvidu-meet/typings'; -import { Document, model, Schema } from 'mongoose'; +import { model, Schema } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** - * Extended interface for Recording documents in MongoDB. - * Includes the base MeetRecordingInfo plus internal access secrets. + * Mongoose Document interface for Recordings. + * Extends the MeetRecordingInfo interface with schemaVersion for migration tracking + * and internal access secrets. */ -export interface MeetRecordingDocument extends MeetRecordingInfo, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; - accessSecrets?: { +export interface MeetRecordingDocument extends MeetRecordingInfo, SchemaMigratableDocument { + accessSecrets: { public: string; private: string; }; } /** - * Mongoose schema for Recording entity. - * Defines the structure for recording documents in MongoDB. + * Mongoose schema for MeetRecordingInfo entity. + * Defines the structure and validation rules for recording documents in MongoDB. */ const MeetRecordingSchema = new Schema( { @@ -96,17 +96,7 @@ const MeetRecordingSchema = new Schema( } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - // Remove MongoDB internal fields - delete ret._id; - delete ret.schemaVersion; - // Remove access secrets before returning (they should only be accessed via specific methods) - delete ret.accessSecrets; - return ret; - } - } + versionKey: false } ); @@ -122,6 +112,6 @@ MeetRecordingSchema.index({ size: -1, _id: -1 }); export const meetRecordingCollectionName = 'MeetRecording'; /** - * Mongoose model for Recording entity. + * Mongoose model for MeetRecordingInfo entity. */ export const MeetRecordingModel = model(meetRecordingCollectionName, MeetRecordingSchema); diff --git a/meet-ce/backend/src/models/mongoose-schemas/room-member.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/room-member.schema.ts index a5d8abc9..080dfe70 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/room-member.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/room-member.schema.ts @@ -1,16 +1,13 @@ import { MeetRoomMember, MeetRoomMemberRole } from '@openvidu-meet/typings'; -import { Document, Schema, model } from 'mongoose'; +import { Schema, model } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** - * Mongoose Document interface for MeetRoomMember. - * Extends the MeetRoomMember interface with MongoDB Document functionality. - * Note: effectivePermissions is computed, not stored. + * Mongoose Document interface for room members. + * Extends the MeetRoomMember interface with schemaVersion for migration tracking. */ -export interface MeetRoomMemberDocument extends MeetRoomMember, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; -} +export interface MeetRoomMemberDocument extends MeetRoomMember, SchemaMigratableDocument {} const permissionFields = { canRecord: { type: Boolean }, @@ -51,6 +48,7 @@ const MeetRoomMemberPartialPermissionsSchema = createPermissionsSchema(false); /** * Mongoose schema for MeetRoomMember entity. + * Defines the structure and validation rules for room member documents in MongoDB. */ const MeetRoomMemberSchema = new Schema( { @@ -98,14 +96,7 @@ const MeetRoomMemberSchema = new Schema( } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - delete ret._id; - delete ret.schemaVersion; - return ret; - } - } + versionKey: false } ); @@ -119,6 +110,6 @@ MeetRoomMemberSchema.index({ memberId: 1 }); export const meetRoomMemberCollectionName = 'MeetRoomMember'; /** - * Mongoose model for MeetRoomMember. + * Mongoose model for MeetRoomMember entity. */ export const MeetRoomMemberModel = model(meetRoomMemberCollectionName, MeetRoomMemberSchema); diff --git a/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts index fe5cb62e..6c9f85cb 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts @@ -7,42 +7,38 @@ import { MeetRoomThemeMode, MeetingEndAction } from '@openvidu-meet/typings'; -import { Document, Schema, model } from 'mongoose'; +import { Schema, model } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; import { MeetRoomMemberPermissionsSchema } from './room-member.schema.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** - * Mongoose Document interface for MeetRoom. - * Extends the MeetRoom interface with MongoDB Document functionality. + * Mongoose Document interface for rooms. + * Extends the MeetRoom interface with schemaVersion for migration tracking. */ -export interface MeetRoomDocument extends MeetRoom, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; -} +export interface MeetRoomDocument extends MeetRoom, SchemaMigratableDocument {} /** - * Mongoose schema for MeetRoom auto-deletion policy. + * Sub-schema for auto-deletion policy. */ const MeetRoomAutoDeletionPolicySchema = new Schema( { withMeeting: { type: String, enum: Object.values(MeetRoomDeletionPolicyWithMeeting), - required: true, - default: MeetRoomDeletionPolicyWithMeeting.FAIL + required: true }, withRecordings: { type: String, enum: Object.values(MeetRoomDeletionPolicyWithRecordings), - required: true, - default: MeetRoomDeletionPolicyWithRecordings.FAIL + required: true } }, { _id: false } ); /** - * Mongoose schema for MeetRoom recording configuration. + * Sub-schema recording configuration. */ const MeetRecordingConfigSchema = new Schema( { @@ -64,7 +60,7 @@ const MeetRecordingConfigSchema = new Schema( ); /** - * Mongoose schema for MeetRoom chat configuration. + * Sub-schema for chat configuration. */ const MeetChatConfigSchema = new Schema( { @@ -77,7 +73,7 @@ const MeetChatConfigSchema = new Schema( ); /** - * Mongoose schema for MeetRoom virtual background configuration. + * Sub-schema for virtual background configuration. */ const MeetVirtualBackgroundConfigSchema = new Schema( { @@ -90,7 +86,7 @@ const MeetVirtualBackgroundConfigSchema = new Schema( ); /** - * Mongoose schema for MeetRoom E2EE configuration. + * Sub-schema for E2EE configuration. */ const MeetE2EEConfigSchema = new Schema( { @@ -103,7 +99,7 @@ const MeetE2EEConfigSchema = new Schema( ); /** - * Mongoose schema for MeetRoom captions configuration. + * Sub-schema for captions configuration. */ const MeetCaptionsConfigSchema = new Schema( { @@ -221,7 +217,7 @@ const MeetRoomAnonymousSchema = new Schema( ); /** - * Mongoose schema for MeetRoom configuration. + * Sub-schema for room configuration. */ const MeetRoomConfigSchema = new Schema( { @@ -316,14 +312,7 @@ const MeetRoomSchema = new Schema( } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - delete ret._id; - delete ret.schemaVersion; - return ret; - } - } + versionKey: false } ); @@ -338,6 +327,6 @@ MeetRoomSchema.index({ autoDeletionDate: 1, _id: 1 }); export const meetRoomCollectionName = 'MeetRoom'; /** - * Mongoose model for MeetRoom. + * Mongoose model for MeetRoom entity. */ export const MeetRoomModel = model(meetRoomCollectionName, MeetRoomSchema); diff --git a/meet-ce/backend/src/models/mongoose-schemas/user.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/user.schema.ts index 5bf8aa04..71f95124 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/user.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/user.schema.ts @@ -1,18 +1,16 @@ import { MeetUser, MeetUserRole } from '@openvidu-meet/typings'; -import { Document, model, Schema } from 'mongoose'; +import { model, Schema } from 'mongoose'; import { INTERNAL_CONFIG } from '../../config/internal-config.js'; +import { SchemaMigratableDocument } from '../migration.model.js'; /** - * Mongoose Document interface for User. - * Extends the User interface with MongoDB Document functionality. + * Mongoose Document interface for users. + * Extends the MeetUser interface with schemaVersion for migration tracking. */ -export interface MeetUserDocument extends MeetUser, Document { - /** Schema version for migration tracking (internal use only) */ - schemaVersion?: number; -} +export interface MeetUserDocument extends MeetUser, SchemaMigratableDocument {} /** - * Mongoose schema for User entity. + * Mongoose schema for MeetUser entity. * Defines the structure and validation rules for user documents in MongoDB. */ const MeetUserSchema = new Schema( @@ -49,14 +47,7 @@ const MeetUserSchema = new Schema( } }, { - toObject: { - versionKey: false, - transform: (_doc, ret) => { - delete ret._id; - delete ret.schemaVersion; - return ret; - } - } + versionKey: false } ); @@ -70,6 +61,6 @@ MeetUserSchema.index({ name: 1, role: 1, _id: 1 }); export const meetUserCollectionName = 'MeetUser'; /** - * Mongoose model for User entity. + * Mongoose model for MeetUser entity. */ export const MeetUserModel = model(meetUserCollectionName, MeetUserSchema);