user(); if (!$user) { return ['name' => 'required']; } $svc = app(TicketFieldSettingsService::class); // Built-in field rules from service (already flat) $rules = $svc->getValidationRules($user); unset($rules['custom_data']); // Add individual flat rules for each visible custom field foreach ($svc->getEffectiveFields($user) as $field) { if (!($field['is_custom'] ?? false) || !($field['visible'] ?? false)) { continue; } $rule = ($field['required'] ?? false) ? ['required'] : ['nullable']; $type = $field['type'] ?? 'text'; if ($type === 'number') { $rule[] = 'numeric'; } elseif ($type === 'email') { $rule[] = 'email'; } elseif ($type === 'date') { $rule[] = 'date'; } elseif ($type === 'datetime') { $rule[] = 'date'; } elseif (is_int($field['max_length'] ?? null)) { $rule[] = 'string'; $rule[] = 'max:' . $field['max_length']; } $rules[$field['key']] = $rule; } // Relation existence checks $relations = [ 'ticket_status_id' => 'tickets_dict_status', 'ticket_priority_id' => 'tickets_dict_priority', 'ticket_severity_id' => 'tickets_dict_severity', 'ticket_category_id' => 'tickets_dict_category', 'contact_id' => 'contacts', 'account_id' => 'accounts', 'lead_id' => 'leads', 'parent_id' => 'tickets', 'ticket_owner_id' => 'users', ]; foreach ($relations as $field => $table) { $existing = (array) ($rules[$field] ?? ['nullable']); if (!in_array("exists:{$table},id", $existing, true)) { $existing[] = "exists:{$table},id"; } $rules[$field] = $existing; } return $rules; } protected function failedValidation(Validator $validator): void { throw new HttpResponseException(response()->json([ 'status' => false, 'errors' => $validator->errors(), 'message' => 'Validation failed', ], 422)); } }