Improve conferences, guest entry, Afia, and cross-app scheduling.
Deploy Ladill Meet / deploy (push) Successful in 50s

Route guests through silent SSO to the Meet product page, fix Afia context
query, add conference green-room UX and copy, and extend service API for
Care/CRM/Invoice calendar integration.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-01 20:12:57 +00:00
co-authored by Cursor
parent be8f76cd47
commit 799c302e2a
32 changed files with 601 additions and 89 deletions
+20 -4
View File
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use App\Models\Participant;
use App\Models\Room;
use App\Models\Session;
use App\Services\Meet\ConferenceService;
use App\Services\Meet\InvitationService;
use App\Services\Meet\SecurityPolicyService;
use App\Services\Meet\SessionService;
@@ -24,6 +25,7 @@ class JoinController extends Controller
protected SecurityPolicyService $security,
protected WebinarService $webinars,
protected SpaceService $spaces,
protected ConferenceService $conferences,
) {}
public function show(Request $request, Room $room): View|RedirectResponse
@@ -120,9 +122,11 @@ class JoinController extends Controller
$displayName = $user?->name ?? ($validated['display_name'] ?? 'Guest');
$email = $user?->email ?? ($validated['email'] ?? null);
$kind = $room->isConference() ? 'conference' : 'meeting';
[$allowed, $reason] = $this->security->canJoin($room, $user, $email ?? $displayName.'@guest.local');
if (! $allowed && $reason !== 'passcode_required') {
return back()->withErrors(['join' => $reason ?? 'Unable to join meeting.']);
return back()->withErrors(['join' => $reason ?? "Unable to join {$kind}."]);
}
try {
@@ -136,20 +140,20 @@ class JoinController extends Controller
if (! $room->activeSession() && $user && $user->ownerRef() === $room->host_user_ref) {
$session = $this->sessions->start($room, $user);
} elseif (! $room->activeSession()) {
return back()->withErrors(['join' => 'Meeting has not started yet. Please wait for the host.']);
return back()->withErrors(['join' => ucfirst($kind).' has not started yet. Please wait for the host.']);
} else {
$session = $room->activeSession();
}
} else {
if (! $room->activeSession()) {
return back()->withErrors(['join' => 'Meeting has not started yet. Please wait for the host.']);
return back()->withErrors(['join' => ucfirst($kind).' has not started yet. Please wait for the host.']);
}
$session = $room->activeSession();
}
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
if (in_array($e->getStatusCode(), [402, 503], true)) {
return back()->withErrors(['join' => $e->getMessage() ?: 'Unable to start meeting.']);
return back()->withErrors(['join' => $e->getMessage() ?: "Unable to start {$kind}."]);
}
throw $e;
@@ -159,6 +163,8 @@ class JoinController extends Controller
if ($room->isSpace()) {
$role = $this->spaces->resolveJoinRole($room, $user, $role);
} elseif ($room->isConference() && $role !== 'host') {
$role = $this->conferences->resolveJoinRole($room, $user, $email, $role);
} elseif ($room->isWebinar() && $role !== 'host') {
$token = $request->session()->get("meet.webinar.{$room->uuid}");
$reg = $token
@@ -174,10 +180,20 @@ class JoinController extends Controller
$displayName = $reg->display_name;
}
if ($room->isConference() && ! $this->conferences->canJoinSession($room, $session, $role)) {
return back()->withErrors([
'join' => 'The conference has not gone live yet. Assigned speakers can join from the green room link when the host starts.',
]);
}
$joinStatus = $room->requiresWaitingRoom($user, $role) ? 'waiting' : 'joined';
$participant = $this->sessions->joinParticipant($session, $user, $role, $displayName, $email, $joinStatus);
if ($room->isConference() && $session->session_mode === 'green_room') {
$this->conferences->registerPresenter($session, $user, $role);
}
app(InvitationService::class)->markAcceptedOnJoin($room, $user, $email);
$this->sessions->rememberParticipantSession($request, $participant, $session);