from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime # --------------------------------------------------------------------------- # Nodes # --------------------------------------------------------------------------- class NodeRecord(BaseModel): node_id: str name: str lat: float = 0.0 lon: float = 0.0 status: str = "offline" # online / offline / recording / unconfigured configured: bool = False last_seen: Optional[datetime] = None assigned_system_id: Optional[str] = None class CommandPayload(BaseModel): action: str # discord_join / discord_leave / op25_restart guild_id: Optional[str] = None channel_id: Optional[str] = None # --------------------------------------------------------------------------- # Systems # --------------------------------------------------------------------------- class SystemRecord(BaseModel): system_id: str name: str type: str # P25 / DMR / NBFM config: Dict[str, Any] = {} # OP25-compatible config blob class SystemCreate(BaseModel): name: str type: str config: Dict[str, Any] = {} # --------------------------------------------------------------------------- # Calls # --------------------------------------------------------------------------- class CallRecord(BaseModel): call_id: str node_id: str system_id: Optional[str] = None talkgroup_id: Optional[int] = None talkgroup_name: Optional[str] = None freq: Optional[float] = None srcaddr: Optional[str] = None started_at: datetime ended_at: Optional[datetime] = None audio_url: Optional[str] = None transcript: Optional[str] = None # populated later by STT incident_id: Optional[str] = None # populated later by intelligence layer location: Optional[Dict[str, float]] = None # {lat, lng} tags: List[str] = [] status: str = "active" # active / ended # --------------------------------------------------------------------------- # Incidents # --------------------------------------------------------------------------- class IncidentRecord(BaseModel): incident_id: str title: Optional[str] = None type: Optional[str] = None # fire / police / ems / etc. status: str = "active" # active / resolved location: Optional[Dict[str, float]] = None call_ids: List[str] = [] started_at: datetime updated_at: datetime summary: Optional[str] = None tags: List[str] = []