"""The contract every search backend implements.""" from __future__ import annotations from abc import ABC, abstractmethod from apps.search.types import SearchRequest, SearchResult class SearchBackend(ABC): """ Strategy interface for keyword search. Two implementations ship with the project: * :class:`apps.search.backends.elastic.ElasticsearchBackend` - the default, used in every environment that runs the ELK stack. * :class:`apps.search.backends.postgres.PostgresBackend` - a full-text fallback that keeps the API (and the test suite) working without any external search service. Keeping the surface this small is deliberate: the views, the serializers and the frontend are completely unaware of which engine answered the query. """ #: Human readable identifier, surfaced in the API response and health check. name: str = "base" @abstractmethod def search(self, request: SearchRequest) -> SearchResult: """Execute a search and return ranked hits plus facet counts.""" @abstractmethod def suggest(self, prefix: str, limit: int = 8) -> list[str]: """Return type-ahead completions for a partial name or skill.""" @abstractmethod def ping(self) -> bool: """Raise or return ``False`` when the backend is not usable."""