Issue
PR #233 recently added "Smart Room Booking & Clash Detection". I reviewed the backend code in:
backend/controllers/roomBookingController.js
backend/routes/roomBooking.js
Potential Race Condition
If the clash detection works like this:
// 1. Check for conflicts
const conflicts = await Booking.find({ roomId, timeSlot });
if (conflicts.length > 0) return error;
// 2. Create booking
await Booking.create({ roomId, timeSlot });
Then two simultaneous requests will both pass the check (step 1) and both create bookings (step 2) — resulting in a double-booked room.
What to check
-
Database-level constraint: Does the mongoose schema have a unique compound index on [room, startDate, startTime]?
bookingSchema.index({ roomId: 1, date: 1, startTime: 1 }, { unique: true });
-
Transaction usage: Is the clash-check + create wrapped in a MongoDB transaction?
const session = await mongoose.startSession();
session.withTransaction(async () => {
// check + create atomically
});
-
Authorization: Can any student book any room, or are there permissions? Does isAuthenticated.js + authorizeRole.js middleware protect the room booking endpoints?
-
Clash detection logic: Does it check:
- Overlapping time ranges (not just exact matches)?
- Different days?
- Recurring bookings?
Fix
Add a unique compound index and use transactions:
// In schema
bookingSchema.index({ roomId: 1, date: 1, startTime: 1, endTime: 1 });
// In controller
const session = await mongoose.startSession();
try {
await session.withTransaction(async () => {
const conflict = await Booking.findOne({
roomId, date,
$or: [
{ startTime: { $lt: newEndTime }, endTime: { $gt: newStartTime } }
]
}).session(session);
if (conflict) throw new Error('Room already booked');
await Booking.create([{ roomId, date, startTime, endTime }], { session });
});
} finally {
session.endSession();
}
Issue
PR #233 recently added "Smart Room Booking & Clash Detection". I reviewed the backend code in:
backend/controllers/roomBookingController.jsbackend/routes/roomBooking.jsPotential Race Condition
If the clash detection works like this:
Then two simultaneous requests will both pass the check (step 1) and both create bookings (step 2) — resulting in a double-booked room.
What to check
Database-level constraint: Does the mongoose schema have a unique compound index on
[room, startDate, startTime]?Transaction usage: Is the clash-check + create wrapped in a MongoDB transaction?
Authorization: Can any student book any room, or are there permissions? Does
isAuthenticated.js+authorizeRole.jsmiddleware protect the room booking endpoints?Clash detection logic: Does it check:
Fix
Add a unique compound index and use transactions: