Initial commit: CMS backend for Old Vine Hotel
- 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
This commit is contained in:
116
models/RoomCategory.js
Normal file
116
models/RoomCategory.js
Normal file
@@ -0,0 +1,116 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const roomCategorySchema = new mongoose.Schema({
|
||||
// Basic category information
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
unique: true
|
||||
},
|
||||
slug: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
lowercase: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
shortDescription: {
|
||||
type: String,
|
||||
maxlength: 200
|
||||
},
|
||||
|
||||
// Category images (gallery)
|
||||
images: [{
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isPrimary: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
order: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}],
|
||||
|
||||
// Pricing information (range for this category)
|
||||
priceRange: {
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
|
||||
// Category features/amenities (common to all rooms in this category)
|
||||
features: [{
|
||||
type: String
|
||||
}],
|
||||
|
||||
// SEO and metadata
|
||||
metaTitle: String,
|
||||
metaDescription: String,
|
||||
|
||||
// Display settings
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
displayOrder: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
|
||||
// Statistics (calculated)
|
||||
roomCount: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}, {
|
||||
timestamps: true,
|
||||
toJSON: { virtuals: true },
|
||||
toObject: { virtuals: true }
|
||||
});
|
||||
|
||||
// Indexes
|
||||
roomCategorySchema.index({ slug: 1 });
|
||||
roomCategorySchema.index({ isActive: 1, displayOrder: 1 });
|
||||
|
||||
// Pre-save middleware to generate slug
|
||||
roomCategorySchema.pre('save', function(next) {
|
||||
if (this.isModified('name') || !this.slug) {
|
||||
this.slug = this.name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '');
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
// Virtual for primary image
|
||||
roomCategorySchema.virtual('primaryImage').get(function() {
|
||||
const primary = this.images.find(img => img.isPrimary);
|
||||
return primary ? primary.url : (this.images.length > 0 ? this.images[0].url : null);
|
||||
});
|
||||
|
||||
// Virtual for image count
|
||||
roomCategorySchema.virtual('imageCount').get(function() {
|
||||
return this.images.length;
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('RoomCategory', roomCategorySchema);
|
||||
|
||||
Reference in New Issue
Block a user