Maintenance Blocks (PL-T185)
At a glance
Time-based blocks that take a resource off the bookable inventory. Supports one-off blocks (resurfacing a court next Tuesday) and recurring blocks (weekly league night every Wednesday) using an RFC 5545 RRULE subset with BYDAY filter, UNTIL/COUNT limits, a hard two-year horizon, and an on-demand expansion service consumed by the booking engine for conflict detection.
How it works
MaintenanceBlock is a Beanie document attached to a resource with a start datetime, an end datetime, and a free-text reason that surfaces in the admin calendar and on the customer wizard's unavailability message. One-off blocks store a single interval. Recurring blocks add a FREQ field (DAILY, WEEKLY, MONTHLY) plus optional BYDAY filter (e.g.
WEEKLY × MO,WE,FR for Monday/Wednesday/Friday league nights), an UNTIL date or COUNT cap, and a max two-year recurring horizon to keep expansion bounded and predictable. The block-expansion service exposes get_blocked_intervals(resource_id, range_start, range_end) that materializes recurring blocks into concrete intervals on demand — the booking engine calls this during conflict detection so a customer trying to book Lane 3 next Wednesday at 19:00 sees the slot as unavailable rather than getting a confusing 409 after submit. To cancel a recurring series mid-flight, operators set cancelled_from to a date — every occurrence on or after that date stops appearing without losing the historical record of past blocks.
The API surface is GET /chain/maintenance-blocks/expanded for ranged queries, POST to create, and DELETE to remove. The admin UI provides a dedicated maintenance-blocks page where operators can scan upcoming and active blocks, filter by resource, and create new blocks with a wizard that handles both one-off and recurring patterns with sensible field defaults.
Key capabilities
- One-off and recurring blocks (DAILY / WEEKLY / MONTHLY)
- BYDAY filter for weekly recurrence (e.g. MO,WE,FR)
- UNTIL and COUNT limits with hard two-year horizon
- cancelled_from to truncate a recurring series at a date
- On-demand expansion service consumed by the booking engine
- Admin UI with filter-by-resource and wizard for new blocks
In practice
Tuesday morning the head of grounds tells the venue manager that Lanes 5-8 need resurfacing this Friday from 09:00 to 17:00. The manager opens Maintenance → New Block, picks the four resources, sets the interval, types "Resurfacing — supplier on site" as the reason, and saves. Within seconds the booking calendar greys out the affected slots, online customers attempting to book those lanes see them as unavailable with a polite "closed for maintenance" message, and the operator console excludes them from drop-in walk-in assignment.
Two months later, when the venue introduces a Wednesday-night corporate league, the manager creates a recurring WEEKLY block on lanes 1-4 from 18:00-22:00 with UNTIL set to next year — every Wednesday until then is automatically protected.
Features in this subsystem
9| ID | Status | Features |
|---|---|---|
| F22.02.01 | Shipped | MaintenanceBlock Beanie document ✅ |
| F22.02.02 | Shipped | One-off block with start/end/reason ✅ |
| F22.02.03 | Shipped | Recurring block with FREQ=DAILY/WEEKLY/MONTHLY ✅ |
| F22.02.04 | Shipped | BYDAY filter for weekly recurrence ✅ |
| F22.02.05 | Shipped | UNTIL and COUNT limits; max 2-year recurring horizon ✅ |
| F22.02.06 | Shipped | cancelled_from field to cancel recurring series from a date ✅ |
| F22.02.07 | Shipped | Block expansion service: get_blocked_intervals() ✅ |
| F22.02.08 | Shipped | API: GET expanded intervals, POST create, DELETE block ✅ |
| F22.02.09 | Shipped | Admin UI: maintenance blocks management page ✅ |
Related subsystems
Stakeholders who need this subsystem
Surfaces in 1 stakeholder analyses