44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
from typing import Any, Literal
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ConceptInput(BaseModel):
|
|
"""Stage 1a — input contract. Frozen interface for frontend codegen."""
|
|
|
|
parcel_geojson: dict[str, Any] = Field(
|
|
..., description="GeoJSON Polygon of the parcel (WGS84 / EPSG:4326)"
|
|
)
|
|
housing_class: Literal["econom", "comfort", "business"] = "comfort"
|
|
target_floors: int = Field(9, ge=1, le=30)
|
|
development_type: Literal["spot", "mid_rise", "high_rise"] = "mid_rise"
|
|
land_cost_rub: float | None = Field(None, description="Optional land cost for financial model")
|
|
|
|
|
|
class TEAP(BaseModel):
|
|
"""Технико-экономические показатели."""
|
|
|
|
built_area_sqm: float
|
|
total_floor_area_sqm: float
|
|
residential_area_sqm: float
|
|
apartments_count: int
|
|
density: float
|
|
parking_spaces: int
|
|
|
|
|
|
class FinancialModel(BaseModel):
|
|
revenue_rub: float
|
|
cost_rub: float
|
|
gross_margin_rub: float
|
|
irr: float
|
|
|
|
|
|
class ConceptVariant(BaseModel):
|
|
strategy: Literal["max_area", "max_insolation", "balanced"]
|
|
buildings_geojson: dict[str, Any]
|
|
teap: TEAP
|
|
financial: FinancialModel
|
|
|
|
|
|
class ConceptOutput(BaseModel):
|
|
variants: list[ConceptVariant]
|