Status
Priority
High
Context
ADR-0037 (2026-05-24). Resources need configurable booking policy, per-node access control (view and booking), and lead time enforcement. Supersedes the "Resource reservation role gating" backlog card (field_required_position_roles design).
D7 equivalent: Content Access module for per-node role restrictions. This is the D11 pattern using five fields on rsvp_resource + node access system + validation constraints.
Decided
- Sub-module:
rsvp_resource_policy— fields, constraints, and node access realm all in one sub-module - Anonymous view: login always required to view any rsvp_resource node.
field_view_rolesgates authenticated users only; anonymous → redirect to login viahook_node_access()on the bundle - Bypass + lead time: bypass-eligible users are exempt from lead time enforcement. Coordinators can make same-day bookings on Restricted resources
Five fields to add to rsvp_resource
FieldTypeNotesfield_booking_policylist_stringopen | moderated | restricted — default: moderated
field_request_lead_timeintegerBusiness days; only used when policy = restricted
field_bypass_rolesentity_reference (user_role, unlimited)Roles that auto-confirm regardless of policy. Empty = coordinator+ default (ADR-0029)
field_required_booking_rolesentity_reference (user_role, unlimited)Roles eligible to book. Empty = any community member
field_view_rolesentity_reference (user_role, unlimited)Roles that can view the resource. Empty = any authenticated user
Decision tree on reservation create
- View access: authenticated AND (
field_view_rolesempty OR user holds a listed role) → else 403 - Booking access:
field_required_booking_rolesempty OR user holds a listed role → else 403 - Conflict check:
ReservationConflictconstraint (always runs) - Bypass check: user holds a
field_bypass_rolesrole (or coordinator+ if field is empty) → auto-confirm, skip lead time - Lead time check:
ReservationLeadTimeconstraint (only if policy = restricted AND user is not bypass-eligible) - Policy = open → auto-confirm
- Policy = moderated or restricted → tentative → coordinator queue
Code to write
ReservationLeadTimevalidation constraint inrsvp_system_module/src/Plugin/Validation/Constraint/— sibling ofReservationConflict. Checks business-day lead time; bypass-eligible users exempt- Update
hook_node_presaveinrsvp_reservation_widget.moduleto readfield_bypass_rolesfrom the resource (falling back to coordinator+ when empty) hook_node_access()inrsvp_resource_policysub-module: anonymous → always deny view on rsvp_resource bundle; authenticated +field_view_roles→ role check- Access check for booking eligibility (
field_required_booking_roles) before reservation form renders
Recipe: rsvp_resource_policy
- New recipe in
rsvp-recipes/recipes/rsvp_resource_policy/ - Depends on
rsvp_resourcesbase recipe - Adds all five field storage + instance configs to
rsvp_resource - Form display: policy field group, lead time shown conditionally via
#statesAPI - Not included in
rsvp_full_stack— opt-in
Related
- ADR-0037 — Full design and decision rationale
- ADR-0017 —
rsvp_reservationarchitecture,ReservationConflictpattern - ADR-0029 — Coordinator bypass (platform default preserved when
field_bypass_rolesis empty)