From bd3dd6e659771a46c7f3c708955bbb043f77e92a Mon Sep 17 00:00:00 2001 From: team2 Date: Fri, 27 Feb 2026 20:19:03 +0100 Subject: [PATCH] move controller service logics into a service --- .../Admin/ModelGenerationConfigController.php | 93 +++++++------------ .../ModelGenerationConfigAdminService.php | 87 +++++++++++++++++ 2 files changed, 119 insertions(+), 61 deletions(-) create mode 100644 src/Service/Admin/ModelGenerationConfigAdminService.php diff --git a/src/Controller/Admin/ModelGenerationConfigController.php b/src/Controller/Admin/ModelGenerationConfigController.php index 0a67a5a..6a8cf12 100644 --- a/src/Controller/Admin/ModelGenerationConfigController.php +++ b/src/Controller/Admin/ModelGenerationConfigController.php @@ -5,101 +5,72 @@ declare(strict_types=1); namespace App\Controller\Admin; use App\Entity\ModelGenerationConfig; -use App\Knowledge\Retrieval\NdjsonHybridRetriever; -use App\Repository\ModelGenerationConfigRepository; -use App\Service\ModelGenerationConfigManager; -use Doctrine\ORM\EntityManagerInterface; +use App\Service\Admin\ModelGenerationConfigAdminService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; #[Route('/admin/model-config')] -class ModelGenerationConfigController extends AbstractController +final class ModelGenerationConfigController extends AbstractController { #[Route('/', name: 'admin_model_config_list')] - public function list(ModelGenerationConfigRepository $repository): Response + public function list(ModelGenerationConfigAdminService $svc): Response { $this->denyAccessUnlessGranted('ROLE_KNOWLEDGE_ADMIN'); - $configs = $repository->findBy( - [], - ['active' => 'DESC', 'modelName' => 'ASC', 'version' => 'DESC'] - ); - return $this->render('admin/model_config/list.html.twig', [ - 'configs' => $configs, + 'configs' => $svc->list(), ]); } - #[Route('/create', name: 'admin_model_config_create')] + #[Route('/create', name: 'admin_model_config_create', methods: ['GET', 'POST'])] public function create( Request $request, - EntityManagerInterface $em, - ModelGenerationConfigRepository $repository + ModelGenerationConfigAdminService $svc ): Response { $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN'); if ($request->isMethod('POST')) { + try { + $svc->create($request->request->all()); + $this->addFlash('success', 'Konfiguration erstellt.'); - $modelName = (string) $request->request->get('model_name'); - $version = $repository->findNextVersion($modelName); - - $retrievalMaxChunks = (int) $request->request->get('retrieval_max_chunks', 25); - $retrievalVectorTopK = (int) $request->request->get('retrieval_vector_top_k', 25); - - $config = new ModelGenerationConfig( - modelName: $modelName, - version: $version, - stream: (bool) $request->request->get('stream'), - temperature: (float) $request->request->get('temperature'), - topK: (int) $request->request->get('top_k'), - topP: (float) $request->request->get('top_p'), - repeatPenalty: (float) $request->request->get('repeat_penalty'), - numCtx: (int) $request->request->get('num_ctx'), - active: false, - retrievalMaxChunks: $retrievalMaxChunks, - retrievalVectorTopK: $retrievalVectorTopK - ); - - $em->persist($config); - $em->flush(); - - return $this->redirectToRoute('admin_model_config_list'); + return $this->redirectToRoute('admin_model_config_list'); + } catch (\Throwable $e) { + $this->addFlash('danger', $e->getMessage()); + } } return $this->render('admin/model_config/create.html.twig'); } - #[Route('/{id}/activate', name: 'admin_model_config_activate')] + #[Route('/{id}/activate', name: 'admin_model_config_activate', methods: ['POST'])] public function activate( ModelGenerationConfig $config, - ModelGenerationConfigManager $manager + ModelGenerationConfigAdminService $svc ): Response { $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN'); - $manager->activate($config); + $svc->activate($config); return $this->redirectToRoute('admin_model_config_list'); } - #[Route('/{id}/test-retrieval', name: 'admin_model_config_test_retrieval')] + #[Route('/{id}/test-retrieval', name: 'admin_model_config_test_retrieval', methods: ['GET', 'POST'])] public function testRetrieval( ModelGenerationConfig $config, Request $request, - NdjsonHybridRetriever $retriever + ModelGenerationConfigAdminService $svc ): Response { $this->denyAccessUnlessGranted('ROLE_KNOWLEDGE_ADMIN'); - $results = []; $prompt = ''; + $results = []; if ($request->isMethod('POST')) { - $prompt = trim((string) $request->request->get('prompt')); - - if ($prompt !== '') { - $results = $retriever->retrieveInternal($prompt, $config); - } + $prompt = trim((string)$request->request->get('prompt')); + $results = $svc->testRetrieval($config, $prompt); } return $this->render('admin/model_config/test_retrieval.html.twig', [ @@ -113,24 +84,24 @@ class ModelGenerationConfigController extends AbstractController public function delete( ModelGenerationConfig $config, Request $request, - EntityManagerInterface $em + ModelGenerationConfigAdminService $svc ): Response { $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN'); - if ($config->isActive()) { - $this->addFlash('danger', 'Aktive Konfiguration kann nicht gelöscht werden.'); - return $this->redirectToRoute('admin_model_config_list'); + if (!$this->isCsrfTokenValid( + 'delete_model_config_'.$config->getId(), + $request->request->get('_token') + )) { + throw $this->createAccessDeniedException(); } - if (!$this->isCsrfTokenValid('delete_model_config_'.$config->getId(), $request->request->get('_token'))) { - throw $this->createAccessDeniedException('Invalid CSRF token.'); + try { + $svc->delete($config); + $this->addFlash('success', 'Konfiguration gelöscht.'); + } catch (\Throwable $e) { + $this->addFlash('danger', $e->getMessage()); } - $em->remove($config); - $em->flush(); - - $this->addFlash('success', 'Konfiguration gelöscht.'); - return $this->redirectToRoute('admin_model_config_list'); } } \ No newline at end of file diff --git a/src/Service/Admin/ModelGenerationConfigAdminService.php b/src/Service/Admin/ModelGenerationConfigAdminService.php new file mode 100644 index 0000000..f1a2015 --- /dev/null +++ b/src/Service/Admin/ModelGenerationConfigAdminService.php @@ -0,0 +1,87 @@ +repository->findBy( + [], + ['active' => 'DESC', 'modelName' => 'ASC', 'version' => 'DESC'] + ); + } + + public function create(array $data): ModelGenerationConfig + { + $modelName = $this->requireString($data['model_name'] ?? null, 'model_name'); + + $version = $this->repository->findNextVersion($modelName); + + $config = new ModelGenerationConfig( + modelName: $modelName, + version: $version, + stream: (bool)($data['stream'] ?? false), + temperature: (float)($data['temperature'] ?? 0.7), + topK: (int)($data['top_k'] ?? 40), + topP: (float)($data['top_p'] ?? 0.9), + repeatPenalty: (float)($data['repeat_penalty'] ?? 1.1), + numCtx: (int)($data['num_ctx'] ?? 4096), + active: false, + retrievalMaxChunks: (int)($data['retrieval_max_chunks'] ?? 25), + retrievalVectorTopK: (int)($data['retrieval_vector_top_k'] ?? 25), + ); + + $this->em->persist($config); + $this->em->flush(); + + return $config; + } + + public function activate(ModelGenerationConfig $config): void + { + $this->manager->activate($config); + } + + public function delete(ModelGenerationConfig $config): void + { + if ($config->isActive()) { + throw new \RuntimeException('Aktive Konfiguration kann nicht gelöscht werden.'); + } + + $this->em->remove($config); + $this->em->flush(); + } + + public function testRetrieval(ModelGenerationConfig $config, string $prompt): array + { + if (trim($prompt) === '') { + return []; + } + + return $this->retriever->retrieveInternal($prompt, $config); + } + + private function requireString(mixed $value, string $field): string + { + if (!is_string($value) || trim($value) === '') { + throw new \InvalidArgumentException("Invalid value for {$field}"); + } + return trim($value); + } +} \ No newline at end of file