Backup #2062

ID2062
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Controller/Api/ExplorerController.php
Version41
Typ modified
Größe9.3 KB
Hash02976b1e30e003009ea9ff25993109eef83a913a1ee843feebf41d97be4fe8c0
Datum2025-12-28 23:29:55
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace Controller\Api;

// @responsibility: REST-API für Doc2Vector Explorer (Dokumente, Chunks, Suche)

use Domain\Repository\ChunkExplorerRepositoryInterface;
use Domain\Repository\DokumentExplorerRepositoryInterface;
use Domain\Repository\SeiteExplorerRepositoryInterface;
use Domain\Service\SearchServiceInterface;
use Domain\Constants;
use Framework\Controller;
use Infrastructure\Traits\JsonDecodeTrait;

class ExplorerController extends Controller
{
    use JsonDecodeTrait;

    private DokumentExplorerRepositoryInterface $dokumentRepository;
    private SeiteExplorerRepositoryInterface $seiteRepository;
    private ChunkExplorerRepositoryInterface $chunkRepository;
    private SearchServiceInterface $searchService;

    public function __construct(
        DokumentExplorerRepositoryInterface $dokumentRepository,
        SeiteExplorerRepositoryInterface $seiteRepository,
        ChunkExplorerRepositoryInterface $chunkRepository,
        SearchServiceInterface $searchService
    ) {
        $this->dokumentRepository = $dokumentRepository;
        $this->seiteRepository = $seiteRepository;
        $this->chunkRepository = $chunkRepository;
        $this->searchService = $searchService;
    }

