# Real-Time Setup

## Stack

- Broadcaster: **Laravel Reverb** (`config/broadcasting.php`, `config/reverb.php`)
- Client: **Laravel Echo v2** + Pusher-protocol JS client, already bootstrapped in
  `resources/js/echo.js` and imported by `resources/js/app.js`
- Run locally: `php artisan reverb:start` (already part of `composer dev`)
- `.env`: `BROADCAST_CONNECTION=reverb`, `REVERB_APP_KEY`, `REVERB_APP_SECRET`, `REVERB_HOST`,
  `REVERB_PORT`, `REVERB_SCHEME` — mirrored client-side as `VITE_REVERB_*`

## ⚠️ Required fix: broadcasting-auth endpoint mismatch

`routes/channels.php` registers broadcast auth here:

```
Broadcast::routes(['prefix' => 'api', 'middleware' => ['api', 'auth:sanctum']]);
```

That puts the auth endpoint at **`/api/broadcasting/auth`**. Laravel Echo's default is
**`/broadcasting/auth`** (no `/api`), and `resources/js/echo.js` doesn't override it. Result: any
private-channel subscription from a page served by the Livewire panel currently fails silently —
including the existing `App.Models.User.{id}` listener in `app.js` used for admin flash toasts.

Two ways to fix it, pick one:

- Point Echo's `authEndpoint` config at `/api/broadcasting/auth`, **or**
- Register a second `Broadcast::routes()` call on the `web`/`auth` guard at the default path,
  alongside the existing one in `routes/channels.php`.

Either way, this also depends on the web session actually reaching that endpoint authenticated.
`config/sanctum.php` has `'guard' => ['web']`, which needs
`Illuminate\Support\Facades\Sanctum`'s stateful-domain cookie auth
(`EnsureFrontendRequestsAreStateful`) present in the `api` middleware group — check
`bootstrap/app.php` before assuming the first option works unmodified.

**Verify before building anything on top of it:** open dev tools → Network, subscribe to a private
channel, and confirm the auth request returns `200` with an `auth` token — not `401`/`404`/`419`.
