feat(facilities): add room booking with a database-enforced clash guard (fixes #297) - #302
Open
MOHITKOURAV01 wants to merge 1 commit into
Open
Conversation
Bookings are embedded in the facility document so that no-overlap is expressible as the filter of one findOneAndUpdate: the update only applies when the facility holds no live booking on that date whose interval intersects the requested one. Two people booking the same hall at the same instant means the second matches nothing and gets a 409, on a plain mongod with no transaction and no discretised time grid. The guarded interval is the requested window widened by the facility's setup buffer on each side, so clear-down time is protected by the database rather than written in a note. A pending request holds the room, because approving a request whose slot was taken while it queued is worse than a short wait. Availability answers what is free on a date - per room, with the gaps large enough to book - and the register refuses to shrink opening hours under a booking that would be left outside them. Closes Sitaram8472#297
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
Closes #297
Description
Shared spaces — the auditorium, the labs, the sports hall, the seminar room — are booked in a paper diary, and the diary cannot stop two people writing on it an hour apart. This adds a facility register and a booking system whose central guarantee is that the double booking is impossible rather than unlikely.
The clash guard is one conditional update
Bookings are embedded in the facility document, and that is the design decision the whole module rests on. It lets "this room is free at that time" be expressed as the filter of a single
findOneAndUpdate:"This facility has no live booking on that date whose interval intersects mine." If two requests race, the second one's filter no longer matches and it gets a 409. A read-then-write version lets both pass the check before either writes, which is the paper diary reimplemented in JavaScript.
I considered a separate
Bookingcollection, which is the more conventional shape. It needs either a transaction — this project does not assume a replica set — or a unique index over a discretised time grid, which forces every booking onto fixed 30-minute boundaries. Embedding gives a real guarantee on a plainmongod, and a booking is never queried without its facility.The buffer is part of the guarded interval
Every facility carries
bufferMinutes. The interval the database protects is the requested window widened by the buffer on each side, so the chairs going out and the chairs coming back are enforced rather than written in a note somebody is supposed to read. A hall booked 14:00–15:00 with a 30-minute buffer genuinely blocks 13:30–15:30, and the availability view shows only gaps large enough to survive it.The rest
Pages / Components Added or Modified
backend/models/Facility.js— newbackend/controllers/facilityController.js— newbackend/routes/facilityRoutes.js— newfrontend/src/pages/FacilityBooking.jsx— newbackend/server.js— mounts/api/facilities(additions only)frontend/src/App.jsx— adds the/facilitiesroute (additions only)Screenshots
/facilitiesopens on availability: pick a date and optionally a window, and every room answers free or taken in one screen. Each room is drawn as a day bar with its booked intervals laid over it, scaled to that room's own opening hours rather than a fixed 24-hour axis, with the free gaps below it as clickable chips. Admins get the approval queue and the facility register on the same page.Images omitted because the view needs seeded facilities to be worth looking at — happy to add them.
Checklist
npm run lint— 18 problems, identical tomain, all pre-existing and outside this PR's filesnpx vite buildsucceedsnode --checkclean on every backend file added or changedmainand each of my other open PRs to confirm no conflict