backend: streamline migration models by removing Document extension and integrating schemaVersion for migration tracking

This commit is contained in:
juancarmore 2026-02-22 13:39:35 +01:00
parent 0777f299d9
commit a9818f0cdc
8 changed files with 85 additions and 147 deletions

View File

@ -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.
*/

View File

@ -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<MeetApiKeyDocument>(
{
schemaVersion: {
@ -18,18 +20,17 @@ const MeetApiKeySchema = new Schema<MeetApiKeyDocument>(
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<MeetApiKeyDocument>(meetApiKeyCollectionName, MeetApiKeySchema);

View File

@ -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<MeetGlobalConfigDocument>(
{
@ -123,14 +121,7 @@ const MeetGlobalConfigSchema = new Schema<MeetGlobalConfigDocument>(
}
},
{
toObject: {
versionKey: false,
transform: (_doc, ret) => {
delete ret._id;
delete ret.schemaVersion;
return ret;
}
}
versionKey: false
}
);

View File

@ -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<MeetMigrationDocument>(
{
@ -24,13 +23,11 @@ const MigrationSchema = new Schema<MeetMigrationDocument>(
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<MeetMigrationDocument>(
}
},
{
versionKey: false,
toObject: {
transform: (_doc, ret) => {
delete ret._id;
return ret;
}
}
versionKey: false
}
);

View File

@ -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<MeetRecordingDocument>(
{
@ -96,17 +96,7 @@ const MeetRecordingSchema = new Schema<MeetRecordingDocument>(
}
},
{
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<MeetRecordingDocument>(meetRecordingCollectionName, MeetRecordingSchema);

View File

@ -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<MeetRoomMemberDocument>(
{
@ -98,14 +96,7 @@ const MeetRoomMemberSchema = new Schema<MeetRoomMemberDocument>(
}
},
{
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<MeetRoomMemberDocument>(meetRoomMemberCollectionName, MeetRoomMemberSchema);

View File

@ -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<MeetRoomDocument>(
}
},
{
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<MeetRoomDocument>(meetRoomCollectionName, MeetRoomSchema);

View File

@ -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<MeetUserDocument>(
@ -49,14 +47,7 @@ const MeetUserSchema = new Schema<MeetUserDocument>(
}
},
{
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<MeetUserDocument>(meetUserCollectionName, MeetUserSchema);