Files
isaaccladandCursor 965fb992e9
Deploy Ladill Meet / deploy (push) Failing after 7s
Initial Ladill Meet release.
Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 23:35:29 +00:00

106 lines
3.4 KiB
PHP

<?php
namespace App\Services\Meet;
use App\Models\ContactGroup;
use App\Models\Member;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
class ContactService
{
/**
* @return Collection<int, array<string, mixed>>
*/
public function searchOrgMembers(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
{
$members = Member::owned($ownerRef)
->where('organization_id', $organizationId)
->when($query !== '', function ($q) use ($query) {
$q->whereIn('user_ref', User::query()
->where(function ($u) use ($query) {
$u->where('name', 'like', "%{$query}%")
->orWhere('email', 'like', "%{$query}%");
})
->pluck('public_id'));
})
->limit($limit)
->get();
return $members->map(function (Member $member) {
$user = User::where('public_id', $member->user_ref)->first();
return [
'user_ref' => $member->user_ref,
'email' => $user?->email,
'name' => $user?->name ?? $member->user_ref,
'role' => $member->role,
'source' => 'org',
];
})->filter(fn ($c) => filled($c['email']));
}
/**
* @return Collection<int, array<string, mixed>>
*/
public function search(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
{
$org = $this->searchOrgMembers($organizationId, $ownerRef, $query, $limit);
if ($org->count() >= $limit) {
return $org;
}
$platform = $this->searchPlatformContacts($query, $limit - $org->count());
$emails = $org->pluck('email')->filter()->all();
return $org->merge($platform->reject(fn ($c) => in_array($c['email'], $emails, true)))->take($limit);
}
/**
* @return Collection<int, array<string, mixed>>
*/
public function fromGroup(ContactGroup $group): Collection
{
return $group->members->map(fn ($m) => [
'email' => $m->email,
'name' => $m->display_name,
'user_ref' => $m->user_ref,
'source' => 'group',
])->filter(fn ($c) => filled($c['email']));
}
/**
* @return Collection<int, array<string, mixed>>
*/
protected function searchPlatformContacts(string $query, int $limit): Collection
{
$url = rtrim((string) config('identity.api_url'), '/');
$key = config('identity.api_key');
if ($url === '' || $key === '' || $query === '') {
return collect();
}
try {
$response = Http::withToken($key)
->timeout(5)
->get("{$url}/team/search", ['q' => $query, 'limit' => $limit]);
if (! $response->successful()) {
return collect();
}
return collect($response->json('contacts', []))->map(fn ($c) => [
'user_ref' => $c['public_id'] ?? null,
'email' => $c['email'] ?? null,
'name' => $c['name'] ?? null,
'source' => 'platform',
])->filter(fn ($c) => filled($c['email']));
} catch (\Throwable) {
return collect();
}
}
}