Protokoll #29039

ID29039
Zeitstempel2025-12-28 23:32:11.765931
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens2,326 (Input: 139, Output: 2,187)
Dauer98 ms
Request-Zeit2025-12-28 23:32:11.765931
Response-Zeit2025-12-28 23:32:11.863438

Request

{
    "event": "PreToolUse",
    "tool_name": "Edit",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/UseCases\/Search\/EnhancedSearchUseCase.php",
        "old_string": "    \/**\n     * Search within a specific taxonomy term and its children.\n     *\n     * @return array<array<string, mixed>>\n     *\/",
        "new_string": "    \/**\n     * Search within a specific taxonomy term and its children.\n     *\n     * @return array<array<string, mixed>>\n     *\n     * @throws \\RuntimeException When search service or repository operations fail\n     *\/"
    }
}

Response

{
    "tool_response": {
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/UseCases\/Search\/EnhancedSearchUseCase.php",
        "oldString": "    \/**\n     * Search within a specific taxonomy term and its children.\n     *\n     * @return array<array<string, mixed>>\n     *\/",
        "newString": "    \/**\n     * Search within a specific taxonomy term and its children.\n     *\n     * @return array<array<string, mixed>>\n     *\n     * @throws \\RuntimeException When search service or repository operations fail\n     *\/",
        "originalFile": "<?php\n\ndeclare(strict_types=1);\n\nnamespace UseCases\\Search;\n\n\/\/ @responsibility: Erweiterte Suche mit Taxonomie-Term-ID-Filterung\n\nuse Domain\\Repository\\ChunkTaxonomyRepositoryInterface;\nuse Domain\\Repository\\TaxonomyRepositoryInterface;\nuse Domain\\Service\\SearchServiceInterface;\n\nfinal class EnhancedSearchUseCase\n{\n    public function __construct(\n        private SearchServiceInterface $searchService,\n        private ChunkTaxonomyRepositoryInterface $chunkTaxonomyRepository,\n        private TaxonomyRepositoryInterface $taxonomyRepository\n    ) {\n    }\n\n    \/**\n     * Enhanced search with taxonomy term ID filtering.\n     *\n     * @param string $query Search query\n     * @param array<int> $taxonomyTermIds Filter by these taxonomy term IDs\n     * @param bool $includeChildTerms Include child terms in filter (recursive)\n     * @param int $limit Maximum results\n     * @return array{\n     *     results: array<array<string, mixed>>,\n     *     taxonomy_filter: array{term_ids: array<int>, chunk_ids: array<int>},\n     *     total_before_filter: int,\n     *     total_after_filter: int\n     * }\n     *\n     * @throws \\RuntimeException When search service or repository operations fail\n     *\/\n    public function execute(\n        string $query,\n        array $taxonomyTermIds = [],\n        bool $includeChildTerms = false,\n        int $limit = 10\n    ): array {\n        \/\/ If no taxonomy filter, delegate directly to search service\n        if (empty($taxonomyTermIds)) {\n            $results = $this->searchService->search($query, [], $limit);\n\n            return [\n                'results' => $results,\n                'taxonomy_filter' => ['term_ids' => [], 'chunk_ids' => []],\n                'total_before_filter' => count($results),\n                'total_after_filter' => count($results),\n            ];\n        }\n\n        \/\/ Expand term IDs if includeChildTerms is true\n        $effectiveTermIds = $includeChildTerms\n            ? $this->expandWithChildTerms($taxonomyTermIds)\n            : $taxonomyTermIds;\n\n        \/\/ Get chunk IDs that match the taxonomy filter\n        $filteredChunkIds = $this->getChunkIdsForTerms($effectiveTermIds);\n\n        if (empty($filteredChunkIds)) {\n            return [\n                'results' => [],\n                'taxonomy_filter' => ['term_ids' => $effectiveTermIds, 'chunk_ids' => []],\n                'total_before_filter' => 0,\n                'total_after_filter' => 0,\n            ];\n        }\n\n        \/\/ Perform search with higher limit to allow for filtering\n        $searchResults = $this->searchService->search($query, [], $limit * 5);\n        $totalBeforeFilter = count($searchResults);\n\n        \/\/ Filter results to only include chunks matching taxonomy\n        $filteredResults = array_filter(\n            $searchResults,\n            static fn (array $result): bool => in_array($result['chunk_id'] ?? 0, $filteredChunkIds, true)\n        );\n\n        \/\/ Re-index and limit\n        $filteredResults = array_values($filteredResults);\n        $limitedResults = array_slice($filteredResults, 0, $limit);\n\n        return [\n            'results' => $limitedResults,\n            'taxonomy_filter' => [\n                'term_ids' => $effectiveTermIds,\n                'chunk_ids' => $filteredChunkIds,\n            ],\n            'total_before_filter' => $totalBeforeFilter,\n            'total_after_filter' => count($filteredResults),\n        ];\n    }\n\n    \/**\n     * Search within a specific taxonomy term and its children.\n     *\n     * @return array<array<string, mixed>>\n     *\/\n    public function searchInTaxonomy(string $query, int $termId, int $limit = 10): array\n    {\n        $result = $this->execute($query, [$termId], true, $limit);\n\n        return $result['results'];\n    }\n\n    \/**\n     * Get search suggestions based on taxonomy structure.\n     *\n     * @return array{\n     *     terms: array<array{id: int, name: string, chunk_count: int}>,\n     *     suggested_filters: array<int>\n     * }\n     *\/\n    public function getSuggestionsForQuery(string $query): array\n    {\n        \/\/ First, get search results without filter\n        $results = $this->searchService->search($query, [], 20);\n\n        if (empty($results)) {\n            return ['terms' => [], 'suggested_filters' => []];\n        }\n\n        \/\/ Extract chunk IDs from results\n        $chunkIds = array_map(\n            static fn (array $r): int => (int) ($r['chunk_id'] ?? 0),\n            $results\n        );\n        $chunkIds = array_filter($chunkIds);\n\n        \/\/ Find common taxonomy terms for these chunks\n        $termCounts = [];\n        foreach ($chunkIds as $chunkId) {\n            $mappings = $this->chunkTaxonomyRepository->findByChunkId($chunkId);\n            foreach ($mappings as $mapping) {\n                $termId = $mapping->getTaxonomyTermId();\n                if (!isset($termCounts[$termId])) {\n                    $termCounts[$termId] = 0;\n                }\n                $termCounts[$termId]++;\n            }\n        }\n\n        \/\/ Sort by count and get top terms\n        arsort($termCounts);\n        $topTermIds = array_slice(array_keys($termCounts), 0, 5);\n\n        \/\/ Get term details\n        $terms = [];\n        foreach ($topTermIds as $termId) {\n            $term = $this->taxonomyRepository->find($termId);\n            if ($term !== null) {\n                $terms[] = [\n                    'id' => $termId,\n                    'name' => $term['name'],\n                    'chunk_count' => $termCounts[$termId],\n                ];\n            }\n        }\n\n        return [\n            'terms' => $terms,\n            'suggested_filters' => $topTermIds,\n        ];\n    }\n\n    \/**\n     * Expand term IDs to include all child terms.\n     *\n     * @param array<int> $termIds\n     * @return array<int>\n     *\/\n    private function expandWithChildTerms(array $termIds): array\n    {\n        $allTerms = $this->taxonomyRepository->findAll();\n        $expanded = $termIds;\n\n        \/\/ Build parent-child map\n        $childrenMap = [];\n        foreach ($allTerms as $term) {\n            $parentId = $term['parent_id'];\n            if ($parentId !== null) {\n                if (!isset($childrenMap[$parentId])) {\n                    $childrenMap[$parentId] = [];\n                }\n                $childrenMap[$parentId][] = $term['id'];\n            }\n        }\n\n        \/\/ Recursively add children\n        $queue = $termIds;\n        while (!empty($queue)) {\n            $currentId = array_shift($queue);\n            if (isset($childrenMap[$currentId])) {\n                foreach ($childrenMap[$currentId] as $childId) {\n                    if (!in_array($childId, $expanded, true)) {\n                        $expanded[] = $childId;\n                        $queue[] = $childId;\n                    }\n                }\n            }\n        }\n\n        return $expanded;\n    }\n\n    \/**\n     * Get chunk IDs that have mappings to any of the given taxonomy terms.\n     *\n     * @param array<int> $termIds\n     * @return array<int>\n     *\/\n    private function getChunkIdsForTerms(array $termIds): array\n    {\n        $chunkIds = [];\n\n        foreach ($termIds as $termId) {\n            $mappings = $this->chunkTaxonomyRepository->findByTaxonomyTermId($termId);\n            foreach ($mappings as $mapping) {\n                $chunkId = $mapping['chunk_id'];\n                if ($chunkId > 0 && !in_array($chunkId, $chunkIds, true)) {\n                    $chunkIds[] = $chunkId;\n                }\n            }\n        }\n\n        return $chunkIds;\n    }\n}\n",
        "structuredPatch": [
            {
                "oldStart": 99,
                "oldLines": 6,
                "newStart": 99,
                "newLines": 8,
                "lines": [
                    "      * Search within a specific taxonomy term and its children.",
                    "      *",
                    "      * @return array<array<string, mixed>>",
                    "+     *",
                    "+     * @throws \\RuntimeException When search service or repository operations fail",
                    "      *\/",
                    "     public function searchInTaxonomy(string $query, int $termId, int $limit = 10): array",
                    "     {"
                ]
            }
        ],
        "userModified": false,
        "replaceAll": false
    }
}
← Vorheriger Zur Liste Nächster →