roles ?? []) || $user->isAdmin(); }); /** * Per-ticket channel for message/detail changes (drives both the live * message thread and live ticket-header updates). OR, not else-if — the * owner's account holds both client and operator roles at once, so both * branches must be checked rather than picking one based on role alone. * Payloads here also stay minimal (never the message body itself), so an * internal note can safely broadcast on the same channel a client is * subscribed to — the client's own computed properties never touch * internal messages regardless of which event arrived. */ Broadcast::channel('ticket.{ticketId}', function ($user, int $ticketId) { $ticket = Ticket::query()->find($ticketId); if (! $ticket) { return false; } return (in_array('operator', $user->roles ?? []) && $ticket->isVisibleToOperator($user)) || $ticket->customer_id === $user->id; }); /** * Every logged-in user's own private notification stream (bell realtime * updates + in-tab browser push, see NotificationCreated). Laravel's * default `App.Models.User.{id}` naming convention is kept verbatim so it * matches what `$notifiable->notify()` already implies, rather than * inventing a shorter alias. */ Broadcast::channel('App.Models.User.{id}', function ($user, int $id) { return $user->id === $id; });