fix: validate Google Places search results against company name
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

Previously search_place() blindly returned the first result, which
could be a completely unrelated business. Now validates that at least
one significant word from the company name appears in the Google
result before accepting it. Prevents wrong GBP profiles being linked
to companies (e.g. Rozsadni Bracia getting Zielony Zolwik's profile).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-02-20 20:45:29 +01:00
parent 2c5e7d32df
commit 9029c3641e
2 changed files with 25 additions and 5 deletions

View File

@ -1780,7 +1780,7 @@ def fetch_google_business_data(
# Use Wejherowo coordinates as location bias (most companies are local)
location_bias = {'latitude': 54.6059, 'longitude': 18.2350, 'radius': 50000.0}
place_result = places_service.search_place(search_query, location_bias=location_bias)
place_result = places_service.search_place(search_query, location_bias=location_bias, company_name=company.name)
if not place_result:
result['steps'][-1]['status'] = 'warning'

View File

@ -136,16 +136,19 @@ class GooglePlacesService:
logger.error(f"Places API request error for {place_id}: {e}")
return None
def search_place(self, query: str, location_bias: Dict = None) -> Optional[Dict[str, Any]]:
def search_place(self, query: str, location_bias: Dict = None,
company_name: str = None) -> Optional[Dict[str, Any]]:
"""
Search for a place by text query.
Args:
query: Search text (e.g., "TERMO Wejherowo")
location_bias: Optional location bias {"latitude": 54.6, "longitude": 18.2, "radius": 5000}
company_name: Optional company name for result validation.
If provided, verifies the result name matches before returning.
Returns:
First matching place or None
Best matching place or None
"""
body = {
"textQuery": query,
@ -175,9 +178,26 @@ class GooglePlacesService:
response.raise_for_status()
data = response.json()
places = data.get('places', [])
if places:
if not places:
logger.warning(f"No places found for query: {query}")
return None
if not company_name:
return places[0]
logger.warning(f"No places found for query: {query}")
# Validate: at least one significant word from company name must appear in result name
skip_words = {'sp', 'z', 'o', 'oo', 'sa', 'sc', 'j', 'k', 'ul', 'i', 'w', 'do', 'na', 'po', 'ze'}
name_words = {w.lower() for w in company_name.split() if len(w) > 1 and w.lower() not in skip_words}
for place in places:
google_name = place.get('displayName', {}).get('text', '').lower()
if any(word in google_name for word in name_words):
return place
logger.warning(
f"No name match for '{company_name}' in Google results: "
f"{[p.get('displayName', {}).get('text', '') for p in places]}"
)
return None
except requests.exceptions.RequestException as e:
logger.error(f"Places search error for '{query}': {e}")