Facilities
Part of the IP4CMS portal. β All module guides
What it's for β Facilities is where you register the bookable amenities your community offers β pool houses, tennis courts, club lounges, function venues β and control how residents reserve them. Each facility can be booked one of two ways: internally (the portal generates time slots from your opening hours and handles the reservations, approvals and cancellations) or via an external booking link (the portal just sends residents off to a third-party booking site). For internal facilities, the module also manages availability, recurring opening-hours rules, and the full booking lifecycle that residents see in the member portal.
Where to find it β Main portal menu under Facilities (route /app/facilities, which opens the list at /app/facilities/list). From there you also reach Facility Bookings (/app/facilities/bookings) and the Booking Calendar (/app/facilities/booking-calendar).
Before you start
- Your tenant's licence must include the
facilitiesmodule, or the Facilities menu and list won't appear. - Internal bookings, slots and availability additionally need both
facilities:bookingsandfeasibilitiesenabled on the licence. If either is missing you'll see an amber warning, and the Facility Setup and Facility Availability steps are hidden β you can still create an external-link facility, but not generate internal slots. (The internal booking engine relies on the feasibility engine to model and reserve time.) - You need facility permissions (see Permissions & access). Without
facilities:readyou can't open the list. - At least one base location must exist first β every facility must be attached to one. Base locations come from the Locations module; the Base Location dropdown is populated from there.
Key tasks
Create a facility
- Go to Facilities and click Add Facility (visible only if you can manage facilities).
- The editor opens as a stepper. On the Facility Info step, fill in:
- Cover Photo β optional. JPEG, PNG or WebP, max 10 MB. Shown on the member-portal facility list and detail page. If you're creating a new facility the photo is held and uploaded once you save.
- Base Location (required) β the physical location the facility belongs to, chosen from your base locations.
- Facility Name (required) β e.g. "Pool House", "Tennis Court". Max 255 characters.
- Accent Colour β a colour used to tag the facility in calendars and lists. Pick from the swatch or type a hex value.
- Booking Mode (required) β Internal booking (portal-managed slots) or External booking link (hand off to another site).
- Slot Interval Minutes β the granularity of generated booking slots (5β1440, default 60). Only meaningful for internal facilities.
- External Booking URL (required for external mode) β the
https://β¦address residents are sent to. Only shown when Booking Mode is External. Open Method chooses whether it opens in the Browser or embedded as an Iframe. - Available to β Both, Members, or Community. Controls who can see and book the facility (see member vs community).
- Require booking approval before confirmation β when ticked, resident bookings start as pending and must be approved.
- Allow residents to cancel bookings β whether residents may cancel their own bookings from the member portal.
- Booking Limits β optional caps: Max Booking Attendees (per booking), Max Member Bookings / Day and / Week (how often one member can book), and Max Facility Bookings / Day and / Week (total bookings the facility accepts in that window). Leave blank for no cap.
- Description β resident-facing summary. Internal Notes β for your operations team only.
- Click Next (or Save Facility). The facility saves; a held cover photo uploads immediately after.
For an external-link facility you're essentially done after this step β there are no internal slots to configure. For an internal facility, continue to Facility Setup and Facility Availability (the next two steps), which only appear once the facility is saved and the booking engine is licensed.
Configure opening hours (Facility Setup)
This step turns your weekly opening hours into the recurring slot rules that drive availability. It only appears for internal facilities once saved.
- Open the saved facility and go to the Facility Setup step.
- Choose an opening mode:
- Always Open β the facility is bookable 24/7 (a single rule covering all days, 00:00β23:59).
- Specify Opening Hours β a weekly matrix. For each day pick Open or Closed, and for open days set an Opening Time and Closing Time (closing must be after opening).
- Changes save automatically (a status line shows "Saving changesβ¦" then "Changes saved automatically"). On save the screen replaces the facility's recurring slot rules with the ones you've defined and regenerates the booking slots residents see.
The setup screen is a simplified front end for slot rules: it shows one time window per day. If a facility already has rules with multiple windows on the same day (e.g. a morning and an evening session), you'll see a notice that only the first window per day is displayed β editing here may overwrite the extra windows. Internally, days that share the same opening/closing times are grouped into one rule named "Facility - Schedule n".
Manage availability and booking slots (Facility Availability)
The Facility Availability step shows a calendar of the facility's generated booking slots and any manual availability, colour-coded by source.
- Add Booking Slots β pick a From Date and To Date and the portal generates slots across that range from the current slot rules. Existing bookings are left untouched.
- Remove Booking Slots β pick a date range to delete generated slots in it. Existing bookings and manual availability are left untouched.
- Manual availability β open a calendar entry to view its Starts At / Ends At, Source (manual, generated, booking, etc.) and Timezone. You can delete manual entries; generated/locked slots are managed via regenerate/remove instead.
Generating slots requires the facilities:availability:manage permission. The availability you generate here is exactly what residents browse and book against in the member portal.
Use the Booking Calendar
Facilities β Booking Calendar gives a cross-facility view of all bookings, in either a List or Calendar layout.
- Use the facility checklist and status checklist (Pending, Approved, Confirmed, Rejected, Cancelled, Completed) to filter what's shown. Bookings are colour-coded by status.
- In Calendar view, click an event to open its Booking Details.
- From a booking you can Approve, Reject or Cancel it (subject to your permissions and the booking's current status β see below).
- Deep-linking with a
?facilityId=β¦automatically narrows the calendar to that one facility.
Approve, reject or cancel a booking
You can act on bookings from Facility Bookings (/app/facilities/bookings) or the Booking Calendar.
- Approve / Reject β only shown for pending bookings (those on facilities that require approval), and only if you can approve. Approving moves the booking to approved and reserves (locks) its availability; rejecting frees it.
- Cancel β available for any active booking (not already cancelled, rejected or completed) if you can manage bookings. You confirm first; the slot is then released.
- Each action asks for confirmation and shows a success or error message. The row/event updates in place.
Make a booking (admin) β member vs community bookings
Bookings are usually created by residents in the member portal, but an operator with facilities:bookings:manage can create one on a member's behalf via the API. When a booking is created the portal:
- Validates the time window and checks for conflicts with existing confirmed/approved bookings.
- Enforces the facility's booking caps (per-member per-day/week and per-facility per-day/week) and lead-time rules (min/max days before booking).
- Enforces attendee limits (min/max attendees).
- Sets the status to confirmed straight away if the facility doesn't require approval, or pending if it does (in which case an operator must approve it).
A confirmed booking locks the matching availability so the slot can't be double-booked.
Member vs community β the Available to setting decides the audience: Members (residents/members only), Community (the wider community), or Both. This is stored as two flags (members_only / community_only) and controls which residents see and can book the facility in the member portal.
How the data connects
- What you enter β where it's stored. Each facility is a row in the tenant
facilitytable (name, description, internal notes, colour, photo URL, booking mode, external URL/open method, audience flags, approval/cancel policy, attendee and booking caps, slot interval, and thelocation_idit belongs to). Records are tenant-scoped and soft-deleted (adeleted_atflag) rather than erased. - Opening hours β slot rules. The Facility Setup matrix is saved as
facility_slot_rulerows (the days each rule applies to, start/end time, and optional rule-level overrides for approval, cancel, lead time and attendee counts). Saving setup replaces these rules and regenerates slots. - Slot rules β availability. Generated slots and manual entries live in
resource_availability(the feasibility engine's table, withresource_type = 'facility'). This is what the member portal reads to show open times. Each facility is mirrored as a feasibility resource (typefacility, with the slot interval) so the engine can model and reserve its time. - Availability β bookings. A booking is a
facility_bookingrow linked to the facility, the booking member, the slot rule that matched, and the property location. It records the time window, attendee count, status, approval/cancel metadata, and the specific availability IDs it reserved. Confirmed/approved bookings lock those availability records so nothing else can take the slot. - Locations. Every facility hangs off a base location (and bookings also capture the member's property location), tying facilities into the Locations module.
- Members & the member portal. Residents browse facilities, view generated availability, and create/cancel their own bookings from the member portal β all backed by the same
facility,resource_availabilityandfacility_bookingdata you manage here. For external-link facilities, residents are simply launched to the external URL.
Permissions & access
Facilities appears only if the facilities module is licensed. Internal bookings, availability and slot management additionally require facilities:bookings and feasibilities on the licence. Actions are gated by these permissions (a tenant admin has all of them):
| Action | Permission |
|---|---|
| View the facility list / open a facility | facilities:read |
| Create, edit, delete a facility; upload/remove its photo | facilities:manage |
| View availability and slot rules | facilities:availability:read |
| Generate/remove slots, edit availability and slot rules (Facility Setup & Availability) | facilities:availability:manage |
| View bookings (Bookings list / Booking Calendar) | facilities:bookings:read |
| Approve or reject a pending booking | facilities:bookings:approve |
| Cancel a booking / create a booking on a member's behalf | facilities:bookings:manage |
Buttons (Add, Edit, Disable, Delete, Approve, Reject, Cancel) are hidden when you lack the matching permission, and the API enforces the same checks. Member booking vs admin approval: residents create bookings themselves in the member portal; if the facility has Require approval on, those bookings land as pending and stay unusable until an operator with facilities:bookings:approve approves them β otherwise they're confirmed automatically.
Tips & gotchas
- Internal facilities need two extra modules. Slots, availability and bookings only work when both
facilities:bookingsandfeasibilitiesare licensed. Without them you can still create and list facilities and use external-link mode, but the Setup and Availability steps stay hidden. - Save before you configure. Opening Hours and Availability are stored against a saved facility, so the Setup and Availability steps tell you to save the Info step first. The editor saves automatically when you click Next from the Info step.
- Saving Setup is destructive to rules. Saving opening hours replaces the facility's slot rules and regenerates availability. If a facility was set up with multiple time windows per day elsewhere, the simplified matrix shows only the first window β re-saving can drop the others.
- Generating slots doesn't touch bookings. Both Add Booking Slots and Remove Booking Slots explicitly leave existing bookings (and manual availability) untouched β they only add or remove generated slots in the chosen date range.
- Times are handled in UTC. The booking calendar renders events in UTC; bear that in mind when reading start/end times.
- Approve/Reject only show for pending. If a facility doesn't require approval, bookings are confirmed immediately and you'll only ever see a Cancel option, not Approve/Reject.
- Caps and lead time are enforced at booking time. Per-member and per-facility daily/weekly caps, min/max lead days, and attendee limits all block a booking that violates them β set them deliberately, as a too-tight cap will silently stop residents booking.
- Disable vs delete. From the list you can Disable a facility (hides it from booking while keeping its data) or Delete it (soft-delete, retained for audit). Disabling is the safer choice when you just want to pause bookings.
- External link is a hand-off. External-mode facilities have no internal slots, availability or approval flow β the portal only stores and launches the URL (in the browser or an iframe).