Configuration
The published config/appointments.php in full:
use RoundlyConsulting\Appointments\Models\Appointment;
use RoundlyConsulting\Appointments\Models\Participant;
use RoundlyConsulting\Appointments\Reviews\DatabaseVerifiedAttendanceResolver;
return [
'model' => Appointment::class,
'participant' => Participant::class,
// bigint | uuid | ulid — the key type of the polymorphic participant column
'key_type' => env('APPOINTMENTS_KEY_TYPE', 'bigint'),
'table_names' => [
'appointments' => 'appointments',
'participants' => 'appointment_participants',
],
'timezone' => null,
'default_duration_minutes' => 60,
'prevent_conflicts' => false,
'recurrence' => [
'max_occurrences' => 365,
],
'reviews' => [
'verified_attendance_resolver' => DatabaseVerifiedAttendanceResolver::class,
'require_verified_attendance' => false,
],
'approvals' => [
'enforce_transitions' => false,
],
];Every key
| Key | Default | Purpose |
|---|---|---|
model | Appointment::class | Appointment model. Point it at a subclass of the packaged model to customise behaviour; any other class throws InvalidConfigurationException. |
participant | Participant::class | Participant model; same rules as model. |
key_type | bigint | Key type of the polymorphic participant_id column — bigint, uuid or ulid (env APPOINTMENTS_KEY_TYPE). Set before you migrate; any other value throws InvalidConfigurationException when the migrations run. |
table_names.appointments | appointments | Table the migrations create and the Appointment model reads and writes. Set it before you migrate. Blank = not set (appointments); any other value must be a string. |
table_names.participants | appointment_participants | Table the migrations create and the Participant model reads and writes. Set it before you migrate. Blank = not set (appointment_participants); any other value must be a string. |
timezone | null | Zone stored on a new appointment when none is given, and the zone a wall-clock string without an offset is read in; not set (null or blank) uses config('app.timezone'), anything else must be a timezone PHP knows (Europe/Bratislava). Each appointment keeps the zone it was booked in, so changing this later doesn’t re-time existing ones. |
default_duration_minutes | 60 | Duration applied when neither a duration nor an end time is given; ends_at is derived from it. 1–525600. |
prevent_conflicts | false | When true, creating, rescheduling or adding a participant throws on an overlapping booking for a participant. Can also be enabled per call. |
recurrence.max_occurrences | 365 | Hard cap on the number of occurrences one recurring series may expand to, 1–100000. |
reviews.verified_attendance_resolver | DatabaseVerifiedAttendanceResolver::class | Decides whether a review is verified (default: the author is a participant of a completed appointment). Must implement VerifiedAttendanceResolver. Not set (left out, null or blank) still binds DatabaseVerifiedAttendanceResolver; to never verify, name NullVerifiedAttendanceResolver::class explicitly. |
reviews.require_verified_attendance | false | When true, review() throws for an unverified author instead of storing an unverified review. |
approvals.enforce_transitions | false | When true, the approval status-sync listener respects the transition matrix — a mapped but illegal move is skipped. |
The bool keys also take env-style strings — true/1/on/yes and false/0/off/no — and the int keys take integer strings ('45'). A key that is not set (absent, null, or blank: '' or whitespace) takes its default. Anything else — a mistyped switch ('disabled'), a duration or cap that isn’t a whole number in range ('an hour', 0), a non-string table name, an unknown timezone, a resolver that isn’t a VerifiedAttendanceResolver — throws InvalidConfigurationException naming the key instead of quietly reading as a default.
Environment
Only the participant key type is env-backed. It types a database column, so set it before you publish and run the migrations:
# bigint | uuid | ulid — set before you publish and run the migrations
APPOINTMENTS_KEY_TYPE=bigintThe about command
php artisan about --only=appointments reports the effective setup:
- Model and Participant model — the short class names of the resolved models.
- Appointments table and Participants table — the configured table names.
- Default timezone — SET or APP DEFAULT. Only presence is reported, never the value.
- Default duration — e.g. 60 min — and Max occurrences, the recurrence cap.
- Prevent conflicts, Require verified attendance and Approval transitions — ON or OFF.
- Attendance resolver — the class name of the bound review resolver.
A malformed table name, timezone, default duration, occurrence cap or resolver shows as INVALID, so about still renders on a misconfigured host while the real read path throws.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.