'required|integer', 'requested_date' => 'required|valid_date[Y-m-d]', 'requested_time' => 'required', 'status' => 'permit_empty|in_list[draft,viewed,selected,booked,expired,cancelled]', 'preview_token' => 'permit_empty|max_length[64]', ]; protected $validationMessages = []; protected $skipValidation = false; protected $cleanValidationRules = true; protected $allowCallbacks = true; protected $beforeInsert = ['preparePreview']; protected $beforeUpdate = ['normalizeJsonFields']; protected function preparePreview(array $eventData): array { $eventData = $this->normalizeJsonFields($eventData); if (empty($eventData['data']['preview_token'])) { $eventData['data']['preview_token'] = bin2hex(random_bytes(32)); } if (empty($eventData['data']['status'])) { $eventData['data']['status'] = 'draft'; } return $eventData; } protected function normalizeJsonFields(array $eventData): array { foreach (['services', 'available_days_snapshot', 'available_slots_snapshot'] as $field) { if (isset($eventData['data'][$field]) && is_array($eventData['data'][$field])) { $eventData['data'][$field] = json_encode($eventData['data'][$field]); // Removed AppointmentPreviewModel as appointment_previews table is dropped // Removed the entire class definition as it is no longer needed