from commerce.models import SourceSystem from commerce.services import IngestResult, ingest_source_record from .base import SourceAdapter class AdapterRegistry: def __init__(self): self._adapters: dict[str, SourceAdapter] = {} def register(self, adapter: SourceAdapter): code = adapter.source_code.strip().lower() if not code: raise ValueError("Adapter source_code must not be empty") if code in self._adapters: raise ValueError(f"Adapter '{code}' is already registered") self._adapters[code] = adapter return adapter def get(self, source_code: str) -> SourceAdapter: try: return self._adapters[source_code.strip().lower()] except KeyError as exc: raise LookupError(f"Adapter '{source_code}' is not registered") from exc def codes(self) -> tuple[str, ...]: return tuple(sorted(self._adapters)) adapter_registry = AdapterRegistry() def sync_registered_source(source_code: str, *, entity_type: str) -> list[IngestResult]: adapter = adapter_registry.get(source_code) if entity_type not in adapter.supported_entity_types(): raise ValueError( f"Adapter '{source_code}' does not support entity type '{entity_type}'" ) source, _ = SourceSystem.objects.get_or_create( code=adapter.source_code, defaults={"name": adapter.source_name}, ) results = [] for external in adapter.iter_records(entity_type=entity_type): results.append( ingest_source_record( source=source, entity_type=external.entity_type, external_id=external.external_id, payload=external.payload, source_updated_at=external.source_updated_at, ) ) return results