Auto-provision Meet workspace for Sales Centre demo links.
Deploy Ladill Meet / deploy (push) Successful in 1m38s
Deploy Ladill Meet / deploy (push) Successful in 1m38s
Create rep user, organization, and branch on first demo room request so sales reps do not need to onboard in Meet first. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,6 +10,7 @@ use App\Services\Integrations\WebhookDispatcher;
|
||||
use App\Services\Meet\CalendarService;
|
||||
use App\Services\Meet\InvitationService;
|
||||
use App\Services\Meet\RoomService;
|
||||
use App\Services\Meet\SalesCentreWorkspaceProvisioner;
|
||||
use App\Services\Meet\SessionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -25,12 +26,17 @@ class ServiceRoomController extends Controller
|
||||
protected InvitationService $invitations,
|
||||
protected CalendarService $calendar,
|
||||
protected WebhookDispatcher $webhooks,
|
||||
protected SalesCentreWorkspaceProvisioner $salesCentreWorkspace,
|
||||
) {}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $this->validateRoomPayload($request);
|
||||
|
||||
if (($validated['source']['app'] ?? '') === 'sales_centre') {
|
||||
$this->salesCentreWorkspace->ensureHost($validated);
|
||||
}
|
||||
|
||||
$organization = $this->resolveOrganization($validated);
|
||||
abort_unless($organization->owner_ref === $validated['owner_ref'], 403);
|
||||
|
||||
@@ -147,6 +153,8 @@ class ServiceRoomController extends Controller
|
||||
'owner_ref' => [$required, 'string'],
|
||||
'organization_id' => ['nullable', 'integer', 'exists:meet_organizations,id'],
|
||||
'host_user_ref' => [$partial ? 'sometimes' : 'required', 'string'],
|
||||
'host_name' => ['nullable', 'string', 'max:255'],
|
||||
'host_email' => ['nullable', 'email', 'max:255'],
|
||||
'title' => [$partial ? 'sometimes' : 'required', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string'],
|
||||
'type' => ['nullable', 'string', Rule::in(self::SERVICE_TYPES)],
|
||||
@@ -169,9 +177,17 @@ class ServiceRoomController extends Controller
|
||||
/** @param array<string, mixed> $validated */
|
||||
private function resolveOrganization(array $validated): Organization
|
||||
{
|
||||
return isset($validated['organization_id'])
|
||||
? Organization::findOrFail($validated['organization_id'])
|
||||
: Organization::owned($validated['owner_ref'])->firstOrFail();
|
||||
if (isset($validated['organization_id'])) {
|
||||
return Organization::findOrFail($validated['organization_id']);
|
||||
}
|
||||
|
||||
if (($validated['source']['app'] ?? '') === 'sales_centre') {
|
||||
$host = User::where('public_id', $validated['host_user_ref'])->firstOrFail();
|
||||
|
||||
return $this->salesCentreWorkspace->ensureOrganization($host);
|
||||
}
|
||||
|
||||
return Organization::owned($validated['owner_ref'])->firstOrFail();
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $validated */
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Meet;
|
||||
|
||||
use App\Models\Branch;
|
||||
use App\Models\Organization;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SalesCentreWorkspaceProvisioner
|
||||
{
|
||||
public function __construct(
|
||||
protected OrganizationResolver $organizations,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $validated
|
||||
*/
|
||||
public function ensureHost(array $validated): User
|
||||
{
|
||||
$publicId = (string) $validated['host_user_ref'];
|
||||
|
||||
return User::updateOrCreate(
|
||||
['public_id' => $publicId],
|
||||
[
|
||||
'name' => trim((string) ($validated['host_name'] ?? '')) ?: 'Sales representative',
|
||||
'email' => $this->resolveEmail($publicId, $validated['host_email'] ?? null),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
public function ensureOrganization(User $host): Organization
|
||||
{
|
||||
$ref = $host->ownerRef();
|
||||
$existing = Organization::owned($ref)->first();
|
||||
|
||||
if ($existing) {
|
||||
$this->organizations->ensureOwnerMember($host, $existing);
|
||||
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$label = trim($host->name) !== '' ? $host->name.' workspace' : 'Sales workspace';
|
||||
|
||||
$organization = Organization::create([
|
||||
'owner_ref' => $ref,
|
||||
'name' => $label,
|
||||
'slug' => Str::slug($label).'-'.Str::lower(Str::random(4)),
|
||||
'timezone' => config('app.timezone', 'Africa/Accra'),
|
||||
'settings' => [
|
||||
'onboarded' => true,
|
||||
'org_type' => 'sales',
|
||||
'provisioned_by' => 'sales_centre',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->organizations->ensureOwnerMember($host, $organization);
|
||||
|
||||
Branch::create([
|
||||
'owner_ref' => $ref,
|
||||
'organization_id' => $organization->id,
|
||||
'name' => 'Main',
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
AuditLogger::record($ref, 'organization.created', $organization->id, $ref, Organization::class, $organization->id);
|
||||
|
||||
return $organization;
|
||||
}
|
||||
|
||||
private function resolveEmail(string $publicId, mixed $email): string
|
||||
{
|
||||
$email = trim((string) $email);
|
||||
|
||||
return $email !== '' ? $email : $publicId.'@users.ladill.com';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user