    /**
     * GET /api/v1/explorer/stats
     */
    public function stats(): void
    {
        try {
            $this->json([
                'success' => true,
                'data' => [
                    'dokumente' => $this->dokumentRepository->countDokumente(),
                    'seiten' => $this->seiteRepository->countSeiten(),
                    'chunks' => $this->chunkRepository->getChunkStats(),
                    'taxonomy_categories' => $this->chunkRepository->getTopTaxonomyCategories(Constants::DEFAULT_LIMIT),
                ],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Explorer.stats] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/dokumente
     */
    public function listDokumente(): void
    {
        try {
            $dokumente = $this->dokumentRepository->getDokumenteWithFullStats();

            $this->json([
                'success' => true,
                'data' => $dokumente,
                'meta' => ['total' => count($dokumente)],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Explorer.listDokumente] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/dokumente/{id}
     */
    public function getDokument(string $id): void
    {
        try {
            $dokument = $this->dokumentRepository->getDokumentRoot((int) $id);

            if ($dokument === null) {
                $this->json(['success' => false, 'error' => 'Dokument nicht gefunden'], 404);

                return;
            }

            $this->json([
                'success' => true,
                'data' => [
                    'dokument' => $dokument,
                    'seiten' => $this->seiteRepository->getSeitenWithStatsForParent((int) $id),
                    'taxonomy' => $this->seiteRepository->getTaxonomyForDokumentTree((int) $id),
                ],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Explorer.getDokument] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/seiten
     */
    public function listSeiten(): void
    {
        try {
            $search = $this->getString('search');
            $parentId = $this->getString('parent_id');
            $limit = $this->getLimit(Constants::DEFAULT_LIMIT, Constants::PERCENT_HALF);
            $offset = $this->getInt('offset');

            $total = $this->seiteRepository->countSeitenFiltered($search, $parentId);
            $seiten = $this->seiteRepository->getSeitenPaginated($search, $parentId, $limit, $offset);

            $this->json([
                'success' => true,
                'data' => $seiten,
                'meta' => [
                    'total' => $total,
                    'limit' => $limit,
                    'offset' => $offset,
                ],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Explorer.listSeiten] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/seiten/{id}
     */
    public function getSeite(string $id): void
    {
        try {
            $seite = $this->seiteRepository->getSeiteWithParent((int) $id);

            if ($seite === null) {
                $this->json(['success' => false, 'error' => 'Seite nicht gefunden'], 404);

                return;
            }

            $chunks = $this->chunkRepository->getChunksDetailedForDokument((int) $id);

            // Decode JSON fields in chunks
            foreach ($chunks as &$c) {
                $c['entities'] = $this->decodeJsonArray($c['entities'] ?? null);
                $c['keywords'] = $this->decodeJsonArray($c['keywords'] ?? null);
                $c['taxonomy_path'] = $this->decodeJsonArray($c['taxonomy_path'] ?? null);
            }

            $this->json([
                'success' => true,
                'data' => [
                    'seite' => $seite,
                    'chunks' => $chunks,
                    'unterseiten' => $this->seiteRepository->getUnterseiten((int) $id),
                ],
            ]);
        } catch (\Exception $e) {
            error_log(sprintf('[API.Explorer.getSeite] %s: %s', get_class($e), $e->getMessage()));
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/chunks
     */
    public function listChunks(): void
    {
        try {
            $category = $this->getString('category');
            $status = $this->getString('status');
            $search = $this->getString('search');
            $limit = $this->getLimit(Constants::DEFAULT_LIMIT, Constants::PERCENT_HALF);
            $offset = $this->getInt('offset');

            $total = $this->chunkRepository->countChunksFiltered($category, $status, $search);
            $chunks = $this->chunkRepository->getChunksFilteredPaginated($category, $status, $search, $limit, $offset);

            $this->json([
                'success' => true,
                'data' => $chunks,
                'meta' => [
                    'total' => $total,
                    'limit' => $limit,
                    'offset' => $offset,
                ],
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/chunks/{id}
     */
    public function getChunk(string $id): void
    {
        try {
            $chunk = $this->chunkRepository->getChunk((int) $id);

            if ($chunk === null) {
                $this->json(['success' => false, 'error' => 'Chunk nicht gefunden'], 404);

                return;
            }

            $this->json([
                'success' => true,
                'data' => $chunk,
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/taxonomie
     */
    public function taxonomie(): void
    {
        try {
            $this->json([
                'success' => true,
                'data' => [
                    'categories' => $this->chunkRepository->getTopTaxonomyCategories(Constants::DEFAULT_LIMIT),
                    'top_keywords' => $this->chunkRepository->getTopKeywords(50),
                ],
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * GET /api/v1/explorer/entities
     */
    public function entities(): void
    {
        try {
            $this->json([
                'success' => true,
                'data' => $this->chunkRepository->getEntitiesGrouped(Constants::DEFAULT_LIMIT),
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }

    /**
     * POST /api/v1/explorer/suche
     */
    public function suche(): void
    {
        try {
            $input = $this->getJsonInput();

            $query = trim($input['query'] ?? '');
            if ($query === '') {
                $this->json(['success' => false, 'error' => 'Query ist erforderlich'], 400);

                return;
            }

            $filters = [];
            if (!empty($input['category'])) {
                $filters['taxonomy_category'] = $input['category'];
            }

            $limit = min((int) ($input['limit'] ?? 10), 50);

            $results = $this->searchService->search($query, $filters, $limit);
            $suggestions = $this->searchService->suggestRelatedSearches($results);

            $this->json([
                'success' => true,
                'data' => [
                    'query' => $query,
                    'results' => $results,
                    'suggestions' => $suggestions,
                    'count' => count($results),
                ],
            ]);
        } catch (\Exception $e) {
            $this->jsonError($e->getMessage());
        }
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
2066 45 modified 9.6 KB 2025-12-28 23:30
2065 44 modified 9.5 KB 2025-12-28 23:30
2064 43 modified 9.4 KB 2025-12-28 23:30
2063 42 modified 9.4 KB 2025-12-28 23:30
2062 41 modified 9.3 KB 2025-12-28 23:29
2061 40 modified 9.2 KB 2025-12-28 23:29
2060 39 modified 9.1 KB 2025-12-28 23:29
2059 38 modified 9.0 KB 2025-12-28 23:29
2058 37 modified 8.9 KB 2025-12-28 23:29
2057 36 modified 8.8 KB 2025-12-28 23:29
1811 35 modified 8.7 KB 2025-12-27 15:30
1810 34 modified 8.7 KB 2025-12-27 15:30
1809 33 modified 8.6 KB 2025-12-27 15:30
1808 32 modified 8.6 KB 2025-12-27 15:30
1807 31 modified 8.6 KB 2025-12-27 15:30
1503 30 modified 8.6 KB 2025-12-25 17:49
1242 29 modified 8.6 KB 2025-12-25 12:34
1241 28 modified 8.6 KB 2025-12-25 12:34
1240 27 modified 8.6 KB 2025-12-25 12:34
1239 26 modified 8.6 KB 2025-12-25 12:34
1238 25 modified 8.5 KB 2025-12-25 12:34
1237 24 modified 8.5 KB 2025-12-25 12:34
1236 23 modified 8.5 KB 2025-12-25 12:34
1235 22 modified 8.5 KB 2025-12-25 12:34
1234 21 modified 8.5 KB 2025-12-25 12:34
1232 20 modified 8.0 KB 2025-12-25 12:33
702 19 modified 8.0 KB 2025-12-23 07:53
625 18 modified 8.0 KB 2025-12-23 04:43
624 17 modified 7.9 KB 2025-12-23 04:43
622 16 modified 7.9 KB 2025-12-23 04:43
591 15 modified 7.9 KB 2025-12-23 04:25
532 14 modified 13.4 KB 2025-12-22 22:18
356 13 modified 15.0 KB 2025-12-22 08:19
354 12 modified 16.0 KB 2025-12-22 08:18
353 11 modified 16.6 KB 2025-12-22 08:18
352 10 modified 17.3 KB 2025-12-22 08:18
351 9 modified 18.6 KB 2025-12-22 08:18
350 8 modified 18.4 KB 2025-12-22 08:16
318 7 modified 18.5 KB 2025-12-22 08:06
317 6 modified 18.5 KB 2025-12-22 08:06
295 5 modified 18.5 KB 2025-12-22 08:03
294 4 modified 18.5 KB 2025-12-22 08:03
285 3 modified 18.5 KB 2025-12-22 07:59
284 2 modified 18.5 KB 2025-12-22 07:59
42 1 modified 19.2 KB 2025-12-20 17:24

← Zurück zur Übersicht