- Complete Express.js API server - MongoDB integration with Mongoose - Admin authentication and authorization - Room management (CRUD operations) - Booking management system - Guest management - Payment processing (Stripe integration) - Content management (pages, blog, gallery) - Media upload and management - Integration services (Booking.com, Expedia, Opera PMS, Trip.com) - Email notifications - Comprehensive logging and error handling
154 lines
3.3 KiB
JavaScript
154 lines
3.3 KiB
JavaScript
const mongoose = require('mongoose');
|
|
|
|
const mediaSchema = new mongoose.Schema({
|
|
// File information
|
|
filename: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
originalName: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
url: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
thumbnailUrl: String,
|
|
|
|
// File details
|
|
mimeType: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
size: {
|
|
type: Number,
|
|
required: true
|
|
},
|
|
|
|
// Media type
|
|
type: {
|
|
type: String,
|
|
enum: ['image', 'video', 'document', 'other'],
|
|
required: true
|
|
},
|
|
|
|
// Image specific
|
|
dimensions: {
|
|
width: Number,
|
|
height: Number
|
|
},
|
|
|
|
// Categorization
|
|
folder: {
|
|
type: String,
|
|
default: 'general',
|
|
enum: ['general', 'rooms', 'gallery', 'blog', 'hero', 'about', 'facilities', 'avatars']
|
|
},
|
|
tags: [String],
|
|
|
|
// Metadata
|
|
alt: String,
|
|
caption: String,
|
|
description: String,
|
|
|
|
// Usage tracking
|
|
usedIn: [{
|
|
model: String, // 'Content', 'BlogPost', 'Room', etc.
|
|
documentId: mongoose.Schema.Types.ObjectId,
|
|
field: String
|
|
}],
|
|
|
|
// Upload information
|
|
uploadedBy: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Admin',
|
|
required: true
|
|
},
|
|
|
|
// Status
|
|
isPublic: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
}, {
|
|
timestamps: true,
|
|
toJSON: { virtuals: true },
|
|
toObject: { virtuals: true }
|
|
});
|
|
|
|
// Indexes
|
|
mediaSchema.index({ folder: 1, createdAt: -1 });
|
|
mediaSchema.index({ type: 1 });
|
|
mediaSchema.index({ uploadedBy: 1 });
|
|
mediaSchema.index({ tags: 1 });
|
|
mediaSchema.index({ filename: 1 });
|
|
|
|
// Virtual for file extension
|
|
mediaSchema.virtual('extension').get(function() {
|
|
return this.filename.split('.').pop().toLowerCase();
|
|
});
|
|
|
|
// Virtual for is image
|
|
mediaSchema.virtual('isImage').get(function() {
|
|
return this.type === 'image';
|
|
});
|
|
|
|
// Virtual for file size in MB
|
|
mediaSchema.virtual('sizeInMB').get(function() {
|
|
return (this.size / (1024 * 1024)).toFixed(2);
|
|
});
|
|
|
|
// Static method to get media by folder
|
|
mediaSchema.statics.getByFolder = function(folder, options = {}) {
|
|
const { limit = 50, skip = 0, type } = options;
|
|
|
|
const query = { folder };
|
|
if (type) query.type = type;
|
|
|
|
return this.find(query)
|
|
.populate('uploadedBy', 'firstName lastName')
|
|
.sort({ createdAt: -1 })
|
|
.skip(skip)
|
|
.limit(limit);
|
|
};
|
|
|
|
// Static method to search media
|
|
mediaSchema.statics.search = function(searchTerm, options = {}) {
|
|
const { folder, type, limit = 50 } = options;
|
|
|
|
const query = {
|
|
$or: [
|
|
{ originalName: new RegExp(searchTerm, 'i') },
|
|
{ alt: new RegExp(searchTerm, 'i') },
|
|
{ caption: new RegExp(searchTerm, 'i') },
|
|
{ tags: new RegExp(searchTerm, 'i') }
|
|
]
|
|
};
|
|
|
|
if (folder) query.folder = folder;
|
|
if (type) query.type = type;
|
|
|
|
return this.find(query)
|
|
.populate('uploadedBy', 'firstName lastName')
|
|
.sort({ createdAt: -1 })
|
|
.limit(limit);
|
|
};
|
|
|
|
// Instance method to track usage
|
|
mediaSchema.methods.addUsage = function(model, documentId, field) {
|
|
this.usedIn.push({ model, documentId, field });
|
|
return this.save();
|
|
};
|
|
|
|
// Instance method to remove usage
|
|
mediaSchema.methods.removeUsage = function(model, documentId, field) {
|
|
this.usedIn = this.usedIn.filter(usage =>
|
|
!(usage.model === model && usage.documentId.equals(documentId) && usage.field === field)
|
|
);
|
|
return this.save();
|
|
};
|
|
|
|
module.exports = mongoose.model('Media', mediaSchema);
|
|
|