- Two sidebar fields: 'Must include' and 'Must exclude' (comma-separated) - Must-exclude terms forwarded to eBay _nkw as -term prefixes (native eBay support) so exclusions reduce the eBay result set at the source — improves market comp quality as a side effect - Must-include applied client-side only (substring, case-insensitive) - Both applied client-side via passesFilter() for instant response without re-fetching (cache-friendly) - Exclude input has subtle red border tint (color-mix) to signal intent - Hint text: 're-search to apply to eBay' reminds user negatives need a new search to take effect at the eBay level
30 lines
1.1 KiB
Python
30 lines
1.1 KiB
Python
"""PlatformAdapter abstract base and shared types."""
|
|
from __future__ import annotations
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass, field
|
|
from typing import Optional
|
|
from app.db.models import Listing, Seller
|
|
|
|
|
|
@dataclass
|
|
class SearchFilters:
|
|
max_price: Optional[float] = None
|
|
min_price: Optional[float] = None
|
|
condition: Optional[list[str]] = field(default_factory=list)
|
|
location_radius_km: Optional[int] = None
|
|
pages: int = 1 # number of result pages to fetch (48 listings/page)
|
|
must_include: list[str] = field(default_factory=list) # client-side title filter
|
|
must_exclude: list[str] = field(default_factory=list) # forwarded to eBay -term AND client-side
|
|
|
|
|
|
class PlatformAdapter(ABC):
|
|
@abstractmethod
|
|
def search(self, query: str, filters: SearchFilters) -> list[Listing]: ...
|
|
|
|
@abstractmethod
|
|
def get_seller(self, seller_platform_id: str) -> Optional[Seller]: ...
|
|
|
|
@abstractmethod
|
|
def get_completed_sales(self, query: str) -> list[Listing]:
|
|
"""Fetch recently completed/sold listings for price comp data."""
|
|
...
|