Route Care tickets to per-staff service points instead of shared branch queues.
Deploy Ladill Care / deploy (push) Successful in 1m40s

Provision one consultation point per doctor (room + identity) and role-based
points for pharmacy, lab, billing, and triage. Fixed-doctor appointments and
walk-ins issue only to the assigned point; Call next respects that assignment
and flags unresolved patients rather than random routing.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-17 17:22:14 +00:00
co-authored by Cursor
parent c5151ad476
commit e73b39b678
22 changed files with 1331 additions and 97 deletions
+81 -6
View File
@@ -4,11 +4,18 @@ namespace App\Services\Care;
/**
* Canonical Care Ladill Queue department / specialty contexts.
*
* Mapping:
* - Department/service Queue ServiceQueue (+ Queue Department)
* - Service point (room/desk/counter) Queue Counter
* - Staff assignment Counter staff_ref / staff_display_name
*/
class CareQueueContexts
{
public const RECEPTION = 'reception';
public const TRIAGE = 'triage';
public const CONSULTATION = 'consultation';
public const PHARMACY = 'pharmacy';
@@ -17,19 +24,63 @@ class CareQueueContexts
public const BILLING = 'billing';
public const IMAGING = 'imaging';
public const ROUTING_ROUTED = 'routed';
public const ROUTING_UNRESOLVED = 'unresolved';
/**
* Core department queues provisioned for every branch when Queue integration is on.
* Consultation/pharmacy/lab/billing use assigned_only routing (per service point).
*
* @return array<string, array{name: string, prefix: string}>
* @return array<string, array{name: string, prefix: string, routing_mode: string, type: string}>
*/
public static function departments(): array
{
return [
self::RECEPTION => ['name' => 'Reception', 'prefix' => 'R'],
self::CONSULTATION => ['name' => 'Consultation', 'prefix' => 'C'],
self::PHARMACY => ['name' => 'Pharmacy', 'prefix' => 'P'],
self::LABORATORY => ['name' => 'Laboratory', 'prefix' => 'L'],
self::BILLING => ['name' => 'Billing', 'prefix' => 'B'],
self::RECEPTION => [
'name' => 'Reception',
'prefix' => 'R',
'routing_mode' => 'shared_pool',
'type' => 'reception',
],
self::TRIAGE => [
'name' => 'Triage',
'prefix' => 'T',
'routing_mode' => 'assigned_only',
'type' => 'consultation',
],
self::CONSULTATION => [
'name' => 'Consultation',
'prefix' => 'C',
'routing_mode' => 'assigned_only',
'type' => 'consultation',
],
self::PHARMACY => [
'name' => 'Pharmacy',
'prefix' => 'P',
'routing_mode' => 'assigned_only',
'type' => 'pharmacy',
],
self::LABORATORY => [
'name' => 'Laboratory',
'prefix' => 'L',
'routing_mode' => 'assigned_only',
'type' => 'laboratory',
],
self::BILLING => [
'name' => 'Billing',
'prefix' => 'B',
'routing_mode' => 'assigned_only',
'type' => 'cashier',
],
self::IMAGING => [
'name' => 'Imaging',
'prefix' => 'I',
'routing_mode' => 'assigned_only',
'type' => 'laboratory',
],
];
}
@@ -43,6 +94,15 @@ class CareQueueContexts
return array_key_exists($context, config('care.specialty_modules', []));
}
public static function usesAssignedRouting(string $context): bool
{
if (self::isSpecialty($context)) {
return true;
}
return (self::departments()[$context]['routing_mode'] ?? 'shared_pool') === 'assigned_only';
}
public static function queueExternalKey(string $context, int|string $careBranchId): string
{
if (self::isSpecialty($context)) {
@@ -52,6 +112,12 @@ class CareQueueContexts
return "care:dept:{$context}:queue:{$careBranchId}";
}
public static function departmentExternalKey(string $context, int|string $careBranchId): string
{
return "care:dept:{$context}:branch:{$careBranchId}";
}
/** @deprecated Prefer pointExternalKey — kept for legacy single-counter stubs. */
public static function counterExternalKey(string $context, int|string $careBranchId): string
{
if (self::isSpecialty($context)) {
@@ -60,4 +126,13 @@ class CareQueueContexts
return "care:dept:{$context}:counter:{$careBranchId}";
}
public static function pointExternalKey(
string $context,
int|string $careBranchId,
string $pointKind,
int|string $pointId,
): string {
return "care:point:{$context}:{$pointKind}:{$careBranchId}:{$pointId}";
}
}