feat: Phase 2 - Laravel Reverb + real-time notifications
- Install laravel/reverb + laravel-echo + pusher-js - Configure broadcasting to reverb in .env.example + .env - Add Echo + Pusher client in resources/js/app.js - Update all 14 notifications to implement ShouldBroadcast + broadcastOn() - Update NotificationBell component to listen for real-time events - Add Livewire.emit in notification-bell blade for JS-to-Livewire bridge Tests: 101 passing (319 assertions)
This commit is contained in:
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Feature;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class FeatureCompletedNotification extends Notification
|
||||
class FeatureCompletedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class FeatureCompletedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -28,4 +29,14 @@ class FeatureCompletedNotification extends Notification
|
||||
'message' => "Elemento '{$this->feature->name}' marcado como completado",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$projectId = $this->feature->layer?->phase?->project_id;
|
||||
if (! $projectId) {
|
||||
return [];
|
||||
}
|
||||
$userIds = \App\Models\Project::find($projectId)?->users->pluck('id')->toArray() ?? [];
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), $userIds);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Inspection;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class InspectionCompletedNotification extends Notification
|
||||
class InspectionCompletedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class InspectionCompletedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -29,4 +30,10 @@ class InspectionCompletedNotification extends Notification
|
||||
'message' => "Inspección completada en '{$this->inspection->feature?->name}': ".($this->inspection->result ?? 'sin resultado'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = $this->inspection->project->users->pluck('id')->toArray();
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), $userIds);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Inspection;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class InspectionDeletedNotification extends Notification
|
||||
class InspectionDeletedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class InspectionDeletedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -29,4 +30,10 @@ class InspectionDeletedNotification extends Notification
|
||||
'message' => "Inspección eliminada en '{$this->inspection->feature?->name}' por {$this->deletedBy}",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = $this->inspection->project->users->pluck('id')->toArray();
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), $userIds);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Inspection;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class InspectionUpdatedNotification extends Notification
|
||||
class InspectionUpdatedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class InspectionUpdatedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -30,4 +31,10 @@ class InspectionUpdatedNotification extends Notification
|
||||
'message' => "Inspección actualizada en '{$this->inspection->feature?->name}'",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = $this->inspection->project->users->pluck('id')->toArray();
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), $userIds);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Issue;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class IssueAssignedNotification extends Notification
|
||||
class IssueAssignedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class IssueAssignedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -27,4 +28,9 @@ class IssueAssignedNotification extends Notification
|
||||
'message' => "Se te ha asignado la incidencia '{$this->issue->title}'",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new \Illuminate\Broadcasting\PrivateChannel('user.'.$this->issue->assigned_to)];
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,11 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\IssueComment;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class IssueCommentedNotification extends Notification
|
||||
class IssueCommentedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -15,7 +16,7 @@ class IssueCommentedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -30,4 +31,13 @@ class IssueCommentedNotification extends Notification
|
||||
'message' => "{$this->comment->user?->name} comentó en '{$issue?->title}': ".Str::limit($this->comment->body, 60),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$issue = $this->comment->issue;
|
||||
$userIds = [];
|
||||
if ($issue->assigned_to) $userIds[] = $issue->assigned_to;
|
||||
if ($issue->reported_by) $userIds[] = $issue->reported_by;
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), array_unique($userIds));
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Issue;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class IssueReportedNotification extends Notification
|
||||
class IssueReportedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class IssueReportedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -28,4 +29,10 @@ class IssueReportedNotification extends Notification
|
||||
'message' => "Nuevo issue '{$this->issue->title}' (prioridad: {$this->issue->priority})",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = $this->issue->project->users->pluck('id')->toArray();
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), $userIds);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Issue;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class IssueStatusChangedNotification extends Notification
|
||||
class IssueStatusChangedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class IssueStatusChangedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -34,4 +35,12 @@ class IssueStatusChangedNotification extends Notification
|
||||
'message' => "La incidencia '{$this->issue->title}' ha sido {$label}",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = [];
|
||||
if ($this->issue->assigned_to) $userIds[] = $this->issue->assigned_to;
|
||||
if ($this->issue->reported_by) $userIds[] = $this->issue->reported_by;
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), array_unique($userIds));
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\IssueTask;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class IssueTaskAssignedNotification extends Notification
|
||||
class IssueTaskAssignedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class IssueTaskAssignedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -28,4 +29,9 @@ class IssueTaskAssignedNotification extends Notification
|
||||
'message' => "Se te ha asignado la tarea '{$this->task->title}'",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new \Illuminate\Broadcasting\PrivateChannel('user.'.$this->task->assigned_to)];
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\IssueTask;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class IssueTaskOverdueNotification extends Notification
|
||||
class IssueTaskOverdueNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class IssueTaskOverdueNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -28,4 +29,9 @@ class IssueTaskOverdueNotification extends Notification
|
||||
'message' => "Tarea vencida: '{$this->task->title}' (venció el {$this->task->due_date?->format('d/m/Y')})",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new \Illuminate\Broadcasting\PrivateChannel('user.'.$this->task->assigned_to)];
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Task;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class TaskAssignedNotification extends Notification
|
||||
class TaskAssignedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class TaskAssignedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -27,4 +28,9 @@ class TaskAssignedNotification extends Notification
|
||||
'message' => "Se te ha asignado la tarea '{$this->task->title}'",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new \Illuminate\Broadcasting\PrivateChannel('user.'.$this->task->assigned_to)];
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,10 @@ namespace App\Notifications;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Task;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class TaskCommentNotification extends Notification
|
||||
class TaskCommentNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -15,7 +16,7 @@ class TaskCommentNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -28,4 +29,12 @@ class TaskCommentNotification extends Notification
|
||||
'message' => "Nuevo comentario en '{$this->task->title}' por {$this->comment->user->name}: ".substr($this->comment->body, 0, 100),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = [];
|
||||
if ($this->task->assigned_to) $userIds[] = $this->task->assigned_to;
|
||||
if ($this->task->created_by) $userIds[] = $this->task->created_by;
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), array_unique($userIds));
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Task;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class TaskOverdueNotification extends Notification
|
||||
class TaskOverdueNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class TaskOverdueNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -27,4 +28,9 @@ class TaskOverdueNotification extends Notification
|
||||
'message' => "Tarea vencida: '{$this->task->title}' (venció el {$this->task->due_date?->format('d/m/Y')})",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [new \Illuminate\Broadcasting\PrivateChannel('user.'.$this->task->assigned_to)];
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Task;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class TaskStatusChangedNotification extends Notification
|
||||
class TaskStatusChangedNotification extends Notification implements ShouldBroadcast
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
@@ -14,7 +15,7 @@ class TaskStatusChangedNotification extends Notification
|
||||
|
||||
public function via($notifiable): array
|
||||
{
|
||||
return ['database'];
|
||||
return ['database', 'broadcast'];
|
||||
}
|
||||
|
||||
public function toArray($notifiable): array
|
||||
@@ -42,4 +43,12 @@ class TaskStatusChangedNotification extends Notification
|
||||
'message' => "La tarea '{$this->task->title}' cambió de {$oldLabel} a {$label}",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
$userIds = [];
|
||||
if ($this->task->assigned_to) $userIds[] = $this->task->assigned_to;
|
||||
if ($this->task->created_by) $userIds[] = $this->task->created_by;
|
||||
return array_map(fn ($id) => new \Illuminate\Broadcasting\PrivateChannel("user.{$id}"), array_unique($userIds));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user