""" Base de datos Supabase PostgreSQL — conexión y utilidades. """ import os from pathlib import Path from dotenv import load_dotenv env_path = Path(__file__).parent.parent.parent / ".env" load_dotenv(dotenv_path=env_path, override=True) SUPABASE_URL = os.getenv("SUPABASE_URL") SUPABASE_KEY = os.getenv("SUPABASE_ANON_KEY") if not SUPABASE_URL or not SUPABASE_KEY: raise ValueError("Missing SUPABASE_URL or SUPABASE_ANON_KEY in .env file") try: from supabase import create_client, Client supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY) except Exception as e: print(f"[WARNING] Supabase sync client failed: {e}. Using mock client for now.") import uuid class MockResponse: def __init__(self, data=None): self.data = data or [] class MockTable: def __init__(self): self.data = {} self.mode = None def select(self, *args): self.mode = "select" return self def insert(self, data): self.data = data self.mode = "insert" return self def eq(self, field, value): self.mode = "eq" self.filter_field = field self.filter_value = value return self def execute(self): if self.mode == "insert": row = {**self.data, "id": str(uuid.uuid4())} return MockResponse([row]) return MockResponse([]) class MockClient: def table(self, name): return MockTable() supabase = MockClient() def get_db() -> Client: """Retorna cliente Supabase.""" return supabase def get_connection() -> Client: """Alias for get_db for backwards compatibility.""" return get_db() async def init_db() -> None: """ Inicializa BD. En Supabase, tablas ya existen en el schema_supabase.sql. Esta función valida conexión y seed data si es necesario. """ try: # Valida conexión leyendo rutas result = supabase.table("rutas").select("id").eq("id", "RUTA-01").execute() if not result.data: # Seed data si no existe _seed_datos_demo() print("[OK] BD Supabase inicializada") except Exception as e: print(f"[ERROR] Error inicializacion BD: {e}") raise def _seed_datos_demo() -> None: """Inserta datos demo si no existen.""" try: # Rutas supabase.table("rutas").insert({ "id": "RUTA-01", "nombre": "Ruta 01 — Sector Centro", "turno": "mañana" }).execute() # Puntos ruta puntos = [ {"ruta_id": "RUTA-01", "orden": 1, "nombre": "Estación Central", "lat": 20.5238, "lng": -100.8143, "tiempo_estimado_min": 0}, {"ruta_id": "RUTA-01", "orden": 2, "nombre": "Col. Independencia", "lat": 20.5255, "lng": -100.8090, "tiempo_estimado_min": 8}, {"ruta_id": "RUTA-01", "orden": 3, "nombre": "Blvd. A. López Mateos", "lat": 20.5271, "lng": -100.8021, "tiempo_estimado_min": 18}, {"ruta_id": "RUTA-01", "orden": 4, "nombre": "Col. Jardines del Bosque", "lat": 20.5290, "lng": -100.7965, "tiempo_estimado_min": 28}, {"ruta_id": "RUTA-01", "orden": 5, "nombre": "Mercado Hidalgo", "lat": 20.5310, "lng": -100.7910, "tiempo_estimado_min": 38}, ] for punto in puntos: supabase.table("puntos_ruta").insert(punto).execute() # Truck status supabase.table("truck_status").insert({ "route_id": "RUTA-01", "current_position_id": 1, "status": "EN_RUTA" }).execute() # Notification templates templates = [ {"trigger_event": "ruta_iniciada", "title": "Ruta iniciada", "body": "El camión ha comenzado su ruta. Prepárate."}, {"trigger_event": "aproximandose", "title": "¡Camión cerca!", "body": "El camión llega en ~{eta} minutos. Saca tu basura."}, {"trigger_event": "falla_mecanica", "title": "Aviso de servicio", "body": "El camión reportó una falla. Te notificaremos cuando se reanude."}, {"trigger_event": "ruta_tarde", "title": "Cambio de horario", "body": "El camión de la mañana pasará en el turno de la tarde."}, {"trigger_event": "completado", "title": "Ruta completada", "body": "El camión completó su paso por tu zona. ¡Hasta mañana!"}, ] for template in templates: try: supabase.table("notification_templates").insert(template).execute() except: pass # Ignorar duplicados print("[OK] Datos demo insertados") except Exception as e: print(f"[ERROR] Error seed data: {e}")