from typing import Literal from pydantic import BaseModel, Field from app.models.common import GeoJSON, Point PatternKind = Literal["omni", "sector", "file"] class AntennaPatternSpec(BaseModel): pattern: PatternKind = "omni" azimuth_deg: float = 0 tilt_deg: float = 0 gain_dbi: float = 0 beamwidth_h: float | None = Field(default=None, gt=0) beamwidth_v: float | None = Field(default=None, gt=0) pattern_file: str | None = None front_to_back_db: float = Field(default=25, ge=0) sidelobe_floor_db: float = Field(default=-30, le=0) class PatternSample(BaseModel): azimuth_deg: float elevation_deg: float gain_dbi: float class PatternResponse(BaseModel): pattern: PatternKind samples: list[PatternSample] class BeamRequest(BaseModel): origin: Point antenna: AntennaPatternSpec radius_m: float = Field(gt=0) class BeamResponse(BaseModel): geojson: GeoJSON