Files
ladill-frontdesk/app/Http/Controllers/Frontdesk/AiController.php
T
isaaccladandCursor 5a42759886
Deploy Ladill Frontdesk / deploy (push) Successful in 34s
Wire Afia into Frontdesk and sync the app launcher catalog.
Add the AI assistant button, chat endpoint, and Frontdesk-specific prompts, and include Frontdesk in the shared launcher config used by the app switcher.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 01:40:32 +00:00

71 lines
2.7 KiB
PHP

<?php
namespace App\Http\Controllers\Frontdesk;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Frontdesk\Concerns\ScopesToAccount;
use App\Models\Device;
use App\Models\Host;
use App\Models\Visit;
use App\Models\Visitor;
use App\Services\Afia\AfiaService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AiController extends Controller
{
use ScopesToAccount;
public function chat(Request $request, AfiaService $afia): JsonResponse
{
$validated = $request->validate([
'message' => ['required', 'string', 'max:2000'],
'history' => ['nullable', 'array', 'max:20'],
'history.*.role' => ['nullable', 'string'],
'history.*.text' => ['nullable', 'string'],
]);
if (! $afia->enabled()) {
return response()->json(['message' => 'Afia is not available right now.'], 503);
}
try {
$reply = $afia->chat(trim($validated['message']), $validated['history'] ?? [], $this->context($request));
} catch (\Throwable $e) {
report($e);
return response()->json(['message' => 'Afia could not respond right now. Please try again.'], 502);
}
return response()->json(['reply' => $reply]);
}
/** @return array<string, mixed> */
private function context(Request $request): array
{
$owner = $this->ownerRef($request);
$organization = $this->organization($request);
$visitQuery = Visit::owned($owner)->where('organization_id', $organization->id);
$this->scopeToBranch($request, $visitQuery);
return [
'signed_in' => 'yes',
'organization' => $organization->name,
'visitors_today' => (clone $visitQuery)->where(function ($q) {
$q->whereDate('checked_in_at', today())
->orWhereDate('scheduled_at', today());
})->count(),
'currently_inside' => (clone $visitQuery)->currentlyInside()->count(),
'expected_arrivals' => (clone $visitQuery)->whereIn('status', [
Visit::STATUS_EXPECTED,
Visit::STATUS_SCHEDULED,
])->whereDate('scheduled_at', today())->count(),
'registered_visitors' => Visitor::owned($owner)->where('organization_id', $organization->id)->count(),
'active_hosts' => Host::owned($owner)->where('organization_id', $organization->id)->where('is_available', true)->count(),
'registered_devices' => Device::owned($owner)->where('organization_id', $organization->id)->count(),
'online_devices' => Device::owned($owner)->where('organization_id', $organization->id)->where('status', 'online')->count(),
];
}
}