# `PhoenixLiveCalendar.BookingConfig`
[🔗](https://github.com/mdon/phoenix_live_calendar/blob/v0.5.0/lib/phoenix_live_calendar/booking_config.ex#L1)

Defines constraints for bookable time slots.

This is not an event — it's a template that defines the rules for creating events
(like Cal.com's Event Types or a clinic's appointment type configuration).

## Examples

    # Standard 30-minute meetings with 5-minute buffer
    %PhoenixLiveCalendar.BookingConfig{
      duration: 30,
      buffer_after: 5,
      min_notice: 60,
      max_advance: 30
    }

    # Flexible duration consultation (15-60 min)
    %PhoenixLiveCalendar.BookingConfig{
      duration: 30,
      min_duration: 15,
      max_duration: 60,
      slot_interval: 15,
      buffer_before: 10,
      buffer_after: 10
    }

    # Group class with capacity
    %PhoenixLiveCalendar.BookingConfig{
      duration: 60,
      seats: 20,
      min_notice: 120,
      availability: [
        %PhoenixLiveCalendar.Availability{
          days_of_week: [1, 3, 5],
          start_time: ~T[09:00:00],
          end_time: ~T[10:00:00]
        }
      ]
    }

## Fields

- `duration` — Default slot duration in minutes (default: 30)
- `min_duration` / `max_duration` — Allowed range for free-form booking
- `slot_interval` — Minutes between slot start times. If nil, defaults to `duration`.
  Example: duration=60, slot_interval=15 means slots at 9:00, 9:15, 9:30, 9:45, 10:00...
- `buffer_before` / `buffer_after` — Required gap in minutes before/after each booking
- `min_notice` — Minimum minutes in advance a booking can be made (0 = no restriction)
- `max_advance` — Maximum days in advance a booking can be made (nil = no limit)
- `seats` — Number of concurrent bookings per slot (1 = exclusive, >1 = group/shared)
- `availability` — List of `PhoenixLiveCalendar.Availability` windows when slots are offered
- `timezone` — IANA timezone string for interpreting availability times

# `t`

```elixir
@type t() :: %PhoenixLiveCalendar.BookingConfig{
  availability: [PhoenixLiveCalendar.Availability.t()] | nil,
  buffer_after: non_neg_integer(),
  buffer_before: non_neg_integer(),
  duration: pos_integer(),
  max_advance: pos_integer() | nil,
  max_duration: pos_integer() | nil,
  min_duration: pos_integer() | nil,
  min_notice: non_neg_integer(),
  seats: pos_integer(),
  slot_interval: pos_integer() | nil,
  timezone: String.t() | nil
}
```

# `effective_max_duration`

```elixir
@spec effective_max_duration(t()) :: pos_integer()
```

Returns the effective max duration in minutes.

# `effective_min_duration`

```elixir
@spec effective_min_duration(t()) :: pos_integer()
```

Returns the effective min duration in minutes.

# `effective_slot_interval`

```elixir
@spec effective_slot_interval(t()) :: pos_integer()
```

Returns the effective slot interval in minutes.

If `slot_interval` is nil, falls back to `duration`.

# `total_blocked_time`

```elixir
@spec total_blocked_time(t()) :: pos_integer()
```

Returns the total blocked time around a booking in minutes (buffer_before + duration + buffer_after).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
