Promote Events speakers from attendee to panelist on rejoin.
Deploy Ladill Meet / deploy (push) Successful in 1m7s

Upgrade existing participant roles when a verified speaker token is present, and sync panelist access while already in the room so speaker-panel placement and publish rights apply.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-03 18:05:15 +00:00
co-authored by Cursor
parent f9c82d0d1f
commit 3d68f7a83b
3 changed files with 91 additions and 7 deletions
@@ -63,6 +63,8 @@ class MeetingRoomController extends Controller
abort_unless($participant->status === 'joined', 403, "You are not in this {$kind}.");
$participant = $this->sessions->syncEventsSpeakerRole($request, $participant);
$token = $this->media->isConfigured()
? $this->sessions->generateMediaToken($participant)
: '';
@@ -520,8 +522,11 @@ class MeetingRoomController extends Controller
$participantUuid = $request->session()->get("meet.participant.{$session->uuid}");
abort_unless($participantUuid, 403);
return Participant::where('uuid', $participantUuid)
->where('session_id', $session->id)
->firstOrFail();
return $this->sessions->syncEventsSpeakerRole(
$request,
Participant::where('uuid', $participantUuid)
->where('session_id', $session->id)
->firstOrFail()
);
}
}
+41 -4
View File
@@ -7,6 +7,7 @@ use App\Models\Room;
use App\Models\Session;
use App\Models\User;
use App\Services\Meet\Media\MediaProviderInterface;
use App\Support\EventsRegistrationSession;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
@@ -108,15 +109,13 @@ class SessionService
$updates['joined_at'] = $existing->joined_at ?? now();
}
if (in_array($role, ['host', 'co_host'], true)) {
$updates['role'] = $role;
} elseif ($existing->role === 'guest' && $role !== 'guest') {
if ($this->shouldPromoteParticipantRole($existing->role, $role)) {
$updates['role'] = $role;
}
$existing->update($updates);
return $existing;
return $existing->fresh();
}
$joinedAt = $status === 'joined' ? now() : null;
@@ -196,6 +195,43 @@ class SessionService
return $participant->fresh();
}
public function syncEventsSpeakerRole(Request $request, Participant $participant): Participant
{
$participant->loadMissing('session.room');
$room = $participant->session->room;
if (! $room->isEventsLinked() || ! EventsRegistrationSession::isSpeakerVerified($request, $room)) {
return $participant;
}
return $this->promoteParticipantRole($participant, 'panelist');
}
private function promoteParticipantRole(Participant $participant, string $role): Participant
{
if ($this->shouldPromoteParticipantRole($participant->role, $role)) {
$participant->update(['role' => $role]);
return $participant->fresh();
}
return $participant;
}
private function shouldPromoteParticipantRole(string $currentRole, string $newRole): bool
{
static $rank = [
'guest' => 10,
'attendee' => 20,
'participant' => 25,
'panelist' => 40,
'co_host' => 50,
'host' => 60,
];
return ($rank[$newRole] ?? 0) > ($rank[$currentRole] ?? 0);
}
protected function findExistingParticipant(Session $session, ?string $userRef, ?string $email): ?Participant
{
$active = fn ($q) => $q->whereIn('status', ['invited', 'waiting', 'joined']);
@@ -244,6 +280,7 @@ class SessionService
if ($user) {
$existing = $this->joinedParticipantForUser($session, $user);
if ($existing) {
$existing = $this->promoteParticipantRole($existing, $role);
$this->rememberParticipantSession($request, $existing, $session);
return $existing;