diff --git a/services/nginx/app/classes/system_search_service.php b/services/nginx/app/classes/system_search_service.php index e836f3c9..b0c5e4a6 100644 --- a/services/nginx/app/classes/system_search_service.php +++ b/services/nginx/app/classes/system_search_service.php @@ -207,25 +207,28 @@ class system_search_service $activeTypes, $this->associationEntityTypes() )); - foreach ($customerNumbers as $customerNumber) { - $associated = $this->executeLexicalSearch( - $associationTypes, - [(string)$customerNumber], - [], - $ownOnlyTypes, - $ownCustomerNumber, - $permissionsCatalogAll, - $permissionsCatalogOwn, - $moduleConfigVisibility, - [$customerNumber] - ); - foreach ($associated as &$item) { - if (!isset($item['association_reason'])) { - $item['association_reason'] = 'customer:' . $customerNumber; + $associationTypes = array_values(array_diff($associationTypes, $ownOnlyTypes)); + if (!empty($associationTypes)) { + foreach ($customerNumbers as $customerNumber) { + $associated = $this->executeLexicalSearch( + $associationTypes, + [(string)$customerNumber], + [], + $ownOnlyTypes, + $ownCustomerNumber, + $permissionsCatalogAll, + $permissionsCatalogOwn, + $moduleConfigVisibility, + [$customerNumber] + ); + foreach ($associated as &$item) { + if (!isset($item['association_reason'])) { + $item['association_reason'] = 'customer:' . $customerNumber; + } + $item['score'] = max((int)$item['score'], 35); } - $item['score'] = max((int)$item['score'], 35); + $initialResults = $this->mergeResults($initialResults, $associated); } - $initialResults = $this->mergeResults($initialResults, $associated); } } } diff --git a/services/nginx/app/tests/Unit/Search/SystemSearchServiceIntentFlowTest.php b/services/nginx/app/tests/Unit/Search/SystemSearchServiceIntentFlowTest.php index fa02c08b..fc3261bd 100644 --- a/services/nginx/app/tests/Unit/Search/SystemSearchServiceIntentFlowTest.php +++ b/services/nginx/app/tests/Unit/Search/SystemSearchServiceIntentFlowTest.php @@ -385,6 +385,30 @@ it('caps AI-driven expanded terms to prevent query amplification', function (): expect($maxLen)->toBeLessThanOrEqual(64); }); +it('does not expand associations for own-only entity types', function (): void { + $parser = new FakeSystemSearchIntentParser(); + $service = new TestableSystemSearchService($parser, [ + [[ + 'entity_type' => 'customers', + 'entity_id' => '10', + 'title' => 'Acme', + 'customer_number' => 1234, + 'score' => 80, + ]], + [], + ]); + + $service->search([ + 'query' => 'acme', + 'allowed_types' => ['customers', 'orders'], + 'own_only_types' => ['orders'], + 'own_customer_number' => 4444, + 'include_associations' => true, + ]); + + expect(count($service->lexicalCalls))->toBe(1); +}); + it('expands danish discount wording into lexical discount synonyms', function (): void { $parser = new FakeSystemSearchIntentParser(); $service = new TestableSystemSearchService($parser, [[