46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
"""IO contracts for the rule-based квартирография recommender.
|
|
|
|
POST /api/v1/analytics/recommend/mix
|
|
"""
|
|
|
|
from typing import Any, Literal
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
ClassLiteral = Literal["Comfort", "Comfort+", "Business", "Elite"]
|
|
|
|
|
|
class RecommendMixInput(BaseModel):
|
|
district_name: str = Field(..., min_length=2, max_length=80)
|
|
area_total_m2: float | None = Field(default=None, ge=100, le=500_000)
|
|
target_class: ClassLiteral | None = None
|
|
months_window: int = Field(default=12, ge=3, le=36)
|
|
|
|
|
|
class RecommendBucket(BaseModel):
|
|
bucket: str
|
|
share_pct: float
|
|
deal_count: int
|
|
area_avg_m2: float
|
|
area_median_m2: float
|
|
price_median_per_m2: float
|
|
price_p25_per_m2: float
|
|
price_p75_per_m2: float
|
|
units_planned: int | None = None
|
|
revenue_planned_rub: float | None = None
|
|
|
|
|
|
class RecommendComparable(BaseModel):
|
|
obj_id: int
|
|
comm_name: str | None = None
|
|
dev_name: str | None = None
|
|
obj_class: str | None = None
|
|
flat_count: int | None = None
|
|
sold_perc: float | None = None
|
|
|
|
|
|
class RecommendMixOutput(BaseModel):
|
|
scope: dict[str, Any]
|
|
buckets: list[RecommendBucket]
|
|
summary: dict[str, Any]
|
|
comparables: list[RecommendComparable]
|