Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions backend/app/api/v1/endpoints/artisan.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ async def get_nearby_artisans(
radius_km: float = Query(
25.0, ge=0, le=200, description="Search radius in kilometers"
),
skill: str
| None = Query(None, description="Filter by skill keyword (e.g., plumber)"),
min_rating: float
| None = Query(None, ge=0, le=5, description="Minimum average rating"),
available: bool | None = Query(None, description="Filter by current availability"),
specialties: list[str] | None = Query(None, description="Filter by skills"),
min_rating: float | None = Query(None, ge=0, le=5, description="Min rating"),
max_price: float | None = Query(None, ge=0, description="Max hourly rate"),
min_experience: int | None = Query(None, ge=0, description="Min experience"),
available: bool | None = Query(None, description="Filter by availability"),
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1, le=100),
):
Expand All @@ -97,8 +97,10 @@ async def get_nearby_artisans(
latitude=lat,
longitude=lon,
radius_km=radius_km,
specialties=[skill] if skill else None,
specialties=specialties,
min_rating=min_rating,
max_price=max_price,
min_experience=min_experience,
is_available=available if available is not None else True,
limit=page_size * page, # Fetch enough for pagination
)
Expand Down Expand Up @@ -465,6 +467,8 @@ def list_artisans(
limit: int = Query(20, ge=1, le=100),
specialties: list[str] | None = Query(None),
min_rating: float | None = Query(None, ge=0, le=5),
max_price: float | None = Query(None, ge=0),
min_experience: int | None = Query(None, ge=0),
is_available: bool | None = Query(None),
has_location: bool | None = Query(None),
):
Expand All @@ -475,6 +479,8 @@ def list_artisans(
limit=limit,
specialties=specialties,
min_rating=min_rating,
max_price=max_price,
min_experience=min_experience,
is_available=is_available,
has_location=has_location,
)
Expand Down
6 changes: 6 additions & 0 deletions backend/app/schemas/artisan.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ class NearbyArtisansRequest(BaseModel):
min_rating: float | None = Field(
None, ge=0, le=5, description="Minimum rating filter"
)
max_price: float | None = Field(
None, ge=0, description="Maximum hourly rate filter"
)
min_experience: int | None = Field(
None, ge=0, description="Minimum experience years filter"
)
is_available: bool | None = Field(True, description="Filter by availability")
limit: int | None = Field(20, ge=1, le=100, description="Maximum number of results")

Expand Down
14 changes: 14 additions & 0 deletions backend/app/services/artisan.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ def list_artisans(
limit: int = 100,
specialties: list[str] | None = None,
min_rating: float | None = None,
max_price: float | None = None,
min_experience: int | None = None,
is_available: bool | None = None,
has_location: bool | None = None,
) -> list[Artisan]:
Expand All @@ -179,6 +181,12 @@ def list_artisans(
if min_rating is not None:
query = query.filter(Artisan.rating >= min_rating)

if max_price is not None:
query = query.filter(Artisan.hourly_rate <= max_price)

if min_experience is not None:
query = query.filter(Artisan.experience_years >= min_experience)

if is_available is not None:
query = query.filter(Artisan.is_available == is_available)

Expand Down Expand Up @@ -231,6 +239,12 @@ async def find_nearby_artisans(self, request: NearbyArtisansRequest) -> dict:
if request.min_rating is not None:
query = query.filter(Artisan.rating >= request.min_rating)

if request.max_price is not None:
query = query.filter(Artisan.hourly_rate <= request.max_price)

if request.min_experience is not None:
query = query.filter(Artisan.experience_years >= request.min_experience)

if request.is_available is not None:
query = query.filter(Artisan.is_available == request.is_available)

Expand Down
2 changes: 2 additions & 0 deletions backend/app/services/artisan_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def _build_cache_key(request: NearbyArtisansRequest) -> str:
"radius": request.radius_km,
"specialties": sorted(request.specialties or []), # order-independent
"min_rating": request.min_rating,
"max_price": request.max_price,
"min_experience": request.min_experience,
"available": request.is_available,
"limit": request.limit,
}
Expand Down
Loading
Loading