"""Pydantic schemas for API request/response models.""" from datetime import datetime from pydantic import BaseModel class ListingResponse(BaseModel): """Funda listing combined with its ELO rating data.""" global_id: str tiny_id: str | None = None url: str | None = None title: str | None = None city: str | None = None postcode: str | None = None province: str | None = None neighbourhood: str | None = None municipality: str | None = None latitude: float | None = None longitude: float | None = None object_type: str | None = None house_type: str | None = None offering_type: str | None = None construction_type: str | None = None construction_year: str | None = None energy_label: str | None = None living_area: int | None = None plot_area: int | None = None bedrooms: int | None = None rooms: int | None = None has_garden: bool | None = None has_balcony: bool | None = None has_solar_panels: bool | None = None has_heat_pump: bool | None = None has_roof_terrace: bool | None = None is_energy_efficient: bool | None = None is_monument: bool | None = None current_price: int | None = None status: str | None = None price_per_sqm: float | None = None publication_date: str | None = None elo_rating: float comparison_count: int wins: int losses: int class MatchupResponse(BaseModel): """A pair of listings to compare.""" listing_a: ListingResponse listing_b: ListingResponse class CompareRequest(BaseModel): """Submit the result of a pairwise comparison.""" winner_id: str loser_id: str class CompareResponse(BaseModel): """Result of a comparison submission with ELO changes.""" winner_id: str loser_id: str elo_change: float new_winner_elo: float new_loser_elo: float class RankingResponse(BaseModel): """A listing with its rank position.""" rank: int listing: ListingResponse class ComparisonHistoryItem(BaseModel): """A single historical comparison record.""" id: int listing_a_title: str | None listing_b_title: str | None winner_title: str | None listing_a_id: str listing_b_id: str winner_id: str elo_a_before: float elo_b_before: float elo_a_after: float elo_b_after: float created_at: datetime class StatsResponse(BaseModel): """Overall statistics about comparisons and ratings.""" total_comparisons: int total_rated_listings: int total_listings: int avg_elo: float | None max_elo: float | None min_elo: float | None elo_distribution: list[dict] recent_comparisons: list[ComparisonHistoryItem]