Files
location_service/app/schemas/property_owner_response.py
2026-02-02 23:45:28 +05:30

173 lines
4.6 KiB
Python

from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime
# -----------------------------
# Owner Response Schema
# -----------------------------
class OwnerResponse(BaseModel):
owner_id: str = Field(..., example="OWN_9001")
full_name: str = Field(..., example="Michael Anderson")
email: Optional[str] = Field(None, example="michael.anderson@email.com")
phone: Optional[str] = Field(None, example="+14155552671")
entity_type: str = Field(..., example="Individual")
mailing_address: Optional[str] = Field(
None,
example="742 Evergreen Terrace, San Diego, CA 92101"
)
credit_score_est: Optional[int] = Field(None, ge=300, le=850, example=780)
income_bracket: Optional[str] = Field(None, example="$100k+")
net_worth_est: Optional[int] = Field(None, example=1250000)
portfolio_size: Optional[int] = Field(None, example=3)
min_price_expectation: Optional[int] = Field(None, example=650000)
preferred_close_days: Optional[int] = Field(None, example=30)
urgency_score: Optional[int] = Field(None, ge=0, le=100, example=72)
is_absentee: Optional[bool] = Field(None, example=True)
willing_to_sell: Optional[bool] = Field(None, example=True)
willing_to_partner: Optional[bool] = Field(None, example=False)
# ⚠ Recommended: Do not expose in public APIs
tax_id_hash: Optional[str] = Field(
None,
example="HASHX9921",
description="Hashed tax identifier (masked)"
)
class Config:
from_attributes = True
# -----------------------------
# Property Response Schema
# -----------------------------
class PropertyResponse(BaseModel):
property_id: str = Field(..., example="PROP_1001")
internal_asset_code: str = Field(..., example="ASSET-LA-7782")
structure_type: str = Field(..., example="SingleFamily")
listing_status: str = Field(..., example="ForSale")
occupancy_status: str = Field(..., example="OwnerOccupied")
property_grade: str = Field(..., example="A")
energy_rating: Optional[str] = Field(None, example="B+")
year_built: int = Field(..., example=2006)
floors_count: int = Field(..., example=2)
bedrooms: int = Field(..., example=4)
bathrooms: int = Field(..., example=3)
total_built_sqft: int = Field(..., example=2480)
lot_size_sqft: Optional[int] = Field(None, example=6200)
garage_spaces: Optional[int] = Field(None, example=2)
purchase_price: Optional[int] = Field(None, example=590000)
expected_sale_price: Optional[int] = Field(None, example=740000)
market_value_est: Optional[int] = Field(None, example=685000)
current_rent: Optional[int] = Field(None, example=0)
rental_yield_percent: Optional[float] = Field(None, example=6.2)
vacancy_days: Optional[int] = Field(None, example=0)
tenant_present: Optional[bool] = Field(None, example=False)
# Structural / Condition
exterior_condition: Optional[str] = Field(None, example="Good")
foundation_type: Optional[str] = Field(None, example="Slab")
roof_type: Optional[str] = Field(None, example="Gable")
roof_material: Optional[str] = Field(None, example="Asphalt Shingle")
roof_condition: Optional[str] = Field(None, example="Good")
roof_pitch: Optional[str] = Field(None, example="Medium")
roof_age_years: Optional[int] = Field(None, example=7)
siding_material: Optional[str] = Field(None, example="Hardie Board")
gutter_status: Optional[str] = Field(None, example="Functional")
hvac_type: Optional[str] = Field(None, example="Central")
electric_type: Optional[str] = Field(None, example="Copper")
plumbing_type: Optional[str] = Field(None, example="PEX")
solar_installed: Optional[bool] = Field(None, example=False)
# Risk Indicators
mold_risk_level: Optional[str] = Field(None, example="Low")
termite_risk_level: Optional[str] = Field(None, example="Low")
structural_risk_level: Optional[str] = Field(None, example="Low")
fire_damage_flag: Optional[bool] = Field(None, example=False)
water_damage_flag: Optional[bool] = Field(None, example=False)
# Timestamps
created_at: Optional[datetime] = Field(
None,
example="2026-01-29T16:43:44.285Z"
)
updated_at: Optional[datetime] = Field(
None,
example="2026-01-29T16:43:44.285Z"
)
class Config:
from_attributes = True
# -----------------------------
# Final Nearest Asset Response
# -----------------------------
class NearestAssetResponse(BaseModel):
owner: OwnerResponse
property: PropertyResponse
distanceMeters: float = Field(..., example=342.55)