GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

145 lines
4.9 KiB

<?php
namespace App\Http\Controllers;
use App\Services\AuditLogService;
use App\Services\ProjectSearchChatService;
use App\Services\ProjectSearchService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use RuntimeException;
use Throwable;
class ProjectSearchController extends Controller
{
public function __construct(
private readonly ProjectSearchService $projectSearch,
private readonly ProjectSearchChatService $chat,
private readonly AuditLogService $audit
) {
}
public function index(Request $request): View
{
$username = (string) $request->session()->get('ldap_username', '');
$indexRuns = $this->projectSearch->isAvailable()
? $this->projectSearch->indexStatus()
: [];
$activeSession = $username !== '' && $this->chat->isAvailable()
? $this->chat->activeSession($username)
: null;
$messages = $activeSession !== null
? $this->chat->messagesForSessionId((int) $activeSession['id'])
: [];
$chatHistory = $username !== '' && $this->chat->isAvailable()
? $this->chat->recentEndedSessions($username, 8)
: [];
return view('project-search.index', [
'sources' => $this->projectSearch->listSources(),
'indexRuns' => array_slice($indexRuns, 0, 5),
'indexAvailable' => $this->projectSearch->isAvailable(),
'chatAvailable' => $this->chat->isAvailable(),
'ollamaConfigured' => (string) config('ollama.base_url') !== '',
'oauthClientId' => (string) config('project_search.oauth_client_id'),
'oauthScope' => (string) config('project_search.oauth_scope'),
'oauthTokenUrl' => rtrim((string) config('app.url'), '/').'/oauth/token',
'activeSession' => $activeSession,
'messages' => $messages,
'chatHistory' => $chatHistory,
]);
}
public function ask(Request $request): JsonResponse
{
$validated = $request->validate([
'query' => ['required', 'string', 'min:3', 'max:500'],
'sources' => ['sometimes', 'array'],
'sources.*' => ['string', 'max:64'],
'limit' => ['sometimes', 'integer', 'min:1', 'max:50'],
]);
$username = (string) $request->session()->get('ldap_username', '');
if ($username === '') {
return response()->json(['message' => 'Sesi login tidak valid.'], 401);
}
try {
$sources = $validated['sources'] ?? [];
$session = $this->chat->getOrCreateActiveSession($username, $sources);
$sessionId = (int) $session['id'];
$history = $this->chat->conversationHistoryForOllama($sessionId);
$userMessage = $this->chat->addUserMessage($sessionId, $validated['query']);
$result = $this->projectSearch->ask(
$validated['query'],
$sources,
(int) ($validated['limit'] ?? config('project_search.default_limit', 20)),
$history
);
$assistantMessage = $this->chat->addAssistantMessage(
$sessionId,
$result['answer'],
$result['results'],
$result['meta']
);
$this->audit->log(
'project_search.chat.ask',
'web',
$username,
null,
'project_search',
$request,
200,
[
'session_id' => $sessionId,
'query' => $validated['query'],
'result_count' => $result['meta']['result_count'] ?? 0,
'sources' => $result['meta']['sources'] ?? [],
]
);
return response()->json([
'session' => $session,
'user_message' => $userMessage,
'assistant_message' => $assistantMessage,
]);
} catch (RuntimeException $e) {
return response()->json(['message' => $e->getMessage()], 422);
} catch (Throwable) {
return response()->json(['message' => 'Gagal memproses pencarian proyek.'], 500);
}
}
public function endChat(Request $request): JsonResponse
{
$username = (string) $request->session()->get('ldap_username', '');
if ($username === '') {
return response()->json(['message' => 'Sesi login tidak valid.'], 401);
}
$ended = $this->chat->endActiveSession($username);
if ($ended) {
$this->audit->log(
'project_search.chat.end',
'web',
$username,
null,
'project_search',
$request,
200,
[]
);
}
return response()->json(['ended' => $ended]);
}
}