This is my mongoose schema for an event planning website where there are different types of services such as catering,venues etc, this is done using discriminator.
const mongoose = require('mongoose');
const PackageSchema = new mongoose.Schema({
package_id: { type: Number },
name: { type: String, required: true },
price: { type: Number, required: true },
description: { type: String, required: true }
});
//added
const baseOptions = {
discriminatorKey: "type",
collection: "Service",
};
const ServiceSchema = new mongoose.Schema(
{
vendor_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
packages: [PackageSchema],
service_name: {
type: String,
required: true
},
service_type: {
type: String,
enum: ['decor', 'venue', 'catering', 'photography'],
required: true
},
cancellation_policy: {
type: String,
enum: ['Flexible', 'Moderate', 'Strict'],
required: true
},
staff: {
type: String,
enum: ['Male', 'Female'],
required: true
},
description: {
type: String,
required: true
},
start_price: {
type: Number,
required: true
},
average_rating: {
type: Number,
default: 0,
min: 0,
max: 5,
},
location_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Location',
required: true
},
},
baseOptions
);
const BaseService = mongoose.model('Service', ServiceSchema);
const CateringService = BaseService.discriminator('CateringService', new mongoose.Schema({
cuisine: { type: String, required: true }
})
);
const VenueService = BaseService.discriminator('VenueService', new mongoose.Schema({
capacity : { type: Number, required: true },
outdoor : { type: String,enum: ['outdoor', 'banquet'], required: true }
})
);
const PhotographyService = BaseService.discriminator('PhotographyService', new mongoose.Schema({
drone : { type: Boolean, required: true },
})
);
const DecorService = BaseService.discriminator('DecorService', new mongoose.Schema({
decortype : { type: String,
enum: ['wedding', 'birthday party', 'anniversary', 'formal events'],
required: true },
})
);
ServiceSchema.pre('save', async function(next) {
try {
const service = this;
// Check if the 'packages' field is modified or not
if (service.isModified('packages')) {
// Calculate the package_id for each package in the array
service.packages.forEach((pkg, index) => {
// Set the package_id to the next number
pkg.package_id = index + 1;
});
}
next();
} catch (error) {
next(error);
}
});
const Service = mongoose.model('Service', ServiceSchema);
module.exports = Service;
this is my vendormiddleware to ensure only vendor or admin can add a new service such as venue. Similar code is for admin too.
function vendorMiddleware(req, res, next) {
if (req.user && req.user.role === "vendor") {
next();
} else {
return res.status(403).json({ msg: "Forbidden: Access denied!" });
}
}
module.exports = vendorMiddleware;
and this is my route code for posting a new venue
// Place middleware here to ensure only vendor or admin can add a venue
router.use([vendorMiddleware, adminMiddleware]);
// POST endpoint to add a new venue
router.post('/newvenue', async (req, res) => {
try {
// Extract venue details from the request body
const { vendor_id, capacity, outdoor, service_name, service_type, description, start_price, location_id, packages } = req.body;
// Create a new venue service instance
const newVenue = new VenueService({
vendor_id,
service_name,
service_type,
description,
start_price,
location_id,
packages, // Assuming packages are included in the request body
capacity,
outdoor
});
// Save the new venue service to the database
await newVenue.save();
res.status(201).json({ msg: 'Venue added successfully!', venue: newVenue });
} catch (error) {
console.error(error);
res.status(500).json({ msg: 'Internal Server Error' });
}
});
I have tried debugging but I dont know why i keep on getting “msg”: “Forbidden: Access denied!” error when i test this on postman (doesn’t matter if i am logged in as admin or vendor). The middleware functions are working just fine for adding reviews/other functions so i dont think the issue lies there.