- How do I set up Laravel Zap for appointment booking in a healthcare app?
- Start by installing Zap via Composer, publishing its migrations and config, then add the `HasSchedules` trait to your `Doctor` or `Resource` model. Define availabilities (e.g., office hours) and blocked times (e.g., lunch breaks) using Zap’s fluent API. Use `getBookableSlots()` to fetch open appointment times, and `appointment()->create()` to book slots with conflict checks.
- Does Zap support recurring appointments like weekly therapy sessions?
- Yes, Zap includes 15+ recurrence rules (daily, weekly, monthly ordinals, etc.) out of the box. Define a recurring pattern with `recurs()->weekly()->onDays([1, 3, 5])` or similar, and Zap handles the scheduling logic. You can also customize end dates, exceptions, and timezones for complex patterns.
- Can I use Zap with Laravel 12 or PHP 8.2?
- No, Zap requires PHP 8.5+ and Laravel 13.x due to its use of modern PHP features like enums and attributes. If you’re on an older stack, consider alternatives like Spatie Scheduler or build custom logic with Carbon and Eloquent. Zap’s architecture isn’t backward-compatible for performance or security reasons.
- How do I handle timezones in Zap for a global app?
- Zap normalizes all times to UTC internally but respects your app’s timezone config (set in `config/app.php`). For user-facing displays, convert timestamps using Carbon’s `setTimezone()` or Zap’s built-in helpers like `formatForTimezone()`. Test edge cases like daylight saving transitions with your target timezones to avoid overlap errors.
- What’s the best way to integrate Zap with a React calendar UI like FullCalendar?
- Use Zap’s query methods like `schedulesForDateRange()` to fetch appointments, availabilities, and blocked times, then format the data for FullCalendar’s event source. For real-time updates, listen to Laravel events (e.g., `appointment.created`) and push changes via Laravel Echo or a similar service. Zap’s API is designed to be frontend-agnostic.
- How do I migrate existing appointment data to Zap?
- Extend Zap’s `Schedule` and `SchedulePeriod` models to match your legacy schema, then write a custom migration script. Use Zap’s fluent API to recreate appointments, availabilities, and blocked times (e.g., `Zap::for($resource)->appointment()->create([...])`). Test with a subset of data first, and handle UUID/ULID migrations separately if needed.
- Does Zap support multi-resource booking (e.g., booking a doctor *and* a room at once)?
- Not natively, but you can implement this by querying each resource’s availability separately and checking conflicts manually. For example, fetch bookable slots for both the doctor and room, then validate overlaps before creating appointments. Consider using Laravel transactions to ensure atomicity across resources.
- How do I test Zap’s conflict detection in PHPUnit?
- Use Zap’s `isBookableAtTime()` method in your tests to verify overlap rules. Mock the `SchedulePeriod` model to simulate existing appointments or blocked times, then assert whether a new slot should be bookable. For recurrence testing, use Pest or PHPUnit’s data providers to cover edge cases like DST transitions or month-end dates.
- Can I attach custom metadata (e.g., patient ID, invoice reference) to appointments?
- Yes, Zap allows arbitrary metadata on appointments via the `metadata` attribute. Store structured data like `['patient_id' => 123, 'invoice_reference' => 'INV-456']` and retrieve it later with `$appointment->metadata`. This is useful for integrations with CRMs, billing systems, or analytics tools.
- What are the performance implications of querying large schedules (e.g., 100K+ appointments)?
- Zap’s `schedulesForDateRange()` and `getBookableSlots()` methods are optimized for typical use cases, but heavy queries may impact performance. For large datasets, add database indexes on `start_at` and `end_at` columns, or use Laravel’s query caching. Test with production-like data volumes and consider pagination for frontend displays.