import uuid from urllib.parse import urlparse from repositories.pocketbase_client import pb_client from repositories.repo_config import USE_MOCK_REPOSITORIES COLLECTION = 'competitors' def _extract_domain(url): """Strips scheme/path/www from a URL down to a bare domain for dedup comparisons.""" netloc = urlparse(url if '://' in url else f'//{url}').netloc or url return netloc.lower().lstrip('www.') class CompetitorRepository: """Data access for the `competitors` collection.""" def get_by_domain(self, tenant_id, domain): """Used by CSV bulk import to skip duplicate competitors within a tenant.""" candidates = pb_client.list(COLLECTION, filter_str=f'tenant_id = "{tenant_id}"', per_page=200) return next((c for c in candidates if _extract_domain(c.get('website', '')) == domain), None) def get_by_id(self, competitor_id): return pb_client.get_one(COLLECTION, competitor_id) def list_for_tenant(self, tenant_id, active_only=True): """Returns a tenant's competitors, active-only by default.""" filter_str = f'tenant_id = "{tenant_id}"' if active_only: filter_str += ' && active = true' return pb_client.list(COLLECTION, filter_str=filter_str, per_page=200) def create(self, data): return pb_client.create(COLLECTION, data) def update(self, competitor_id, data): return pb_client.update(COLLECTION, competitor_id, data) class MockCompetitorRepository: """In-memory stand-in for CompetitorRepository.""" def __init__(self): self._records = {} def get_by_domain(self, tenant_id, domain): return next(( r for r in self._records.values() if r.get('tenant_id') == tenant_id and _extract_domain(r.get('website', '')) == domain ), None) def get_by_id(self, competitor_id): return self._records.get(competitor_id) def list_for_tenant(self, tenant_id, active_only=True): return [ r for r in self._records.values() if r.get('tenant_id') == tenant_id and (not active_only or r.get('active')) ] def create(self, data): record_id = data.get('id') or str(uuid.uuid4()) record = {'id': record_id, 'active': True, 'change_detected': False, **data} self._records[record_id] = record return record def update(self, competitor_id, data): if competitor_id not in self._records: return None self._records[competitor_id] = {**self._records[competitor_id], **data} return self._records[competitor_id] competitor_repository = MockCompetitorRepository() if USE_MOCK_REPOSITORIES else CompetitorRepository()