Files
ladill-care/app/Services/Queue/QueueClient.php
T
isaaccladandCursor dec282d25d
Deploy Ladill Care / deploy (push) Successful in 53s
Embed Ladill Queue on role pages and add specialty modules under Settings.
Remove the standalone Service Queues nav so call-next/now-serving lives on clinical queue, appointments, pharmacy, lab, and specialty surfaces; Pro orgs can activate dentistry and related modules with branch departments and queue stubs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 15:55:47 +00:00

157 lines
4.3 KiB
PHP

<?php
namespace App\Services\Queue;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
class QueueClient
{
private function base(): string
{
return rtrim((string) config('care.queue.api_url'), '/');
}
private function token(): string
{
return (string) (config('care.queue.api_key') ?? '');
}
private function http(string $owner)
{
return Http::withToken($this->token())
->acceptJson()
->timeout(12)
->withQueryParameters(['owner' => $owner]);
}
public function configured(): bool
{
return $this->token() !== '' && $this->base() !== '';
}
/**
* @return array<string, mixed>
*/
public function status(string $owner): array
{
$response = $this->http($owner)->get($this->base().'/integrations/status');
$response->throw();
return (array) ($response->json('data') ?? []);
}
/**
* @return array<string, mixed>
*/
public function enable(string $owner, string $organizationName, ?string $branchName = null): array
{
$this->http($owner)->post($this->base().'/integrations/provision', array_filter([
'organization_name' => $organizationName,
'branch_name' => $branchName,
'industry' => 'healthcare',
]))->throw();
return $this->syncIntegration($owner, true);
}
/**
* @return array<string, mixed>
*/
public function syncIntegration(string $owner, bool $enabled = true): array
{
$response = $this->http($owner)->patch($this->base().'/integrations', [
'care_enabled' => $enabled,
]);
$response->throw();
return (array) ($response->json('data') ?? []);
}
public function disable(string $owner): void
{
// Local Care setting only; Queue must be disabled separately in Queue settings.
}
public function isLinked(string $owner): bool
{
if (! $this->configured()) {
return false;
}
try {
$status = $this->status($owner);
return (bool) ($status['provisioned'] ?? false)
&& (bool) data_get($status, 'integrations.care', false);
} catch (RequestException) {
return false;
}
}
/**
* @return list<array<string, mixed>>
*/
public function counters(string $owner): array
{
$response = $this->http($owner)->get($this->base().'/counters');
$response->throw();
return (array) ($response->json('data') ?? []);
}
/**
* @return array<string, mixed>
*/
public function console(string $owner, string $counterUuid): array
{
$response = $this->http($owner)->get($this->base().'/counters/'.$counterUuid.'/console');
$response->throw();
return (array) ($response->json('data') ?? []);
}
/**
* @param array<string, mixed> $payload
* @return array<string, mixed>
*/
public function consoleAction(string $owner, string $counterUuid, array $payload): array
{
$response = $this->http($owner)->post($this->base().'/counters/'.$counterUuid.'/console', $payload);
$response->throw();
return (array) ($response->json('data') ?? []);
}
/**
* Best-effort specialty queue sync. Care integration API is read/console-only today,
* so stubs remain Care-side until Queue exposes create-queue for service tokens.
*
* @param list<array<string, mixed>> $stubs
* @return list<array<string, mixed>>
*/
public function syncSpecialtyQueueStubs(string $owner, array $stubs): array
{
if (! $this->configured() || $stubs === []) {
return $stubs;
}
try {
$existing = collect($this->counters($owner))
->flatMap(fn ($c) => $c['queues'] ?? [])
->map(fn ($q) => strtolower((string) ($q['name'] ?? '')))
->filter()
->all();
} catch (\Throwable) {
return $stubs;
}
foreach ($stubs as $i => $stub) {
$name = strtolower((string) ($stub['name'] ?? ''));
$stubs[$i]['synced'] = $name !== '' && in_array($name, $existing, true);
}
return $stubs;
}
}