ExBooking. Policy
(ExBooking v0.1.0)
View Source
Pure booking-policy predicates.
Policy checks evaluate a candidate slot against caller-supplied rules: lead time, booking window, and daily cap. Notice policies for cancellation and reschedule transitions are evaluated by the facade lifecycle functions.
Example
iex> rule = %ExBooking.AvailabilityRule{timezone: "Etc/UTC", windows: [], lead_time_min: 60}
...> resource = %ExBooking.Resource{id: "resource_1", timezone: "Etc/UTC"}
...> slot = ExBooking.Interval.new!(~U[2026-07-13 09:30:00Z], ~U[2026-07-13 10:00:00Z])
...> ExBooking.Policy.violations(slot, rule, resource, ~U[2026-07-13 09:00:00Z])
[{:lead_time, 30}]
Summary
Functions
Evaluates a cancellation or reschedule policy against now and the existing
booking. Returns :ok, or {:error, :not_allowed} when the policy forbids
the action, or {:error, :min_notice} when it is requested too close to the
start.
Validates a lifecycle notice policy before temporal arithmetic.
Returns every policy violation for slot against a resource's rule, evaluated
relative to the caller-supplied now. An empty list means the slot is
allowed.
Types
@type reason() :: {:lead_time, pos_integer()} | {:outside_window, Date.t()} | {:daily_cap, String.t(), Date.t()}
A policy violation reason.
Functions
@spec notice_ok(ExBooking.Interval.t(), map() | nil, DateTime.t()) :: :ok | {:error, :not_allowed | :min_notice}
Evaluates a cancellation or reschedule policy against now and the existing
booking. Returns :ok, or {:error, :not_allowed} when the policy forbids
the action, or {:error, :min_notice} when it is requested too close to the
start.
Examples
iex> existing = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:30:00Z])
...>
...> ExBooking.Policy.notice_ok(
...> existing,
...> %{min_notice_min: 60, allowed: true},
...> ~U[2026-07-13 07:00:00Z]
...> )
:ok
iex> existing = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:30:00Z])
...>
...> ExBooking.Policy.notice_ok(
...> existing,
...> %{min_notice_min: 120, allowed: true},
...> ~U[2026-07-13 08:00:00Z]
...> )
{:error, :min_notice}
Validates a lifecycle notice policy before temporal arithmetic.
nil is an allowed inherited policy. Non-nil policies must contain exactly
:allowed and :min_notice_min with their documented types.
Examples
iex> ExBooking.Policy.validate(%{allowed: true, min_notice_min: 60}, :cancellation_policy)
:ok
@spec violations( ExBooking.Interval.t(), ExBooking.AvailabilityRule.t(), ExBooking.Resource.t(), DateTime.t() ) :: [reason()]
Returns every policy violation for slot against a resource's rule, evaluated
relative to the caller-supplied now. An empty list means the slot is
allowed.
Examples
iex> rule = %ExBooking.AvailabilityRule{
...> timezone: "Etc/UTC",
...> windows: [],
...> lead_time_min: 120
...> }
...>
...> resource = %ExBooking.Resource{id: "res_1", timezone: "Etc/UTC"}
...> slot = ExBooking.Interval.new!(~U[2026-07-13 09:30:00Z], ~U[2026-07-13 10:00:00Z])
...> ExBooking.Policy.violations(slot, rule, resource, ~U[2026-07-13 09:00:00Z])
[{:lead_time, 90}]