""" Entidades del dominio — sin dependencias externas. Alineadas con el esquema de Persona A. """ from dataclasses import dataclass, field from datetime import datetime from enum import Enum from typing import Optional class EstadoCamion(str, Enum): EN_RUTA = "EN_RUTA" APROXIMANDOSE = "APROXIMANDOSE" COMPLETADO = "COMPLETADO" AVERIADA = "AVERIADA" # truck_status: AVERIADA RETRASADA = "RETRASADA" # truck_status: RETRASADA class TipoNotificacion(str, Enum): RUTA_INICIADA = "ruta_iniciada" APROXIMANDOSE = "aproximandose" COMPLETADO = "completado" FALLA_MECANICA = "falla_mecanica" RUTA_TARDE = "ruta_tarde" @dataclass class Coordenada: lat: float lng: float @dataclass class PuntoRuta: orden: int # == current_position_id en truck_status nombre: str coordenada: Coordenada tiempo_estimado_min: int @dataclass class Ruta: id: str # ej. "RUTA-01" nombre: str puntos: list[PuntoRuta] = field(default_factory=list) turno: str = "mañana" @dataclass class TruckStatus: """Espejo directo de la tabla truck_status de Persona A.""" route_id: str current_position_id: int last_update: datetime status: EstadoCamion @dataclass class NotificationPreferences: """Preferencias del usuario — leídas antes de cada notificación.""" user_id: int notify_proximity: bool = True notify_breakdown: bool = True notify_delay: bool = True notify_route_start: bool = True @dataclass class ETAResult: """Lo que ve el ciudadano — sin coordenadas, sin índice de waypoint.""" address_id: int route_id: str status: str eta_minutos: Optional[int] ventana_inicio: Optional[str] # ej. "7:20 pm" ventana_fin: Optional[str] # ej. "7:35 pm" mensaje: str