Core models
Service
Defines what can be booked: name, duration in minutes, buffer times, price.
ServiceProvider
A staff member or resource that performs services, with their own schedule config.
Appointment
A booking record linking a customer, service, provider, and time slot.
OpeningHour
Defines the tenant’s weekly hours, used as the base for slot availability.
Service model
ServiceProvider model
Each provider can have their own weekly schedule stored asschedule_config (JSON). When no provider-level config exists, the system falls back to the tenant’s opening hours.
Availability calculation
Availability checks use theSpatie\OpeningHours library and collision detection against existing appointments.
OpeningHour model records:
Appointment lifecycle
Event dispatch on creation
Appointment creation automatically dispatches theAppointmentCreated event:
Public booking page
Customers book at/t/{tenant}/book (path-based local, or {tenant}.domain.com/book in production).
The BookingController serves the Inertia page with the tenant’s active services, active providers, and their availability configuration. The frontend renders available time slots based on the provider’s schedule.
Appointment management portal
Customers receive a signed URL after booking:Reminder jobs
The scheduler dispatches appointment reminder jobs every hour:reminder_sent_at = null and scheduled_at within the configured reminder window, sends the reminder email, and updates reminder_sent_at.
Email notifications
| Mail class | Trigger | Recipient |
|---|---|---|
| Appointment confirmed | AppointmentCreated event | Customer email |
| Appointment reminder | Reminder job (scheduled hourly) | Customer email |
customer_email field on the Appointment record. Guest bookings (no user account) are fully supported.
Panel management
The Filament tenant panel (/app) includes:
AppointmentResource— view, filter, and manage all appointmentsServiceResource— create and manage bookable servicesServiceProviderResource— manage staff/resource schedules