from datetime import datetime, timezone from typing import Optional from sqlalchemy import Index, Integer, String, Boolean, DateTime, Text, Float from sqlalchemy.orm import mapped_column, Mapped from app.database import Base class Upstream(Base): __tablename__ = "upstreams" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String(255), nullable=False) base_url: Mapped[str] = mapped_column(String(512), nullable=False) api_prefix: Mapped[str] = mapped_column(String(128), default="/api/v1") # none | bearer | api_key | login_password auth_type: Mapped[str] = mapped_column(String(32), default="login_password") # JSON: {"email":"..","password":".."} or {"token":".."} etc. auth_config_json: Mapped[str] = mapped_column(Text, default="{}") rate_endpoint: Mapped[str] = mapped_column(String(256), default="/groups/rates") groups_endpoint: Mapped[str] = mapped_column(String(256), default="/groups/available") enabled: Mapped[bool] = mapped_column(Boolean, default=True) check_interval_seconds: Mapped[int] = mapped_column(Integer, default=600) timeout_seconds: Mapped[int] = mapped_column(Integer, default=30) # unknown | healthy | unhealthy last_status: Mapped[str] = mapped_column(String(32), default="unknown") last_checked_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True) consecutive_failures: Mapped[int] = mapped_column(Integer, default=0) # Balance tracking balance: Mapped[Optional[float]] = mapped_column(Float, nullable=True) balance_updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) balance_endpoint: Mapped[str] = mapped_column(String(256), default="") balance_response_path: Mapped[str] = mapped_column(String(256), default="") balance_divisor: Mapped[float] = mapped_column(Float, default=1.0) # Balance alert balance_alert_threshold: Mapped[Optional[float]] = mapped_column(Float, nullable=True) balance_alert_notified: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[datetime] = mapped_column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at: Mapped[datetime] = mapped_column( DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc) ) __table_args__ = ( Index("ix_upstream_enabled", "enabled"), )